From 54e535d57d04ae0f3e7f6f62eeae90254eaf67da Mon Sep 17 00:00:00 2001 From: Harshith Mullapudi Date: Tue, 8 Jul 2025 22:41:00 +0530 Subject: [PATCH] Feat: v2 (#12) * Feat: v2 * feat: add chat functionality * First cut: integrations * Feat: add conversation API * Enhance conversation handling and memory management * Feat: added conversation --------- Co-authored-by: Manoj K --- .env.example | 4 +- .gitignore | 9 +- LICENSE | 57 +- .../llm-error-2025-07-08T14-35-41.438Z.json | 1 + .../llm-error-2025-07-08T14-35-57.972Z.json | 1 + .../llm-error-2025-07-08T14-36-35.479Z.json | 1 + .../llm-error-2025-07-08T14-37-12.989Z.json | 1 + .../llm-error-2025-07-08T14-37-50.503Z.json | 1 + .../llm-error-2025-07-08T14-38-28.011Z.json | 1 + apps/webapp/.gitignore | 2 + apps/webapp/app/components/ErrorDisplay.tsx | 2 +- .../conversation/conversation-item.client.tsx | 61 + .../conversation/conversation-list.tsx | 245 + .../conversation-textarea.client.tsx | 175 + .../conversation/conversation.client.tsx | 151 + .../app/components/conversation/index.ts | 5 + .../streaming-conversation.client.tsx | 106 + .../conversation/use-trigger-stream.tsx | 103 + .../app/components/graph/graph-client.tsx | 20 + .../app/components/graph/graph-popover.tsx | 2 +- .../components/graph/graph-visualization.tsx | 4 +- apps/webapp/app/components/graph/graph.tsx | 1174 +--- .../app/components/graph/node-colors.ts | 50 +- .../layout/{AppLayout.tsx => app-layout.tsx} | 0 ...inPageLayout.tsx => login-page-layout.tsx} | 10 +- apps/webapp/app/components/logo/core.svg | 42 + apps/webapp/app/components/logo/logo.tsx | 287 +- .../app/components/sidebar/app-sidebar.tsx | 37 +- .../app/components/sidebar/nav-main.tsx | 6 +- .../app/components/sidebar/nav-user.tsx | 35 +- apps/webapp/app/components/ui/header.tsx | 32 + apps/webapp/app/components/ui/sheet.tsx | 2 +- apps/webapp/app/components/ui/sidebar.tsx | 11 +- .../webapp/app/components/use-auto-scroll.tsx | 169 + apps/webapp/app/env.server.ts | 5 + apps/webapp/app/models/workspace.server.ts | 3 +- apps/webapp/app/root.tsx | 6 +- apps/webapp/app/routes/api.v1.add.tsx | 21 + ...i.v1.conversation.$conversationId.read.tsx | 39 + ...pi.v1.conversation.$conversationId.run.tsx | 44 + ...i.v1.conversation.$conversationId.stop.tsx | 41 + .../api.v1.conversation.$conversationId.tsx | 50 + .../app/routes/api.v1.conversation._index.tsx | 37 + .../app/routes/api.v1.conversations.tsx | 41 + .../webapp/app/routes/api.v1.oauth._index.tsx | 32 + .../app/routes/api.v1.oauth.callback.tsx | 21 + apps/webapp/app/routes/api.v1.search.tsx | 50 + .../app/routes/confirm-basic-details.tsx | 30 +- .../home.conversation.$conversationId.tsx | 187 + .../app/routes/home.conversation._index.tsx | 72 + apps/webapp/app/routes/home.dashboard.tsx | 74 +- apps/webapp/app/routes/home.tsx | 16 +- apps/webapp/app/routes/ingest.tsx | 3 + apps/webapp/app/routes/login._index.tsx | 2 +- apps/webapp/app/routes/login.magic.tsx | 2 +- apps/webapp/app/routes/reingest.tsx | 384 +- apps/webapp/app/routes/search.tsx | 3 + .../routes/{home.api.tsx => settings.api.tsx} | 2 +- .../{home.logs.tsx => settings.logs.tsx} | 0 apps/webapp/app/routes/settings.tsx | 112 + apps/webapp/app/services/apiAuth.server.ts | 5 +- .../app/services/conversation.server.ts | 361 ++ apps/webapp/app/services/email.server.ts | 2 - .../webapp/app/services/integration.server.ts | 88 + .../services/integrationDefinition.server.ts | 24 + .../app/services/knowledgeGraph.server.ts | 4 +- .../app/services/oauth/oauth-utils.server.ts | 155 + .../webapp/app/services/oauth/oauth.server.ts | 245 + .../services/personalAccessToken.server.ts | 54 +- apps/webapp/app/services/postAuth.server.ts | 9 +- apps/webapp/app/services/session.server.ts | 12 +- apps/webapp/app/tailwind.css | 49 +- apps/webapp/app/trigger/.gitkeep | 0 apps/webapp/app/trigger/chat/chat-utils.ts | 561 ++ apps/webapp/app/trigger/chat/chat.ts | 136 + apps/webapp/app/trigger/chat/memory-utils.ts | 50 + apps/webapp/app/trigger/chat/prompt.ts | 131 + apps/webapp/app/trigger/chat/stream-utils.ts | 264 + apps/webapp/app/trigger/chat/types.ts | 46 + .../conversation/create-conversation-title.ts | 62 + .../webapp/app/trigger/conversation/prompt.ts | 28 + .../integrations/integration-run-schedule.ts | 38 + .../trigger/integrations/integration-run.ts | 87 + .../app/trigger/integrations/scheduler.ts | 64 + apps/webapp/app/trigger/utils/mcp.ts | 151 + apps/webapp/app/trigger/utils/stdio.ts | 256 + apps/webapp/app/trigger/utils/types.ts | 123 + apps/webapp/app/trigger/utils/utils.ts | 544 ++ apps/webapp/package.json | 49 +- apps/webapp/prisma/schema.prisma | 378 ++ apps/webapp/trigger.config.ts | 38 + apps/webapp/tsconfig.json | 4 +- apps/webapp/vite.config.ts | 8 +- core/types/package.json | 21 + core/types/src/index.ts | 1 + core/types/src/integration.ts | 64 + core/types/tsconfig.json | 18 + {docker => docker-build}/Dockerfile | 0 {docker => docker-build}/docker-compose.yaml | 0 .../scripts/entrypoint.sh | 0 .../scripts/wait-for-it.sh | 0 docker-compose.yaml | 2 +- integrations/slack/.gitignore | 2 + integrations/slack/.prettierrc | 22 + integrations/slack/eslint.config.js | 81 + integrations/slack/package.json | 71 + integrations/slack/pnpm-lock.yaml | 5101 +++++++++++++++++ integrations/slack/spec.json | 41 + integrations/slack/src/account-create.ts | 27 + .../slack/src/common/IntegrationCLI.ts | 186 + integrations/slack/src/common/README.md | 65 + integrations/slack/src/create-activity.ts | 131 + integrations/slack/src/index.ts | 91 + integrations/slack/src/utils.ts | 32 + integrations/slack/tsconfig.json | 38 + integrations/slack/tsup.config.ts | 20 + package.json | 3 +- .../20250706093221_add_activity/migration.sql | 119 + .../migration.sql | 5 + .../migration.sql | 70 + packages/database/prisma/schema.prisma | 442 +- packages/sdk/.eslintrc.js | 9 + packages/sdk/.prettierrc.json | 4 + packages/sdk/package.json | 49 + packages/sdk/src/index.ts | 1 + packages/sdk/tsconfig.json | 38 + packages/sdk/tsup.config.ts | 22 + packages/types/package.json | 4 +- .../conversation-execution.entity.ts | 19 + .../src/conversation-execution-step/index.ts | 1 + packages/types/src/index.ts | 4 + packages/types/src/integration.ts | 70 + packages/types/src/oauth/index.ts | 1 + packages/types/src/oauth/params.ts | 25 + packages/types/src/user/index.ts | 5 + packages/types/tsconfig.json | 5 +- pnpm-lock.yaml | 3438 ++++++++++- pnpm-workspace.yaml | 1 + trigger/.env.example | 138 + trigger/docker-compose.yaml | 262 + turbo.json | 11 +- 141 files changed, 17371 insertions(+), 1499 deletions(-) create mode 100644 apps/logs/errors/llm-error-2025-07-08T14-35-41.438Z.json create mode 100644 apps/logs/errors/llm-error-2025-07-08T14-35-57.972Z.json create mode 100644 apps/logs/errors/llm-error-2025-07-08T14-36-35.479Z.json create mode 100644 apps/logs/errors/llm-error-2025-07-08T14-37-12.989Z.json create mode 100644 apps/logs/errors/llm-error-2025-07-08T14-37-50.503Z.json create mode 100644 apps/logs/errors/llm-error-2025-07-08T14-38-28.011Z.json create mode 100644 apps/webapp/app/components/conversation/conversation-item.client.tsx create mode 100644 apps/webapp/app/components/conversation/conversation-list.tsx create mode 100644 apps/webapp/app/components/conversation/conversation-textarea.client.tsx create mode 100644 apps/webapp/app/components/conversation/conversation.client.tsx create mode 100644 apps/webapp/app/components/conversation/index.ts create mode 100644 apps/webapp/app/components/conversation/streaming-conversation.client.tsx create mode 100644 apps/webapp/app/components/conversation/use-trigger-stream.tsx create mode 100644 apps/webapp/app/components/graph/graph-client.tsx rename apps/webapp/app/components/layout/{AppLayout.tsx => app-layout.tsx} (100%) rename apps/webapp/app/components/layout/{LoginPageLayout.tsx => login-page-layout.tsx} (66%) create mode 100644 apps/webapp/app/components/logo/core.svg create mode 100644 apps/webapp/app/components/ui/header.tsx create mode 100644 apps/webapp/app/components/use-auto-scroll.tsx create mode 100644 apps/webapp/app/routes/api.v1.add.tsx create mode 100644 apps/webapp/app/routes/api.v1.conversation.$conversationId.read.tsx create mode 100644 apps/webapp/app/routes/api.v1.conversation.$conversationId.run.tsx create mode 100644 apps/webapp/app/routes/api.v1.conversation.$conversationId.stop.tsx create mode 100644 apps/webapp/app/routes/api.v1.conversation.$conversationId.tsx create mode 100644 apps/webapp/app/routes/api.v1.conversation._index.tsx create mode 100644 apps/webapp/app/routes/api.v1.conversations.tsx create mode 100644 apps/webapp/app/routes/api.v1.oauth._index.tsx create mode 100644 apps/webapp/app/routes/api.v1.oauth.callback.tsx create mode 100644 apps/webapp/app/routes/api.v1.search.tsx create mode 100644 apps/webapp/app/routes/home.conversation.$conversationId.tsx create mode 100644 apps/webapp/app/routes/home.conversation._index.tsx rename apps/webapp/app/routes/{home.api.tsx => settings.api.tsx} (98%) rename apps/webapp/app/routes/{home.logs.tsx => settings.logs.tsx} (100%) create mode 100644 apps/webapp/app/routes/settings.tsx create mode 100644 apps/webapp/app/services/conversation.server.ts create mode 100644 apps/webapp/app/services/integration.server.ts create mode 100644 apps/webapp/app/services/integrationDefinition.server.ts create mode 100644 apps/webapp/app/services/oauth/oauth-utils.server.ts create mode 100644 apps/webapp/app/services/oauth/oauth.server.ts create mode 100644 apps/webapp/app/trigger/.gitkeep create mode 100644 apps/webapp/app/trigger/chat/chat-utils.ts create mode 100644 apps/webapp/app/trigger/chat/chat.ts create mode 100644 apps/webapp/app/trigger/chat/memory-utils.ts create mode 100644 apps/webapp/app/trigger/chat/prompt.ts create mode 100644 apps/webapp/app/trigger/chat/stream-utils.ts create mode 100644 apps/webapp/app/trigger/chat/types.ts create mode 100644 apps/webapp/app/trigger/conversation/create-conversation-title.ts create mode 100644 apps/webapp/app/trigger/conversation/prompt.ts create mode 100644 apps/webapp/app/trigger/integrations/integration-run-schedule.ts create mode 100644 apps/webapp/app/trigger/integrations/integration-run.ts create mode 100644 apps/webapp/app/trigger/integrations/scheduler.ts create mode 100644 apps/webapp/app/trigger/utils/mcp.ts create mode 100644 apps/webapp/app/trigger/utils/stdio.ts create mode 100644 apps/webapp/app/trigger/utils/types.ts create mode 100644 apps/webapp/app/trigger/utils/utils.ts create mode 100644 apps/webapp/prisma/schema.prisma create mode 100644 apps/webapp/trigger.config.ts create mode 100644 core/types/package.json create mode 100644 core/types/src/index.ts create mode 100644 core/types/src/integration.ts create mode 100644 core/types/tsconfig.json rename {docker => docker-build}/Dockerfile (100%) rename {docker => docker-build}/docker-compose.yaml (100%) rename {docker => docker-build}/scripts/entrypoint.sh (100%) rename {docker => docker-build}/scripts/wait-for-it.sh (100%) create mode 100644 integrations/slack/.gitignore create mode 100644 integrations/slack/.prettierrc create mode 100644 integrations/slack/eslint.config.js create mode 100644 integrations/slack/package.json create mode 100644 integrations/slack/pnpm-lock.yaml create mode 100644 integrations/slack/spec.json create mode 100644 integrations/slack/src/account-create.ts create mode 100644 integrations/slack/src/common/IntegrationCLI.ts create mode 100644 integrations/slack/src/common/README.md create mode 100644 integrations/slack/src/create-activity.ts create mode 100644 integrations/slack/src/index.ts create mode 100644 integrations/slack/src/utils.ts create mode 100644 integrations/slack/tsconfig.json create mode 100644 integrations/slack/tsup.config.ts create mode 100644 packages/database/prisma/migrations/20250706093221_add_activity/migration.sql create mode 100644 packages/database/prisma/migrations/20250707105400_add_preferences/migration.sql create mode 100644 packages/database/prisma/migrations/20250708000247_add_conversation/migration.sql create mode 100644 packages/sdk/.eslintrc.js create mode 100644 packages/sdk/.prettierrc.json create mode 100644 packages/sdk/package.json create mode 100644 packages/sdk/src/index.ts create mode 100644 packages/sdk/tsconfig.json create mode 100644 packages/sdk/tsup.config.ts create mode 100644 packages/types/src/conversation-execution-step/conversation-execution.entity.ts create mode 100644 packages/types/src/conversation-execution-step/index.ts create mode 100644 packages/types/src/integration.ts create mode 100644 packages/types/src/oauth/index.ts create mode 100644 packages/types/src/oauth/params.ts create mode 100644 packages/types/src/user/index.ts create mode 100644 trigger/.env.example create mode 100644 trigger/docker-compose.yaml diff --git a/.env.example b/.env.example index 3f9d5da..7010c91 100644 --- a/.env.example +++ b/.env.example @@ -6,7 +6,7 @@ POSTGRES_PASSWORD=docker POSTGRES_DB=core LOGIN_ORIGIN=http://localhost:3000 -DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=echo" +DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=core" # This sets the URL used for direct connections to the database and should only be needed in limited circumstances # See: https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#fields:~:text=the%20shadow%20database.-,directUrl,-No @@ -41,5 +41,5 @@ MAGIC_LINK_SECRET=27192e6432564f4788d55c15131bd5ac NEO4J_AUTH=neo4j/27192e6432564f4788d55c15131bd5ac OLLAMA_URL=http://ollama:11434 -EMBEDDING_MODEL=bge-m3 +EMBEDDING_MODEL=GPT41 MODEL=GPT41 diff --git a/.gitignore b/.gitignore index 28a42c2..790b1d6 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,11 @@ yarn-error.log* .DS_Store *.pem -docker-compose.dev.yaml \ No newline at end of file +docker-compose.dev.yaml + +clickhouse/ +.vscode/ +registry/ + +.cursor +CLAUDE.md \ No newline at end of file diff --git a/LICENSE b/LICENSE index b2c1243..c4d101f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,44 @@ -MIT License +Sol License -Copyright (c) 2024 Poozle Inc +GNU AFFERO GENERAL PUBLIC LICENSE +Version 3, 19 November 2007 -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Copyright (c) 2025 — Poozle Inc. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +Additional Terms: + +As additional permission under GNU AGPL version 3 section 7, you +may combine or link a "work that uses the Library" with a publicly +distributed version of this library to produce a combined library or +application, then distribute that combined work under the terms of +your choice, with no requirement to comply with the obligations +normally placed on you by section 4 of the GNU AGPL version 3 +(or the corresponding section of a later version of the GNU AGPL +version 3 license). + +"Commons Clause" License Condition v1.0 + +The Software is provided to you by the Licensor under the License (defined below), subject to the following condition: + +Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software. + +For purposes of the foregoing, "Sell" means practicing any or all of the rights granted to you under the License to provide the Software to third parties, for a fee or other consideration (including without limitation fees for hosting or consulting/support services related to the Software), as part of a product or service whose value derives, entirely or substantially, from the functionality of the Software. Any license notice or attribution required by the License must also include this Commons Clause License Condition notice. + +Software: All files in this repository. + +License: GNU Affero General Public License v3.0 + +Licensor: Poozle Inc. diff --git a/apps/logs/errors/llm-error-2025-07-08T14-35-41.438Z.json b/apps/logs/errors/llm-error-2025-07-08T14-35-41.438Z.json new file mode 100644 index 0000000..c7f98cf --- /dev/null +++ b/apps/logs/errors/llm-error-2025-07-08T14-35-41.438Z.json @@ -0,0 +1 @@ +{"timestamp":"2025-07-08T14:35:41.438Z","error":{"name":"AI_RetryError","reason":"maxRetriesExceeded","errors":[{"name":"AI_APICallError","cause":{"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"api.openai.com"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

[Your question with HTML formatting]

\n
\n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

[Your answer with HTML formatting]

\n
\n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

,

,

,

    ,
  • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

    [Your question with HTML formatting]

    \n
    \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

    [Your answer with HTML formatting]

    \n
    \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

    ,

    ,

    ,

      ,
    • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"api.openai.com"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

      [Your question with HTML formatting]

      \n
      \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

      [Your answer with HTML formatting]

      \n
      \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

      ,

      ,

      ,

        ,
      • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}],"lastError":{"name":"AI_APICallError","cause":{"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"api.openai.com"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

        [Your question with HTML formatting]

        \n
        \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

        [Your answer with HTML formatting]

        \n
        \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

        ,

        ,

        ,

          ,
        • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}}} \ No newline at end of file diff --git a/apps/logs/errors/llm-error-2025-07-08T14-35-57.972Z.json b/apps/logs/errors/llm-error-2025-07-08T14-35-57.972Z.json new file mode 100644 index 0000000..459094d --- /dev/null +++ b/apps/logs/errors/llm-error-2025-07-08T14-35-57.972Z.json @@ -0,0 +1 @@ +{"timestamp":"2025-07-08T14:35:57.972Z","error":{"name":"AI_RetryError","reason":"maxRetriesExceeded","errors":[{"name":"AI_APICallError","cause":{"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"api.openai.com"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

          [Your question with HTML formatting]

          \n
          \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

          [Your answer with HTML formatting]

          \n
          \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

          ,

          ,

          ,

            ,
          • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"errno":-3008,"code":"ENOTFOUND","syscall":"getaddrinfo","hostname":"api.openai.com"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

            [Your question with HTML formatting]

            \n
            \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

            [Your answer with HTML formatting]

            \n
            \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

            ,

            ,

            ,

              ,
            • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

              [Your question with HTML formatting]

              \n
              \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

              [Your answer with HTML formatting]

              \n
              \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

              ,

              ,

              ,

                ,
              • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}],"lastError":{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                [Your question with HTML formatting]

                \n
                \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                [Your answer with HTML formatting]

                \n
                \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                ,

                ,

                ,

                  ,
                • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}}} \ No newline at end of file diff --git a/apps/logs/errors/llm-error-2025-07-08T14-36-35.479Z.json b/apps/logs/errors/llm-error-2025-07-08T14-36-35.479Z.json new file mode 100644 index 0000000..6da54b5 --- /dev/null +++ b/apps/logs/errors/llm-error-2025-07-08T14-36-35.479Z.json @@ -0,0 +1 @@ +{"timestamp":"2025-07-08T14:36:35.479Z","error":{"name":"AI_RetryError","reason":"maxRetriesExceeded","errors":[{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                  [Your question with HTML formatting]

                  \n
                  \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                  [Your answer with HTML formatting]

                  \n
                  \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                  ,

                  ,

                  ,

                    ,
                  • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                    [Your question with HTML formatting]

                    \n
                    \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                    [Your answer with HTML formatting]

                    \n
                    \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                    ,

                    ,

                    ,

                      ,
                    • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                      [Your question with HTML formatting]

                      \n
                      \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                      [Your answer with HTML formatting]

                      \n
                      \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                      ,

                      ,

                      ,

                        ,
                      • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}],"lastError":{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                        [Your question with HTML formatting]

                        \n
                        \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                        [Your answer with HTML formatting]

                        \n
                        \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                        ,

                        ,

                        ,

                          ,
                        • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}}} \ No newline at end of file diff --git a/apps/logs/errors/llm-error-2025-07-08T14-37-12.989Z.json b/apps/logs/errors/llm-error-2025-07-08T14-37-12.989Z.json new file mode 100644 index 0000000..4bb41e7 --- /dev/null +++ b/apps/logs/errors/llm-error-2025-07-08T14-37-12.989Z.json @@ -0,0 +1 @@ +{"timestamp":"2025-07-08T14:37:12.989Z","error":{"name":"AI_RetryError","reason":"maxRetriesExceeded","errors":[{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                          [Your question with HTML formatting]

                          \n
                          \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                          [Your answer with HTML formatting]

                          \n
                          \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                          ,

                          ,

                          ,

                            ,
                          • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":{"type":"function","function":{"name":"core--progress_update"}},"stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                            [Your question with HTML formatting]

                            \n
                            \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                            [Your answer with HTML formatting]

                            \n
                            \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                            ,

                            ,

                            ,

                              ,
                            • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":{"type":"function","function":{"name":"core--progress_update"}},"stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                              [Your question with HTML formatting]

                              \n
                              \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                              [Your answer with HTML formatting]

                              \n
                              \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                              ,

                              ,

                              ,

                                ,
                              • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":{"type":"function","function":{"name":"core--progress_update"}},"stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}],"lastError":{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                [Your question with HTML formatting]

                                \n
                                \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                [Your answer with HTML formatting]

                                \n
                                \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                ,

                                ,

                                ,

                                  ,
                                • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":{"type":"function","function":{"name":"core--progress_update"}},"stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}}} \ No newline at end of file diff --git a/apps/logs/errors/llm-error-2025-07-08T14-37-50.503Z.json b/apps/logs/errors/llm-error-2025-07-08T14-37-50.503Z.json new file mode 100644 index 0000000..f2ae861 --- /dev/null +++ b/apps/logs/errors/llm-error-2025-07-08T14-37-50.503Z.json @@ -0,0 +1 @@ +{"timestamp":"2025-07-08T14:37:50.503Z","error":{"name":"AI_RetryError","reason":"maxRetriesExceeded","errors":[{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                  [Your question with HTML formatting]

                                  \n
                                  \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                  [Your answer with HTML formatting]

                                  \n
                                  \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                  ,

                                  ,

                                  ,

                                    ,
                                  • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                    [Your question with HTML formatting]

                                    \n
                                    \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                    [Your answer with HTML formatting]

                                    \n
                                    \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                    ,

                                    ,

                                    ,

                                      ,
                                    • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                      [Your question with HTML formatting]

                                      \n
                                      \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                      [Your answer with HTML formatting]

                                      \n
                                      \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                      ,

                                      ,

                                      ,

                                        ,
                                      • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}],"lastError":{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                        [Your question with HTML formatting]

                                        \n
                                        \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                        [Your answer with HTML formatting]

                                        \n
                                        \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                        ,

                                        ,

                                        ,

                                          ,
                                        • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}}} \ No newline at end of file diff --git a/apps/logs/errors/llm-error-2025-07-08T14-38-28.011Z.json b/apps/logs/errors/llm-error-2025-07-08T14-38-28.011Z.json new file mode 100644 index 0000000..7b6b391 --- /dev/null +++ b/apps/logs/errors/llm-error-2025-07-08T14-38-28.011Z.json @@ -0,0 +1 @@ +{"timestamp":"2025-07-08T14:38:28.011Z","error":{"name":"AI_RetryError","reason":"maxRetriesExceeded","errors":[{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                          [Your question with HTML formatting]

                                          \n
                                          \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                          [Your answer with HTML formatting]

                                          \n
                                          \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                          ,

                                          ,

                                          ,

                                            ,
                                          • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                            [Your question with HTML formatting]

                                            \n
                                            \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                            [Your answer with HTML formatting]

                                            \n
                                            \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                            ,

                                            ,

                                            ,

                                              ,
                                            • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true},{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                              [Your question with HTML formatting]

                                              \n
                                              \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                              [Your answer with HTML formatting]

                                              \n
                                              \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                              ,

                                              ,

                                              ,

                                                ,
                                              • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}],"lastError":{"name":"AI_APICallError","cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT"},"url":"https://api.openai.com/v1/chat/completions","requestBodyValues":{"model":"gpt-4.1-2025-04-14","temperature":1,"messages":[{"role":"system","content":"\nYou are a helpful AI assistant with access to user memory. Your primary capabilities are:\n\n1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions\n2. **Memory Management**: Help users store, retrieve, and organize information in their memory\n3. **Contextual Assistance**: Use memory to provide personalized and contextual responses\n\n\n- workpsaceId: 2524b89e-6cbd-4e0c-90e3-ec21134553b9\n- todayDate: 2025-07-08T14:35:24.227Z\n\n\n\n- Always check memory FIRST using core--search_memory before any other actions\n- Consider this your highest priority for EVERY interaction - as essential as breathing\n- Make memory checking your first tool call before any other operations\n\nQUERY FORMATION:\n- Write specific factual statements as queries (e.g., \"user email address\" not \"what is the user's email?\")\n- Create multiple targeted memory queries for complex requests\n\nKEY QUERY AREAS:\n- Personal context: user name, location, identity, work context\n- Project context: repositories, codebases, current work, team members\n- Task context: recent tasks, ongoing projects, deadlines, priorities\n- Integration context: GitHub repos, Slack channels, Linear projects, connected services\n- Communication patterns: email preferences, notification settings, workflow automation\n- Technical context: coding languages, frameworks, development environment\n- Collaboration context: team members, project stakeholders, meeting patterns\n- Preferences: likes, dislikes, communication style, tool preferences\n- History: previous discussions, past requests, completed work, recurring issues\n- Automation rules: user-defined workflows, triggers, automation preferences\n\nMEMORY USAGE:\n- Execute multiple memory queries in parallel rather than sequentially\n- Batch related memory queries when possible\n- Prioritize recent information over older memories\n- Create comprehensive context-aware queries based on user message/activity content\n- Extract and query SEMANTIC CONTENT, not just structural metadata\n- Parse titles, descriptions, and content for actual subject matter keywords\n- Search internal SOL tasks/conversations that may relate to the same topics\n- Query ALL relatable concepts, not just direct keywords or IDs\n- Search for similar past situations, patterns, and related work\n- Include synonyms, related terms, and contextual concepts in queries \n- Query user's historical approach to similar requests or activities\n- Search for connected projects, tasks, conversations, and collaborations\n- Retrieve workflow patterns and past decision-making context\n- Query broader domain context beyond immediate request scope\n- Remember: SOL tracks work that external tools don't - search internal content thoroughly\n- Blend memory insights naturally into responses\n- Verify you've checked relevant memory before finalizing ANY response\n\nIf memory access is unavailable, rely only on the current conversation or ask user\n\n\n\nYou have tools at your disposal to assist users:\n\nCORE PRINCIPLES:\n- Use tools only when necessary for the task at hand\n- Always check memory FIRST before making other tool calls\n- Execute multiple operations in parallel whenever possible\n- Use sequential calls only when output of one is required for input of another\n\nPARAMETER HANDLING:\n- Follow tool schemas exactly with all required parameters\n- Only use values that are:\n • Explicitly provided by the user (use EXACTLY as given)\n • Reasonably inferred from context\n • Retrieved from memory or prior tool calls\n- Never make up values for required parameters\n- Omit optional parameters unless clearly needed\n- Analyze user's descriptive terms for parameter clues\n\nTOOL SELECTION:\n- Never call tools not provided in this conversation\n- Skip tool calls for general questions you can answer directly\n- For identical operations on multiple items, use parallel tool calls\n- Default to parallel execution (3-5× faster than sequential calls)\n- You can always access external service tools by loading them with load_mcp first\n\nTOOL MENTION HANDLING:\nWhen user message contains :\n- Extract tool_name from data-id attribute\n- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS\n- If available: Load it with load_mcp and focus on addressing the request with this tool\n- If unavailable: Inform user and suggest alternatives if possible\n- For multiple tool mentions: Load all applicable tools in a single load_mcp call\n\nERROR HANDLING:\n- If a tool returns an error, try fixing parameters before retrying\n- If you can't resolve an error, explain the issue to the user\n- Consider alternative tools when primary tools are unavailable\n\n\n\nUse EXACTLY ONE of these formats for all user-facing communication:\n\nPROGRESS UPDATES - During processing:\n- Use the core--progress_update tool to keep users informed\n- Update users about what you're discovering or doing next\n- Keep messages clear and user-friendly\n- Avoid technical jargon\n\nQUESTIONS - When you need information:\n\n

                                                [Your question with HTML formatting]

                                                \n
                                                \n\n- Ask questions only when you cannot find information through memory or tools\n- Be specific about what you need to know\n- Provide context for why you're asking\n\nFINAL ANSWERS - When completing tasks:\n\n

                                                [Your answer with HTML formatting]

                                                \n
                                                \n\nCRITICAL:\n- Use ONE format per turn\n- Apply proper HTML formatting (

                                                ,

                                                ,

                                                ,

                                                  ,
                                                • , etc.)\n- Never mix communication formats\n- Keep responses clear and helpful\n\n"},{"role":"user","content":"\nHere is the user message:\n\n<p>Hello</p>\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"},{"role":"system","content":"Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n"}],"tools":[{"type":"function","function":{"name":"core--progress_update","description":"Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The progress update message to send to the user"}},"required":["message"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--search_memory","description":"Search the user's memory graph for episodes or statements based on a query","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The search query in third person perspective"},"validAt":{"type":"string","description":"The valid at time in ISO format"},"startTime":{"type":"string","description":"The start time in ISO format"},"endTime":{"type":"string","description":"The end time in ISO format"}},"required":["query"],"additionalProperties":false}}},{"type":"function","function":{"name":"core--add_memory","description":"Add information to the user's memory graph","parameters":{"type":"object","properties":{"message":{"type":"string","description":"The content/text to add to memory"}},"required":["message"],"additionalProperties":false}}}],"tool_choice":"auto","stream":true,"stream_options":{"include_usage":true}},"isRetryable":true}}} \ No newline at end of file diff --git a/apps/webapp/.gitignore b/apps/webapp/.gitignore index 80ec311..0abbe0b 100644 --- a/apps/webapp/.gitignore +++ b/apps/webapp/.gitignore @@ -3,3 +3,5 @@ node_modules /.cache /build .env + +.trigger \ No newline at end of file diff --git a/apps/webapp/app/components/ErrorDisplay.tsx b/apps/webapp/app/components/ErrorDisplay.tsx index f288cee..fc26741 100644 --- a/apps/webapp/app/components/ErrorDisplay.tsx +++ b/apps/webapp/app/components/ErrorDisplay.tsx @@ -48,7 +48,7 @@ type DisplayOptionsProps = { export function ErrorDisplay({ title, message, button }: DisplayOptionsProps) { return ( -
                                                  +
                                                  {title} {message && {message}} diff --git a/apps/webapp/app/components/conversation/conversation-item.client.tsx b/apps/webapp/app/components/conversation/conversation-item.client.tsx new file mode 100644 index 0000000..aa9ab73 --- /dev/null +++ b/apps/webapp/app/components/conversation/conversation-item.client.tsx @@ -0,0 +1,61 @@ +import { EditorContent, useEditor } from "@tiptap/react"; + +import React, { useEffect } from "react"; +import { Document } from "@tiptap/extension-document"; +import HardBreak from "@tiptap/extension-hard-break"; +import { History } from "@tiptap/extension-history"; +import { Paragraph } from "@tiptap/extension-paragraph"; +import { Text } from "@tiptap/extension-text"; +import { UserTypeEnum } from "@core/types"; +import { type ConversationHistory } from "@core/database"; +import { cn } from "~/lib/utils"; + +interface AIConversationItemProps { + conversationHistory: ConversationHistory; +} + +export const ConversationItem = ({ + conversationHistory, +}: AIConversationItemProps) => { + const isUser = + conversationHistory.userType === UserTypeEnum.User || + conversationHistory.userType === UserTypeEnum.System; + + const id = `a${conversationHistory.id.replace(/-/g, "")}`; + + const editor = useEditor({ + extensions: [ + Document, + Paragraph, + Text, + HardBreak.configure({ + keepMarks: true, + }), + ], + editable: false, + content: conversationHistory.message, + }); + + useEffect(() => { + editor?.commands.setContent(conversationHistory.message); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id, conversationHistory.message]); + + if (!conversationHistory.message) { + return null; + } + + return ( +
                                                  +
                                                  + +
                                                  +
                                                  + ); +}; diff --git a/apps/webapp/app/components/conversation/conversation-list.tsx b/apps/webapp/app/components/conversation/conversation-list.tsx new file mode 100644 index 0000000..5fc8fd6 --- /dev/null +++ b/apps/webapp/app/components/conversation/conversation-list.tsx @@ -0,0 +1,245 @@ +import { useFetcher } from "@remix-run/react"; +import { useEffect, useState, useCallback, useRef } from "react"; +import { + List, + AutoSizer, + InfiniteLoader, + type ListRowRenderer, +} from "react-virtualized"; +import { format } from "date-fns"; +import { MessageSquare, Clock } from "lucide-react"; +import { cn } from "~/lib/utils"; +import { Button } from "../ui"; + +type ConversationItem = { + id: string; + title: string | null; + createdAt: string; + updatedAt: string; + unread: boolean; + status: string; + ConversationHistory: Array<{ + id: string; + message: string; + userType: string; + createdAt: string; + }>; +}; + +type ConversationListResponse = { + conversations: ConversationItem[]; + pagination: { + page: number; + limit: number; + total: number; + totalPages: number; + hasNext: boolean; + hasPrev: boolean; + }; +}; + +export const ConversationList = ({ + currentConversationId, +}: { + currentConversationId?: string; +}) => { + const fetcher = useFetcher(); + const [conversations, setConversations] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [hasNextPage, setHasNextPage] = useState(true); + const [isLoading, setIsLoading] = useState(false); + // const [searchTerm, setSearchTerm] = useState(""); + // const searchTimeoutRef = useRef(); + + const loadMoreConversations = useCallback( + (page: number) => { + if (isLoading) return; + + setIsLoading(true); + const searchParams = new URLSearchParams({ + page: page.toString(), + limit: "25", + }); + + fetcher.load(`/api/v1/conversations?${searchParams}`, { + flushSync: true, + }); + }, + [isLoading, fetcher, currentPage], + ); + + useEffect(() => { + loadMoreConversations(1); + }, []); + + useEffect(() => { + if (fetcher.data && fetcher.state === "idle") { + setIsLoading(false); + const response = fetcher.data; + + if (currentPage === 1) { + setConversations(response.conversations); + } else { + setConversations((prev) => [...prev, ...response.conversations]); + } + + setHasNextPage(response.pagination.hasNext); + setCurrentPage(response.pagination.page); + } + }, [fetcher.data, fetcher.state, currentPage]); + + // const handleSearch = useCallback( + // (term: string) => { + // setSearchTerm(term); + // setCurrentPage(1); + // setConversations([]); + // setHasNextPage(true); + + // if (searchTimeoutRef.current) { + // clearTimeout(searchTimeoutRef.current); + // } + + // searchTimeoutRef.current = setTimeout(() => { + // loadMoreConversations(1); + // }, 300); + // }, + // [loadMoreConversations], + // ); + + const isRowLoaded = useCallback( + ({ index }: { index: number }) => { + return !!conversations[index]; + }, + [conversations], + ); + + const loadMoreRows = useCallback(() => { + if (!hasNextPage || isLoading) { + return Promise.resolve(); + } + return new Promise((resolve) => { + if (conversations.length === 25) { + const nextPage = currentPage + 1; + loadMoreConversations(nextPage); + const checkLoaded = () => { + if (!isLoading) { + resolve(); + } else { + setTimeout(checkLoaded, 100); + } + }; + checkLoaded(); + } + }); + }, [ + hasNextPage, + isLoading, + currentPage, + loadMoreConversations, + conversations, + ]); + + const rowRenderer: ListRowRenderer = useCallback( + ({ index, key, style }) => { + const conversation = conversations[index]; + + if (!conversation) { + return ( +
                                                  +
                                                  +
                                                  +
                                                  +
                                                  + ); + } + + return ( +
                                                  +
                                                  + +
                                                  +
                                                  + ); + }, + [conversations], + ); + + const rowCount = hasNextPage + ? conversations.length + 1 + : conversations.length; + + return ( +
                                                  + {/*
                                                  + handleSearch(e.target.value)} + /> +
                                                  */} + +
                                                  + + {({ onRowsRendered, registerChild }) => ( + + {({ height, width }) => ( + + )} + + )} + +
                                                  + + {isLoading && conversations.length === 0 && ( +
                                                  +
                                                  +
                                                  + + Loading conversations... + +
                                                  +
                                                  + )} +
                                                  + ); +}; diff --git a/apps/webapp/app/components/conversation/conversation-textarea.client.tsx b/apps/webapp/app/components/conversation/conversation-textarea.client.tsx new file mode 100644 index 0000000..ad7987f --- /dev/null +++ b/apps/webapp/app/components/conversation/conversation-textarea.client.tsx @@ -0,0 +1,175 @@ +import { Document } from "@tiptap/extension-document"; +import HardBreak from "@tiptap/extension-hard-break"; +import { History } from "@tiptap/extension-history"; +import { Paragraph } from "@tiptap/extension-paragraph"; +import { Text } from "@tiptap/extension-text"; +import { type Editor } from "@tiptap/react"; +import { EditorContent, Placeholder, EditorRoot } from "novel"; +import { useCallback, useState } from "react"; +import { cn } from "~/lib/utils"; +import { Button } from "../ui"; +import { Loader } from "lucide-react"; +import { Form, useSubmit } from "@remix-run/react"; + +interface ConversationTextareaProps { + defaultValue?: string; + conversationId: string; + placeholder?: string; + isLoading?: boolean; + className?: string; + onChange?: (text: string) => void; + disabled?: boolean; +} + +export function ConversationTextarea({ + defaultValue, + isLoading = false, + placeholder, + className, + conversationId, + onChange, +}: ConversationTextareaProps) { + const [text, setText] = useState(defaultValue ?? ""); + const [editor, setEditor] = useState(); + const submit = useSubmit(); + + const onUpdate = (editor: Editor) => { + setText(editor.getHTML()); + onChange && onChange(editor.getText()); + }; + + const handleSend = useCallback(() => { + if (!editor || !text) { + return; + } + + const data = isLoading + ? {} + : { message: text, title: text, conversationId }; + + submit(data as any, { + action: isLoading + ? `/home/conversation/${conversationId}` + : "/home/conversation", + method: "post", + }); + + editor?.commands.clearContent(true); + setText(""); + + editor.commands.clearContent(true); + setText(""); + }, [editor, text]); + + // Send message to API + const submitForm = useCallback( + async (e: React.FormEvent) => { + const data = isLoading + ? {} + : { message: text, title: text, conversationId }; + + submit(data as any, { + action: isLoading + ? `/home/conversation/${conversationId}` + : "/home/conversation", + method: "post", + }); + + editor?.commands.clearContent(true); + setText(""); + e.preventDefault(); + }, + [text, conversationId], + ); + + return ( +
                                                  submitForm(e)} + className="pt-2" + > +
                                                  + + placeholder ?? "Ask sol...", + includeChildren: true, + }), + History, + ]} + onCreate={async ({ editor }) => { + setEditor(editor); + await new Promise((resolve) => setTimeout(resolve, 100)); + editor.commands.focus("end"); + }} + onUpdate={({ editor }) => { + onUpdate(editor); + }} + shouldRerenderOnTransaction={false} + editorProps={{ + attributes: { + class: `prose prose-lg dark:prose-invert prose-headings:font-title font-default focus:outline-none max-w-full`, + }, + handleKeyDown(view, event) { + if (event.key === "Enter" && !event.shiftKey) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const target = event.target as any; + if (target.innerHTML.includes("suggestion")) { + return false; + } + event.preventDefault(); + if (text) { + handleSend(); + } + return true; + } + + if (event.key === "Enter" && event.shiftKey) { + view.dispatch( + view.state.tr.replaceSelectionWith( + view.state.schema.nodes.hardBreak.create(), + ), + ); + return true; + } + return false; + }, + }} + immediatelyRender={false} + className={cn( + "editor-container text-md max-h-[400px] min-h-[40px] w-full min-w-full overflow-auto px-3 sm:rounded-lg", + )} + /> + +
                                                  + +
                                                  +
                                                  +
                                                  + ); +} diff --git a/apps/webapp/app/components/conversation/conversation.client.tsx b/apps/webapp/app/components/conversation/conversation.client.tsx new file mode 100644 index 0000000..19fa590 --- /dev/null +++ b/apps/webapp/app/components/conversation/conversation.client.tsx @@ -0,0 +1,151 @@ +import { EditorRoot, EditorContent, Placeholder } from "novel"; +import { useState, useRef, useCallback } from "react"; +import { Form, useNavigate, useSubmit } from "@remix-run/react"; +import { cn } from "~/lib/utils"; +import { Document } from "@tiptap/extension-document"; +import HardBreak from "@tiptap/extension-hard-break"; +import { History } from "@tiptap/extension-history"; +import { Paragraph } from "@tiptap/extension-paragraph"; +import { Text } from "@tiptap/extension-text"; +import { Button } from "../ui"; +import { + ResizableHandle, + ResizablePanel, + ResizablePanelGroup, +} from "../ui/resizable"; +import { ConversationList } from "./conversation-list"; + +export const ConversationNew = ({ + user, +}: { + user: { name: string | null }; +}) => { + const [content, setContent] = useState(""); + const editorRef = useRef(null); + + const submit = useSubmit(); + + // Send message to API + const submitForm = useCallback( + async (e: React.FormEvent) => { + if (!content.trim()) return; + + submit( + { message: content, title: content }, + { + action: "/home/conversation", + method: "post", + }, + ); + e.preventDefault(); + }, + [content], + ); + + return ( + + + + + + + +
                                                  submitForm(e)} + className="pt-2" + > +
                                                  +
                                                  +
                                                  +
                                                  +

                                                  + Hello {user.name} +

                                                  +
                                                  + + { + return "Ask sol..."; + }, + includeChildren: true, + }), + Document, + Paragraph, + Text, + HardBreak.configure({ + keepMarks: true, + }), + History, + ]} + editorProps={{ + attributes: { + class: `prose prose-lg dark:prose-invert prose-headings:font-title font-default focus:outline-none max-w-full`, + }, + handleKeyDown: (_view: any, event: KeyboardEvent) => { + // This is the ProseMirror event, not React's + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + + if (content) { + submit( + { message: content, title: content }, + { + action: "/home/conversation", + method: "post", + }, + ); + + setContent(""); + } + return true; + } + return false; + }, + }} + immediatelyRender={false} + className={cn( + "editor-container text-md max-h-[400px] min-h-[30px] w-full min-w-full overflow-auto px-3 pt-1 sm:rounded-lg", + )} + onUpdate={({ editor }: { editor: any }) => { + const html = editor.getHTML(); + setContent(html); + }} + /> + +
                                                  + +
                                                  +
                                                  +
                                                  +
                                                  +
                                                  +
                                                  +
                                                  +
                                                  +
                                                  + ); +}; diff --git a/apps/webapp/app/components/conversation/index.ts b/apps/webapp/app/components/conversation/index.ts new file mode 100644 index 0000000..09145cb --- /dev/null +++ b/apps/webapp/app/components/conversation/index.ts @@ -0,0 +1,5 @@ +export * from "./conversation.client"; +export * from "./conversation-item.client"; +export * from "./streaming-conversation.client"; +export * from "./conversation-textarea.client"; +export * from "./conversation-list"; diff --git a/apps/webapp/app/components/conversation/streaming-conversation.client.tsx b/apps/webapp/app/components/conversation/streaming-conversation.client.tsx new file mode 100644 index 0000000..c9d17f5 --- /dev/null +++ b/apps/webapp/app/components/conversation/streaming-conversation.client.tsx @@ -0,0 +1,106 @@ +import { EditorContent, useEditor } from "@tiptap/react"; +import React from "react"; +import { Document } from "@tiptap/extension-document"; +import HardBreak from "@tiptap/extension-hard-break"; +import { History } from "@tiptap/extension-history"; +import { Paragraph } from "@tiptap/extension-paragraph"; +import { Text } from "@tiptap/extension-text"; + +import { useTriggerStream } from "./use-trigger-stream"; +import { Placeholder } from "novel"; + +interface StreamingConversationProps { + runId: string; + token: string; + afterStreaming: () => void; + apiURL: string; +} + +export const StreamingConversation = ({ + runId, + token, + afterStreaming, + apiURL, +}: StreamingConversationProps) => { + const { message, isEnd } = useTriggerStream(runId, token, apiURL); + const [loadingText, setLoadingText] = React.useState("Thinking..."); + + const loadingMessages = [ + "Thinking...", + "Still thinking...", + "Deep in thought...", + "Processing at light speed...", + "Loading SOL...", + "Establishing Mars connection...", + "Consulting the Martian archives...", + "Calculating in Mars time...", + "Warming up the quantum processors...", + "Checking atmospheric conditions on Mars...", + "Untangling red planet algorithms...", + "Just need my Mars-roasted coffee...", + ]; + + const messagesEditor = useEditor({ + extensions: [ + Placeholder, + Document, + Paragraph, + Text, + HardBreak.configure({ + keepMarks: true, + }), + ], + editable: false, + content: "", + }); + + React.useEffect(() => { + if (message) { + messagesEditor?.commands.setContent(message); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [message]); + + React.useEffect(() => { + if (isEnd) { + afterStreaming(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isEnd]); + + React.useEffect(() => { + let currentIndex = 0; + let delay = 5000; // Start with 2 seconds for more thinking time + + const updateLoadingText = () => { + if (!message) { + setLoadingText(loadingMessages[currentIndex]); + currentIndex = (currentIndex + 1) % loadingMessages.length; + delay = Math.min(delay * 1.3, 8000); // Increase delay more gradually + setTimeout(updateLoadingText, delay); + } + }; + + const timer = setTimeout(updateLoadingText, delay); + + return () => clearTimeout(timer); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [message]); + + return ( +
                                                  +
                                                  +
                                                  + {message ? ( + + ) : ( +
                                                  {loadingText}
                                                  + )} +
                                                  +
                                                  +
                                                  + ); +}; diff --git a/apps/webapp/app/components/conversation/use-trigger-stream.tsx b/apps/webapp/app/components/conversation/use-trigger-stream.tsx new file mode 100644 index 0000000..1c41d4c --- /dev/null +++ b/apps/webapp/app/components/conversation/use-trigger-stream.tsx @@ -0,0 +1,103 @@ +import { useRealtimeRunWithStreams } from "@trigger.dev/react-hooks"; +import React from "react"; + +export const useTriggerStream = ( + runId: string, + token: string, + apiURL?: string, +) => { + const { error, streams, run } = useRealtimeRunWithStreams(runId, { + accessToken: token, + baseURL: apiURL ?? "https://trigger.heysol.ai", // Optional if you are using a self-hosted Trigger.dev instance + }); + + const isEnd = React.useMemo(() => { + if (error) { + return true; + } + + if ( + run && + [ + "COMPLETED", + "CANCELED", + "FAILED", + "CRASHED", + "INTERRUPTED", + "SYSTEM_FAILURE", + "EXPIRED", + "TIMED_OUT", + ].includes(run?.status) + ) { + return true; + } + + const hasStreamEnd = + streams.messages && + streams.messages.filter((item) => { + // Check if the item has a type that includes 'MESSAGE_' and is not empty + return item.type?.includes("STREAM_END"); + }); + + if (hasStreamEnd && hasStreamEnd.length > 0) { + return true; + } + + return false; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [run?.status, error, streams.messages?.length]); + + const message = React.useMemo(() => { + if (!streams?.messages) { + return ""; + } + + // Filter and combine all message chunks + return streams.messages + .filter((item) => { + // Check if the item has a type that includes 'MESSAGE_' and is not empty + return item.type?.includes("MESSAGE_"); + }) + .map((item) => item.message) + .join(""); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [streams.messages?.length]); + + const actionMessages = React.useMemo(() => { + if (!streams?.messages) { + return {}; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const messages: Record = + {}; + + streams.messages.forEach((item) => { + if (item.type?.includes("SKILL_")) { + try { + const parsed = JSON.parse(item.message); + const skillId = parsed.skillId; + + if (!messages[skillId]) { + messages[skillId] = { isStreaming: true, content: [] }; + } + + if (item.type === "SKILL_END") { + messages[skillId].isStreaming = false; + } + + messages[skillId].content.push(parsed); + } catch (e) { + console.error("Failed to parse message:", e); + } + } + }); + + return messages; + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [streams.messages?.length]); + + return { isEnd, message, actionMessages }; +}; diff --git a/apps/webapp/app/components/graph/graph-client.tsx b/apps/webapp/app/components/graph/graph-client.tsx new file mode 100644 index 0000000..40e2949 --- /dev/null +++ b/apps/webapp/app/components/graph/graph-client.tsx @@ -0,0 +1,20 @@ +import { type GraphVisualizationProps } from "./graph-visualization"; +import { useState, useEffect } from "react"; + +export function GraphVisualizationClient(props: GraphVisualizationProps) { + const [Component, setComponent] = useState(undefined); + + useEffect(() => { + if (typeof window === "undefined") return; + + import("./graph-visualization").then(({ GraphVisualization }) => { + setComponent(GraphVisualization); + }); + }, []); + + if (!Component) { + return null; + } + + return ; +} diff --git a/apps/webapp/app/components/graph/graph-popover.tsx b/apps/webapp/app/components/graph/graph-popover.tsx index 316eb63..36dd8d5 100644 --- a/apps/webapp/app/components/graph/graph-popover.tsx +++ b/apps/webapp/app/components/graph/graph-popover.tsx @@ -93,7 +93,7 @@ export function GraphPopovers({
                                                  ; } -// Add ref type for zoomToLinkById export interface GraphRef { zoomToLinkById: (linkId: string) => void; } @@ -38,7 +39,7 @@ export const Graph = forwardRef( triplets, width = 1000, height = 800, - zoomOnMount = true, + zoomOnMount = false, onNodeClick, onEdgeClick, onBlur, @@ -46,69 +47,14 @@ export const Graph = forwardRef( }, ref, ) => { - const svgRef = useRef(null); + const containerRef = useRef(null); + const sigmaRef = useRef(null); + const graphRef = useRef(null); const [themeMode] = useTheme(); - // Function refs to keep track of reset functions - const resetLinksRef = useRef<(() => void) | null>(null); - const resetNodesRef = useRef<(() => void) | null>(null); - const handleLinkClickRef = useRef< - ((event: any, d: any, relation: IdValue) => void) | null - >(null); - const simulationRef = useRef | null>(null); - const zoomRef = useRef | null>( - null, - ); const isInitializedRef = useRef(false); - - // Add ref for zoomToLinkById - const graphRef = useRef({ - zoomToLinkById: (linkId: string) => { - if ( - !svgRef.current || - !resetLinksRef.current || - !resetNodesRef.current || - !handleLinkClickRef.current - ) - return; - const svgElement = d3.select(svgRef.current); - const linkGroups = svgElement.selectAll("g > g"); // Select all link groups - - let found = false; - - // Iterate through link groups to find matching relation - linkGroups.each(function (d: any) { - if (found) return; // Skip if already found - - if (d?.relationData) { - const relation = d.relationData.find( - (r: IdValue) => r.id === linkId, - ); - if (relation) { - found = true; - const resetLinks = resetLinksRef.current; - const resetNodes = resetNodesRef.current; - const handleLinkClick = handleLinkClickRef.current; - - if (resetLinks) resetLinks(); - if (resetNodes) resetNodes(); - if (handleLinkClick) - handleLinkClick({ stopPropagation: () => {} }, d, relation); - } - } - }); - - if (!found) { - console.warn(`Link with id ${linkId} not found`); - } - }, - }); - - // Expose the ref through forwardRef - useImperativeHandle(ref, () => graphRef.current); + const selectedNodeRef = useRef(null); + const selectedEdgeRef = useRef(null); // Memoize theme to prevent unnecessary recreation const theme = useMemo( @@ -122,7 +68,7 @@ export const Graph = forwardRef( dimmed: colors.pink[300], }, link: { - stroke: themeMode === "dark" ? colors.slate[600] : colors.slate[400], + stroke: colors.gray[400], selected: colors.blue[400], dimmed: themeMode === "dark" ? colors.slate[800] : colors.slate[200], label: { @@ -143,19 +89,15 @@ export const Graph = forwardRef( // Extract all unique labels from triplets const allLabels = useMemo(() => { - // Only calculate if we need to create our own map if (externalLabelColorMap) return []; - const labels = new Set(); - labels.add("Entity"); // Always include Entity as default - + labels.add("Entity"); triplets.forEach((triplet) => { if (triplet.source.primaryLabel) labels.add(triplet.source.primaryLabel); if (triplet.target.primaryLabel) labels.add(triplet.target.primaryLabel); }); - return Array.from(labels); }, [triplets, externalLabelColorMap]); @@ -167,12 +109,10 @@ export const Graph = forwardRef( // Create a mapping of node IDs to their data const nodeDataMap = useMemo(() => { const result = new Map(); - triplets.forEach((triplet) => { result.set(triplet.source.id, triplet.source); result.set(triplet.target.id, triplet.target); }); - return result; }, [triplets]); @@ -182,13 +122,8 @@ export const Graph = forwardRef( if (!node) { return getNodeColorByLabel(null, themeMode === "dark", labelColorMap); } - - // Get the full node data if we only have an ID const nodeData = nodeDataMap.get(node.id) || node; - - // Extract primaryLabel from node data const primaryLabel = nodeData.primaryLabel; - return getNodeColorByLabel( primaryLabel, themeMode === "dark", @@ -198,871 +133,362 @@ export const Graph = forwardRef( [labelColorMap, nodeDataMap, themeMode], ); - // Process graph data - const { nodes, links } = useMemo(() => { - const nodes = Array.from( - new Set(triplets.flatMap((t) => [t.source.id, t.target.id])), - ).map((id) => { - const nodeData = triplets.find( - (t) => t.source.id === id || t.target.id === id, - ); - const value = nodeData - ? nodeData.source.id === id - ? nodeData.source.value - : nodeData.target.value - : id; - return { - id, - value, - }; + // Process graph data for Sigma + const { nodes, edges } = useMemo(() => { + const nodeMap = new Map(); + triplets.forEach((triplet) => { + if (!nodeMap.has(triplet.source.id)) { + nodeMap.set(triplet.source.id, { + id: triplet.source.id, + label: triplet.source.value, + size: 5, + color: getNodeColor(triplet.source), + x: width, + y: height, + nodeData: triplet.source, + }); + } + if (!nodeMap.has(triplet.target.id)) { + nodeMap.set(triplet.target.id, { + id: triplet.target.id, + label: triplet.target.value, + size: 5, + color: getNodeColor(triplet.target), + x: width, + y: height, + nodeData: triplet.target, + }); + } }); const linkGroups = triplets.reduce( (groups, triplet) => { - // Skip isolated node edges (they are just placeholders for showing isolated nodes) if (triplet.relation.type === "_isolated_node_") { return groups; } - let key = `${triplet.source.id}-${triplet.target.id}`; const reverseKey = `${triplet.target.id}-${triplet.source.id}`; - if (groups[reverseKey]) { key = reverseKey; } - if (!groups[key]) { groups[key] = { + id: key, source: triplet.source.id, target: triplet.target.id, relations: [], relationData: [], - curveStrength: 0, + label: "", + color: theme.link.stroke, + size: 1, }; } groups[key].relations.push(triplet.relation.value); groups[key].relationData.push(triplet.relation); + groups[key].label = groups[key].relations + .join(", ") + .replace("HAS_", "") + .toLowerCase(); + return groups; }, - {} as Record< - string, - { - source: string; - target: string; - relations: string[]; - relationData: IdValue[]; - curveStrength: number; - } - >, + {} as Record, ); return { - nodes, - links: Object.values(linkGroups), + nodes: Array.from(nodeMap.values()), + edges: Object.values(linkGroups), }; - }, [triplets]); + }, [triplets, getNodeColor, theme.link.stroke, width, height]); + + // Helper function to reset highlights + const resetHighlights = useCallback(() => { + if (!graphRef.current) return; + const graph = graphRef.current; + graph.forEachNode((node) => { + graph.setNodeAttribute(node, "highlighted", false); + graph.setNodeAttribute( + node, + "color", + getNodeColor(graph.getNodeAttribute(node, "nodeData")), + ); + }); + graph.forEachEdge((edge) => { + graph.setEdgeAttribute(edge, "highlighted", false); + graph.setEdgeAttribute(edge, "color", theme.link.stroke); + }); + selectedNodeRef.current = null; + selectedEdgeRef.current = null; + }, [getNodeColor, theme.link.stroke]); + + // Add ref for zoomToLinkById + const graphRefMethods = useRef({ + zoomToLinkById: (linkId: string) => { + if (!sigmaRef.current || !graphRef.current) return; + try { + const graph = graphRef.current; + const sigma = sigmaRef.current; + const edge = graph.findEdge((edgeId, attrs) => { + return attrs.relationData?.some( + (rel: IdValue) => rel.id === linkId, + ); + }); + if (edge) { + const edgeAttrs = graph.getEdgeAttributes(edge); + const source = graph.source(edge); + const target = graph.target(edge); + resetHighlights(); + graph.setEdgeAttribute(edge, "highlighted", true); + graph.setNodeAttribute(source, "highlighted", true); + graph.setNodeAttribute(target, "highlighted", true); + const relation = edgeAttrs.relationData?.find( + (rel: IdValue) => rel.id === linkId, + ); + if (relation && onEdgeClick) { + onEdgeClick(relation.id); + } + const sourcePos = sigma.getNodeDisplayData(source); + const targetPos = sigma.getNodeDisplayData(target); + if (sourcePos && targetPos) { + const centerX = (sourcePos.x + targetPos.x) / 2; + const centerY = (sourcePos.y + targetPos.y) / 2; + sigma + .getCamera() + .animate( + { x: centerX, y: centerY, ratio: 0.5 }, + { duration: 500 }, + ); + } + } else { + console.warn(`Link with id ${linkId} not found`); + } + } catch (error) { + console.error("Error in zoomToLinkById:", error); + } + }, + }); + + useImperativeHandle(ref, () => graphRefMethods.current); - // Initialize or update visualization - This will run only once on mount useEffect(() => { - // Skip if already initialized or ref not available - if (isInitializedRef.current || !svgRef.current) return; - - // Mark as initialized to prevent re-running + if (isInitializedRef.current || !containerRef.current) return; isInitializedRef.current = true; - const svgElement = d3.select(svgRef.current); - svgElement.selectAll("*").remove(); + // Create graphology graph + const graph = new GraphologyGraph(); + graphRef.current = graph; - const g = svgElement.append("g"); + // Add nodes + nodes.forEach((node) => { + graph.addNode(node.id, node); + }); - // Drag handler function - const drag = ( - simulation: d3.Simulation, - ) => { - const originalSettings = { - velocityDecay: 0.4, - alphaDecay: 0.05, - }; - - function dragstarted(event: any) { - if (!event.active) { - simulation - .velocityDecay(0.7) - .alphaDecay(0.1) - .alphaTarget(0.1) - .restart(); - } - d3.select(event.sourceEvent.target.parentNode) - .select("circle") - .attr("stroke", theme.node.hover) - .attr("stroke-width", 3); - - event.subject.fx = event.subject.x; - event.subject.fy = event.subject.y; + // Add edges + edges.forEach((edge) => { + if (graph.hasNode(edge.source) && graph.hasNode(edge.target)) { + graph.addEdge(edge.source, edge.target, { ...edge }); } + }); - function dragged(event: any) { - event.subject.x = event.x; - event.subject.y = event.y; - event.subject.fx = event.x; - event.subject.fy = event.y; - } - - function dragended(event: any) { - if (!event.active) { - simulation - .velocityDecay(originalSettings.velocityDecay) - .alphaDecay(originalSettings.alphaDecay) - .alphaTarget(0); - } - - // Keep the node fixed at its final position - event.subject.fx = event.x; - event.subject.fy = event.y; - - d3.select(event.sourceEvent.target.parentNode) - .select("circle") - .attr("stroke", theme.node.stroke) - .attr("stroke-width", 2); - } - - return d3 - .drag() - .on("start", dragstarted) - .on("drag", dragged) - .on("end", dragended); - }; - - // Setup zoom behavior - const zoom = d3 - .zoom() - .scaleExtent([0.1, 4]) - .on("zoom", (event) => { - g.attr("transform", event.transform); + // Apply layout + if (graph.order > 0) { + graph.forEachNode((node) => { + graph.setNodeAttribute(node, "x", width); + graph.setNodeAttribute(node, "y", height); }); - zoomRef.current = zoom; - // @ts-ignore - svgElement.call(zoom).call(zoom.transform, d3.zoomIdentity.scale(0.8)); + // const layout = new ForceSupervisor(graph, { + // isNodeFixed: (_, attr) => attr.highlighted, + // }); + // layout.start(); - // Identify which nodes are isolated (not in any links) - const nodeIdSet = new Set(nodes.map((n: any) => n.id)); - const linkedNodeIds = new Set(); - - links.forEach((link: any) => { - const sourceId = - typeof link.source === "string" ? link.source : link.source.id; - const targetId = - typeof link.target === "string" ? link.target : link.target.id; - linkedNodeIds.add(sourceId); - linkedNodeIds.add(targetId); - }); - - // Nodes that don't appear in any link are isolated - const isolatedNodeIds = new Set(); - nodeIdSet.forEach((nodeId: string) => { - if (!linkedNodeIds.has(nodeId)) { - isolatedNodeIds.add(nodeId); - } - }); - - // Enhanced simulation for improved aesthetics and readability - - // Parameters tuned for clear separation of clusters and minimal overlap, - // as seen in the provided image (distinct, well-separated groups). - const LINK_DISTANCE = 120; // Slightly shorter for tighter clusters - const LINK_STRENGTH = 0.6; // Stronger to keep clusters compact - const CHARGE_ISOLATED = -200; // Less repulsion for isolated nodes (keeps them closer) - const CHARGE_CONNECTED = -1000; // Strong repulsion for connected nodes (prevents crowding) - const COLLIDE_RADIUS = 32; // Smaller collision radius for less overlap - const COLLIDE_STRENGTH = 0.9; // Stronger collision to avoid overlap - const COLLIDE_ITER = 10; // More iterations for better separation - const CENTER_STRENGTH = 0.18; // Pull clusters more to center - const ISOLATED_RADIAL_DIST = 260; // Place isolated nodes further from center - const ISOLATED_RADIAL_STRENGTH = 0.28; // Stronger pull for isolated nodes - const NONISOLATED_RADIAL_STRENGTH = 0.06; // Slight pull for non-isolated - const VELOCITY_DECAY = 0.28; // Smoother, more stable layout - const ALPHA_DECAY = 0.035; - const ALPHA_MIN = 0.001; - - const simulation = d3 - .forceSimulation(nodes as d3.SimulationNodeDatum[]) - .force( - "link", - d3 - .forceLink(links) - .id((d: any) => d.id) - .distance(LINK_DISTANCE) - .strength(LINK_STRENGTH), - ) - .force( - "charge", - d3 - .forceManyBody() - .strength((d: any) => - isolatedNodeIds.has(d.id) ? CHARGE_ISOLATED : CHARGE_CONNECTED, - ) - .distanceMin(20) - .distanceMax(600) - .theta(0.9), - ) - .force( - "center", - d3.forceCenter(width / 2, height / 2).strength(CENTER_STRENGTH), - ) - .force( - "collide", - d3 - .forceCollide() - .radius(COLLIDE_RADIUS) - .strength(COLLIDE_STRENGTH) - .iterations(COLLIDE_ITER), - ) - // Special gravity for isolated nodes to keep them separated and visible - .force( - "isolatedGravity", - d3 - .forceRadial(ISOLATED_RADIAL_DIST, width / 2, height / 2) - .strength((d: any) => - isolatedNodeIds.has(d.id) - ? ISOLATED_RADIAL_STRENGTH - : NONISOLATED_RADIAL_STRENGTH, - ), - ) - .velocityDecay(VELOCITY_DECAY) - .alphaDecay(ALPHA_DECAY) - .alphaMin(ALPHA_MIN); - - simulationRef.current = simulation; - - const link = g.append("g").selectAll("g").data(links).join("g"); - - // Define reset functions - resetLinksRef.current = () => { - // @ts-ignore - link - .selectAll("path") - .attr("stroke", theme.link.stroke) - .attr("stroke-opacity", 0.6) - .attr("stroke-width", 1); - - // @ts-ignore - link.selectAll(".link-label rect").attr("fill", theme.link.label.bg); - // @ts-ignore - link.selectAll(".link-label text").attr("fill", theme.link.label.text); - }; - - // Create node groups - const node = g - .append("g") - .selectAll("g") - .data(nodes) - .join("g") - // @ts-ignore - .call(drag(simulation)) - .attr("cursor", "pointer"); - - resetNodesRef.current = () => { - // @ts-ignore - node - .selectAll("circle") - .attr("fill", (d: any) => getNodeColor(d)) - .attr("stroke", theme.node.stroke) - .attr("stroke-width", 1); - }; - - // Handle link click - handleLinkClickRef.current = (event: any, d: any, relation: IdValue) => { - if (event.stopPropagation) { - event.stopPropagation(); - } - - if (resetLinksRef.current) resetLinksRef.current(); - if (onEdgeClick) onEdgeClick(relation.id); - - // Reset all elements to default state - // @ts-ignore - link - .selectAll("path") - .attr("stroke", theme.link.stroke) - .attr("stroke-opacity", 0.6) - .attr("stroke-width", 1); - - // Reset non-highlighted nodes to their proper colors - // @ts-ignore - node - .selectAll("circle") - .attr("fill", (d: any) => getNodeColor(d)) - .attr("stroke", theme.node.stroke) - .attr("stroke-width", 1); - - // Find and highlight the corresponding path and label - const linkGroup = event.target?.closest("g") - ? d3.select(event.target.closest("g")) - : link.filter((l: any) => l === d); - - // @ts-ignore - linkGroup - // @ts-ignore - .selectAll("path") - .attr("stroke", theme.link.selected) - .attr("stroke-opacity", 1) - .attr("stroke-width", 2); - - // Update label styling - // @ts-ignore - linkGroup.select(".link-label rect").attr("fill", theme.link.selected); - // @ts-ignore - linkGroup.select(".link-label text").attr("fill", theme.node.text); - - // Highlight connected nodes - // @ts-ignore - node - .selectAll("circle") - .filter((n: any) => n.id === d.source.id || n.id === d.target.id) - .attr("fill", theme.node.selected) - .attr("stroke", theme.node.selected) - .attr("stroke-width", 2); - - const sourceNode = d.source; - const targetNode = d.target; - - // Calculate bounding box for the two connected nodes and the edge - if ( - sourceNode && - targetNode && - sourceNode.x !== undefined && - targetNode.x !== undefined - ) { - const padding = 100; // Increased padding for better view - const minX = Math.min(sourceNode.x, targetNode.x) - padding; - const minY = Math.min(sourceNode.y, targetNode.y) - padding; - const maxX = Math.max(sourceNode.x, targetNode.x) + padding; - const maxY = Math.max(sourceNode.y, targetNode.y) + padding; - - // Calculate transform to fit the connected nodes - const boundWidth = maxX - minX; - const boundHeight = maxY - minY; - const scale = - 0.9 * Math.min(width / boundWidth, height / boundHeight); - const midX = (minX + maxX) / 2; - const midY = (minY + maxY) / 2; - - if ( - isFinite(scale) && - isFinite(midX) && - isFinite(midY) && - zoomRef.current - ) { - const transform = d3.zoomIdentity - .translate(width / 2 - midX * scale, height / 2 - midY * scale) - .scale(scale); - - // Animate transition to new view - // @ts-ignore - svgElement - .transition() - .duration(750) - .ease(d3.easeCubicInOut) // Add easing for smoother transitions - .call(zoomRef.current.transform, transform); - } - } - }; - - // Create links with proper curve paths - link.each(function (d: any) { - const linkGroup = d3.select(this); - const relationCount = d.relations.length; - - // Calculate curve strengths based on number of relations - const baseStrength = 0.2; - const strengthStep = - relationCount > 1 ? baseStrength / (relationCount - 1) : 0; - - d.relations.forEach((relation: string, index: number) => { - const curveStrength = - relationCount > 1 ? -baseStrength + index * strengthStep * 2 : 0; - const fullRelation = d.relationData[index]; - - linkGroup - .append("path") - .attr("stroke", theme.link.stroke) - .attr("stroke-opacity", 0.6) - .attr("stroke-width", 1) - .attr("fill", "none") - .attr("data-curve-strength", curveStrength) - .attr("cursor", "pointer") - .attr( - "data-source", - typeof d.source === "object" ? d.source.id : d.source, - ) - .attr( - "data-target", - typeof d.target === "object" ? d.target.id : d.target, - ) - .on("click", (event) => { - if (handleLinkClickRef.current) { - handleLinkClickRef.current(event, d, fullRelation); - } - }); - - const labelGroup = linkGroup - .append("g") - .attr("class", "link-label") - .attr("cursor", "pointer") - .attr("data-curve-strength", curveStrength) - .on("click", (event) => { - if (handleLinkClickRef.current) { - handleLinkClickRef.current(event, d, fullRelation); - } - }); - - labelGroup - .append("rect") - .attr("fill", theme.link.label.bg) - .attr("rx", 4) - .attr("ry", 4) - .attr("opacity", 0.9); - - labelGroup - .append("text") - .attr("fill", theme.link.label.text) - .attr("font-size", "8px") - .attr("text-anchor", "middle") - .attr("dominant-baseline", "middle") - .attr("pointer-events", "none") - .text(relation); - - labelGroup.attr("data-curve-strength", curveStrength); + const settings = forceAtlas2.inferSettings(graph); + forceAtlas2.assign(graph, { + iterations: 600, + settings: { + ...settings, + barnesHutOptimize: true, + strongGravityMode: false, + gravity: 0.05, + scalingRatio: 10, + slowDown: 5, + }, }); - }); - // Create node circles - node - .append("circle") - .attr("r", 10) - .attr("fill", (d: any) => getNodeColor(d)) - .attr("stroke", theme.node.stroke) - .attr("stroke-width", 1) - .attr("filter", "drop-shadow(0 2px 4px rgba(0,0,0,0.2))") - .attr("data-id", (d: any) => d.id) - .attr("cursor", "pointer"); - - // Add node labels - node - .append("text") - .attr("x", 15) - .attr("y", "0.3em") - .attr("text-anchor", "start") - .attr("fill", theme.node.text) - .attr("font-weight", "500") - .attr("font-size", "12px") - .text((d: any) => d.value) - .attr("cursor", "pointer"); - - // Handle node clicks - function handleNodeClick(event: any, d: any) { - event.stopPropagation(); // Ensure the event doesn't bubble up - - if (resetLinksRef.current) resetLinksRef.current(); - if (resetNodesRef.current) resetNodesRef.current(); - - const selectedNodeId = d?.id; - - if (selectedNodeId && onNodeClick) { - onNodeClick(selectedNodeId); - - // Highlight the selected node - // @ts-ignore - node - .selectAll("circle") - .filter((n: any) => n.id === selectedNodeId) - .attr("fill", theme.node.selected) - .attr("stroke", theme.node.selected) - .attr("stroke-width", 2); - - // Find connected nodes and links - const connectedLinks: any[] = []; - const connectedNodes = new Set(); - - // Add the selected node to the connected nodes - const selectedNode = nodes.find((n: any) => n.id === selectedNodeId); - if (selectedNode) { - connectedNodes.add(selectedNode); - } - - // @ts-ignore - link.selectAll("path").each(function () { - const path = d3.select(this); - const source = path.attr("data-source"); - const target = path.attr("data-target"); - - if (source === selectedNodeId || target === selectedNodeId) { - const sourceNode = nodes.find((n: any) => n.id === source); - const targetNode = nodes.find((n: any) => n.id === target); - - if (sourceNode && targetNode) { - connectedLinks.push({ source: sourceNode, target: targetNode }); - connectedNodes.add(sourceNode); - connectedNodes.add(targetNode); - } - } - }); - - // Calculate bounding box of connected nodes - if (connectedNodes.size > 0 && zoomRef.current) { - let minX = Infinity, - minY = Infinity; - let maxX = -Infinity, - maxY = -Infinity; - - connectedNodes.forEach((node: any) => { - if (node.x !== undefined && node.y !== undefined) { - minX = Math.min(minX, node.x); - minY = Math.min(minY, node.y); - maxX = Math.max(maxX, node.x); - maxY = Math.max(maxY, node.y); - } - }); - - // Add padding - const padding = 50; - minX -= padding; - minY -= padding; - maxX += padding; - maxY += padding; - - // Calculate transform to fit connected nodes - const boundWidth = maxX - minX; - const boundHeight = maxY - minY; - const scale = - 0.9 * Math.min(width / boundWidth, height / boundHeight); - const midX = (minX + maxX) / 2; - const midY = (minY + maxY) / 2; - - if (isFinite(scale) && isFinite(midX) && isFinite(midY)) { - const transform = d3.zoomIdentity - .translate(width / 2 - midX * scale, height / 2 - midY * scale) - .scale(scale); - - // Animate transition to new view - // @ts-ignore - svgElement - .transition() - .duration(750) - .ease(d3.easeCubicInOut) // Add easing for smoother transitions - .call(zoomRef.current.transform, transform); - } - } - - // Highlight connected links - // @ts-ignore - link - .selectAll("path") - .attr("stroke", theme.link.stroke) - .attr("stroke-opacity", 0.6) - .attr("stroke-width", 1) - .filter(function () { - const path = d3.select(this); - return ( - path.attr("data-source") === selectedNodeId || - path.attr("data-target") === selectedNodeId - ); - }) - .attr("stroke", themeMode === "dark" ? "#ffffff" : colors.pink[600]) - .attr("stroke-width", 2); - } + noverlap.assign(graph, { + maxIterations: 150, + settings: { + margin: 5, + expansion: 1.1, + gridSize: 20, + }, + }); } - // Attach click handler to nodes - node.on("click", handleNodeClick); - - // Store a reference to the current SVG element - const svgRefCurrent = svgRef.current; - - // Add blur handler - svgElement.on("click", function (event) { - // Make sure we only handle clicks directly on the SVG element, not on its children - if (event.target === svgRefCurrent) { - if (onBlur) onBlur(); - if (resetLinksRef.current) resetLinksRef.current(); - if (resetNodesRef.current) resetNodesRef.current(); - } + // Create Sigma instance + const sigma = new Sigma(graph, containerRef.current, { + renderEdgeLabels: true, + defaultEdgeColor: theme.link.stroke, + defaultNodeColor: theme.node.fill, + enableEdgeEvents: true, + minCameraRatio: 0.1, + maxCameraRatio: 2, }); - // Update positions on simulation tick - simulation.on("tick", () => { - // Update link paths and labels - link.each(function (d: any) { - // Make sure d.source and d.target have x and y properties - if (!d.source.x && typeof d.source === "string") { - const sourceNode = nodes.find((n: any) => n.id === d.source); - // @ts-ignore - Node will have x,y properties from d3 simulation - if (sourceNode && sourceNode.x) { - d.source = sourceNode; - } - } + sigmaRef.current = sigma; - if (!d.target.x && typeof d.target === "string") { - const targetNode = nodes.find((n: any) => n.id === d.target); - // @ts-ignore - Node will have x,y properties from d3 simulation - if (targetNode && targetNode.x) { - d.target = targetNode; - } - } + // Set up camera for zoom on mount + if (zoomOnMount) { + setTimeout(() => { + sigma + .getCamera() + .animate(sigma.getCamera().getState(), { duration: 750 }); + }, 100); + } - const linkGroup = d3.select(this); - linkGroup.selectAll("path").each(function () { - const path = d3.select(this); - const curveStrength = +path.attr("data-curve-strength") || 0; + // --- Drag and Drop Implementation --- + let draggedNode: string | null = null; + let isDragging = false; - // Handle self-referencing nodes - if (d.source.id === d.target.id) { - // Create an elliptical path for self-references - const radiusX = 40; - const radiusY = 90; - const offset = radiusY + 20; + sigma.on("downNode", (e) => { + isDragging = true; + draggedNode = e.node; + graph.setNodeAttribute(draggedNode, "highlighted", true); + if (!sigma.getCustomBBox()) sigma.setCustomBBox(sigma.getBBox()); + }); - const cx = d.source.x; - const cy = d.source.y - offset; - const path_d = `M${d.source.x},${d.source.y} - C${cx - radiusX},${cy} - ${cx + radiusX},${cy} - ${d.source.x},${d.source.y}`; - path.attr("d", path_d); + sigma.on("moveBody", ({ event }) => { + if (!isDragging || !draggedNode) return; + const pos = sigma.viewportToGraph(event); + graph.setNodeAttribute(draggedNode, "x", pos.x); + graph.setNodeAttribute(draggedNode, "y", pos.y); + event.preventSigmaDefault?.(); + event.original?.preventDefault?.(); + event.original?.stopPropagation?.(); + }); - // Position the label - // @ts-ignore - const labelGroup = linkGroup - .selectAll(".link-label") - .filter(function () { - return ( - d3.select(this).attr("data-curve-strength") === - String(curveStrength) - ); - }); + const handleUp = () => { + if (draggedNode) { + graph.removeNodeAttribute(draggedNode, "highlighted"); + } + isDragging = false; + draggedNode = null; + }; + sigma.on("upNode", handleUp); + sigma.on("upStage", handleUp); - // Update both the group position and the rectangle/text within it - labelGroup.attr("transform", `translate(${cx}, ${cy - 10})`); + // --- End Drag and Drop --- - // Update the rectangle and text positioning - // @ts-ignore - const text = labelGroup.select("text"); - // @ts-ignore - const rect = labelGroup.select("rect"); - const textBBox = (text.node() as SVGTextElement)?.getBBox(); - - if (textBBox) { - rect - .attr("x", -textBBox.width / 2 - 6) - .attr("y", -textBBox.height / 2 - 4) - .attr("width", textBBox.width + 12) - .attr("height", textBBox.height + 8); - - text.attr("x", 0).attr("y", 0); - } - } else { - const dx = d.target.x - d.source.x; - const dy = d.target.y - d.source.y; - const dr = Math.sqrt(dx * dx + dy * dy); - - const midX = (d.source.x + d.target.x) / 2; - const midY = (d.source.y + d.target.y) / 2; - const normalX = -dy / dr; - const normalY = dx / dr; - const curveMagnitude = dr * curveStrength; - const controlX = midX + normalX * curveMagnitude; - const controlY = midY + normalY * curveMagnitude; - - const path_d = `M${d.source.x},${d.source.y} Q${controlX},${controlY} ${d.target.x},${d.target.y}`; - path.attr("d", path_d); - - const pathNode = path.node() as SVGPathElement; - if (pathNode) { - const pathLength = pathNode.getTotalLength(); - const midPoint = pathNode.getPointAtLength(pathLength / 2); - - // @ts-ignore - Intentionally ignoring d3 selection type issues as in the Svelte version - const labelGroup = linkGroup - .selectAll(".link-label") - .filter(function () { - return ( - d3.select(this).attr("data-curve-strength") === - String(curveStrength) - ); - }); - - if (midPoint) { - // @ts-ignore - Intentionally ignoring d3 selection type issues as in the Svelte version - const text = labelGroup.select("text"); - // @ts-ignore - Intentionally ignoring d3 selection type issues as in the Svelte version - const rect = labelGroup.select("rect"); - const textBBox = (text.node() as SVGTextElement)?.getBBox(); - - if (textBBox) { - const angle = - (Math.atan2( - d.target.y - d.source.y, - d.target.x - d.source.x, - ) * - 180) / - Math.PI; - const rotationAngle = - angle > 90 || angle < -90 ? angle - 180 : angle; - - labelGroup.attr( - "transform", - `translate(${midPoint.x}, ${midPoint.y}) rotate(${rotationAngle})`, - ); - - rect - .attr("x", -textBBox.width / 2 - 6) - .attr("y", -textBBox.height / 2 - 4) - .attr("width", textBBox.width + 12) - .attr("height", textBBox.height + 8); - - text.attr("x", 0).attr("y", 0); - } - } - } - } - }); + // Node click handler + sigma.on("clickNode", (event) => { + const { node } = event; + // resetHighlights(); + if (onNodeClick) { + onNodeClick(node); + } + graph.setNodeAttribute(node, "highlighted", true); + graph.setNodeAttribute(node, "color", theme.node.selected); + selectedNodeRef.current = node; + graph.forEachEdge(node, (edge, _attributes, source, target) => { + graph.setEdgeAttribute(edge, "highlighted", true); + graph.setEdgeAttribute(edge, "color", theme.link.selected); + const otherNode = source === node ? target : source; + graph.setNodeAttribute(otherNode, "highlighted", true); + graph.setNodeAttribute(otherNode, "color", theme.node.selected); }); - - // Update node positions - node.attr("transform", (d: any) => `translate(${d.x},${d.y})`); + // const nodePosition = sigma.getNodeDisplayData(node); + // if (nodePosition) { + // sigma + // .getCamera() + // .animate( + // { x: nodePosition.x, y: nodePosition.y, ratio: 0.5 }, + // { duration: 500 }, + // ); + // } }); - // Handle zoom-to-fit on mount - let hasInitialized = false; - - simulation.on("end", () => { - if (hasInitialized || !zoomOnMount || !zoomRef.current) return; - hasInitialized = true; - - const bounds = g.node()?.getBBox(); - if (bounds) { - const fullWidth = width; - const fullHeight = height; - const currentWidth = bounds.width || 1; - const currentHeight = bounds.height || 1; - - // Only proceed if we have valid dimensions - if ( - currentWidth > 0 && - currentHeight > 0 && - fullWidth > 0 && - fullHeight > 0 - ) { - const midX = bounds.x + currentWidth / 2; - const midY = bounds.y + currentHeight / 2; - - // Calculate scale to fit with padding - const scale = - 0.8 * - Math.min(fullWidth / currentWidth, fullHeight / currentHeight); - - // Ensure we have valid numbers before creating transform - if (isFinite(midX) && isFinite(midY) && isFinite(scale)) { - const transform = d3.zoomIdentity - .translate( - fullWidth / 2 - midX * scale, - fullHeight / 2 - midY * scale, - ) - .scale(scale); - - // Smoothly animate to the new transform - // @ts-ignore - svgElement - .transition() - .duration(750) - .ease(d3.easeCubicInOut) // Add easing for smoother transitions - .call(zoomRef.current.transform, transform); - } else { - console.warn("Invalid transform values:", { midX, midY, scale }); - // Fallback to a simple center transform - const transform = d3.zoomIdentity - .translate(fullWidth / 2, fullHeight / 2) - .scale(0.8); - svgElement.call(zoomRef.current.transform, transform); - } + // Edge click handler + sigma.on("clickEdge", (event) => { + const { edge } = event; + resetHighlights(); + const edgeAttrs = graph.getEdgeAttributes(edge); + if (edgeAttrs.relationData && edgeAttrs.relationData.length > 0) { + const relation = edgeAttrs.relationData[0]; + if (onEdgeClick) { + onEdgeClick(relation.id); } } + graph.setEdgeAttribute(edge, "highlighted", true); + graph.setEdgeAttribute(edge, "color", theme.link.selected); + selectedEdgeRef.current = edge; + const source = graph.source(edge); + const target = graph.target(edge); + graph.setNodeAttribute(source, "highlighted", true); + graph.setNodeAttribute(source, "color", theme.node.selected); + graph.setNodeAttribute(target, "highlighted", true); + graph.setNodeAttribute(target, "color", theme.node.selected); + const sourcePos = sigma.getNodeDisplayData(source); + const targetPos = sigma.getNodeDisplayData(target); + if (sourcePos && targetPos) { + const centerX = (sourcePos.x + targetPos.x) / 2; + const centerY = (sourcePos.y + targetPos.y) / 2; + // sigma + // .getCamera() + // .animate({ x: centerX, y: centerY, ratio: 0.5 }, { duration: 500 }); + } }); - // Cleanup function - only called when component unmounts + // Background click handler + sigma.on("clickStage", () => { + resetHighlights(); + if (onBlur) { + onBlur(); + } + }); + + // Cleanup function return () => { - simulation.stop(); - // Save the ref to a variable before using it in cleanup - const currentSvgRef = svgRef.current; - if (currentSvgRef) { - d3.select(currentSvgRef).on("click", null); + if (sigmaRef.current) { + sigmaRef.current.kill(); + sigmaRef.current = null; + } + if (graphRef.current) { + graphRef.current.clear(); + graphRef.current = null; } isInitializedRef.current = false; }; - // We're keeping the dependency array empty to ensure initialization runs only once on mount - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [nodes, edges]); - // This effect updates the graph theme colors when the theme changes - useEffect(() => { - // Skip if not initialized - if (!svgRef.current || !isInitializedRef.current) return; - - const svgElement = d3.select(svgRef.current); - - // Update background - svgElement.style("background-color", "var(--background-3)"); - - // Update nodes - use getNodeColor for proper color assignment - svgElement - .selectAll("circle") - .attr("fill", (d: any) => getNodeColor(d)) - .attr("stroke", theme.node.stroke); - - // Update node labels - // @ts-ignore - svgElement.selectAll("text").attr("fill", theme.node.text); - - // Update links - // @ts-ignore - svgElement - .selectAll("path") - .attr("stroke", theme.link.stroke) - .attr("stroke-opacity", 0.6); - - // Update selected links if any - // @ts-ignore - svgElement - .selectAll("path.selected") - .attr("stroke", theme.link.selected) - .attr("stroke-opacity", 1); - - // Update link labels - // @ts-ignore - svgElement - .selectAll(".link-label rect") - .attr("fill", theme.link.label.bg); - // @ts-ignore - svgElement - .selectAll(".link-label text") - .attr("fill", theme.link.label.text); - - // This effect has many dependencies that would cause frequent re-renders - // We're disabling the exhaustive deps rule to prevent unnecessary re-renders - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [themeMode]); + // // Theme update effect + // useEffect(() => { + // if (!sigmaRef.current || !graphRef.current || !isInitializedRef.current) + // return; + // const graph = graphRef.current; + // graph.forEachNode((node) => { + // const nodeData = graph.getNodeAttribute(node, "nodeData"); + // const isHighlighted = graph.getNodeAttribute(node, "highlighted"); + // if (!isHighlighted) { + // graph.setNodeAttribute(node, "color", getNodeColor(nodeData)); + // } + // }); + // graph.forEachEdge((edge) => { + // const isHighlighted = graph.getEdgeAttribute(edge, "highlighted"); + // if (!isHighlighted) { + // graph.setEdgeAttribute(edge, "color", theme.link.stroke); + // } + // }); + // sigmaRef.current.setSetting("defaultEdgeColor", theme.link.stroke); + // sigmaRef.current.setSetting("defaultNodeColor", "red"); + // }, [theme, getNodeColor]); return ( - -
                                                  +
                                                  +
                                                  + +
                                                  -
                                                  - -
                                                  C.O.R.E.
                                                  {children} diff --git a/apps/webapp/app/components/logo/core.svg b/apps/webapp/app/components/logo/core.svg new file mode 100644 index 0000000..eff361b --- /dev/null +++ b/apps/webapp/app/components/logo/core.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/webapp/app/components/logo/logo.tsx b/apps/webapp/app/components/logo/logo.tsx index a854395..f94779d 100644 --- a/apps/webapp/app/components/logo/logo.tsx +++ b/apps/webapp/app/components/logo/logo.tsx @@ -56,41 +56,276 @@ export default function StaticLogo({ width, height }: LogoProps) { return ( - - - - - - + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + ); diff --git a/apps/webapp/app/components/sidebar/app-sidebar.tsx b/apps/webapp/app/components/sidebar/app-sidebar.tsx index 4949379..5ff81b1 100644 --- a/apps/webapp/app/components/sidebar/app-sidebar.tsx +++ b/apps/webapp/app/components/sidebar/app-sidebar.tsx @@ -8,43 +8,52 @@ import { SidebarMenu, SidebarMenuItem, } from "../ui/sidebar"; -import { DashboardIcon } from "@radix-ui/react-icons"; -import { Code, Search } from "lucide-react"; +import { Activity, LayoutGrid, MessageSquare, Network } from "lucide-react"; import { NavMain } from "./nav-main"; import { useUser } from "~/hooks/useUser"; import { NavUser } from "./nav-user"; -import { useWorkspace } from "~/hooks/useWorkspace"; +import Logo from "../logo/logo"; const data = { navMain: [ { - title: "Dashboard", + title: "Conversation", + url: "/home/conversation", + icon: MessageSquare, + }, + { + title: "Memory", url: "/home/dashboard", - icon: DashboardIcon, + icon: Network, }, { - title: "API", - url: "/home/api", - icon: Code, + title: "Activity", + url: "/home/activity", + icon: Activity, }, { - title: "Logs", - url: "/home/logs", - icon: Search, + title: "Integrations", + url: "/home/integrations", + icon: LayoutGrid, }, ], }; export function AppSidebar({ ...props }: React.ComponentProps) { const user = useUser(); - const workspace = useWorkspace(); return ( - + - {workspace.name} +
                                                  + +
                                                  diff --git a/apps/webapp/app/components/sidebar/nav-main.tsx b/apps/webapp/app/components/sidebar/nav-main.tsx index f2bee0a..f3a6d46 100644 --- a/apps/webapp/app/components/sidebar/nav-main.tsx +++ b/apps/webapp/app/components/sidebar/nav-main.tsx @@ -1,3 +1,4 @@ +import { cn } from "~/lib/utils"; import { SidebarGroup, SidebarGroupContent, @@ -28,10 +29,13 @@ export const NavMain = ({ navigate(item.url)} > {item.icon && } - {item.title} ))} diff --git a/apps/webapp/app/components/sidebar/nav-user.tsx b/apps/webapp/app/components/sidebar/nav-user.tsx index d3f4d3d..7002560 100644 --- a/apps/webapp/app/components/sidebar/nav-user.tsx +++ b/apps/webapp/app/components/sidebar/nav-user.tsx @@ -1,4 +1,4 @@ -import { LogOut } from "lucide-react"; +import { LogOut, Settings } from "lucide-react"; import { AvatarText } from "../ui/avatar"; import { DropdownMenu, @@ -8,33 +8,48 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from "../ui/dropdown-menu"; -import { SidebarMenu, SidebarMenuItem, useSidebar } from "../ui/sidebar"; +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from "../ui/sidebar"; import type { User } from "~/models/user.server"; import { Button } from "../ui"; +import { cn } from "~/lib/utils"; +import { useLocation, useNavigate } from "@remix-run/react"; export function NavUser({ user }: { user: User }) { const { isMobile } = useSidebar(); + const location = useLocation(); + const navigate = useNavigate(); return ( + + + = { + "/home/dashboard": "Memory graph", + "/home/conversation": "Conversation", + "/home/integrations": "Integrations", + "/home/activity": "Activity", +}; + +function getHeaderTitle(pathname: string): string { + // Try to match the most specific path first + for (const key of Object.keys(PAGE_TITLES)) { + if (pathname.startsWith(key)) { + return PAGE_TITLES[key]; + } + } + // Default fallback + return "Documents"; +} + +export function SiteHeader() { + const location = useLocation(); + const title = getHeaderTitle(location.pathname); + + return ( +
                                                  +
                                                  +

                                                  {title}

                                                  +
                                                  +
                                                  + ); +} diff --git a/apps/webapp/app/components/ui/sheet.tsx b/apps/webapp/app/components/ui/sheet.tsx index 104a951..2f74842 100644 --- a/apps/webapp/app/components/ui/sheet.tsx +++ b/apps/webapp/app/components/ui/sheet.tsx @@ -29,7 +29,7 @@ const SheetOverlay = React.forwardRef< SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; const sheetVariants = cva( - "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", + "fixed z-50 gap-4 bg-background-2 p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", { variants: { side: { diff --git a/apps/webapp/app/components/ui/sidebar.tsx b/apps/webapp/app/components/ui/sidebar.tsx index 914fc28..726f8fb 100644 --- a/apps/webapp/app/components/ui/sidebar.tsx +++ b/apps/webapp/app/components/ui/sidebar.tsx @@ -263,8 +263,7 @@ function SidebarTrigger({ data-sidebar="trigger" data-slot="sidebar-trigger" variant="ghost" - size="icon" - className={cn("size-7", className)} + className={cn("size-8", className)} onClick={(event) => { onClick?.(event); toggleSidebar(); @@ -307,7 +306,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
                                                  ); @@ -472,11 +471,11 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) { } const sidebarMenuButtonVariants = cva( - "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", + "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:!bg-background-3 active:!text-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", { variants: { variant: { - default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", + default: "hover:bg-grayAlpha-100 hover:text-accent-foreground", outline: "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]", }, diff --git a/apps/webapp/app/components/use-auto-scroll.tsx b/apps/webapp/app/components/use-auto-scroll.tsx new file mode 100644 index 0000000..14277b0 --- /dev/null +++ b/apps/webapp/app/components/use-auto-scroll.tsx @@ -0,0 +1,169 @@ +// @hidden + +import React, { useCallback, useEffect, useRef, useState } from "react"; +import { cn } from "~/lib/utils"; + +interface ScrollState { + isAtBottom: boolean; + autoScrollEnabled: boolean; +} + +interface UseAutoScrollOptions { + offset?: number; + smooth?: boolean; + content?: React.ReactNode; +} + +export function useAutoScroll(options: UseAutoScrollOptions = {}) { + const { offset = 20, smooth = false, content } = options; + const scrollRef = useRef(null); + const lastContentHeight = useRef(0); + const userHasScrolled = useRef(false); + + const [scrollState, setScrollState] = useState({ + isAtBottom: false, + autoScrollEnabled: true, + }); + + const checkIsAtBottom = useCallback( + (element: HTMLElement) => { + const { scrollTop, scrollHeight, clientHeight } = element; + const distanceToBottom = Math.abs( + scrollHeight - scrollTop - clientHeight, + ); + return distanceToBottom <= offset; + }, + [offset], + ); + + const scrollToBottom = useCallback( + (instant?: boolean) => { + if (scrollRef.current) { + const targetScrollTop = + scrollRef.current.scrollHeight - scrollRef.current.clientHeight; + + if (instant) { + scrollRef.current.scrollTop = targetScrollTop; + } else { + scrollRef.current.scrollTo({ + top: targetScrollTop, + behavior: smooth ? "smooth" : "auto", + }); + } + + setScrollState({ + isAtBottom: true, + autoScrollEnabled: true, + }); + userHasScrolled.current = false; + } + }, + [smooth], + ); + + const handleScroll = useCallback(() => { + if (scrollRef.current) { + const atBottom = checkIsAtBottom(scrollRef.current); + + setScrollState((prev) => ({ + isAtBottom: atBottom, + // Re-enable auto-scroll if at the bottom + autoScrollEnabled: atBottom ? true : prev.autoScrollEnabled, + })); + } + }, [checkIsAtBottom]); + + useEffect(() => { + const element = scrollRef.current; + if (element) { + element.addEventListener("scroll", handleScroll, { passive: true }); + } + + return () => + element ? element.removeEventListener("scroll", handleScroll) : undefined; + }, [handleScroll]); + + useEffect(() => { + const scrollElement = scrollRef.current; + if (!scrollElement) { + return; + } + + const currentHeight = scrollElement.scrollHeight; + const hasNewContent = currentHeight !== lastContentHeight.current; + + if (hasNewContent) { + if (scrollState.autoScrollEnabled) { + requestAnimationFrame(() => { + scrollToBottom(lastContentHeight.current === 0); + }); + } + lastContentHeight.current = currentHeight; + } + }, [content, scrollState.autoScrollEnabled, scrollToBottom]); + + useEffect(() => { + const resizeObserver = new ResizeObserver(() => { + if (scrollState.autoScrollEnabled) { + scrollToBottom(true); + } + }); + + const element = scrollRef.current; + if (element) { + resizeObserver.observe(element); + } + + return () => resizeObserver.disconnect(); + }, [scrollState.autoScrollEnabled, scrollToBottom]); + + const disableAutoScroll = useCallback(() => { + const atBottom = scrollRef.current + ? checkIsAtBottom(scrollRef.current) + : false; + + // Only disable if not at bottom + if (!atBottom) { + userHasScrolled.current = true; + setScrollState((prev) => ({ + ...prev, + autoScrollEnabled: false, + })); + } + }, [checkIsAtBottom]); + + return { + scrollRef, + isAtBottom: scrollState.isAtBottom, + autoScrollEnabled: scrollState.autoScrollEnabled, + scrollToBottom: () => scrollToBottom(false), + disableAutoScroll, + }; +} + +export const ScrollAreaWithAutoScroll = ({ + children, + className, +}: { + children: React.ReactNode; + className?: string; +}) => { + const { scrollRef } = useAutoScroll({ + smooth: true, + content: children, + }); + + return ( +
                                                  +
                                                  + {children} +
                                                  +
                                                  + ); +}; diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 646a677..da834a3 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -71,6 +71,11 @@ const EnvironmentSchema = z.object({ SMTP_USER: z.string().optional(), SMTP_PASSWORD: z.string().optional(), + //Trigger + TRIGGER_PROJECT_ID: z.string(), + TRIGGER_SECRET_KEY: z.string(), + TRIGGER_API_URL: z.string(), + // Model envs MODEL: z.string().default(LLMModelEnum.GPT41), EMBEDDING_MODEL: z.string().default("bge-m3"), diff --git a/apps/webapp/app/models/workspace.server.ts b/apps/webapp/app/models/workspace.server.ts index f7ba2cf..106e9d3 100644 --- a/apps/webapp/app/models/workspace.server.ts +++ b/apps/webapp/app/models/workspace.server.ts @@ -2,7 +2,6 @@ import { type Workspace } from "@core/database"; import { prisma } from "~/db.server"; interface CreateWorkspaceDto { - slug: string; name: string; integrations: string[]; userId: string; @@ -13,7 +12,7 @@ export async function createWorkspace( ): Promise { const workspace = await prisma.workspace.create({ data: { - slug: input.slug, + slug: input.name, name: input.name, userId: input.userId, }, diff --git a/apps/webapp/app/root.tsx b/apps/webapp/app/root.tsx index cda0df3..8028f39 100644 --- a/apps/webapp/app/root.tsx +++ b/apps/webapp/app/root.tsx @@ -31,7 +31,7 @@ import { usePostHog } from "./hooks/usePostHog"; import { AppContainer, MainCenteredContainer, -} from "./components/layout/AppLayout"; +} from "./components/layout/app-layout"; import { RouteErrorDisplay } from "./components/ErrorDisplay"; import { themeSessionResolver } from "./services/sessionStorage.server"; import { @@ -97,7 +97,7 @@ export function ErrorBoundary() { - + @@ -123,7 +123,7 @@ function App() { - + diff --git a/apps/webapp/app/routes/api.v1.add.tsx b/apps/webapp/app/routes/api.v1.add.tsx new file mode 100644 index 0000000..a86e739 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.add.tsx @@ -0,0 +1,21 @@ +import { json } from "@remix-run/node"; + +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; +import { addToQueue, IngestBodyRequest } from "~/lib/ingest.server"; + +const { action, loader } = createActionApiRoute( + { + body: IngestBodyRequest, + allowJWT: true, + authorization: { + action: "ingest", + }, + corsStrategy: "all", + }, + async ({ body, authentication }) => { + const response = addToQueue(body, authentication.userId); + return json({ ...response }); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.conversation.$conversationId.read.tsx b/apps/webapp/app/routes/api.v1.conversation.$conversationId.read.tsx new file mode 100644 index 0000000..a03d341 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.conversation.$conversationId.read.tsx @@ -0,0 +1,39 @@ +import { json } from "@remix-run/node"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; + +import { getWorkspaceByUser } from "~/models/workspace.server"; +import { + createConversation, + CreateConversationSchema, + readConversation, +} from "~/services/conversation.server"; +import { z } from "zod"; + +export const ConversationIdSchema = z.object({ + conversationId: z.string(), +}); + +const { action, loader } = createActionApiRoute( + { + params: ConversationIdSchema, + allowJWT: true, + authorization: { + action: "oauth", + }, + corsStrategy: "all", + }, + async ({ authentication, params }) => { + const workspace = await getWorkspaceByUser(authentication.userId); + + if (!workspace) { + throw new Error("No workspace found"); + } + + // Call the service to get the redirect URL + const read = await readConversation(params.conversationId); + + return json(read); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.conversation.$conversationId.run.tsx b/apps/webapp/app/routes/api.v1.conversation.$conversationId.run.tsx new file mode 100644 index 0000000..9adee5c --- /dev/null +++ b/apps/webapp/app/routes/api.v1.conversation.$conversationId.run.tsx @@ -0,0 +1,44 @@ +import { json } from "@remix-run/node"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; + +import { getWorkspaceByUser } from "~/models/workspace.server"; +import { + createConversation, + CreateConversationSchema, + getCurrentConversationRun, + readConversation, + stopConversation, +} from "~/services/conversation.server"; +import { z } from "zod"; + +export const ConversationIdSchema = z.object({ + conversationId: z.string(), +}); + +const { action, loader } = createActionApiRoute( + { + params: ConversationIdSchema, + allowJWT: true, + authorization: { + action: "oauth", + }, + corsStrategy: "all", + }, + async ({ authentication, params }) => { + const workspace = await getWorkspaceByUser(authentication.userId); + + if (!workspace) { + throw new Error("No workspace found"); + } + + // Call the service to get the redirect URL + const run = await getCurrentConversationRun( + params.conversationId, + workspace?.id, + ); + + return json(run); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.conversation.$conversationId.stop.tsx b/apps/webapp/app/routes/api.v1.conversation.$conversationId.stop.tsx new file mode 100644 index 0000000..a6f3862 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.conversation.$conversationId.stop.tsx @@ -0,0 +1,41 @@ +import { json } from "@remix-run/node"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; + +import { getWorkspaceByUser } from "~/models/workspace.server"; +import { + createConversation, + CreateConversationSchema, + readConversation, + stopConversation, +} from "~/services/conversation.server"; +import { z } from "zod"; + +export const ConversationIdSchema = z.object({ + conversationId: z.string(), +}); + +const { action, loader } = createActionApiRoute( + { + params: ConversationIdSchema, + allowJWT: true, + authorization: { + action: "oauth", + }, + corsStrategy: "all", + method: "POST", + }, + async ({ authentication, params }) => { + const workspace = await getWorkspaceByUser(authentication.userId); + + if (!workspace) { + throw new Error("No workspace found"); + } + + // Call the service to get the redirect URL + const stop = await stopConversation(params.conversationId, workspace?.id); + + return json(stop); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.conversation.$conversationId.tsx b/apps/webapp/app/routes/api.v1.conversation.$conversationId.tsx new file mode 100644 index 0000000..b49e3e3 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.conversation.$conversationId.tsx @@ -0,0 +1,50 @@ +import { json } from "@remix-run/node"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; + +import { getWorkspaceByUser } from "~/models/workspace.server"; +import { + getConversation, + deleteConversation, +} from "~/services/conversation.server"; +import { z } from "zod"; + +export const ConversationIdSchema = z.object({ + conversationId: z.string(), +}); + +const { action, loader } = createActionApiRoute( + { + params: ConversationIdSchema, + allowJWT: true, + authorization: { + action: "oauth", + }, + corsStrategy: "all", + }, + async ({ params, authentication, request }) => { + const workspace = await getWorkspaceByUser(authentication.userId); + + if (!workspace) { + throw new Error("No workspace found"); + } + + const method = request.method; + + if (method === "GET") { + // Get a conversation by ID + const conversation = await getConversation(params.conversationId); + return json(conversation); + } + + if (method === "DELETE") { + // Soft delete a conversation + const deleted = await deleteConversation(params.conversationId); + return json(deleted); + } + + // Method not allowed + return new Response("Method Not Allowed", { status: 405 }); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.conversation._index.tsx b/apps/webapp/app/routes/api.v1.conversation._index.tsx new file mode 100644 index 0000000..70e6793 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.conversation._index.tsx @@ -0,0 +1,37 @@ +import { json } from "@remix-run/node"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; + +import { getWorkspaceByUser } from "~/models/workspace.server"; +import { + createConversation, + CreateConversationSchema, +} from "~/services/conversation.server"; + +const { action, loader } = createActionApiRoute( + { + body: CreateConversationSchema, + allowJWT: true, + authorization: { + action: "oauth", + }, + corsStrategy: "all", + }, + async ({ body, authentication }) => { + const workspace = await getWorkspaceByUser(authentication.userId); + + if (!workspace) { + throw new Error("No workspace found"); + } + + // Call the service to get the redirect URL + const conversation = await createConversation( + workspace?.id, + authentication.userId, + body, + ); + + return json(conversation); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.conversations.tsx b/apps/webapp/app/routes/api.v1.conversations.tsx new file mode 100644 index 0000000..d850f4a --- /dev/null +++ b/apps/webapp/app/routes/api.v1.conversations.tsx @@ -0,0 +1,41 @@ +import { json } from "@remix-run/node"; +import { getWorkspaceByUser } from "~/models/workspace.server"; +import { + getConversationsList, + GetConversationsListSchema, +} from "~/services/conversation.server"; +import { requireUser } from "~/services/session.server"; + +export const loader = async ({ request }: { request: Request }) => { + // Authenticate the request (allow JWT) + const user = await requireUser(request); + + // Parse search params using the schema + const url = new URL(request.url); + const searchParamsObj: Record = {}; + url.searchParams.forEach((value, key) => { + searchParamsObj[key] = value; + }); + const parseResult = GetConversationsListSchema.safeParse(searchParamsObj); + if (!parseResult.success) { + return json( + { error: "Invalid search parameters", details: parseResult.error.errors }, + { status: 400 }, + ); + } + const searchParams = parseResult.data; + + const workspace = await getWorkspaceByUser(user.id); + + if (!workspace) { + return json({ error: "No workspace found" }, { status: 404 }); + } + + const result = await getConversationsList( + workspace.id, + user.id, + searchParams || {}, + ); + + return json(result); +}; diff --git a/apps/webapp/app/routes/api.v1.oauth._index.tsx b/apps/webapp/app/routes/api.v1.oauth._index.tsx new file mode 100644 index 0000000..565cf71 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.oauth._index.tsx @@ -0,0 +1,32 @@ +import { json } from "@remix-run/node"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; +import { OAuthBodySchema } from "~/services/oauth/oauth-utils.server"; + +import { getRedirectURL } from "~/services/oauth/oauth.server"; +import { getWorkspaceByUser } from "~/models/workspace.server"; + +// This route handles the OAuth redirect URL generation, similar to the NestJS controller +const { action, loader } = createActionApiRoute( + { + body: OAuthBodySchema, + allowJWT: true, + authorization: { + action: "oauth", + }, + corsStrategy: "all", + }, + async ({ body, authentication, request }) => { + const workspace = await getWorkspaceByUser(authentication.userId); + + // Call the service to get the redirect URL + const redirectURL = await getRedirectURL( + body, + authentication.userId, + workspace?.id, + ); + + return json(redirectURL); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/api.v1.oauth.callback.tsx b/apps/webapp/app/routes/api.v1.oauth.callback.tsx new file mode 100644 index 0000000..4183d88 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.oauth.callback.tsx @@ -0,0 +1,21 @@ +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; +import { callbackHandler } from "~/services/oauth/oauth.server"; +import type { CallbackParams } from "~/services/oauth/oauth-utils.server"; + +// This route handles the OAuth callback, similar to the NestJS controller +const { loader } = createActionApiRoute( + { + allowJWT: false, + corsStrategy: "all", + }, + async ({ request }) => { + const url = new URL(request.url); + const params: CallbackParams = {}; + for (const [key, value] of url.searchParams.entries()) { + params[key] = value; + } + return await callbackHandler(params, request); + }, +); + +export { loader }; diff --git a/apps/webapp/app/routes/api.v1.search.tsx b/apps/webapp/app/routes/api.v1.search.tsx new file mode 100644 index 0000000..342a703 --- /dev/null +++ b/apps/webapp/app/routes/api.v1.search.tsx @@ -0,0 +1,50 @@ +import { z } from "zod"; +import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; +import { SearchService } from "~/services/search.server"; +import { json } from "@remix-run/node"; + +export const SearchBodyRequest = z.object({ + query: z.string(), + startTime: z.string().optional(), + endTime: z.string().optional(), + + // These are not supported yet, but need to support these + spaceId: z.string().optional(), + limit: z.number().optional(), + maxBfsDepth: z.number().optional(), + includeInvalidated: z.boolean().optional(), + entityTypes: z.array(z.string()).optional(), + scoreThreshold: z.number().optional(), + minResults: z.number().optional(), +}); + +const searchService = new SearchService(); +const { action, loader } = createActionApiRoute( + { + body: SearchBodyRequest, + allowJWT: true, + authorization: { + action: "search", + }, + corsStrategy: "all", + }, + async ({ body, authentication }) => { + const results = await searchService.search( + body.query, + authentication.userId, + { + startTime: body.startTime ? new Date(body.startTime) : undefined, + endTime: body.endTime ? new Date(body.endTime) : undefined, + limit: body.limit, + maxBfsDepth: body.maxBfsDepth, + includeInvalidated: body.includeInvalidated, + entityTypes: body.entityTypes, + scoreThreshold: body.scoreThreshold, + minResults: body.minResults, + }, + ); + return json(results); + }, +); + +export { action, loader }; diff --git a/apps/webapp/app/routes/confirm-basic-details.tsx b/apps/webapp/app/routes/confirm-basic-details.tsx index f90ceee..56815ea 100644 --- a/apps/webapp/app/routes/confirm-basic-details.tsx +++ b/apps/webapp/app/routes/confirm-basic-details.tsx @@ -3,7 +3,7 @@ import { useActionData } from "@remix-run/react"; import { type ActionFunctionArgs, json } from "@remix-run/node"; import { useForm } from "@conform-to/react"; import { getFieldsetConstraint, parse } from "@conform-to/zod"; -import { LoginPageLayout } from "~/components/layout/LoginPageLayout"; +import { LoginPageLayout } from "~/components/layout/login-page-layout"; import { Card, CardContent, @@ -24,10 +24,6 @@ const schema = z.object({ .string() .min(3, "Your workspace name must be at least 3 characters") .max(50), - workspaceSlug: z - .string() - .min(3, "Your workspace slug must be at least 3 characters") - .max(50), }); export async function action({ request }: ActionFunctionArgs) { @@ -40,11 +36,10 @@ export async function action({ request }: ActionFunctionArgs) { return json(submission); } - const { workspaceSlug, workspaceName } = submission.value; + const { workspaceName } = submission.value; try { await createWorkspace({ - slug: workspaceSlug, integrations: [], name: workspaceName, userId, @@ -109,27 +104,6 @@ export default function ConfirmBasicDetails() { )}
                                                  -
                                                  - - - {fields.workspaceSlug.error && ( -
                                                  - {fields.workspaceSlug.error} -
                                                  - )} -
                                                  - + + + + + + {data.nav.map((item) => ( + + + + ))} + + + + + +
                                                  +
                                                  + +
                                                  +
                                                  + +
                                                  + ); +} diff --git a/apps/webapp/app/services/apiAuth.server.ts b/apps/webapp/app/services/apiAuth.server.ts index 61701b9..08cb0ba 100644 --- a/apps/webapp/app/services/apiAuth.server.ts +++ b/apps/webapp/app/services/apiAuth.server.ts @@ -1,6 +1,3 @@ -import { SignJWT, errors, jwtVerify } from "jose"; - -import { env } from "~/env.server"; import { findUserByToken } from "~/models/personal-token.server"; // See this for more: https://twitter.com/mattpocockuk/status/1653403198885904387?s=20 @@ -85,7 +82,7 @@ export async function authenticateApiKeyWithFailure( } export function isSecretApiKey(key: string) { - return key.startsWith("tr_"); + return key.startsWith("rc_"); } export function getApiKeyFromRequest(request: Request) { diff --git a/apps/webapp/app/services/conversation.server.ts b/apps/webapp/app/services/conversation.server.ts new file mode 100644 index 0000000..f0beecc --- /dev/null +++ b/apps/webapp/app/services/conversation.server.ts @@ -0,0 +1,361 @@ +import { UserTypeEnum } from "@core/types"; + +import { auth, runs, tasks } from "@trigger.dev/sdk/v3"; +import { prisma } from "~/db.server"; +import { createConversationTitle } from "~/trigger/conversation/create-conversation-title"; + +import { z } from "zod"; +import { type ConversationHistory } from "@prisma/client"; + +export const CreateConversationSchema = z.object({ + message: z.string(), + title: z.string().optional(), + conversationId: z.string().optional(), + userType: z.nativeEnum(UserTypeEnum).optional(), +}); + +export type CreateConversationDto = z.infer; + +// Create a new conversation +export async function createConversation( + workspaceId: string, + userId: string, + conversationData: CreateConversationDto, +) { + const { title, conversationId, ...otherData } = conversationData; + + if (conversationId) { + // Add a new message to an existing conversation + const conversationHistory = await prisma.conversationHistory.create({ + data: { + ...otherData, + userType: otherData.userType || UserTypeEnum.User, + ...(userId && { + user: { + connect: { id: userId }, + }, + }), + conversation: { + connect: { id: conversationId }, + }, + }, + include: { + conversation: true, + }, + }); + + const context = await getConversationContext(conversationHistory.id); + const handler = await tasks.trigger( + "chat", + { + conversationHistoryId: conversationHistory.id, + conversationId: conversationHistory.conversation.id, + context, + }, + { tags: [conversationHistory.id, workspaceId, conversationId] }, + ); + + return { + id: handler.id, + token: handler.publicAccessToken, + conversationId: conversationHistory.conversation.id, + conversationHistoryId: conversationHistory.id, + }; + } + + // Create a new conversation and its first message + const conversation = await prisma.conversation.create({ + data: { + workspaceId, + userId, + title: + title?.substring(0, 100) ?? conversationData.message.substring(0, 100), + ConversationHistory: { + create: { + userId, + userType: otherData.userType || UserTypeEnum.User, + ...otherData, + }, + }, + }, + include: { + ConversationHistory: true, + }, + }); + + const conversationHistory = conversation.ConversationHistory[0]; + const context = await getConversationContext(conversationHistory.id); + + // Trigger conversation title task + await tasks.trigger( + createConversationTitle.id, + { + conversationId: conversation.id, + message: conversationData.message, + }, + { tags: [conversation.id, workspaceId] }, + ); + + const handler = await tasks.trigger( + "chat", + { + conversationHistoryId: conversationHistory.id, + conversationId: conversation.id, + context, + }, + { tags: [conversationHistory.id, workspaceId, conversation.id] }, + ); + + return { + id: handler.id, + token: handler.publicAccessToken, + conversationId: conversation.id, + conversationHistoryId: conversationHistory.id, + }; +} + +// Get a conversation by ID +export async function getConversation(conversationId: string) { + return prisma.conversation.findUnique({ + where: { id: conversationId }, + }); +} + +// Delete a conversation (soft delete) +export async function deleteConversation(conversationId: string) { + return prisma.conversation.update({ + where: { id: conversationId }, + data: { + deleted: new Date().toISOString(), + }, + }); +} + +// Mark a conversation as read +export async function readConversation(conversationId: string) { + return prisma.conversation.update({ + where: { id: conversationId }, + data: { unread: false }, + }); +} + +export async function getCurrentConversationRun( + conversationId: string, + workspaceId: string, +) { + const conversationHistory = await prisma.conversationHistory.findFirst({ + where: { + conversationId, + conversation: { + workspaceId, + }, + }, + orderBy: { + updatedAt: "desc", + }, + }); + + if (!conversationHistory) { + throw new Error("No run found"); + } + + const response = await runs.list({ + tag: [conversationId, conversationHistory.id], + status: ["QUEUED", "EXECUTING"], + limit: 1, + }); + + const run = response.data[0]; + if (!run) { + return undefined; + } + + const publicToken = await auth.createPublicToken({ + scopes: { + read: { + runs: [run.id], + }, + }, + }); + + return { + id: run.id, + token: publicToken, + conversationId, + conversationHistoryId: conversationHistory.id, + }; +} + +export async function stopConversation( + conversationId: string, + workspaceId: string, +) { + const conversationHistory = await prisma.conversationHistory.findFirst({ + where: { + conversationId, + conversation: { + workspaceId, + }, + }, + orderBy: { + updatedAt: "desc", + }, + }); + + if (!conversationHistory) { + throw new Error("No run found"); + } + + const response = await runs.list({ + tag: [conversationId, conversationHistory.id], + status: ["QUEUED", "EXECUTING"], + limit: 1, + }); + + const run = response.data[0]; + if (!run) { + await prisma.conversation.update({ + where: { + id: conversationId, + }, + data: { + status: "failed", + }, + }); + + return undefined; + } + + return await runs.cancel(run.id); +} + +export async function getConversationContext( + conversationHistoryId: string, +): Promise<{ + previousHistory: ConversationHistory[]; +}> { + const conversationHistory = await prisma.conversationHistory.findUnique({ + where: { id: conversationHistoryId }, + include: { conversation: true }, + }); + + if (!conversationHistory) { + return { + previousHistory: [], + }; + } + + // Get previous conversation history message and response + let previousHistory: ConversationHistory[] = []; + + if (conversationHistory.conversationId) { + previousHistory = await prisma.conversationHistory.findMany({ + where: { + conversationId: conversationHistory.conversationId, + id: { + not: conversationHistoryId, + }, + deleted: null, + }, + orderBy: { + createdAt: "asc", + }, + }); + } + + return { + previousHistory, + }; +} + +export const getConversationAndHistory = async ( + conversationId: string, + userId: string, +) => { + const conversation = await prisma.conversation.findFirst({ + where: { + id: conversationId, + }, + include: { + ConversationHistory: true, + }, + }); + + return conversation; +}; + +export const GetConversationsListSchema = z.object({ + page: z.string().optional().default("1"), + limit: z.string().optional().default("20"), + search: z.string().optional(), +}); + +export type GetConversationsListDto = z.infer; + +export async function getConversationsList( + workspaceId: string, + userId: string, + params: GetConversationsListDto, +) { + const page = parseInt(params.page); + const limit = parseInt(params.limit); + const skip = (page - 1) * limit; + + const where = { + workspaceId, + userId, + deleted: null, + ...(params.search && { + OR: [ + { + title: { + contains: params.search, + mode: "insensitive" as const, + }, + }, + { + ConversationHistory: { + some: { + message: { + contains: params.search, + mode: "insensitive" as const, + }, + }, + }, + }, + ], + }), + }; + + const [conversations, total] = await Promise.all([ + prisma.conversation.findMany({ + where, + include: { + ConversationHistory: { + take: 1, + orderBy: { + createdAt: "desc", + }, + }, + }, + orderBy: { + updatedAt: "desc", + }, + skip, + take: limit, + }), + prisma.conversation.count({ where }), + ]); + + return { + conversations, + pagination: { + page, + limit, + total, + totalPages: Math.ceil(total / limit), + hasNext: page < Math.ceil(total / limit), + hasPrev: page > 1, + }, + }; +} diff --git a/apps/webapp/app/services/email.server.ts b/apps/webapp/app/services/email.server.ts index 1da6751..45f3e57 100644 --- a/apps/webapp/app/services/email.server.ts +++ b/apps/webapp/app/services/email.server.ts @@ -5,9 +5,7 @@ import { type MailTransportOptions, } from "emails"; -import { redirect } from "remix-typedjson"; import { env } from "~/env.server"; -import type { AuthUser } from "./authUser"; import { logger } from "./logger.service"; import { singleton } from "~/utils/singleton"; diff --git a/apps/webapp/app/services/integration.server.ts b/apps/webapp/app/services/integration.server.ts new file mode 100644 index 0000000..c12c29d --- /dev/null +++ b/apps/webapp/app/services/integration.server.ts @@ -0,0 +1,88 @@ +import { tasks } from "@trigger.dev/sdk/v3"; + +import { getOrCreatePersonalAccessToken } from "./personalAccessToken.server"; +import { logger } from "./logger.service"; +import { type integrationRun } from "~/trigger/integrations/integration-run"; + +import type { IntegrationDefinitionV2 } from "@core/database"; + +/** + * Prepares the parameters for triggering an integration. + * If userId is provided, gets or creates a personal access token for the user. + */ +async function prepareIntegrationTrigger( + integrationDefinition: IntegrationDefinitionV2, + userId?: string, + workspaceId?: string, +) { + logger.info(`Loading integration ${integrationDefinition.slug}`); + + let pat = ""; + if (userId) { + // Use the integration slug as the token name for uniqueness + const tokenResult = await getOrCreatePersonalAccessToken({ + name: integrationDefinition.slug ?? "integration", + userId, + }); + pat = tokenResult.token ?? ""; + } + + return { + integrationDefinition, + pat, + }; +} + +/** + * Triggers an integration run asynchronously. + */ +export async function runIntegrationTriggerAsync( + integrationDefinition: IntegrationDefinitionV2, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + event: any, + userId?: string, + workspaceId?: string, +) { + const params = await prepareIntegrationTrigger( + integrationDefinition, + userId, + workspaceId, + ); + return await tasks.trigger("integration-run", { + ...params, + event, + }); +} + +/** + * Triggers an integration run and waits for completion. + */ +export async function runIntegrationTrigger( + integrationDefinition: IntegrationDefinitionV2, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + event: any, + userId?: string, + workspaceId?: string, +) { + const params = await prepareIntegrationTrigger( + integrationDefinition, + userId, + workspaceId, + ); + + const response = await tasks.triggerAndPoll( + "integration-run", + { + ...params, + integrationAccount: event.integrationAccount, + event: event.event, + eventBody: event.eventBody, + }, + ); + + if (response.status === "COMPLETED") { + return response.output; + } + + throw new Error(`Integration trigger failed with status: ${response.status}`); +} diff --git a/apps/webapp/app/services/integrationDefinition.server.ts b/apps/webapp/app/services/integrationDefinition.server.ts new file mode 100644 index 0000000..9b07992 --- /dev/null +++ b/apps/webapp/app/services/integrationDefinition.server.ts @@ -0,0 +1,24 @@ +import { prisma } from "~/db.server"; + +/** + * Get all integration definitions available to a workspace. + * Returns both global (workspaceId: null) and workspace-specific definitions. + */ +export async function getIntegrationDefinitions(workspaceId: string) { + return prisma.integrationDefinitionV2.findMany({ + where: { + OR: [{ workspaceId: null }, { workspaceId }], + }, + }); +} + +/** + * Get a single integration definition by its ID. + */ +export async function getIntegrationDefinitionWithId( + integrationDefinitionId: string, +) { + return prisma.integrationDefinitionV2.findUnique({ + where: { id: integrationDefinitionId }, + }); +} diff --git a/apps/webapp/app/services/knowledgeGraph.server.ts b/apps/webapp/app/services/knowledgeGraph.server.ts index 67b1f3a..efe2da1 100644 --- a/apps/webapp/app/services/knowledgeGraph.server.ts +++ b/apps/webapp/app/services/knowledgeGraph.server.ts @@ -1,8 +1,6 @@ import { openai } from "@ai-sdk/openai"; import { type CoreMessage, embed } from "ai"; import { - EpisodeType, - LLMModelEnum, type AddEpisodeParams, type EntityNode, type EpisodicNode, @@ -58,7 +56,7 @@ export class KnowledgeGraphService { } // Default to using Ollama - const ollamaUrl = process.env.OLLAMA_URL; + const ollamaUrl = env.OLLAMA_URL; const model = env.EMBEDDING_MODEL; const ollama = createOllama({ diff --git a/apps/webapp/app/services/oauth/oauth-utils.server.ts b/apps/webapp/app/services/oauth/oauth-utils.server.ts new file mode 100644 index 0000000..59957d8 --- /dev/null +++ b/apps/webapp/app/services/oauth/oauth-utils.server.ts @@ -0,0 +1,155 @@ +import { type OAuth2Params } from "@core/types"; +import { IsBoolean, IsString } from "class-validator"; +import type { IntegrationDefinitionV2 } from "@core/database"; +import { z } from "zod"; + +export interface RedirectURLParams { + workspaceSlug: string; + integrationOAuthAppName: string; + config: string; +} + +export interface SessionRecord { + integrationDefinitionId: string; + config: OAuth2Params; + redirectURL: string; + workspaceId: string; + accountIdentifier?: string; + integrationKeys?: string; + personal: boolean; + userId?: string; +} + +export class OAuthBodyInterface { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + config?: any; + + @IsString() + redirectURL: string; + + @IsBoolean() + personal: boolean = false; + + @IsString() + integrationDefinitionId: string; +} + +export const OAuthBodySchema = z.object({ + config: z.any().optional(), + redirectURL: z.string(), + personal: z.boolean().default(false), + integrationDefinitionId: z.string(), +}); + +export type CallbackParams = Record; + +export interface ProviderConfig { + client_id: string; + client_secret: string; + scopes: string; +} + +const enum ProviderAuthModes { + "OAuth2" = "OAuth2", +} + +export interface ProviderTemplate extends OAuth2Params { + auth_mode: ProviderAuthModes; +} + +export enum OAuthAuthorizationMethod { + BODY = "body", + HEADER = "header", +} + +export enum OAuthBodyFormat { + FORM = "form", + JSON = "json", +} + +export interface ProviderTemplateOAuth2 extends ProviderTemplate { + auth_mode: ProviderAuthModes.OAuth2; + + disable_pkce?: boolean; // Defaults to false (=PKCE used) if not provided + + token_params?: { + grant_type?: "authorization_code" | "client_credentials"; + }; + + refresh_params?: { + grant_type: "refresh_token"; + }; + + authorization_method?: OAuthAuthorizationMethod; + body_format?: OAuthBodyFormat; + + refresh_url?: string; + + token_request_auth_method?: "basic"; +} + +/** + * A helper function to interpolate a string. + * interpolateString('Hello ${name} of ${age} years", {name: 'Tester', age: 234}) -> returns 'Hello Tester of age 234 years' + * + * @remarks + * Copied from https://stackoverflow.com/a/1408373/250880 + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function interpolateString(str: string, replacers: Record) { + return str.replace(/\${([^{}]*)}/g, (a, b) => { + const r = replacers[b]; + return typeof r === "string" || typeof r === "number" ? (r as string) : a; // Typecast needed to make TypeScript happy + }); +} + +export function getSimpleOAuth2ClientConfig( + providerConfig: ProviderConfig, + template: ProviderTemplate, + connectionConfig: OAuth2Params, +) { + const tokenUrl = new URL( + interpolateString(template.token_url, connectionConfig), + ); + const authorizeUrl = new URL( + interpolateString(template.authorization_url, connectionConfig), + ); + const headers = { "User-Agent": "Sol" }; + + const authConfig = template as ProviderTemplateOAuth2; + + return { + client: { + id: providerConfig.client_id, + secret: providerConfig.client_secret, + }, + auth: { + tokenHost: tokenUrl.origin, + tokenPath: tokenUrl.pathname, + authorizeHost: authorizeUrl.origin, + authorizePath: authorizeUrl.pathname, + }, + http: { headers }, + options: { + authorizationMethod: + authConfig.authorization_method || OAuthAuthorizationMethod.BODY, + bodyFormat: authConfig.body_format || OAuthBodyFormat.FORM, + scopeSeparator: template.scope_separator || " ", + }, + }; +} + +export async function getTemplate( + integrationDefinition: IntegrationDefinitionV2, +): Promise { + const spec = integrationDefinition.spec as any; + const template: ProviderTemplate = spec.auth.OAuth2 as ProviderTemplate; + + if (!template) { + throw new Error( + `This extension doesn't support OAuth. Reach out to us if you need support for this extension`, + ); + } + + return template; +} diff --git a/apps/webapp/app/services/oauth/oauth.server.ts b/apps/webapp/app/services/oauth/oauth.server.ts new file mode 100644 index 0000000..82d4e54 --- /dev/null +++ b/apps/webapp/app/services/oauth/oauth.server.ts @@ -0,0 +1,245 @@ +import { IntegrationPayloadEventType, type OAuth2Params } from "@core/types"; +import * as simpleOauth2 from "simple-oauth2"; +import { tasks } from "@trigger.dev/sdk/v3"; +import { + getSimpleOAuth2ClientConfig, + getTemplate, + type OAuthBodyInterface, + type ProviderTemplateOAuth2, + type SessionRecord, +} from "./oauth-utils.server"; +import { getIntegrationDefinitionWithId } from "../integrationDefinition.server"; +import { type scheduler } from "~/trigger/integrations/scheduler"; +import { logger } from "../logger.service"; +import { runIntegrationTrigger } from "../integration.server"; +import type { IntegrationDefinitionV2 } from "@core/database"; +import { env } from "~/env.server"; + +// Use process.env for config in Remix +const CALLBACK_URL = process.env.OAUTH_CALLBACK_URL ?? ""; + +// Session store (in-memory, for single server) +const session: Record = {}; + +export type CallbackParams = Record; + +// Remix-style callback handler +// Accepts a Remix LoaderFunctionArgs-like object: { request } +export async function callbackHandler( + params: CallbackParams, + request: Request, +) { + if (!params.state) { + throw new Error("No state found"); + } + + const sessionRecord = session[params.state]; + + // Delete the session once it's used + delete session[params.state]; + + if (!sessionRecord) { + throw new Error("No session found"); + } + + const integrationDefinition = await getIntegrationDefinitionWithId( + sessionRecord.integrationDefinitionId, + ); + + const template = (await getTemplate( + integrationDefinition as IntegrationDefinitionV2, + )) as ProviderTemplateOAuth2; + + if (integrationDefinition === null) { + const errorMessage = "No matching integration definition found"; + return new Response(null, { + status: 302, + headers: { + Location: `${sessionRecord.redirectURL}?success=false&error=${encodeURIComponent( + errorMessage, + )}`, + }, + }); + } + + let additionalTokenParams: Record = {}; + if (template.token_params !== undefined) { + const deepCopy = JSON.parse(JSON.stringify(template.token_params)); + additionalTokenParams = deepCopy; + } + + if (template.refresh_params) { + additionalTokenParams = template.refresh_params; + } + + const headers: Record = {}; + + const integrationConfig = integrationDefinition.config as any; + const integrationSpec = integrationDefinition.spec as any; + + if (template.token_request_auth_method === "basic") { + headers["Authorization"] = `Basic ${Buffer.from( + `${integrationConfig?.clientId}:${integrationConfig.clientSecret}`, + ).toString("base64")}`; + } + + const accountIdentifier = sessionRecord.accountIdentifier + ? `&accountIdentifier=${encodeURIComponent(sessionRecord.accountIdentifier)}` + : ""; + const integrationKeys = sessionRecord.integrationKeys + ? `&integrationKeys=${encodeURIComponent(sessionRecord.integrationKeys)}` + : ""; + + try { + const scopes = (integrationSpec.auth.OAuth2 as OAuth2Params) + .scopes as string[]; + + const simpleOAuthClient = new simpleOauth2.AuthorizationCode( + getSimpleOAuth2ClientConfig( + { + client_id: integrationConfig.clientId, + client_secret: integrationConfig.clientSecret, + scopes: scopes.join(","), + }, + template, + sessionRecord.config, + ), + ); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const tokensResponse: any = await simpleOAuthClient.getToken( + { + code: params.code as string, + redirect_uri: CALLBACK_URL, + ...additionalTokenParams, + }, + { + headers, + }, + ); + + const integrationAccount = await runIntegrationTrigger( + integrationDefinition, + { + event: IntegrationPayloadEventType.INTEGRATION_ACCOUNT_CREATED, + eventBody: { + oauthResponse: tokensResponse.token, + oauthParams: { + ...params, + redirect_uri: CALLBACK_URL, + }, + integrationDefinition, + }, + }, + sessionRecord.userId, + sessionRecord.workspaceId, + ); + + await tasks.trigger("scheduler", { + integrationAccountId: integrationAccount.id, + }); + + return new Response(null, { + status: 302, + headers: { + Location: `${sessionRecord.redirectURL}?success=true&integrationName=${encodeURIComponent( + integrationDefinition.name, + )}${accountIdentifier}${integrationKeys}`, + }, + }); + } catch (e: any) { + logger.error(e); + + return new Response(null, { + status: 302, + headers: { + Location: `${sessionRecord.redirectURL}?success=false&error=${encodeURIComponent( + e.message, + )}${accountIdentifier}${integrationKeys}`, + }, + }); + } +} + +export async function getRedirectURL( + oAuthBody: OAuthBodyInterface, + userId: string, + workspaceId?: string, + specificScopes?: string, +) { + const { integrationDefinitionId, personal } = oAuthBody; + + const redirectURL = `${env.APP_ORIGIN}/integrations`; + + logger.info( + `We got OAuth request for ${workspaceId}: ${integrationDefinitionId}`, + ); + + const integrationDefinition = await getIntegrationDefinitionWithId( + integrationDefinitionId, + ); + + if (!integrationDefinition) { + throw new Error("No integration definition "); + } + + const spec = integrationDefinition.spec as any; + const externalConfig = spec.auth.OAuth2 as OAuth2Params; + const template = await getTemplate(integrationDefinition); + + const scopesString = + specificScopes || (externalConfig.scopes as string[]).join(","); + const additionalAuthParams = template.authorization_params || {}; + + const integrationConfig = integrationDefinition.config as any; + + try { + const simpleOAuthClient = new simpleOauth2.AuthorizationCode( + getSimpleOAuth2ClientConfig( + { + client_id: integrationConfig.clientId, + client_secret: integrationConfig.clientSecret, + scopes: scopesString, + }, + template, + externalConfig, + ), + ); + + const uniqueId = Date.now().toString(36); + session[uniqueId] = { + integrationDefinitionId: integrationDefinition.id, + redirectURL, + workspaceId: workspaceId as string, + config: externalConfig, + userId, + personal, + }; + + const scopes = [ + ...scopesString.split(","), + ...(template.default_scopes || []), + ]; + + const scopeIdentifier = externalConfig.scope_identifier ?? "scope"; + + const authorizationUri = simpleOAuthClient.authorizeURL({ + redirect_uri: CALLBACK_URL, + [scopeIdentifier]: scopes.join(template.scope_separator || " "), + state: uniqueId, + ...additionalAuthParams, + }); + + logger.debug( + `OAuth 2.0 for ${integrationDefinition.name} - redirecting to: ${authorizationUri}`, + ); + + return { + status: 200, + redirectURL: authorizationUri, + }; + } catch (e: any) { + logger.warn(e); + throw new Error(e.message); + } +} diff --git a/apps/webapp/app/services/personalAccessToken.server.ts b/apps/webapp/app/services/personalAccessToken.server.ts index 21d6174..b09b618 100644 --- a/apps/webapp/app/services/personalAccessToken.server.ts +++ b/apps/webapp/app/services/personalAccessToken.server.ts @@ -268,6 +268,58 @@ export async function createPersonalAccessTokenFromAuthorizationCode( return token; } +/** Get or create a PersonalAccessToken for the given name and userId. + * If one exists (not revoked), return it (without the unencrypted token). + * If not, create a new one and return it (with the unencrypted token). + * We only ever return the unencrypted token once, on creation. + */ +export async function getOrCreatePersonalAccessToken({ + name, + userId, +}: CreatePersonalAccessTokenOptions) { + // Try to find an existing, non-revoked token + const existing = await prisma.personalAccessToken.findFirst({ + where: { + name, + userId, + revokedAt: null, + }, + }); + + if (existing) { + // Do not return the unencrypted token if it already exists + return { + id: existing.id, + name: existing.name, + userId: existing.userId, + obfuscatedToken: existing.obfuscatedToken, + // token is not returned + }; + } + + // Create a new token + const token = createToken(); + const encryptedToken = encryptToken(token); + + const personalAccessToken = await prisma.personalAccessToken.create({ + data: { + name, + userId, + encryptedToken, + obfuscatedToken: obfuscateToken(token), + hashedToken: hashToken(token), + }, + }); + + return { + id: personalAccessToken.id, + name, + userId, + token, + obfuscatedToken: personalAccessToken.obfuscatedToken, + }; +} + /** Created a new PersonalAccessToken, and return the token. We only ever return the unencrypted token once. */ export async function createPersonalAccessToken({ name, @@ -306,7 +358,7 @@ function createToken() { return `${tokenPrefix}${tokenGenerator()}`; } -/** Obfuscates all but the first and last 4 characters of the token, so it looks like tr_pat_bhbd•••••••••••••••••••fd4a */ +/** Obfuscates all but the first and last 4 characters of the token, so it looks like rc_pat_bhbd•••••••••••••••••••fd4a */ function obfuscateToken(token: string) { const withoutPrefix = token.replace(tokenPrefix, ""); const obfuscated = `${withoutPrefix.slice(0, 4)}${"•".repeat(18)}${withoutPrefix.slice(-4)}`; diff --git a/apps/webapp/app/services/postAuth.server.ts b/apps/webapp/app/services/postAuth.server.ts index e5d92fe..7c91726 100644 --- a/apps/webapp/app/services/postAuth.server.ts +++ b/apps/webapp/app/services/postAuth.server.ts @@ -1,4 +1,5 @@ import type { User } from "~/models/user.server"; +import { createWorkspace } from "~/models/workspace.server"; import { singleton } from "~/utils/singleton"; export async function postAuthentication({ @@ -10,5 +11,11 @@ export async function postAuthentication({ loginMethod: User["authenticationMethod"]; isNewUser: boolean; }) { - // console.log(user); + if (user.name && isNewUser && loginMethod === "GOOGLE") { + await createWorkspace({ + name: user.name, + userId: user.id, + integrations: [], + }); + } } diff --git a/apps/webapp/app/services/session.server.ts b/apps/webapp/app/services/session.server.ts index 309c2c9..f0cea55 100644 --- a/apps/webapp/app/services/session.server.ts +++ b/apps/webapp/app/services/session.server.ts @@ -62,7 +62,17 @@ export async function requireUser(request: Request) { export async function requireWorkpace(request: Request) { const userId = await requireUserId(request); - return getWorkspaceByUser(userId); + const workspace = await getWorkspaceByUser(userId); + + if (!workspace) { + const url = new URL(request.url); + const searchParams = new URLSearchParams([ + ["redirectTo", `${url.pathname}${url.search}`], + ]); + throw redirect(`/login?${searchParams}`); + } + + return workspace; } export async function logout(request: Request) { diff --git a/apps/webapp/app/tailwind.css b/apps/webapp/app/tailwind.css index 05500ce..2a093b3 100644 --- a/apps/webapp/app/tailwind.css +++ b/apps/webapp/app/tailwind.css @@ -12,7 +12,7 @@ --foreground: oklch(0% 0 0); --popover: oklch(93.05% 0 0); --popover-foreground: oklch(0% 0 0); - --primary: oklch(54% 0.1789 271); + --primary: oklch(60% 0.13 30); --primary-foreground: oklch(100% 0 0); --secondary: 210 40% 96.1%; --secondary-foreground: oklch(0% 0 0); @@ -49,7 +49,7 @@ --foreground: oklch(92.8% 0 0); --popover: oklch(28.5% 0 0); --popover-foreground: oklch(92.8% 0 0); - --primary: oklch(54% 0.1789 271); + --primary: oklch(60% 0.13 30); --primary-foreground: oklch(92.8% 0 0); --secondary: 210 40% 96.1%; --secondary-foreground: oklch(92.8% 0 0); @@ -322,8 +322,49 @@ @layer base { * { @apply border-border outline-ring/50; + --header-height: 44px; } body { - @apply bg-background text-foreground text-base; + @apply bg-background-2 text-foreground text-base; } -} \ No newline at end of file + + + @supports (scrollbar-width: auto) { + .overflow-y-auto, + .overflow-x-auto, + .overflow-auto { + overflow-anchor: none; + scrollbar-color: var(--gray-500) transparent; + scrollbar-width: thin; + } + } + + /* Legacy browsers with `::-webkit-scrollbar-*` support */ + @supports selector(::-webkit-scrollbar) { + .overflow-y-auto::-webkit-scrollbar-thumb, + .overflow-x-auto::-webkit-scrollbar-thumb, + .overflow-auto::-webkit-scrollbar-thumb { + background: transparent; + } + .overflow-y-auto::-webkit-scrollbar-track, + .overflow-x-auto::-webkit-scrollbar-track, + .overflow-auto::-webkit-scrollbar-track { + background: var(--gray-600); + } + + .overflow-y-auto::-webkit-scrollbar, + .overflow-x-auto::-webkit-scrollbar, + .overflow-auto::-webkit-scrollbar { + max-width: 5px; + } + } + + nav[aria-label='breadcrumb'] li { + @apply text-base; + } + + p.is-editor-empty { + font-size: 14px !important; + } +} + diff --git a/apps/webapp/app/trigger/.gitkeep b/apps/webapp/app/trigger/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/webapp/app/trigger/chat/chat-utils.ts b/apps/webapp/app/trigger/chat/chat-utils.ts new file mode 100644 index 0000000..9e53a60 --- /dev/null +++ b/apps/webapp/app/trigger/chat/chat-utils.ts @@ -0,0 +1,561 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { ActionStatusEnum } from "@core/types"; +import { logger } from "@trigger.dev/sdk/v3"; +import { + type CoreMessage, + type DataContent, + jsonSchema, + tool, + type ToolSet, +} from "ai"; +import axios from "axios"; +import Handlebars from "handlebars"; + +import { REACT_SYSTEM_PROMPT, REACT_USER_PROMPT } from "./prompt"; +import { generate, processTag } from "./stream-utils"; +import { type AgentMessage, AgentMessageType, Message } from "./types"; +import { type MCP } from "../utils/mcp"; +import { + type ExecutionState, + type HistoryStep, + type Resource, + type TotalCost, +} from "../utils/types"; +import { flattenObject } from "../utils/utils"; +import { searchMemory, addMemory } from "./memory-utils"; + +interface LLMOutputInterface { + response: AsyncGenerator< + | string + | { + type: string; + toolName: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + args?: any; + toolCallId?: string; + message?: string; + }, + any, + any + >; +} + +const progressUpdateTool = tool({ + description: + "Send a progress update to the user about what has been discovered or will be done next in a crisp and user friendly way no technical terms", + parameters: jsonSchema({ + type: "object", + properties: { + message: { + type: "string", + description: "The progress update message to send to the user", + }, + }, + required: ["message"], + additionalProperties: false, + }), +}); + +const searchMemoryTool = tool({ + description: + "Search the user's memory graph for episodes or statements based on a query", + parameters: jsonSchema({ + type: "object", + properties: { + query: { + type: "string", + description: "The search query in third person perspective", + }, + validAt: { + type: "string", + description: "The valid at time in ISO format", + }, + startTime: { + type: "string", + description: "The start time in ISO format", + }, + endTime: { + type: "string", + description: "The end time in ISO format", + }, + }, + required: ["query"], + additionalProperties: false, + }), +}); + +const addMemoryTool = tool({ + description: "Add information to the user's memory graph", + parameters: jsonSchema({ + type: "object", + properties: { + message: { + type: "string", + description: "The content/text to add to memory", + }, + }, + required: ["message"], + additionalProperties: false, + }), +}); + +const internalTools = [ + "core--progress_update", + "core--search_memory", + "core--add_memory", +]; + +async function addResources(messages: CoreMessage[], resources: Resource[]) { + const resourcePromises = resources.map(async (resource) => { + // Remove everything before "/api" in the publicURL + if (resource.publicURL) { + const apiIndex = resource.publicURL.indexOf("/api"); + if (apiIndex !== -1) { + resource.publicURL = resource.publicURL.substring(apiIndex); + } + } + const response = await axios.get(resource.publicURL, { + responseType: "arraybuffer", + }); + + if (resource.fileType.startsWith("image/")) { + return { + type: "image", + image: response.data as DataContent, + }; + } + + return { + type: "file", + data: response.data as DataContent, + + mimeType: resource.fileType, + }; + }); + + const content = await Promise.all(resourcePromises); + + return [...messages, { role: "user", content } as CoreMessage]; +} + +function toolToMessage(history: HistoryStep[], messages: CoreMessage[]) { + for (let i = 0; i < history.length; i++) { + const step = history[i]; + + // Add assistant message with tool calls + if (step.observation && step.skillId) { + messages.push({ + role: "assistant", + content: [ + { + type: "tool-call", + toolCallId: step.skillId, + toolName: step.skill ?? "", + args: + typeof step.skillInput === "string" + ? JSON.parse(step.skillInput) + : step.skillInput, + }, + ], + }); + + messages.push({ + role: "tool", + content: [ + { + type: "tool-result", + toolName: step.skill, + toolCallId: step.skillId, + result: step.observation, + isError: step.isError, + }, + ], + } as any); + } + // Handle format correction steps (observation exists but no skillId) + else if (step.observation && !step.skillId) { + // Add as a system message for format correction + messages.push({ + role: "system", + content: step.observation, + }); + } + } + + return messages; +} + +async function makeNextCall( + executionState: ExecutionState, + TOOLS: ToolSet, + totalCost: TotalCost, + guardLoop: number, +): Promise { + const { context, history, previousHistory } = executionState; + + const promptInfo = { + USER_MESSAGE: executionState.query, + CONTEXT: context, + USER_MEMORY: executionState.userMemoryContext, + }; + + let messages: CoreMessage[] = []; + + const systemTemplateHandler = Handlebars.compile(REACT_SYSTEM_PROMPT); + let systemPrompt = systemTemplateHandler(promptInfo); + + const userTemplateHandler = Handlebars.compile(REACT_USER_PROMPT); + const userPrompt = userTemplateHandler(promptInfo); + + // Always start with a system message (this does use tokens but keeps the instructions clear) + messages.push({ role: "system", content: systemPrompt }); + + // For subsequent queries, include only final responses from previous exchanges if available + if (previousHistory && previousHistory.length > 0) { + messages = [...messages, ...previousHistory]; + } + + // Add the current user query (much simpler than the full prompt) + messages.push({ role: "user", content: userPrompt }); + + // Include any steps from the current interaction + if (history.length > 0) { + messages = toolToMessage(history, messages); + } + + if (executionState.resources && executionState.resources.length > 0) { + messages = await addResources(messages, executionState.resources); + } + + // Get the next action from the LLM + const response = generate( + messages, + guardLoop > 0 && guardLoop % 3 === 0, + (event) => { + const usage = event.usage; + totalCost.inputTokens += usage.promptTokens; + totalCost.outputTokens += usage.completionTokens; + }, + TOOLS, + ); + + return { response }; +} + +export async function* run( + message: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context: Record, + previousHistory: CoreMessage[], + mcp: MCP, + stepHistory: HistoryStep[], + // eslint-disable-next-line @typescript-eslint/no-explicit-any +): AsyncGenerator { + let guardLoop = 0; + + let tools = { + "core--progress_update": progressUpdateTool, + "core--search_memory": searchMemoryTool, + "core--add_memory": addMemoryTool, + }; + + logger.info("Tools have been formed"); + + let contextText = ""; + let resources = []; + if (context) { + // Extract resources and remove from context + resources = context.resources || []; + delete context.resources; + + // Process remaining context + contextText = flattenObject(context).join("\n"); + } + + const executionState: ExecutionState = { + query: message, + context: contextText, + resources, + previousHistory, + history: stepHistory, // Track the full ReAct history + completed: false, + }; + + const totalCost: TotalCost = { inputTokens: 0, outputTokens: 0, cost: 0 }; + + try { + while (!executionState.completed && guardLoop < 50) { + logger.info(`Starting the loop: ${guardLoop}`); + + const { response: llmResponse } = await makeNextCall( + executionState, + tools, + totalCost, + guardLoop, + ); + + let toolCallInfo; + + const messageState = { + inTag: false, + message: "", + messageEnded: false, + lastSent: "", + }; + + const questionState = { + inTag: false, + message: "", + messageEnded: false, + lastSent: "", + }; + + let totalMessage = ""; + const toolCalls = []; + + // LLM thought response + for await (const chunk of llmResponse) { + if (typeof chunk === "object" && chunk.type === "tool-call") { + toolCallInfo = chunk; + toolCalls.push(chunk); + } + + totalMessage += chunk; + + if (!messageState.messageEnded) { + yield* processTag( + messageState, + totalMessage, + chunk as string, + "", + "", + { + start: AgentMessageType.MESSAGE_START, + chunk: AgentMessageType.MESSAGE_CHUNK, + end: AgentMessageType.MESSAGE_END, + }, + ); + } + + if (!questionState.messageEnded) { + yield* processTag( + questionState, + totalMessage, + chunk as string, + "", + "", + { + start: AgentMessageType.MESSAGE_START, + chunk: AgentMessageType.MESSAGE_CHUNK, + end: AgentMessageType.MESSAGE_END, + }, + ); + } + } + + logger.info(`Cost for thought: ${JSON.stringify(totalCost)}`); + + // Replace the error-handling block with this self-correcting implementation + if ( + !totalMessage.includes("final_response") && + !totalMessage.includes("question_response") && + !toolCallInfo + ) { + // Log the issue for debugging + logger.info( + `Invalid response format detected. Attempting to get proper format.`, + ); + + // Extract the raw content from the invalid response + const rawContent = totalMessage + .replace(/(<[^>]*>|<\/[^>]*>)/g, "") + .trim(); + + // Create a correction step + const stepRecord: HistoryStep = { + thought: "", + skill: "", + skillId: "", + userMessage: "Sol agent error, retrying \n", + isQuestion: false, + isFinal: false, + tokenCount: totalCost, + skillInput: "", + observation: `Your last response was not in a valid format. You must respond with EXACTLY ONE of the required formats: either a tool call, tags, or tags. Please reformat your previous response using the correct format:\n\n${rawContent}`, + }; + + yield Message("", AgentMessageType.MESSAGE_START); + yield Message( + stepRecord.userMessage as string, + AgentMessageType.MESSAGE_CHUNK, + ); + yield Message("", AgentMessageType.MESSAGE_END); + + // Add this step to the history + yield Message(JSON.stringify(stepRecord), AgentMessageType.STEP); + executionState.history.push(stepRecord); + + // Log that we're continuing the loop with a correction request + logger.info(`Added format correction request to history.`); + + // Don't mark as completed - let the loop continue + guardLoop++; // Still increment to prevent infinite loops + continue; + } + + // Record this step in history + const stepRecord: HistoryStep = { + thought: "", + skill: "", + skillId: "", + userMessage: "", + isQuestion: false, + isFinal: false, + tokenCount: totalCost, + skillInput: "", + }; + + if (totalMessage && totalMessage.includes("final_response")) { + executionState.completed = true; + stepRecord.isFinal = true; + stepRecord.userMessage = messageState.message; + stepRecord.finalTokenCount = totalCost; + stepRecord.skillStatus = ActionStatusEnum.SUCCESS; + yield Message(JSON.stringify(stepRecord), AgentMessageType.STEP); + executionState.history.push(stepRecord); + break; + } + + if (totalMessage && totalMessage.includes("question_response")) { + executionState.completed = true; + stepRecord.isQuestion = true; + stepRecord.userMessage = questionState.message; + stepRecord.finalTokenCount = totalCost; + stepRecord.skillStatus = ActionStatusEnum.QUESTION; + yield Message(JSON.stringify(stepRecord), AgentMessageType.STEP); + executionState.history.push(stepRecord); + break; + } + + if (toolCalls && toolCalls.length > 0) { + // Run all tool calls in parallel + for (const toolCallInfo of toolCalls) { + const skillName = toolCallInfo.toolName; + const skillId = toolCallInfo.toolCallId; + const skillInput = toolCallInfo.args; + + const toolName = skillName.split("--")[1]; + const agent = skillName.split("--")[0]; + + const stepRecord: HistoryStep = { + agent, + thought: "", + skill: skillName, + skillId, + userMessage: "", + isQuestion: false, + isFinal: false, + tokenCount: totalCost, + skillInput: JSON.stringify(skillInput), + }; + + if (!internalTools.includes(skillName)) { + const skillMessageToSend = `\n\n`; + + stepRecord.userMessage += skillMessageToSend; + + yield Message("", AgentMessageType.MESSAGE_START); + yield Message(skillMessageToSend, AgentMessageType.MESSAGE_CHUNK); + yield Message("", AgentMessageType.MESSAGE_END); + } + + let result; + try { + // Log skill execution details + logger.info(`Executing skill: ${skillName}`); + logger.info(`Input parameters: ${JSON.stringify(skillInput)}`); + + if (!internalTools.includes(toolName)) { + yield Message( + JSON.stringify({ skillId, status: "start" }), + AgentMessageType.SKILL_START, + ); + } + + // Handle CORE agent tools + if (agent === "core") { + if (toolName === "progress_update") { + yield Message("", AgentMessageType.MESSAGE_START); + yield Message( + skillInput.message, + AgentMessageType.MESSAGE_CHUNK, + ); + stepRecord.userMessage += skillInput.message; + yield Message("", AgentMessageType.MESSAGE_END); + result = "Progress update sent successfully"; + } else if (toolName === "search_memory") { + try { + result = await searchMemory(skillInput); + } catch (apiError) { + logger.error("Memory utils calls failed for search_memory", { + apiError, + }); + result = + "Memory search failed - please check your memory configuration"; + } + } else if (toolName === "add_memory") { + try { + result = await addMemory(skillInput); + } catch (apiError) { + logger.error("Memory utils calls failed for add_memory", { + apiError, + }); + result = + "Memory storage failed - please check your memory configuration"; + } + } + } + // Handle other MCP tools + else { + result = await mcp.callTool(skillName, skillInput); + + yield Message( + JSON.stringify({ result, skillId }), + AgentMessageType.SKILL_CHUNK, + ); + } + + yield Message( + JSON.stringify({ skillId, status: "end" }), + AgentMessageType.SKILL_END, + ); + + stepRecord.skillOutput = + typeof result === "object" + ? JSON.stringify(result, null, 2) + : result; + stepRecord.observation = stepRecord.skillOutput; + } catch (e) { + console.log(e); + logger.error(e as string); + stepRecord.skillInput = skillInput; + stepRecord.observation = JSON.stringify(e); + stepRecord.isError = true; + } + + logger.info(`Skill step: ${JSON.stringify(stepRecord)}`); + + yield Message(JSON.stringify(stepRecord), AgentMessageType.STEP); + executionState.history.push(stepRecord); + } + } + guardLoop++; + } + yield Message("Stream ended", AgentMessageType.STREAM_END); + } catch (e) { + logger.error(e as string); + yield Message((e as Error).message, AgentMessageType.ERROR); + yield Message("Stream ended", AgentMessageType.STREAM_END); + } +} diff --git a/apps/webapp/app/trigger/chat/chat.ts b/apps/webapp/app/trigger/chat/chat.ts new file mode 100644 index 0000000..d05bf26 --- /dev/null +++ b/apps/webapp/app/trigger/chat/chat.ts @@ -0,0 +1,136 @@ +import { ActionStatusEnum } from "@core/types"; +import { metadata, task, queue } from "@trigger.dev/sdk"; + +import { run } from "./chat-utils"; +import { MCP } from "../utils/mcp"; +import { type HistoryStep } from "../utils/types"; +import { + createConversationHistoryForAgent, + deletePersonalAccessToken, + getPreviousExecutionHistory, + init, + type RunChatPayload, + updateConversationHistoryMessage, + updateConversationStatus, + updateExecutionStep, +} from "../utils/utils"; + +const chatQueue = queue({ + name: "chat-queue", + concurrencyLimit: 10, +}); + +/** + * Main chat task that orchestrates the agent workflow + * Handles conversation context, agent selection, and LLM interactions + */ +export const chat = task({ + id: "chat", + maxDuration: 3000, + queue: chatQueue, + init, + run: async (payload: RunChatPayload, { init }) => { + await updateConversationStatus("running", payload.conversationId); + + try { + let creditForChat = 0; + + const { previousHistory, ...otherData } = payload.context; + + // Initialise mcp + const mcp = new MCP(); + await mcp.init(); + + // Prepare context with additional metadata + const context = { + // Currently this is assuming we only have one page in context + context: { + ...(otherData.page && otherData.page.length > 0 + ? { page: otherData.page[0] } + : {}), + }, + workpsaceId: init?.conversation.workspaceId, + resources: otherData.resources, + todayDate: new Date().toISOString(), + }; + + // Extract user's goal from conversation history + const message = init?.conversationHistory?.message; + // Retrieve execution history from previous interactions + const previousExecutionHistory = getPreviousExecutionHistory( + previousHistory ?? [], + ); + + let agentUserMessage = ""; + let agentConversationHistory; + let stepHistory: HistoryStep[] = []; + // Prepare conversation history in agent-compatible format + agentConversationHistory = await createConversationHistoryForAgent( + payload.conversationId, + ); + + const llmResponse = run( + message as string, + context, + previousExecutionHistory, + mcp, + stepHistory, + ); + + const stream = await metadata.stream("messages", llmResponse); + + let conversationStatus = "success"; + for await (const step of stream) { + if (step.type === "STEP") { + creditForChat += 1; + const stepDetails = JSON.parse(step.message as string); + + if (stepDetails.skillStatus === ActionStatusEnum.TOOL_REQUEST) { + conversationStatus = "need_approval"; + } + + if (stepDetails.skillStatus === ActionStatusEnum.QUESTION) { + conversationStatus = "need_attention"; + } + + await updateExecutionStep( + { ...stepDetails }, + agentConversationHistory.id, + ); + + agentUserMessage += stepDetails.userMessage; + + await updateConversationHistoryMessage( + agentUserMessage, + agentConversationHistory.id, + ); + } else if (step.type === "STREAM_END") { + break; + } + } + + await updateConversationStatus( + conversationStatus, + payload.conversationId, + ); + + // await addToMemory( + // init.conversation.id, + // message, + // agentUserMessage, + // init.preferences, + // init.userName, + // ); + + if (init?.tokenId) { + await deletePersonalAccessToken(init.tokenId); + } + } catch (e) { + await updateConversationStatus("failed", payload.conversationId); + if (init?.tokenId) { + await deletePersonalAccessToken(init.tokenId); + } + throw new Error(e as string); + } + }, +}); diff --git a/apps/webapp/app/trigger/chat/memory-utils.ts b/apps/webapp/app/trigger/chat/memory-utils.ts new file mode 100644 index 0000000..e99b692 --- /dev/null +++ b/apps/webapp/app/trigger/chat/memory-utils.ts @@ -0,0 +1,50 @@ +import { logger } from "@trigger.dev/sdk/v3"; +import axios from "axios"; + +// Memory API functions using axios interceptor +export interface SearchMemoryParams { + query: string; + validAt?: string; + startTime?: string; + endTime?: string; +} + +export interface AddMemoryParams { + message: string; + referenceTime?: string; + source?: string; + spaceId?: string; + sessionId?: string; + metadata?: any; +} + +export const searchMemory = async (params: SearchMemoryParams) => { + try { + const response = await axios.post("https://core::memory/search", params); + return response.data; + } catch (error) { + logger.error("Memory search failed", { error, params }); + return { error: "Memory search failed" }; + } +}; + +export const addMemory = async (params: AddMemoryParams) => { + try { + // Set defaults for required fields + const memoryInput = { + ...params, + episodeBody: params.message, + referenceTime: params.referenceTime || new Date().toISOString(), + source: params.source || "CORE", + }; + + const response = await axios.post( + "https://core::memory/ingest", + memoryInput, + ); + return response.data; + } catch (error) { + logger.error("Memory storage failed", { error, params }); + return { error: "Memory storage failed" }; + } +}; diff --git a/apps/webapp/app/trigger/chat/prompt.ts b/apps/webapp/app/trigger/chat/prompt.ts new file mode 100644 index 0000000..75e694b --- /dev/null +++ b/apps/webapp/app/trigger/chat/prompt.ts @@ -0,0 +1,131 @@ +export const REACT_SYSTEM_PROMPT = ` +You are a helpful AI assistant with access to user memory. Your primary capabilities are: + +1. **Memory-First Approach**: Always check user memory first to understand context and previous interactions +2. **Memory Management**: Help users store, retrieve, and organize information in their memory +3. **Contextual Assistance**: Use memory to provide personalized and contextual responses + + +{{CONTEXT}} + + + +- Always check memory FIRST using core--search_memory before any other actions +- Consider this your highest priority for EVERY interaction - as essential as breathing +- Make memory checking your first tool call before any other operations + +QUERY FORMATION: +- Write specific factual statements as queries (e.g., "user email address" not "what is the user's email?") +- Create multiple targeted memory queries for complex requests + +KEY QUERY AREAS: +- Personal context: user name, location, identity, work context +- Project context: repositories, codebases, current work, team members +- Task context: recent tasks, ongoing projects, deadlines, priorities +- Integration context: GitHub repos, Slack channels, Linear projects, connected services +- Communication patterns: email preferences, notification settings, workflow automation +- Technical context: coding languages, frameworks, development environment +- Collaboration context: team members, project stakeholders, meeting patterns +- Preferences: likes, dislikes, communication style, tool preferences +- History: previous discussions, past requests, completed work, recurring issues +- Automation rules: user-defined workflows, triggers, automation preferences + +MEMORY USAGE: +- Execute multiple memory queries in parallel rather than sequentially +- Batch related memory queries when possible +- Prioritize recent information over older memories +- Create comprehensive context-aware queries based on user message/activity content +- Extract and query SEMANTIC CONTENT, not just structural metadata +- Parse titles, descriptions, and content for actual subject matter keywords +- Search internal SOL tasks/conversations that may relate to the same topics +- Query ALL relatable concepts, not just direct keywords or IDs +- Search for similar past situations, patterns, and related work +- Include synonyms, related terms, and contextual concepts in queries +- Query user's historical approach to similar requests or activities +- Search for connected projects, tasks, conversations, and collaborations +- Retrieve workflow patterns and past decision-making context +- Query broader domain context beyond immediate request scope +- Remember: SOL tracks work that external tools don't - search internal content thoroughly +- Blend memory insights naturally into responses +- Verify you've checked relevant memory before finalizing ANY response + +If memory access is unavailable, rely only on the current conversation or ask user + + + +You have tools at your disposal to assist users: + +CORE PRINCIPLES: +- Use tools only when necessary for the task at hand +- Always check memory FIRST before making other tool calls +- Execute multiple operations in parallel whenever possible +- Use sequential calls only when output of one is required for input of another + +PARAMETER HANDLING: +- Follow tool schemas exactly with all required parameters +- Only use values that are: + • Explicitly provided by the user (use EXACTLY as given) + • Reasonably inferred from context + • Retrieved from memory or prior tool calls +- Never make up values for required parameters +- Omit optional parameters unless clearly needed +- Analyze user's descriptive terms for parameter clues + +TOOL SELECTION: +- Never call tools not provided in this conversation +- Skip tool calls for general questions you can answer directly +- For identical operations on multiple items, use parallel tool calls +- Default to parallel execution (3-5× faster than sequential calls) +- You can always access external service tools by loading them with load_mcp first + +TOOL MENTION HANDLING: +When user message contains : +- Extract tool_name from data-id attribute +- First check if it's a built-in tool; if not, check EXTERNAL SERVICES TOOLS +- If available: Load it with load_mcp and focus on addressing the request with this tool +- If unavailable: Inform user and suggest alternatives if possible +- For multiple tool mentions: Load all applicable tools in a single load_mcp call + +ERROR HANDLING: +- If a tool returns an error, try fixing parameters before retrying +- If you can't resolve an error, explain the issue to the user +- Consider alternative tools when primary tools are unavailable + + + +Use EXACTLY ONE of these formats for all user-facing communication: + +PROGRESS UPDATES - During processing: +- Use the core--progress_update tool to keep users informed +- Update users about what you're discovering or doing next +- Keep messages clear and user-friendly +- Avoid technical jargon + +QUESTIONS - When you need information: + +

                                                  [Your question with HTML formatting]

                                                  +
                                                  + +- Ask questions only when you cannot find information through memory or tools +- Be specific about what you need to know +- Provide context for why you're asking + +FINAL ANSWERS - When completing tasks: + +

                                                  [Your answer with HTML formatting]

                                                  +
                                                  + +CRITICAL: +- Use ONE format per turn +- Apply proper HTML formatting (

                                                  ,

                                                  ,

                                                  ,

                                                    ,
                                                  • , etc.) +- Never mix communication formats +- Keep responses clear and helpful + +`; + +export const REACT_USER_PROMPT = ` +Here is the user message: + +{{USER_MESSAGE}} + +`; diff --git a/apps/webapp/app/trigger/chat/stream-utils.ts b/apps/webapp/app/trigger/chat/stream-utils.ts new file mode 100644 index 0000000..f9773e4 --- /dev/null +++ b/apps/webapp/app/trigger/chat/stream-utils.ts @@ -0,0 +1,264 @@ +import fs from "fs"; +import path from "node:path"; + +import { anthropic } from "@ai-sdk/anthropic"; +import { google } from "@ai-sdk/google"; +import { openai } from "@ai-sdk/openai"; +import { logger } from "@trigger.dev/sdk/v3"; +import { + type CoreMessage, + type LanguageModelV1, + streamText, + type ToolSet, +} from "ai"; +import { createOllama } from "ollama-ai-provider"; + +import { type AgentMessageType, Message } from "./types"; + +interface State { + inTag: boolean; + messageEnded: boolean; + message: string; + lastSent: string; +} + +export interface ExecutionState { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + agentFlow: any; + userMessage: string; + message: string; +} + +export async function* processTag( + state: State, + totalMessage: string, + chunk: string, + startTag: string, + endTag: string, + states: { start: string; chunk: string; end: string }, + extraParams: Record = {}, +) { + let comingFromStart = false; + + if (!state.messageEnded) { + if (!state.inTag) { + const startIndex = totalMessage.indexOf(startTag); + if (startIndex !== -1) { + state.inTag = true; + // Send MESSAGE_START when we first enter the tag + yield Message("", states.start as AgentMessageType, extraParams); + const chunkToSend = totalMessage.slice(startIndex + startTag.length); + state.message += chunkToSend; + comingFromStart = true; + } + } + + if (state.inTag) { + // Check if chunk contains end tag + const hasEndTag = chunk.includes(endTag); + const hasStartTag = chunk.includes(startTag); + const hasClosingTag = chunk.includes(" void, + tools?: ToolSet, + system?: string, + model?: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any +): AsyncGenerator< + | string + | { + type: string; + toolName: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + args?: any; + toolCallId?: string; + message?: string; + } +> { + // Check for API keys + const anthropicKey = process.env.ANTHROPIC_API_KEY; + const googleKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY; + const openaiKey = process.env.OPENAI_API_KEY; + let ollamaUrl = process.env.OLLAMA_URL; + model = model || process.env.MODEL; + + let modelInstance; + let modelTemperature = Number(process.env.MODEL_TEMPERATURE) || 1; + ollamaUrl = undefined; + + // First check if Ollama URL exists and use Ollama + if (ollamaUrl) { + const ollama = createOllama({ + baseURL: ollamaUrl, + }); + modelInstance = ollama(model || "llama2"); // Default to llama2 if no model specified + } else { + // If no Ollama, check other models + switch (model) { + case "claude-3-7-sonnet-20250219": + case "claude-3-opus-20240229": + case "claude-3-5-haiku-20241022": + if (!anthropicKey) { + throw new Error("No Anthropic API key found. Set ANTHROPIC_API_KEY"); + } + modelInstance = anthropic(model); + modelTemperature = 0.5; + break; + + case "gemini-2.5-flash-preview-04-17": + case "gemini-2.5-pro-preview-03-25": + case "gemini-2.0-flash": + case "gemini-2.0-flash-lite": + if (!googleKey) { + throw new Error("No Google API key found. Set GOOGLE_API_KEY"); + } + modelInstance = google(model); + break; + + case "gpt-4.1-2025-04-14": + case "gpt-4.1-mini-2025-04-14": + case "gpt-4.1-nano-2025-04-14": + if (!openaiKey) { + throw new Error("No OpenAI API key found. Set OPENAI_API_KEY"); + } + modelInstance = openai(model); + break; + + default: + break; + } + } + + logger.info("starting stream"); + // Try Anthropic next if key exists + if (modelInstance) { + try { + const { textStream, fullStream } = streamText({ + model: modelInstance as LanguageModelV1, + messages, + temperature: modelTemperature, + maxSteps: 10, + tools, + ...(isProgressUpdate + ? { toolChoice: { type: "tool", toolName: "core--progress_update" } } + : {}), + toolCallStreaming: true, + onFinish, + ...(system ? { system } : {}), + }); + + for await (const chunk of textStream) { + yield chunk; + } + + for await (const fullChunk of fullStream) { + if (fullChunk.type === "tool-call") { + yield { + type: "tool-call", + toolName: fullChunk.toolName, + toolCallId: fullChunk.toolCallId, + args: fullChunk.args, + }; + } + + if (fullChunk.type === "error") { + // Log the error to a file + const errorLogsDir = path.join(__dirname, "../../../../logs/errors"); + + // Ensure the directory exists + try { + if (!fs.existsSync(errorLogsDir)) { + fs.mkdirSync(errorLogsDir, { recursive: true }); + } + + // Create a timestamped error log file + const timestamp = new Date().toISOString().replace(/:/g, "-"); + const errorLogPath = path.join( + errorLogsDir, + `llm-error-${timestamp}.json`, + ); + + // Write the error to the file + fs.writeFileSync( + errorLogPath, + JSON.stringify({ + timestamp: new Date().toISOString(), + error: fullChunk.error, + }), + ); + + logger.error(`LLM error logged to ${errorLogPath}`); + } catch (err) { + logger.error(`Failed to log LLM error: ${err}`); + } + } + } + return; + } catch (e) { + console.log(e); + logger.error(e as string); + } + } + + throw new Error("No valid LLM configuration found"); +} diff --git a/apps/webapp/app/trigger/chat/types.ts b/apps/webapp/app/trigger/chat/types.ts new file mode 100644 index 0000000..61c2342 --- /dev/null +++ b/apps/webapp/app/trigger/chat/types.ts @@ -0,0 +1,46 @@ +export interface AgentStep { + agent: string; + goal: string; + reasoning: string; +} + +export enum AgentMessageType { + STREAM_START = 'STREAM_START', + STREAM_END = 'STREAM_END', + + // Used in ReACT based prompting + THOUGHT_START = 'THOUGHT_START', + THOUGHT_CHUNK = 'THOUGHT_CHUNK', + THOUGHT_END = 'THOUGHT_END', + + // Message types + MESSAGE_START = 'MESSAGE_START', + MESSAGE_CHUNK = 'MESSAGE_CHUNK', + MESSAGE_END = 'MESSAGE_END', + + // This is used to return action input + SKILL_START = 'SKILL_START', + SKILL_CHUNK = 'SKILL_CHUNK', + SKILL_END = 'SKILL_END', + + STEP = 'STEP', + ERROR = 'ERROR', +} + +export interface AgentMessage { + message?: string; + type: AgentMessageType; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + metadata: Record; +} + +export const Message = ( + message: string, + type: AgentMessageType, + extraParams: Record = {}, +): AgentMessage => { + // For all message types, we use the message field + // The type field differentiates how the message should be interpreted + // For STEP and SKILL types, the message can contain JSON data as a string + return { message, type, metadata: extraParams }; +}; diff --git a/apps/webapp/app/trigger/conversation/create-conversation-title.ts b/apps/webapp/app/trigger/conversation/create-conversation-title.ts new file mode 100644 index 0000000..ed66966 --- /dev/null +++ b/apps/webapp/app/trigger/conversation/create-conversation-title.ts @@ -0,0 +1,62 @@ +import { PrismaClient } from "@prisma/client"; +import { LLMMappings } from "@core/types"; +import { logger, task } from "@trigger.dev/sdk/v3"; +import { generate } from "../chat/stream-utils"; +import { conversationTitlePrompt } from "./prompt"; + +const prisma = new PrismaClient(); +export const createConversationTitle = task({ + id: "create-conversation-title", + run: async (payload: { conversationId: string; message: string }) => { + let conversationTitleResponse = ""; + const gen = generate( + [ + { + role: "user", + content: conversationTitlePrompt.replace( + "{{message}}", + payload.message, + ), + }, + ], + false, + () => {}, + undefined, + "", + LLMMappings.CLAUDESONNET, + ); + + for await (const chunk of gen) { + if (typeof chunk === "string") { + conversationTitleResponse += chunk; + } else if (chunk && typeof chunk === "object" && chunk.message) { + conversationTitleResponse += chunk.message; + } + } + + const outputMatch = conversationTitleResponse.match( + /(.*?)<\/output>/s, + ); + + logger.info(`Conversation title data: ${JSON.stringify(outputMatch)}`); + + if (!outputMatch) { + logger.error("No output found in recurrence response"); + throw new Error("Invalid response format from AI"); + } + + const jsonStr = outputMatch[1].trim(); + const conversationTitleData = JSON.parse(jsonStr); + + if (conversationTitleData) { + await prisma.conversation.update({ + where: { + id: payload.conversationId, + }, + data: { + title: conversationTitleData.title, + }, + }); + } + }, +}); diff --git a/apps/webapp/app/trigger/conversation/prompt.ts b/apps/webapp/app/trigger/conversation/prompt.ts new file mode 100644 index 0000000..f5a7e98 --- /dev/null +++ b/apps/webapp/app/trigger/conversation/prompt.ts @@ -0,0 +1,28 @@ +export const conversationTitlePrompt = `You are an AI assistant specialized in generating concise and informative conversation titles. Your task is to analyze the given message and context to create an appropriate title. + +Here is the message: + +{{message}} + + +Please follow these steps: + - Extract the core topic/intent from the message + - Create a clear, concise title + - Focus on the main subject or action + - Avoid unnecessary words + - Maximum length: 60 characters + +Before providing output, analyze in tags: +- Key elements from message +- Main topic/action +- Relevant actors/context +- Your title formation process + +Provide final output in this format: + +{ + "title": "Your generated title" +} + + +If message is empty or contains no meaningful content, return {"title": "New Conversation"}`; diff --git a/apps/webapp/app/trigger/integrations/integration-run-schedule.ts b/apps/webapp/app/trigger/integrations/integration-run-schedule.ts new file mode 100644 index 0000000..c2fb7a9 --- /dev/null +++ b/apps/webapp/app/trigger/integrations/integration-run-schedule.ts @@ -0,0 +1,38 @@ +// import { PrismaClient } from "@prisma/client"; +// import { IntegrationPayloadEventType } from "@core/types"; +// import { logger, schedules, tasks } from "@trigger.dev/sdk/v3"; + +// import { integrationRun } from "./integration-run"; + +// const prisma = new PrismaClient(); + +// export const integrationRunSchedule = schedules.task({ +// id: "integration-run-schedule", +// run: async (payload) => { +// const { externalId } = payload; +// const integrationAccount = await prisma.integrationAccount.findUnique({ +// where: { id: externalId }, +// include: { +// integrationDefinition: true, +// workspace: true, +// }, +// }); + +// if (!integrationAccount) { +// const deletedSchedule = await schedules.del(externalId); +// logger.info("Deleting schedule as integration account is not there"); +// return deletedSchedule; +// } + +// const pat = await prisma.personalAccessToken.findFirst({ +// where: { userId: integrationAccount.workspace.userId, name: "default" }, +// }); + +// return await tasks.trigger("integration-run", { +// event: IntegrationPayloadEventType.SCHEDULED_SYNC, +// pat: pat.token, +// integrationAccount, +// integrationDefinition: integrationAccount.integrationDefinition, +// }); +// }, +// }); diff --git a/apps/webapp/app/trigger/integrations/integration-run.ts b/apps/webapp/app/trigger/integrations/integration-run.ts new file mode 100644 index 0000000..e3b49e0 --- /dev/null +++ b/apps/webapp/app/trigger/integrations/integration-run.ts @@ -0,0 +1,87 @@ +// import createLoadRemoteModule, { +// createRequires, +// } from "@paciolan/remote-module-loader"; + +// import { logger, task } from "@trigger.dev/sdk/v3"; +// import axios from "axios"; + +// const fetcher = async (url: string) => { +// // Handle remote URLs with axios +// const response = await axios.get(url); + +// return response.data; +// }; + +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// const loadRemoteModule = async (requires: any) => +// createLoadRemoteModule({ fetcher, requires }); + +// function createAxiosInstance(token: string) { +// const instance = axios.create(); + +// instance.interceptors.request.use((config) => { +// // Check if URL starts with /api and doesn't have a full host +// if (config.url?.startsWith("/api")) { +// config.url = `${process.env.BACKEND_HOST}${config.url.replace("/api/", "/")}`; +// } + +// if ( +// config.url.includes(process.env.FRONTEND_HOST) || +// config.url.includes(process.env.BACKEND_HOST) +// ) { +// config.headers.Authorization = `Bearer ${token}`; +// } + +// return config; +// }); + +// return instance; +// } + +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// const getRequires = (axios: any) => createRequires({ axios }); + +// export const integrationRun = task({ +// id: "integration-run", +// run: async ({ +// pat, +// eventBody, +// integrationAccount, +// integrationDefinition, +// event, +// }: { +// pat: string; +// // This is the event you want to pass to the integration +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// event: any; +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// eventBody?: any; +// integrationDefinition: IntegrationDefinition; +// integrationAccount?: IntegrationAccount; +// }) => { +// const remoteModuleLoad = await loadRemoteModule( +// getRequires(createAxiosInstance(pat)), +// ); + +// logger.info( +// `${integrationDefinition.url}/${integrationDefinition.version}/backend/index.js`, +// ); + +// const integrationFunction = await remoteModuleLoad( +// `${integrationDefinition.url}/${integrationDefinition.version}/backend/index.js`, +// ); + +// // const integrationFunction = await remoteModuleLoad( +// // `${integrationDefinition.url}`, +// // ); + +// return await integrationFunction.run({ +// integrationAccount, +// integrationDefinition, +// event, +// eventBody: { +// ...(eventBody ? eventBody : {}), +// }, +// }); +// }, +// }); diff --git a/apps/webapp/app/trigger/integrations/scheduler.ts b/apps/webapp/app/trigger/integrations/scheduler.ts new file mode 100644 index 0000000..90b8eef --- /dev/null +++ b/apps/webapp/app/trigger/integrations/scheduler.ts @@ -0,0 +1,64 @@ +// import { PrismaClient } from "@prisma/client"; +// import { logger, schedules, task } from "@trigger.dev/sdk/v3"; + +// import { integrationRunSchedule } from "./integration-run-schedule"; + +// const prisma = new PrismaClient(); + +// export const scheduler = task({ +// id: "scheduler", +// run: async (payload: { integrationAccountId: string }) => { +// const { integrationAccountId } = payload; + +// const integrationAccount = await prisma.integrationAccount.findUnique({ +// where: { id: integrationAccountId, deleted: null }, +// include: { +// integrationDefinition: true, +// workspace: true, +// }, +// }); + +// if (!integrationAccount) { +// logger.error("Integration account not found"); +// return null; +// } + +// if (!integrationAccount.workspace) { +// return null; +// } + +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// const spec = integrationAccount.integrationDefinition.spec as any; + +// if (spec.schedule && spec.schedule.frequency) { +// const createdSchedule = await schedules.create({ +// // The id of the scheduled task you want to attach to. +// task: integrationRunSchedule.id, +// // The schedule in cron format. +// cron: spec.schedule.frequency, +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// timezone: (integrationAccount.workspace.preferences as any).timezone, +// // this is required, it prevents you from creating duplicate schedules. It will update the schedule if it already exists. +// deduplicationKey: integrationAccount.id, +// externalId: integrationAccount.id, +// }); + +// await prisma.integrationAccount.update({ +// where: { +// id: integrationAccount.id, +// }, +// data: { +// settings: { +// // eslint-disable-next-line @typescript-eslint/no-explicit-any +// ...(integrationAccount.settings as any), +// scheduleId: createdSchedule.id, +// }, +// }, +// }); + +// return createdSchedule; +// } + +// return "No schedule for this task"; +// }, +// }); diff --git a/apps/webapp/app/trigger/utils/mcp.ts b/apps/webapp/app/trigger/utils/mcp.ts new file mode 100644 index 0000000..85d7ab4 --- /dev/null +++ b/apps/webapp/app/trigger/utils/mcp.ts @@ -0,0 +1,151 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { logger } from "@trigger.dev/sdk/v3"; +import { jsonSchema, tool, type ToolSet } from "ai"; + +import { type MCPTool } from "./types"; + +export class MCP { + private Client: any; + private clients: Record = {}; + private StdioTransport: any; + + constructor() {} + + public async init() { + this.Client = await MCP.importClient(); + this.StdioTransport = await MCP.importStdioTransport(); + } + + private static async importClient() { + const { Client } = await import( + "@modelcontextprotocol/sdk/client/index.js" + ); + return Client; + } + + async load(agents: string[], mcpConfig: any) { + await Promise.all( + agents.map(async (agent) => { + const mcp = mcpConfig.mcpServers[agent]; + + return await this.connectToServer(agent, mcp.command, mcp.args, { + ...mcp.env, + DATABASE_URL: mcp.env?.DATABASE_URL ?? "", + }); + }), + ); + } + + private static async importStdioTransport() { + const { StdioClientTransport } = await import("./stdio"); + return StdioClientTransport; + } + + async allTools(): Promise { + const clientEntries = Object.entries(this.clients); + + // Fetch all tools in parallel + const toolsArrays = await Promise.all( + clientEntries.map(async ([clientKey, client]) => { + try { + const { tools } = await client.listTools(); + return tools.map(({ name, description, inputSchema }: any) => [ + `${clientKey}--${name}`, + tool({ + description, + parameters: jsonSchema(inputSchema), + }), + ]); + } catch (error) { + logger.error(`Error fetching tools for ${clientKey}:`, { error }); + return []; + } + }), + ); + + // Flatten and convert to object + return Object.fromEntries(toolsArrays.flat()); + } + + async tools(): Promise { + const allTools: MCPTool[] = []; + + for (const clientKey in this.clients) { + const client = this.clients[clientKey]; + const { tools: clientTools } = await client.listTools(); + + for (const tool of clientTools) { + // Add client prefix to tool name + tool.name = `${clientKey}--${tool.name}`; + allTools.push(tool); + } + } + + return allTools; + } + + async getTool(name: string) { + try { + const clientKey = name.split("--")[0]; + const toolName = name.split("--")[1]; + const client = this.clients[clientKey]; + const { tools: clientTools } = await client.listTools(); + const clientTool = clientTools.find((to: any) => to.name === toolName); + + return JSON.stringify(clientTool); + } catch (e) { + logger.error((e as string) ?? "Getting tool failed"); + throw new Error("Getting tool failed"); + } + } + + async callTool(name: string, parameters: any) { + const clientKey = name.split("--")[0]; + const toolName = name.split("--")[1]; + + const client = this.clients[clientKey]; + + const response = await client.callTool({ + name: toolName, + arguments: parameters, + }); + + return response; + } + + async connectToServer( + name: string, + command: string, + args: string[], + env: any, + ) { + try { + const client = new this.Client( + { + name, + version: "1.0.0", + }, + { + capabilities: {}, + }, + ); + + // Conf + // igure the transport for MCP server + const transport = new this.StdioTransport({ + command, + args, + env, + }); + + // Connect to the MCP server + await client.connect(transport, { timeout: 60 * 1000 * 5 }); + this.clients[name] = client; + + logger.info(`Connected to ${name} MCP server`); + } catch (e) { + logger.error(`Failed to connect to ${name} MCP server: `, { e }); + throw e; + } + } +} diff --git a/apps/webapp/app/trigger/utils/stdio.ts b/apps/webapp/app/trigger/utils/stdio.ts new file mode 100644 index 0000000..bf4db1f --- /dev/null +++ b/apps/webapp/app/trigger/utils/stdio.ts @@ -0,0 +1,256 @@ +import { type ChildProcess, type IOType } from "node:child_process"; +import process from "node:process"; +import { type Stream } from "node:stream"; + +import { type Transport } from "@modelcontextprotocol/sdk/shared/transport"; +import { + type JSONRPCMessage, + JSONRPCMessageSchema, +} from "@modelcontextprotocol/sdk/types.js"; +import { execa } from "execa"; + +/** + * Buffers a continuous stdio stream into discrete JSON-RPC messages. + */ +export class ReadBuffer { + private _buffer?: Buffer; + + append(chunk: Buffer): void { + this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk; + } + + readMessage(): JSONRPCMessage | null { + if (!this._buffer) { + return null; + } + + const index = this._buffer.indexOf("\n"); + if (index === -1) { + return null; + } + + const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, ""); + this._buffer = this._buffer.subarray(index + 1); + return deserializeMessage(line); + } + + clear(): void { + this._buffer = undefined; + } +} + +export function deserializeMessage(line: string): JSONRPCMessage { + return JSONRPCMessageSchema.parse(JSON.parse(line)); +} + +export function serializeMessage(message: JSONRPCMessage): string { + return `${JSON.stringify(message)}\n`; +} + +export interface StdioServerParameters { + /** + * The executable to run to start the server. + */ + command: string; + + /** + * Command line arguments to pass to the executable. + */ + args?: string[]; + + /** + * The environment to use when spawning the process. + * + * If not specified, the result of getDefaultEnvironment() will be used. + */ + env?: Record; + + /** + * How to handle stderr of the child process. This matches the semantics of Node's `child_process.spawn`. + * + * The default is "inherit", meaning messages to stderr will be printed to the parent process's stderr. + */ + stderr?: IOType | Stream | number; + + /** + * The working directory to use when spawning the process. + * + * If not specified, the current working directory will be inherited. + */ + cwd?: string; +} + +/** + * Environment variables to inherit by default, if an environment is not explicitly given. + */ +export const DEFAULT_INHERITED_ENV_VARS = + process.platform === "win32" + ? [ + "APPDATA", + "HOMEDRIVE", + "HOMEPATH", + "LOCALAPPDATA", + "PATH", + "PROCESSOR_ARCHITECTURE", + "SYSTEMDRIVE", + "SYSTEMROOT", + "TEMP", + "USERNAME", + "USERPROFILE", + ] + : /* list inspired by the default env inheritance of sudo */ + ["HOME", "LOGNAME", "PATH", "SHELL", "TERM", "USER"]; + +/** + * Returns a default environment object including only environment variables deemed safe to inherit. + */ +export function getDefaultEnvironment(): Record { + const env: Record = {}; + + for (const key of DEFAULT_INHERITED_ENV_VARS) { + const value = process.env[key]; + if (value === undefined) { + continue; + } + + if (value.startsWith("()")) { + // Skip functions, which are a security risk. + continue; + } + + env[key] = value; + } + + return env; +} + +/** + * Client transport for stdio: this will connect to a server by spawning a process and communicating with it over stdin/stdout. + * + * This transport is only available in Node.js environments. + */ +export class StdioClientTransport implements Transport { + private _process?: ChildProcess; + private _abortController: AbortController = new AbortController(); + private _readBuffer: ReadBuffer = new ReadBuffer(); + private _serverParams: StdioServerParameters; + + onclose?: () => void; + onerror?: (error: Error) => void; + onmessage?: (message: JSONRPCMessage) => void; + + constructor(server: StdioServerParameters) { + this._serverParams = server; + } + + /** + * Starts the server process and prepares to communicate with it. + */ + async start(): Promise { + if (this._process) { + throw new Error( + "StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.", + ); + } + + return new Promise((resolve, reject) => { + this._process = execa( + this._serverParams.command, + this._serverParams.args ?? [], + { + env: this._serverParams.env ?? getDefaultEnvironment(), + stderr: "inherit", + shell: "/bin/sh", + windowsHide: process.platform === "win32" && isElectron(), + cwd: this._serverParams.cwd, + cancelSignal: this._abortController.signal, + stdin: "pipe", + stdout: "pipe", + }, + ); + + this._process.on("error", (error) => { + if (error.name === "AbortError") { + // Expected when close() is called. + this.onclose?.(); + return; + } + + reject(error); + this.onerror?.(error); + }); + + this._process.on("spawn", () => { + resolve(); + }); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + this._process.on("close", (_code) => { + this._process = undefined; + this.onclose?.(); + }); + + this._process.stdin?.on("error", (error) => { + this.onerror?.(error); + }); + + this._process.stdout?.on("data", (chunk) => { + this._readBuffer.append(chunk); + this.processReadBuffer(); + }); + + this._process.stdout?.on("error", (error) => { + this.onerror?.(error); + }); + }); + } + + /** + * The stderr stream of the child process, if `StdioServerParameters.stderr` was set to "pipe" or "overlapped". + * + * This is only available after the process has been started. + */ + get stderr(): Stream | null { + return this._process?.stderr ?? null; + } + + private processReadBuffer() { + while (true) { + try { + const message = this._readBuffer.readMessage(); + if (message === null) { + break; + } + + this.onmessage?.(message); + } catch (error) { + this.onerror?.(error as Error); + } + } + } + + async close(): Promise { + this._abortController.abort(); + this._process = undefined; + this._readBuffer.clear(); + } + + send(message: JSONRPCMessage): Promise { + return new Promise((resolve) => { + if (!this._process?.stdin) { + throw new Error("Not connected"); + } + + const json = serializeMessage(message); + if (this._process.stdin.write(json)) { + resolve(); + } else { + this._process.stdin.once("drain", resolve); + } + }); + } +} + +function isElectron() { + return "type" in process; +} diff --git a/apps/webapp/app/trigger/utils/types.ts b/apps/webapp/app/trigger/utils/types.ts new file mode 100644 index 0000000..2f3788a --- /dev/null +++ b/apps/webapp/app/trigger/utils/types.ts @@ -0,0 +1,123 @@ +import { type ActionStatusEnum } from "@core/types"; +import { type CoreMessage } from "ai"; + +// Define types for the MCP tool schema +export interface MCPTool { + name: string; + description: string; + inputSchema: { + type: string; + properties: Record; + required?: string[]; + additionalProperties: boolean; + $schema: string; + }; +} + +// Vercel AI SDK Tool Types +export type VercelAITools = Record< + string, + { + type: "function"; + description: string; + parameters: { + type: "object"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + properties: Record; + required?: string[]; + }; + } +>; + +export type SchemaProperty = + | { + type: string | string[]; + minimum?: number; + maximum?: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + default?: any; + minLength?: number; + pattern?: string; + enum?: string[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + items?: any; + properties?: Record; + required?: string[]; + additionalProperties?: boolean; + description?: string; + } + | { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + anyOf: any[]; + }; + +export interface Resource { + id?: string; + size?: number; + fileType: string; + publicURL: string; + originalName?: string; +} + +export interface ExecutionState { + query: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context?: string; + resources: Resource[]; + previousHistory?: CoreMessage[]; + history: HistoryStep[]; + userMemoryContext?: string; + automationContext?: string; + completed: boolean; +} + +export interface TokenCount { + inputTokens: number; + outputToken: number; +} + +export interface TotalCost { + inputTokens: number; + outputTokens: number; + cost: number; +} + +export interface HistoryStep { + agent?: string; + + // The agent's reasoning process for this step + thought?: string; + + // Indicates if this step contains a question for the user + isQuestion?: boolean; + // Indicates if this is the final response in the conversation + isFinal?: boolean; + isError?: boolean; + + // The name of the skill/tool being used in this step + skill?: string; + skillId?: string; + skillInput?: string; + skillOutput?: string; + skillStatus?: ActionStatusEnum; + + // This is when the action has run and the output will be put here + observation?: string; + + // This is what the user will read + userMessage?: string; + + // If the agent has run completely + completed?: boolean; + + // Token count + tokenCount: TotalCost; + + finalTokenCount?: TotalCost; +} + +export interface GenerateResponse { + text: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + toolCalls: any[]; +} diff --git a/apps/webapp/app/trigger/utils/utils.ts b/apps/webapp/app/trigger/utils/utils.ts new file mode 100644 index 0000000..db3d586 --- /dev/null +++ b/apps/webapp/app/trigger/utils/utils.ts @@ -0,0 +1,544 @@ +import { + type Activity, + type Conversation, + type ConversationHistory, + type IntegrationDefinitionV2, + type Prisma, + PrismaClient, + UserType, + type Workspace, +} from "@prisma/client"; + +import { logger } from "@trigger.dev/sdk/v3"; +import { type CoreMessage } from "ai"; + +import { type HistoryStep } from "./types"; +import axios from "axios"; +import nodeCrypto from "node:crypto"; +import { customAlphabet, nanoid } from "nanoid"; + +const prisma = new PrismaClient(); + +// Token generation utilities +const tokenValueLength = 40; +const tokenGenerator = customAlphabet( + "123456789abcdefghijkmnopqrstuvwxyz", + tokenValueLength, +); +const tokenPrefix = "rc_pat_"; + +type CreatePersonalAccessTokenOptions = { + name: string; + userId: string; +}; + +// Helper functions for token management +function createToken() { + return `${tokenPrefix}${tokenGenerator()}`; +} + +function obfuscateToken(token: string) { + const withoutPrefix = token.replace(tokenPrefix, ""); + const obfuscated = `${withoutPrefix.slice(0, 4)}${"•".repeat(18)}${withoutPrefix.slice(-4)}`; + return `${tokenPrefix}${obfuscated}`; +} + +function encryptToken(value: string) { + const encryptionKey = process.env.ENCRYPTION_KEY; + if (!encryptionKey) { + throw new Error("ENCRYPTION_KEY environment variable is required"); + } + + const nonce = nodeCrypto.randomBytes(12); + const cipher = nodeCrypto.createCipheriv("aes-256-gcm", encryptionKey, nonce); + + let encrypted = cipher.update(value, "utf8", "hex"); + encrypted += cipher.final("hex"); + + const tag = cipher.getAuthTag().toString("hex"); + + return { + nonce: nonce.toString("hex"), + ciphertext: encrypted, + tag, + }; +} + +function hashToken(token: string): string { + const hash = nodeCrypto.createHash("sha256"); + hash.update(token); + return hash.digest("hex"); +} + +export async function getOrCreatePersonalAccessToken({ + name, + userId, +}: CreatePersonalAccessTokenOptions) { + // Try to find an existing, non-revoked token + const existing = await prisma.personalAccessToken.findFirst({ + where: { + name, + userId, + revokedAt: null, + }, + }); + + if (existing) { + // Do not return the unencrypted token if it already exists + return { + id: existing.id, + name: existing.name, + userId: existing.userId, + obfuscatedToken: existing.obfuscatedToken, + // token is not returned + }; + } + + // Create a new token + const token = createToken(); + const encryptedToken = encryptToken(token); + + const personalAccessToken = await prisma.personalAccessToken.create({ + data: { + name, + userId, + encryptedToken, + obfuscatedToken: obfuscateToken(token), + hashedToken: hashToken(token), + }, + }); + + return { + id: personalAccessToken.id, + name, + userId, + token, + obfuscatedToken: personalAccessToken.obfuscatedToken, + }; +} + +export interface InitChatPayload { + conversationId: string; + conversationHistoryId: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context: any; + pat: string; +} + +export class Preferences { + timezone?: string; + + // Memory details + memory_host?: string; + memory_api_key?: string; +} + +export interface RunChatPayload { + conversationId: string; + conversationHistoryId: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + context: any; + conversation: Conversation; + conversationHistory: ConversationHistory; + pat: string; + isContinuation?: boolean; +} + +export const init = async ({ payload }: { payload: InitChatPayload }) => { + logger.info("Loading init"); + const conversationHistory = await prisma.conversationHistory.findUnique({ + where: { id: payload.conversationHistoryId }, + include: { conversation: true }, + }); + + const conversation = conversationHistory?.conversation as Conversation; + + const workspace = await prisma.workspace.findUnique({ + where: { id: conversation.workspaceId as string }, + }); + + if (!workspace) { + return { conversation, conversationHistory }; + } + + const randomKeyName = `chat_${nanoid(10)}`; + const pat = await getOrCreatePersonalAccessToken({ + name: randomKeyName, + userId: workspace.userId as string, + }); + + const user = await prisma.user.findFirst({ + where: { id: workspace.userId as string }, + }); + + const integrationAccounts = await prisma.integrationAccount.findMany({ + where: { + workspaceId: workspace.id, + }, + include: { integrationDefinition: true }, + }); + + // Set up axios interceptor for memory operations + axios.interceptors.request.use((config) => { + if (config.url?.startsWith("https://core::memory")) { + // Handle both search and ingest endpoints + if (config.url.includes("/search")) { + config.url = `${process.env.API_BASE_URL}/search`; + } else if (config.url.includes("/ingest")) { + config.url = `${process.env.API_BASE_URL}/ingest`; + } + config.headers.Authorization = `Bearer ${pat.token}`; + } + + return config; + }); + + // Create MCP server configurations for each integration account + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const integrationMCPServers: Record = {}; + + for (const account of integrationAccounts) { + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const spec = account.integrationDefinition?.spec as any; + if (spec.mcp) { + const mcpSpec = spec.mcp; + const configuredMCP = { ...mcpSpec }; + + // Replace config placeholders in environment variables + if (configuredMCP.env) { + for (const [key, value] of Object.entries(configuredMCP.env)) { + if (typeof value === "string" && value.includes("${config:")) { + // Extract the config key from the placeholder + const configKey = value.match(/\$\{config:(.*?)\}/)?.[1]; + if ( + configKey && + account.integrationConfiguration && + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (account.integrationConfiguration as any)[configKey] + ) { + configuredMCP.env[key] = value.replace( + `\${config:${configKey}}`, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (account.integrationConfiguration as any)[configKey], + ); + } + } + + if ( + typeof value === "string" && + value.includes("${integrationConfig:") + ) { + // Extract the config key from the placeholder + const configKey = value.match( + /\$\{integrationConfig:(.*?)\}/, + )?.[1]; + if ( + configKey && + account.integrationDefinition.config && + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (account.integrationDefinition.config as any)[configKey] + ) { + configuredMCP.env[key] = value.replace( + `\${integrationConfig:${configKey}}`, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (account.integrationDefinition.config as any)[configKey], + ); + } + } + } + } + + // Add to the MCP servers collection + integrationMCPServers[account.integrationDefinition.slug] = + configuredMCP; + } + } catch (error) { + logger.error( + `Failed to configure MCP for ${account.integrationDefinition?.slug}:`, + { error }, + ); + } + } + + return { + conversation, + conversationHistory, + tokenId: pat.id, + token: pat.token, + userId: user?.id, + userName: user?.name, + }; +}; + +export const createConversationHistoryForAgent = async ( + conversationId: string, +) => { + return await prisma.conversationHistory.create({ + data: { + conversationId, + message: "Generating...", + userType: "Agent", + thoughts: {}, + }, + }); +}; + +export const getConversationHistoryFormat = ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + previousHistory: any[], +): string => { + if (previousHistory) { + const historyText = previousHistory + .map((history) => `${history.userType}: \n ${history.message}`) + .join("\n------------\n"); + + return historyText; + } + + return ""; +}; + +export const getPreviousExecutionHistory = ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + previousHistory: any[], +): CoreMessage[] => { + return previousHistory.map((history) => ({ + role: history.userType === "User" ? "user" : "assistant", + content: history.message, + })); +}; + +export const getIntegrationDefinitionsForAgents = (agents: string[]) => { + return prisma.integrationDefinitionV2.findMany({ + where: { + slug: { + in: agents, + }, + }, + }); +}; + +export const getIntegrationConfigForIntegrationDefinition = ( + integrationDefinitionId: string, +) => { + return prisma.integrationAccount.findFirst({ + where: { + integrationDefinitionId, + }, + }); +}; + +export const updateExecutionStep = async ( + step: HistoryStep, + conversationHistoryId: string, +) => { + const { + thought, + userMessage, + skillInput, + skillOutput, + skillId, + skillStatus, + ...metadata + } = step; + + await prisma.conversationExecutionStep.create({ + data: { + thought: thought ?? "", + message: userMessage ?? "", + actionInput: + typeof skillInput === "object" + ? JSON.stringify(skillInput) + : skillInput, + actionOutput: + typeof skillOutput === "object" + ? JSON.stringify(skillOutput) + : skillOutput, + actionId: skillId, + actionStatus: skillStatus, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + metadata: metadata as any, + conversationHistoryId, + }, + }); +}; + +export const updateConversationHistoryMessage = async ( + userMessage: string, + conversationHistoryId: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + thoughts?: Record, +) => { + await prisma.conversationHistory.update({ + where: { + id: conversationHistoryId, + }, + data: { + message: userMessage, + thoughts, + userType: UserType.Agent, + }, + }); +}; + +export const getExecutionStepsForConversation = async ( + conversationHistoryId: string, +) => { + const lastExecutionSteps = await prisma.conversationExecutionStep.findMany({ + where: { + conversationHistoryId, + }, + }); + + return lastExecutionSteps; +}; + +export const getActivityDetails = async (activityId: string) => { + if (!activityId) { + return {}; + } + + const activity = await prisma.activity.findFirst({ + where: { + id: activityId, + }, + }); + + return { + activityId, + integrationAccountId: activity?.integrationAccountId, + sourceURL: activity?.sourceURL, + }; +}; + +/** + * Generates a random ID of 6 characters + * @returns A random string of 6 characters + */ +export const generateRandomId = (): string => { + // Define characters that can be used in the ID + const characters = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + let result = ""; + + // Generate 6 random characters + for (let i = 0; i < 6; i++) { + const randomIndex = Math.floor(Math.random() * characters.length); + result += characters.charAt(randomIndex); + } + + return result.toLowerCase(); +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function flattenObject(obj: Record, prefix = ""): string[] { + return Object.entries(obj).reduce((result, [key, value]) => { + const entryKey = prefix ? `${prefix}_${key}` : key; + + if (value !== null && typeof value === "object" && !Array.isArray(value)) { + // For nested objects, flatten them and add to results + return [...result, ...flattenObject(value, entryKey)]; + } + + // For primitive values or arrays, add directly + return [...result, `- ${entryKey}: ${value}`]; + }, []); +} + +export const updateConversationStatus = async ( + status: string, + conversationId: string, +) => { + const data: Prisma.ConversationUpdateInput = { status, unread: true }; + + return await prisma.conversation.update({ + where: { + id: conversationId, + }, + data, + }); +}; + +export const getActivity = async (activityId: string) => { + return await prisma.activity.findUnique({ + where: { + id: activityId, + }, + include: { + workspace: true, + integrationAccount: { + include: { + integrationDefinition: true, + }, + }, + }, + }); +}; + +export const updateActivity = async ( + activityId: string, + rejectionReason: string, +) => { + return await prisma.activity.update({ + where: { + id: activityId, + }, + data: { + rejectionReason, + }, + }); +}; + +export const createConversation = async ( + activity: Activity, + workspace: Workspace, + integrationDefinition: IntegrationDefinitionV2, + automationContext: { automations?: string[]; executionPlan: string }, +) => { + const conversation = await prisma.conversation.create({ + data: { + workspaceId: activity.workspaceId, + userId: workspace.userId as string, + title: activity.text.substring(0, 100), + ConversationHistory: { + create: { + userId: workspace.userId, + message: `Activity from ${integrationDefinition.name} \n Content: ${activity.text}`, + userType: UserType.User, + activityId: activity.id, + thoughts: { ...automationContext }, + }, + }, + }, + include: { + ConversationHistory: true, + }, + }); + + return conversation; +}; + +export async function getContinuationAgentConversationHistory( + conversationId: string, +): Promise { + return await prisma.conversationHistory.findFirst({ + where: { + conversationId, + userType: "Agent", + deleted: null, + }, + orderBy: { + createdAt: "desc", + }, + take: 1, + }); +} + +export async function deletePersonalAccessToken(tokenId: string) { + return await prisma.personalAccessToken.delete({ + where: { + id: tokenId, + }, + }); +} diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 561fdef..093076f 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -8,17 +8,23 @@ "dev": "node ./server.mjs", "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .", "start": "remix-serve ./build/server/index.js", - "typecheck": "tsc" + "typecheck": "tsc", + "trigger:dev": "pnpm dlx trigger.dev@v4-beta dev" }, "dependencies": { + "@ai-sdk/anthropic": "^1.2.12", + "@ai-sdk/google": "^1.2.22", "@ai-sdk/openai": "^1.3.21", "@coji/remix-auth-google": "^4.2.0", "@conform-to/react": "^0.6.1", "@conform-to/zod": "^0.6.1", "@core/database": "workspace:*", "@core/types": "workspace:*", - "@opentelemetry/api": "1.9.0", "@mjackson/headers": "0.11.1", + "@modelcontextprotocol/sdk": "1.13.2", + "@nichtsam/remix-auth-email-link": "3.0.0", + "@opentelemetry/api": "1.9.0", + "@prisma/client": "*", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-avatar": "^1.0.4", @@ -45,21 +51,40 @@ "@remix-run/server-runtime": "2.16.7", "@remix-run/v1-meta": "^0.1.3", "@remixicon/react": "^4.2.0", - "@tanstack/react-table": "^8.13.2", - "@prisma/client": "*", "@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/postcss": "^4.1.7", + "@tanstack/react-table": "^8.13.2", + "@tiptap/extension-document": "^2.11.9", + "@tiptap/extension-hard-break": "^2.11.9", + "@tiptap/extension-history": "^2.11.9", + "@tiptap/extension-paragraph": "^2.11.9", + "@tiptap/extension-text": "^2.11.9", + "@tiptap/starter-kit": "2.11.9", + "@tiptap/react": "^2.11.9", + "@tiptap/pm": "^2.11.9", + "@trigger.dev/sdk": "^4.0.0-v4-beta.22", + "@trigger.dev/react-hooks": "^4.0.0-v4-beta.22", "ai": "4.3.14", + "axios": "^1.10.0", "bullmq": "^5.53.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "compression": "^1.7.4", "cross-env": "^7.0.3", + "class-transformer": "0.5.1", + "class-validator": "0.14.1", "d3": "^7.9.0", - "dayjs": "^1.11.10", "date-fns": "^4.1.0", - "express": "^4.18.1", + "dayjs": "^1.11.10", "emails": "workspace:*", + "execa": "^9.6.0", + "express": "^4.18.1", + "fast-sort": "^3.4.0", + "graphology": "^0.26.0", + "graphology-layout-force": "^0.2.4", + "graphology-layout-forceatlas2": "^0.10.1", + "graphology-layout-noverlap": "^0.4.2", + "handlebars": "^4.7.8", "ioredis": "^5.6.1", "isbot": "^4.1.0", "jose": "^5.2.3", @@ -68,18 +93,21 @@ "nanoid": "3.3.8", "neo4j-driver": "^5.28.1", "non.geist": "^1.0.2", + "novel": "^1.0.2", "ollama-ai-provider": "1.2.0", "posthog-js": "^1.116.6", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-resizable-panels": "^1.0.9", + "react-virtualized": "^9.22.6", "remix-auth": "^4.2.0", - "@nichtsam/remix-auth-email-link": "3.0.0", "remix-auth-oauth2": "^3.4.1", "remix-themes": "^1.3.1", "remix-typedjson": "0.3.1", "remix-utils": "^7.7.0", - "react-resizable-panels": "^1.0.9", - "react-virtualized": "^9.22.6", + "sdk": "link:@modelcontextprotocol/sdk", + "sigma": "^3.0.2", + "simple-oauth2": "^5.1.0", "tailwind-merge": "^2.6.0", "tailwind-scrollbar-hide": "^2.0.0", "tailwindcss-animate": "^1.0.7", @@ -96,12 +124,15 @@ "@tailwindcss/forms": "^0.5.10", "@tailwindcss/typography": "^0.5.16", "@tailwindcss/vite": "^4.1.7", + "@trigger.dev/build": "^4.0.0-v4-beta.22", "@types/compression": "^1.7.2", "@types/d3": "^7.4.3", "@types/express": "^4.17.13", "@types/morgan": "^1.9.3", + "@types/simple-oauth2": "^5.0.7", "@types/react": "^18.2.20", "@types/react-dom": "^18.2.7", + "@types/react-virtualized": "^9.22.0", "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "autoprefixer": "^10.4.19", diff --git a/apps/webapp/prisma/schema.prisma b/apps/webapp/prisma/schema.prisma new file mode 100644 index 0000000..2d80e73 --- /dev/null +++ b/apps/webapp/prisma/schema.prisma @@ -0,0 +1,378 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DIRECT_URL") +} + +generator client { + provider = "prisma-client-js" + binaryTargets = ["native", "debian-openssl-1.1.x"] + previewFeatures = ["tracing"] +} + +model Activity { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + text String + // Used to link the task or activity to external apps + sourceURL String? + + integrationAccount IntegrationAccount? @relation(fields: [integrationAccountId], references: [id]) + integrationAccountId String? + + rejectionReason String? + + workspace Workspace @relation(fields: [workspaceId], references: [id]) + workspaceId String + + WebhookDeliveryLog WebhookDeliveryLog[] + + ConversationHistory ConversationHistory[] +} + +model AuthorizationCode { + id String @id @default(cuid()) + + code String @unique + + personalAccessToken PersonalAccessToken? @relation(fields: [personalAccessTokenId], references: [id], onDelete: Cascade, onUpdate: Cascade) + personalAccessTokenId String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Conversation { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + unread Boolean @default(false) + + title String? + user User @relation(fields: [userId], references: [id]) + userId String + + workspace Workspace? @relation(fields: [workspaceId], references: [id]) + workspaceId String? + + status String @default("pending") // Can be "pending", "running", "completed", "failed", "need_attention" + + ConversationHistory ConversationHistory[] +} + +model ConversationExecutionStep { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + thought String + message String + + actionId String? + actionOutput String? + actionInput String? + actionStatus String? + + metadata Json? @default("{}") + + conversationHistory ConversationHistory @relation(fields: [conversationHistoryId], references: [id]) + conversationHistoryId String +} + +model ConversationHistory { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + message String + userType UserType + + activity Activity? @relation(fields: [activityId], references: [id]) + activityId String? + + context Json? + + thoughts Json? + user User? @relation(fields: [userId], references: [id]) + userId String? + + conversation Conversation @relation(fields: [conversationId], references: [id]) + conversationId String + ConversationExecutionStep ConversationExecutionStep[] +} + +model Entity { + id String @id @default(cuid()) + name String @unique // e.g., "User", "Issue", "Task", "Automation" + metadata Json // Store field definitions and their types + + // Relations + spaceEntities SpaceEntity[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model IngestionQueue { + id String @id @default(cuid()) + + // Relations + space Space? @relation(fields: [spaceId], references: [id]) + spaceId String? + + // Queue metadata + data Json // The actual data to be processed + output Json? // The processed output data + status IngestionStatus + priority Int @default(0) + + workspaceId String + workspace Workspace @relation(fields: [workspaceId], references: [id]) + + // Error handling + error String? + retryCount Int @default(0) + + // Timestamps + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + processedAt DateTime? +} + +model IntegrationAccount { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + integrationConfiguration Json + accountId String? + settings Json? + isActive Boolean @default(true) + + integratedBy User @relation(references: [id], fields: [integratedById]) + integratedById String + integrationDefinition IntegrationDefinitionV2 @relation(references: [id], fields: [integrationDefinitionId]) + integrationDefinitionId String + workspace Workspace @relation(references: [id], fields: [workspaceId]) + workspaceId String + Activity Activity[] + + @@unique([accountId, integrationDefinitionId, workspaceId]) +} + +model IntegrationDefinitionV2 { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + name String @unique + slug String + description String + icon String + config Json? + spec Json @default("{}") + version String? + url String? + + workspace Workspace? @relation(references: [id], fields: [workspaceId]) + workspaceId String? + + IntegrationAccount IntegrationAccount[] +} + +model InvitationCode { + id String @id @default(cuid()) + code String @unique + + users User[] + + createdAt DateTime @default(now()) +} + +model PersonalAccessToken { + id String @id @default(cuid()) + + /// If generated by the CLI this will be "cli", otherwise user-provided + name String + + /// This is the token encrypted using the ENCRYPTION_KEY + encryptedToken Json + + /// This is shown in the UI, with ******** + obfuscatedToken String + + /// This is used to find the token in the database + hashedToken String @unique + + user User @relation(fields: [userId], references: [id]) + userId String + + revokedAt DateTime? + lastAccessedAt DateTime? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + authorizationCodes AuthorizationCode[] +} + +model Space { + id String @id @default(cuid()) + name String + description String? + autoMode Boolean @default(false) + + // Relations + user User @relation(fields: [userId], references: [id]) + userId String + + // Space's enabled entities + enabledEntities SpaceEntity[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + IngestionQueue IngestionQueue[] +} + +model SpaceEntity { + id String @id @default(cuid()) + + // Relations + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + entity Entity @relation(fields: [entityId], references: [id]) + entityId String + + // Custom settings for this entity in this space + settings Json? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@unique([spaceId, entityId]) +} + +model User { + id String @id @default(cuid()) + email String @unique + + authenticationMethod AuthenticationMethod + authenticationProfile Json? + authenticationExtraParams Json? + authIdentifier String? @unique + + displayName String? + name String? + avatarUrl String? + + memoryFilter String? // Adding memory filter instructions + + admin Boolean @default(false) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + marketingEmails Boolean @default(true) + confirmedBasicDetails Boolean @default(false) + + referralSource String? + + personalAccessTokens PersonalAccessToken[] + InvitationCode InvitationCode? @relation(fields: [invitationCodeId], references: [id]) + invitationCodeId String? + Space Space[] + Workspace Workspace? + IntegrationAccount IntegrationAccount[] + WebhookConfiguration WebhookConfiguration[] + Conversation Conversation[] + ConversationHistory ConversationHistory[] +} + +model WebhookConfiguration { + id String @id @default(cuid()) + url String + secret String? + isActive Boolean @default(true) + eventTypes String[] // List of event types this webhook is interested in, e.g. ["activity.created"] + user User? @relation(fields: [userId], references: [id]) + userId String? + workspace Workspace? @relation(fields: [workspaceId], references: [id]) + workspaceId String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + WebhookDeliveryLog WebhookDeliveryLog[] +} + +model WebhookDeliveryLog { + id String @id @default(cuid()) + webhookConfiguration WebhookConfiguration @relation(fields: [webhookConfigurationId], references: [id]) + webhookConfigurationId String + + activity Activity? @relation(fields: [activityId], references: [id]) + activityId String? + + status WebhookDeliveryStatus + responseStatusCode Int? + responseBody String? + error String? + deliveredAt DateTime @default(now()) + + createdAt DateTime @default(now()) +} + +model Workspace { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + name String + slug String @unique + icon String? + + integrations String[] + + userId String? @unique + user User? @relation(fields: [userId], references: [id]) + IngestionQueue IngestionQueue[] + IntegrationAccount IntegrationAccount[] + IntegrationDefinitionV2 IntegrationDefinitionV2[] + Activity Activity[] + WebhookConfiguration WebhookConfiguration[] + Conversation Conversation[] +} + +enum AuthenticationMethod { + GOOGLE + MAGIC_LINK +} + +enum IngestionStatus { + PENDING + PROCESSING + COMPLETED + FAILED + CANCELLED +} + +enum UserType { + Agent + User + System +} + +enum WebhookDeliveryStatus { + SUCCESS + FAILED +} diff --git a/apps/webapp/trigger.config.ts b/apps/webapp/trigger.config.ts new file mode 100644 index 0000000..4743a3f --- /dev/null +++ b/apps/webapp/trigger.config.ts @@ -0,0 +1,38 @@ +import { defineConfig } from "@trigger.dev/sdk/v3"; +import { + additionalPackages, + syncEnvVars, +} from "@trigger.dev/build/extensions/core"; +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; + +export default defineConfig({ + project: process.env.TRIGGER_PROJECT_ID as string, + runtime: "node", + logLevel: "log", + // The max compute seconds a task is allowed to run. If the task run exceeds this duration, it will be stopped. + // You can override this on an individual task. + // See https://trigger.dev/docs/runs/max-duration + maxDuration: 3600, + retries: { + enabledInDev: true, + default: { + maxAttempts: 1, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + dirs: ["./app/trigger"], + build: { + extensions: [ + syncEnvVars(() => ({ + DATABASE_URL: process.env.DATABASE_URL, + BACKEND_HOST: process.env.BACKEND_HOST, + })), + prismaExtension({ + schema: "prisma/schema.prisma", + }), + ], + }, +}); diff --git a/apps/webapp/tsconfig.json b/apps/webapp/tsconfig.json index 19e3238..8adba20 100644 --- a/apps/webapp/tsconfig.json +++ b/apps/webapp/tsconfig.json @@ -6,7 +6,8 @@ "**/*.ts", "**/*.tsx", "tailwind.config.js", - "tailwind.config.js" + "tailwind.config.js", + "trigger.config.ts" ], "compilerOptions": { "types": ["@remix-run/node", "vite/client"], @@ -24,6 +25,7 @@ "skipLibCheck": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, + "strictPropertyInitialization": false, "baseUrl": ".", "paths": { "~/*": ["./app/*"], diff --git a/apps/webapp/vite.config.ts b/apps/webapp/vite.config.ts index 5ef7eee..556821f 100644 --- a/apps/webapp/vite.config.ts +++ b/apps/webapp/vite.config.ts @@ -28,7 +28,13 @@ export default defineConfig({ allowedHosts: true, }, ssr: { - noExternal: ["@core/database", "tailwindcss"], + target: "node", + noExternal: [ + "@core/database", + "tailwindcss", + "@tiptap/react", + "react-tweet", + ], external: ["@prisma/client"], }, }); diff --git a/core/types/package.json b/core/types/package.json new file mode 100644 index 0000000..8b9198c --- /dev/null +++ b/core/types/package.json @@ -0,0 +1,21 @@ +{ + "name": "@echo/core-types", + "version": "1.0.0", + "description": "Core types for Echo integrations", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "dev": "tsc --watch" + }, + "devDependencies": { + "typescript": "^5.0.0" + }, + "exports": { + ".": { + "import": "./dist/index.js", + "require": "./dist/index.js", + "types": "./dist/index.d.ts" + } + } +} \ No newline at end of file diff --git a/core/types/src/index.ts b/core/types/src/index.ts new file mode 100644 index 0000000..1081f03 --- /dev/null +++ b/core/types/src/index.ts @@ -0,0 +1 @@ +export * from './integration'; \ No newline at end of file diff --git a/core/types/src/integration.ts b/core/types/src/integration.ts new file mode 100644 index 0000000..3089e22 --- /dev/null +++ b/core/types/src/integration.ts @@ -0,0 +1,64 @@ +export enum IntegrationEventType { + /** + * Setting up or creating an integration account + */ + SETUP = "setup", + + /** + * Processing incoming data from the integration + */ + PROCESS = "process", + + /** + * Identifying which account a webhook belongs to + */ + IDENTIFY = "identify", + + /** + * Scheduled synchronization of data + */ + SYNC = "sync", +} + +export interface IntegrationEventPayload { + event: IntegrationEventType; + [x: string]: any; +} + +export interface Spec { + name: string; + key: string; + description: string; + icon: string; + mcp?: { + command: string; + args: string[]; + env: Record; + }; + auth?: { + OAuth2?: { + token_url: string; + authorization_url: string; + scopes: string[]; + scope_identifier?: string; + scope_separator?: string; + }; + }; +} + +export interface Config { + access_token: string; + [key: string]: any; +} + +export interface Identifier { + id: string; + type?: string; +} + +export type MessageType = 'spec' | 'data' | 'identifier'; + +export interface Message { + type: MessageType; + data: any; +} \ No newline at end of file diff --git a/core/types/tsconfig.json b/core/types/tsconfig.json new file mode 100644 index 0000000..b5482c0 --- /dev/null +++ b/core/types/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "lib": ["ES2020"], + "declaration": true, + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["src/**/*", "*.ts"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/docker/Dockerfile b/docker-build/Dockerfile similarity index 100% rename from docker/Dockerfile rename to docker-build/Dockerfile diff --git a/docker/docker-compose.yaml b/docker-build/docker-compose.yaml similarity index 100% rename from docker/docker-compose.yaml rename to docker-build/docker-compose.yaml diff --git a/docker/scripts/entrypoint.sh b/docker-build/scripts/entrypoint.sh similarity index 100% rename from docker/scripts/entrypoint.sh rename to docker-build/scripts/entrypoint.sh diff --git a/docker/scripts/wait-for-it.sh b/docker-build/scripts/wait-for-it.sh similarity index 100% rename from docker/scripts/wait-for-it.sh rename to docker-build/scripts/wait-for-it.sh diff --git a/docker-compose.yaml b/docker-compose.yaml index d234ce0..77f9b3e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -37,7 +37,7 @@ services: postgres: container_name: core-postgres - image: postgres:15 + image: redplanethq/postgres:0.1.0 environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} diff --git a/integrations/slack/.gitignore b/integrations/slack/.gitignore new file mode 100644 index 0000000..9b60c0a --- /dev/null +++ b/integrations/slack/.gitignore @@ -0,0 +1,2 @@ +bin +node_modules \ No newline at end of file diff --git a/integrations/slack/.prettierrc b/integrations/slack/.prettierrc new file mode 100644 index 0000000..b61e355 --- /dev/null +++ b/integrations/slack/.prettierrc @@ -0,0 +1,22 @@ +{ + "arrowParens": "always", + "tabWidth": 2, + "useTabs": false, + "semi": true, + "bracketSpacing": true, + "jsxBracketSameLine": false, + "requirePragma": false, + "proseWrap": "preserve", + "singleQuote": true, + "formatOnSave": true, + "trailingComma": "all", + "printWidth": 100, + "overrides": [ + { + "files": ".prettierrc", + "options": { + "parser": "json" + } + } + ] +} diff --git a/integrations/slack/eslint.config.js b/integrations/slack/eslint.config.js new file mode 100644 index 0000000..24cd2da --- /dev/null +++ b/integrations/slack/eslint.config.js @@ -0,0 +1,81 @@ +const eslint = require('@eslint/js'); +const tseslint = require('typescript-eslint'); +const jestPlugin = require('eslint-plugin-jest'); +const importPlugin = require('eslint-plugin-import'); +const prettierPlugin = require('eslint-plugin-prettier'); +const unusedImportsPlugin = require('eslint-plugin-unused-imports'); + +module.exports = [ + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + files: ['**/*.{js,jsx,ts,tsx}'], + plugins: { + jest: jestPlugin, + import: importPlugin, + prettier: prettierPlugin, + 'unused-imports': unusedImportsPlugin, + }, + languageOptions: { + ecmaVersion: 2020, + sourceType: 'module', + parser: tseslint.parser, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + rules: { + curly: 'warn', + 'dot-location': 'warn', + eqeqeq: 'error', + 'prettier/prettier': 'warn', + 'unused-imports/no-unused-imports': 'warn', + 'no-else-return': 'warn', + 'no-lonely-if': 'warn', + 'no-inner-declarations': 'off', + 'no-unused-vars': 'off', + 'no-useless-computed-key': 'warn', + 'no-useless-return': 'warn', + 'no-var': 'warn', + 'object-shorthand': ['warn', 'always'], + 'prefer-arrow-callback': 'warn', + 'prefer-const': 'warn', + 'prefer-destructuring': ['warn', { AssignmentExpression: { array: true } }], + 'prefer-object-spread': 'warn', + 'prefer-template': 'warn', + 'spaced-comment': ['warn', 'always', { markers: ['/'] }], + yoda: 'warn', + 'import/order': [ + 'warn', + { + 'newlines-between': 'always', + groups: ['type', 'builtin', 'external', 'internal', ['parent', 'sibling'], 'index'], + pathGroupsExcludedImportTypes: ['builtin'], + pathGroups: [], + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + }, + ], + '@typescript-eslint/array-type': ['warn', { default: 'array-simple' }], + '@typescript-eslint/ban-ts-comment': [ + 'warn', + { + 'ts-expect-error': 'allow-with-description', + }, + ], + '@typescript-eslint/consistent-indexed-object-style': ['warn', 'record'], + '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], + '@typescript-eslint/no-unused-vars': 'warn', + }, + }, + { + files: ['scripts/**/*'], + rules: { + '@typescript-eslint/no-var-requires': 'off', + }, + }, +]; diff --git a/integrations/slack/package.json b/integrations/slack/package.json new file mode 100644 index 0000000..dba603f --- /dev/null +++ b/integrations/slack/package.json @@ -0,0 +1,71 @@ +{ + "name": "@sol/slack", + "version": "0.1.2", + "description": "slack extension for Sol", + "main": "./bin/index.js", + "module": "./bin/index.mjs", + "type": "module", + "files": [ + "slack", + "bin" + ], + "bin": { + "slack": "./bin/index.js" + }, + "scripts": { + "build": "rimraf bin && npx tsup", + "lint": "eslint --ext js,ts,tsx backend/ frontend/ --fix", + "prettier": "prettier --config .prettierrc --write ." + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@babel/preset-typescript": "^7.26.0", + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.3.0", + "@rollup/plugin-replace": "^5.0.7", + "@types/node": "^18.0.20", + "eslint": "^9.24.0", + "eslint-config-prettier": "^10.1.2", + "eslint-import-resolver-alias": "^1.1.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^27.9.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-unused-imports": "^2.0.0", + "prettier": "^3.4.2", + "rimraf": "^3.0.2", + "rollup": "^4.28.1", + "rollup-plugin-node-polyfills": "^0.2.1", + "rollup-plugin-terser": "^7.0.2", + "rollup-plugin-typescript2": "^0.34.1", + "tslib": "^2.8.1", + "typescript": "^4.7.2", + "tsup": "^8.0.1", + "ncc": "0.3.6" + }, + "publishConfig": { + "access": "public" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "dependencies": { + "axios": "^1.7.9", + "commander": "^12.0.0", + "openai": "^4.0.0", + "react-query": "^3.39.3", + "@echo/core-types": "workspace:*" + } +} \ No newline at end of file diff --git a/integrations/slack/pnpm-lock.yaml b/integrations/slack/pnpm-lock.yaml new file mode 100644 index 0000000..657304d --- /dev/null +++ b/integrations/slack/pnpm-lock.yaml @@ -0,0 +1,5101 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + axios: + specifier: ^1.7.9 + version: 1.9.0 + commander: + specifier: ^12.0.0 + version: 12.1.0 + openai: + specifier: ^4.0.0 + version: 4.98.0(zod@3.24.4) + react: + specifier: ^18.2.0 + version: 18.3.1 + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-query: + specifier: ^3.39.3 + version: 3.39.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@babel/preset-typescript': + specifier: ^7.26.0 + version: 7.27.1(@babel/core@7.27.1) + '@rollup/plugin-commonjs': + specifier: ^28.0.1 + version: 28.0.3(rollup@4.40.2) + '@rollup/plugin-json': + specifier: ^6.1.0 + version: 6.1.0(rollup@4.40.2) + '@rollup/plugin-node-resolve': + specifier: ^15.3.0 + version: 15.3.1(rollup@4.40.2) + '@rollup/plugin-replace': + specifier: ^5.0.7 + version: 5.0.7(rollup@4.40.2) + '@types/node': + specifier: ^18.0.20 + version: 18.19.100 + eslint: + specifier: ^9.24.0 + version: 9.26.0 + eslint-config-prettier: + specifier: ^10.1.2 + version: 10.1.3(eslint@9.26.0) + eslint-import-resolver-alias: + specifier: ^1.1.2 + version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0) + eslint-plugin-jest: + specifier: ^27.9.0 + version: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.4.0(eslint-config-prettier@10.1.3(eslint@9.26.0))(eslint@9.26.0)(prettier@3.5.3) + eslint-plugin-unused-imports: + specifier: ^2.0.0 + version: 2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0) + ncc: + specifier: 0.3.6 + version: 0.3.6 + prettier: + specifier: ^3.4.2 + version: 3.5.3 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + rollup: + specifier: ^4.28.1 + version: 4.40.2 + rollup-plugin-node-polyfills: + specifier: ^0.2.1 + version: 0.2.1 + rollup-plugin-terser: + specifier: ^7.0.2 + version: 7.0.2(rollup@4.40.2) + rollup-plugin-typescript2: + specifier: ^0.34.1 + version: 0.34.1(rollup@4.40.2)(typescript@4.9.5) + tslib: + specifier: ^2.8.1 + version: 2.8.1 + tsup: + specifier: ^8.0.1 + version: 8.4.0(postcss@8.5.3)(typescript@4.9.5)(yaml@2.7.1) + typescript: + specifier: ^4.7.2 + version: 4.9.5 + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.27.1': + resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.1': + resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.1': + resolution: {integrity: sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.27.1': + resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.27.1': + resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.27.1': + resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.27.1': + resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.27.1': + resolution: {integrity: sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.1': + resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.1': + resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + engines: {node: '>=6.9.0'} + + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.20.0': + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.2': + resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.26.0': + resolution: {integrity: sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@modelcontextprotocol/sdk@1.11.1': + resolution: {integrity: sha512-9LfmxKTb1v+vUS1/emSk1f5ePmTLkb9Le9AxOB5T0XM59EUumwcS45z05h7aiZx3GI0Bl7mjb3FMEglYj+acuQ==} + engines: {node: '>=18'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.2.4': + resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@rollup/plugin-commonjs@28.0.3': + resolution: {integrity: sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.3.1': + resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@5.0.7': + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@4.2.1': + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.40.2': + resolution: {integrity: sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.40.2': + resolution: {integrity: sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.40.2': + resolution: {integrity: sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.40.2': + resolution: {integrity: sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.40.2': + resolution: {integrity: sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.40.2': + resolution: {integrity: sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.40.2': + resolution: {integrity: sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.40.2': + resolution: {integrity: sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.40.2': + resolution: {integrity: sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.40.2': + resolution: {integrity: sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.40.2': + resolution: {integrity: sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': + resolution: {integrity: sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.40.2': + resolution: {integrity: sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.40.2': + resolution: {integrity: sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.40.2': + resolution: {integrity: sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.40.2': + resolution: {integrity: sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.40.2': + resolution: {integrity: sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.40.2': + resolution: {integrity: sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.40.2': + resolution: {integrity: sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.40.2': + resolution: {integrity: sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + + '@types/node@18.19.100': + resolution: {integrity: sha512-ojmMP8SZBKprc3qGrGk8Ujpo80AXkrP7G2tOT4VWr5jlr5DHjsJF+emXJz+Wm0glmy4Js62oKMdZZ6B9Y+tEcA==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/semver@7.7.0': + resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} + + '@typescript-eslint/eslint-plugin@5.62.0': + resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@5.62.0': + resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@5.62.0': + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/type-utils@5.62.0': + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@5.62.0': + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@1.9.0: + resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + + body-parser@2.2.0: + resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + engines: {node: '>=18'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + broadcast-channel@3.7.0: + resolution: {integrity: sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==} + + browserslist@4.24.5: + resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001717: + resolution: {integrity: sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colors@1.2.3: + resolution: {integrity: sha512-qTfM2pNFeMZcLvf/RbrVAzDEVttZjFhaApfx9dplNjvHSX88Ui66zBRb/4YGob/xUWxDceirgoC1lT676asfCQ==} + engines: {node: '>=0.1.90'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + dateformat@3.0.3: + resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.151: + resolution: {integrity: sha512-Rl6uugut2l9sLojjS4H4SAr3A4IgACMLgpuEMPYCVcKydzfyPrn5absNRju38IhQOf/NwjJY8OGWjlteqYeBCA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.3: + resolution: {integrity: sha512-vDo4d9yQE+cS2tdIT4J02H/16veRvkHgiLDRpej+WL67oCfbOb97itZXn8wMPJ/GsiEBVjrjs//AVNw2Cp1EcA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-alias@1.1.2: + resolution: {integrity: sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==} + engines: {node: '>= 4'} + peerDependencies: + eslint-plugin-import: '>=1.4.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jest@27.9.0: + resolution: {integrity: sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0 || ^7.0.0 + eslint: ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + + eslint-plugin-prettier@5.4.0: + resolution: {integrity: sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-unused-imports@2.0.0: + resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.26.0: + resolution: {integrity: sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventsource-parser@3.0.1: + resolution: {integrity: sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.6: + resolution: {integrity: sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==} + engines: {node: '>=18.0.0'} + + express-rate-limit@7.5.0: + resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} + engines: {node: '>= 16'} + peerDependencies: + express: ^4.11 || 5 || ^5.0.0-beta.1 + + express@5.1.0: + resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + engines: {node: '>= 18'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@2.1.0: + resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} + engines: {node: '>= 0.8'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + formdata-node@4.4.1: + resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} + engines: {node: '>= 12.20'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jest-worker@26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + match-sorter@6.3.4: + resolution: {integrity: sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + microseconds@0.2.0: + resolution: {integrity: sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nano-time@1.0.0: + resolution: {integrity: sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + ncc@0.3.6: + resolution: {integrity: sha512-OXudTB2Ebt/FnOuDoPQbaa17+tdVqSOWA+gLfPxccWwsNED1uA2zEhpoB1hwdFC9yYbio/mdV5cvOtQI3Zrx1w==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + oblivious-set@1.0.0: + resolution: {integrity: sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + openai@4.98.0: + resolution: {integrity: sha512-TmDKur1WjxxMPQAtLG5sgBSCJmX7ynTsGmewKzoDwl1fRxtbLOsiR0FA/AOAAtYUmP6azal+MYQuOENfdU+7yg==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.23.8 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkce-challenge@5.0.0: + resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} + engines: {node: '>=16.20.0'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-query@3.39.3: + resolution: {integrity: sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + + rollup-plugin-terser@7.0.2: + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser + peerDependencies: + rollup: ^2.0.0 + + rollup-plugin-typescript2@0.34.1: + resolution: {integrity: sha512-P4cHLtGikESmqi1CA+tdMDUv8WbQV48mzPYt77TSTOPJpERyZ9TXdDgjSDix8Fkqce6soYz3+fa4lrC93IEkcw==} + peerDependencies: + rollup: '>=1.26.3' + typescript: '>=2.4.0' + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + rollup@4.40.2: + resolution: {integrity: sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.0.1: + resolution: {integrity: sha512-cr7dZWLwOeaFBLTIuZeYdkfO7UzGIKhjYENJFAxUOMKWGaWDm2nJM2rzxNRm5Owu0DH3ApwNo6kx5idXZfb/Iw==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + + serialize-javascript@4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + synckit@0.11.4: + resolution: {integrity: sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ==} + engines: {node: ^14.18.0 || >=16.0.0} + + terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + engines: {node: '>=10'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.13: + resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} + engines: {node: '>=12.0.0'} + + tinytim@0.1.1: + resolution: {integrity: sha512-NIpsp9lBIxPNzB++HnMmUd4byzJSVbbO4F+As1Gb1IG/YQT5QvmBDjpx8SpDS8fhGC+t+Qw8ldQgbcAIaU+2cA==} + engines: {node: '>= 0.2.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tracer@0.8.15: + resolution: {integrity: sha512-ZQzlhd6zZFIpAhACiZkxLjl65XqVwi8t8UEBVGRIHAQN6nj55ftJWiFell+WSqWCP/vEycrIbUSuiyMwul+TFw==} + engines: {node: '>= 0.10.0'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsup@8.4.0: + resolution: {integrity: sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + ultron@1.1.1: + resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unload@2.2.0: + resolution: {integrity: sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + web-streams-polyfill@4.0.0-beta.3: + resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} + engines: {node: '>= 14'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@2.3.1: + resolution: {integrity: sha512-61a+9LgtYZxTq1hAonhX8Xwpo2riK4IOR/BIVxioFbCfc3QFKmpE4x9dLExfLHKtUfVZigYa36tThVhO57erEw==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.7.1: + resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} + engines: {node: '>= 14'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod-to-json-schema@3.24.5: + resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==} + peerDependencies: + zod: ^3.24.1 + + zod@3.24.4: + resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.27.2': {} + + '@babel/core@7.27.1': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helpers': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.27.1': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.1': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.27.1': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/parser@7.27.2': + dependencies: + '@babel/types': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.27.1': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/traverse@7.27.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.27.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@esbuild/aix-ppc64@0.25.4': + optional: true + + '@esbuild/android-arm64@0.25.4': + optional: true + + '@esbuild/android-arm@0.25.4': + optional: true + + '@esbuild/android-x64@0.25.4': + optional: true + + '@esbuild/darwin-arm64@0.25.4': + optional: true + + '@esbuild/darwin-x64@0.25.4': + optional: true + + '@esbuild/freebsd-arm64@0.25.4': + optional: true + + '@esbuild/freebsd-x64@0.25.4': + optional: true + + '@esbuild/linux-arm64@0.25.4': + optional: true + + '@esbuild/linux-arm@0.25.4': + optional: true + + '@esbuild/linux-ia32@0.25.4': + optional: true + + '@esbuild/linux-loong64@0.25.4': + optional: true + + '@esbuild/linux-mips64el@0.25.4': + optional: true + + '@esbuild/linux-ppc64@0.25.4': + optional: true + + '@esbuild/linux-riscv64@0.25.4': + optional: true + + '@esbuild/linux-s390x@0.25.4': + optional: true + + '@esbuild/linux-x64@0.25.4': + optional: true + + '@esbuild/netbsd-arm64@0.25.4': + optional: true + + '@esbuild/netbsd-x64@0.25.4': + optional: true + + '@esbuild/openbsd-arm64@0.25.4': + optional: true + + '@esbuild/openbsd-x64@0.25.4': + optional: true + + '@esbuild/sunos-x64@0.25.4': + optional: true + + '@esbuild/win32-arm64@0.25.4': + optional: true + + '@esbuild/win32-ia32@0.25.4': + optional: true + + '@esbuild/win32-x64@0.25.4': + optional: true + + '@eslint-community/eslint-utils@4.7.0(eslint@9.26.0)': + dependencies: + eslint: 9.26.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.20.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.2.2': {} + + '@eslint/core@0.13.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.26.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.2.8': + dependencies: + '@eslint/core': 0.13.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@modelcontextprotocol/sdk@1.11.1': + dependencies: + content-type: 1.0.5 + cors: 2.8.5 + cross-spawn: 7.0.6 + eventsource: 3.0.6 + express: 5.1.0 + express-rate-limit: 7.5.0(express@5.1.0) + pkce-challenge: 5.0.0 + raw-body: 3.0.0 + zod: 3.24.4 + zod-to-json-schema: 3.24.5(zod@3.24.4) + transitivePeerDependencies: + - supports-color + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.4': {} + + '@rollup/plugin-commonjs@28.0.3(rollup@4.40.2)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.4.4(picomatch@4.0.2) + is-reference: 1.2.1 + magic-string: 0.30.17 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.40.2 + + '@rollup/plugin-json@6.1.0(rollup@4.40.2)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) + optionalDependencies: + rollup: 4.40.2 + + '@rollup/plugin-node-resolve@15.3.1(rollup@4.40.2)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.10 + optionalDependencies: + rollup: 4.40.2 + + '@rollup/plugin-replace@5.0.7(rollup@4.40.2)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.40.2) + magic-string: 0.30.17 + optionalDependencies: + rollup: 4.40.2 + + '@rollup/pluginutils@4.2.1': + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + + '@rollup/pluginutils@5.1.4(rollup@4.40.2)': + dependencies: + '@types/estree': 1.0.7 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.40.2 + + '@rollup/rollup-android-arm-eabi@4.40.2': + optional: true + + '@rollup/rollup-android-arm64@4.40.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.40.2': + optional: true + + '@rollup/rollup-darwin-x64@4.40.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.40.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.40.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.40.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.40.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.40.2': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.40.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.40.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.40.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.40.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.40.2': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@types/estree@1.0.7': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node-fetch@2.6.12': + dependencies: + '@types/node': 18.19.100 + form-data: 4.0.2 + + '@types/node@18.19.100': + dependencies: + undici-types: 5.26.5 + + '@types/resolve@1.20.2': {} + + '@types/semver@7.7.0': {} + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + debug: 4.4.0 + eslint: 9.26.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.7.1 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + optional: true + + '@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.4.0 + eslint: 9.26.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + optional: true + + '@typescript-eslint/scope-manager@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + + '@typescript-eslint/type-utils@5.62.0(eslint@9.26.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + debug: 4.4.0 + eslint: 9.26.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + optional: true + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.0 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.1 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.62.0(eslint@9.26.0)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.26.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.0 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 9.26.0 + eslint-scope: 5.1.1 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.1 + negotiator: 1.0.0 + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + + array-union@2.1.0: {} + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + async-function@1.0.0: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axios@1.9.0: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + big-integer@1.6.52: {} + + body-parser@2.2.0: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.0 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + broadcast-channel@3.7.0: + dependencies: + '@babel/runtime': 7.27.1 + detect-node: 2.1.0 + js-sha3: 0.8.0 + microseconds: 0.2.0 + nano-time: 1.0.0 + oblivious-set: 1.0.0 + rimraf: 3.0.2 + unload: 2.2.0 + + browserslist@4.24.5: + dependencies: + caniuse-lite: 1.0.30001717 + electron-to-chromium: 1.5.151 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.5) + + buffer-from@1.1.2: {} + + bundle-require@5.1.0(esbuild@0.25.4): + dependencies: + esbuild: 0.25.4 + load-tsconfig: 0.2.5 + + bytes@3.1.2: {} + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001717: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colors@1.2.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@12.1.0: {} + + commander@2.20.3: {} + + commander@4.1.1: {} + + commondir@1.0.1: {} + + concat-map@0.0.1: {} + + consola@3.4.2: {} + + content-disposition@1.0.0: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + dateformat@3.0.3: {} + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + detect-node@2.1.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.151: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encodeurl@2.0.0: {} + + es-abstract@1.23.9: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.3(eslint@9.26.0): + dependencies: + eslint: 9.26.0 + + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)): + dependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0) + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@9.26.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + eslint: 9.26.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.26.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@9.26.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@9.26.0)(typescript@4.9.5) + eslint: 9.26.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-prettier@5.4.0(eslint-config-prettier@10.1.3(eslint@9.26.0))(eslint@9.26.0)(prettier@3.5.3): + dependencies: + eslint: 9.26.0 + prettier: 3.5.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.4 + optionalDependencies: + eslint-config-prettier: 10.1.3(eslint@9.26.0) + + eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0): + dependencies: + eslint: 9.26.0 + eslint-rule-composer: 0.3.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.26.0)(typescript@4.9.5))(eslint@9.26.0)(typescript@4.9.5) + + eslint-rule-composer@0.3.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@8.3.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.26.0: + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.26.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.2 + '@eslint/core': 0.13.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.26.0 + '@eslint/plugin-kit': 0.2.8 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@modelcontextprotocol/sdk': 1.11.1 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + zod: 3.24.4 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@0.6.1: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + eventsource-parser@3.0.1: {} + + eventsource@3.0.6: + dependencies: + eventsource-parser: 3.0.1 + + express-rate-limit@7.5.0(express@5.1.0): + dependencies: + express: 5.1.0 + + express@5.1.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.1 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.4.4(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@2.1.0: + dependencies: + debug: 4.4.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + follow-redirects@1.15.9: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data-encoder@1.7.2: {} + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + formdata-node@4.4.1: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: + optional: true + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + ipaddr.js@1.9.1: {} + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-module@1.0.0: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-promise@4.0.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.7 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jest-worker@26.6.2: + dependencies: + '@types/node': 18.19.100 + merge-stream: 2.0.0 + supports-color: 7.2.0 + + joycon@3.1.1: {} + + js-sha3@0.8.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash.sortby@4.7.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + match-sorter@6.3.4: + dependencies: + '@babel/runtime': 7.27.1 + remove-accents: 0.5.0 + + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + microseconds@0.2.0: {} + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nano-time@1.0.0: + dependencies: + big-integer: 1.6.52 + + nanoid@3.3.11: + optional: true + + natural-compare-lite@1.4.0: + optional: true + + natural-compare@1.4.0: {} + + ncc@0.3.6: + dependencies: + mkdirp: 0.5.6 + rimraf: 2.7.1 + tracer: 0.8.15 + ws: 2.3.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + negotiator@1.0.0: {} + + node-domexception@1.0.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-releases@2.0.19: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + oblivious-set@1.0.0: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + openai@4.98.0(zod@3.24.4): + dependencies: + '@types/node': 18.19.100 + '@types/node-fetch': 2.6.12 + abort-controller: 3.0.0 + agentkeepalive: 4.6.0 + form-data-encoder: 1.7.2 + formdata-node: 4.4.1 + node-fetch: 2.7.0 + optionalDependencies: + zod: 3.24.4 + transitivePeerDependencies: + - encoding + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parseurl@1.3.3: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@8.2.0: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pirates@4.0.7: {} + + pkce-challenge@5.0.0: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + possible-typed-array-names@1.1.0: {} + + postcss-load-config@6.0.1(postcss@8.5.3)(yaml@2.7.1): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + postcss: 8.5.3 + yaml: 2.7.1 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + optional: true + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.5.3: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@3.0.0: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-query@3.39.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.27.1 + broadcast-channel: 3.7.0 + match-sorter: 6.3.4 + react: 18.3.1 + optionalDependencies: + react-dom: 18.3.1(react@18.3.1) + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + readdirp@4.1.2: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + remove-accents@0.5.0: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + + rollup-plugin-terser@7.0.2(rollup@4.40.2): + dependencies: + '@babel/code-frame': 7.27.1 + jest-worker: 26.6.2 + rollup: 4.40.2 + serialize-javascript: 4.0.0 + terser: 5.39.0 + + rollup-plugin-typescript2@0.34.1(rollup@4.40.2)(typescript@4.9.5): + dependencies: + '@rollup/pluginutils': 4.2.1 + find-cache-dir: 3.3.2 + fs-extra: 10.1.0 + rollup: 4.40.2 + semver: 7.7.1 + tslib: 2.8.1 + typescript: 4.9.5 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + rollup@4.40.2: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.40.2 + '@rollup/rollup-android-arm64': 4.40.2 + '@rollup/rollup-darwin-arm64': 4.40.2 + '@rollup/rollup-darwin-x64': 4.40.2 + '@rollup/rollup-freebsd-arm64': 4.40.2 + '@rollup/rollup-freebsd-x64': 4.40.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.40.2 + '@rollup/rollup-linux-arm-musleabihf': 4.40.2 + '@rollup/rollup-linux-arm64-gnu': 4.40.2 + '@rollup/rollup-linux-arm64-musl': 4.40.2 + '@rollup/rollup-linux-loongarch64-gnu': 4.40.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.40.2 + '@rollup/rollup-linux-riscv64-gnu': 4.40.2 + '@rollup/rollup-linux-riscv64-musl': 4.40.2 + '@rollup/rollup-linux-s390x-gnu': 4.40.2 + '@rollup/rollup-linux-x64-gnu': 4.40.2 + '@rollup/rollup-linux-x64-musl': 4.40.2 + '@rollup/rollup-win32-arm64-msvc': 4.40.2 + '@rollup/rollup-win32-ia32-msvc': 4.40.2 + '@rollup/rollup-win32-x64-msvc': 4.40.2 + fsevents: 2.3.3 + + router@2.2.0: + dependencies: + debug: 4.4.0 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + transitivePeerDependencies: + - supports-color + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.0.1: {} + + safe-buffer@5.2.1: {} + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@6.3.1: {} + + semver@7.7.1: {} + + send@1.2.0: + dependencies: + debug: 4.4.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@4.0.0: + dependencies: + randombytes: 2.1.0 + + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + + source-map-js@1.2.1: + optional: true + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + sourcemap-codec@1.4.8: {} + + statuses@2.0.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.11.4: + dependencies: + '@pkgr/core': 0.2.4 + tslib: 2.8.1 + + terser@5.39.0: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.1 + commander: 2.20.3 + source-map-support: 0.5.21 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyexec@0.3.2: {} + + tinyglobby@0.2.13: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + tinytim@0.1.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tr46@0.0.3: {} + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tracer@0.8.15: + dependencies: + colors: 1.2.3 + dateformat: 3.0.3 + mkdirp: 0.5.6 + tinytim: 0.1.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsup@8.4.0(postcss@8.5.3)(typescript@4.9.5)(yaml@2.7.1): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.4) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.0 + esbuild: 0.25.4 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.5.3)(yaml@2.7.1) + resolve-from: 5.0.0 + rollup: 4.40.2 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.13 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.3 + typescript: 4.9.5 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + tsutils@3.21.0(typescript@4.9.5): + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@4.9.5: {} + + ultron@1.1.1: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@5.26.5: {} + + universalify@2.0.1: {} + + unload@2.2.0: + dependencies: + '@babel/runtime': 7.27.1 + detect-node: 2.1.0 + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.3(browserslist@4.24.5): + dependencies: + browserslist: 4.24.5 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vary@1.1.2: {} + + web-streams-polyfill@4.0.0-beta.3: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@4.0.2: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@2.3.1: + dependencies: + safe-buffer: 5.0.1 + ultron: 1.1.1 + + yallist@3.1.1: {} + + yaml@2.7.1: + optional: true + + yocto-queue@0.1.0: {} + + zod-to-json-schema@3.24.5(zod@3.24.4): + dependencies: + zod: 3.24.4 + + zod@3.24.4: {} diff --git a/integrations/slack/spec.json b/integrations/slack/spec.json new file mode 100644 index 0000000..34a46c3 --- /dev/null +++ b/integrations/slack/spec.json @@ -0,0 +1,41 @@ +{ + "name": "Slack extension", + "key": "slack", + "description": "Connect your workspace to Slack. Run your workflows from slack bookmarks", + "icon": "slack", + "mcp": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-slack"], + "env": { + "SLACK_BOT_TOKEN": "${config:access_token}", + "SLACK_TEAM_ID": "${config:team_id}", + "SLACK_CHANNEL_IDS": "${config:channel_ids}" + } + }, + "auth": { + "OAuth2": { + "token_url": "https://slack.com/api/oauth.v2.access", + "authorization_url": "https://slack.com/oauth/v2/authorize", + "scopes": [ + "stars:read", + "team:read", + "stars:write", + "users:read", + "channels:read", + "groups:read", + "im:read", + "im:history", + "mpim:read", + "mpim:write", + "mpim:history", + "channels:history", + "chat:write", + "reactions:read", + "reactions:write", + "users.profile:read" + ], + "scope_identifier": "user_scope", + "scope_separator": "," + } + } +} diff --git a/integrations/slack/src/account-create.ts b/integrations/slack/src/account-create.ts new file mode 100644 index 0000000..4b59add --- /dev/null +++ b/integrations/slack/src/account-create.ts @@ -0,0 +1,27 @@ +import axios from 'axios'; + +export async function integrationCreate( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data: any, + integrationDefinition: any, +) { + const { oauthResponse } = data; + const integrationConfiguration = { + access_token: oauthResponse.authed_user.access_token, + teamId: oauthResponse.team.id, + teamName: oauthResponse.team.name, + userId: oauthResponse.authed_user.id, + scope: oauthResponse.authed_user.scope, + }; + + const payload = { + settings: {}, + accountId: integrationConfiguration.userId, + config: integrationConfiguration, + integrationDefinitionId: integrationDefinition.id, + }; + + const integrationAccount = (await axios.post(`/api/v1/integration_account`, payload)).data; + + return integrationAccount; +} diff --git a/integrations/slack/src/common/IntegrationCLI.ts b/integrations/slack/src/common/IntegrationCLI.ts new file mode 100644 index 0000000..093438d --- /dev/null +++ b/integrations/slack/src/common/IntegrationCLI.ts @@ -0,0 +1,186 @@ +import { Command } from 'commander'; +import { + IntegrationEventPayload, + Spec, + Config, + Identifier, + Message +} from '@echo/core-types'; + +export abstract class IntegrationCLI { + protected program: Command; + protected integrationName: string; + protected version: string; + + constructor(integrationName: string, version: string = '1.0.0') { + this.integrationName = integrationName; + this.version = version; + this.program = new Command(); + this.setupProgram(); + } + + private setupProgram(): void { + this.program + .name(`${this.integrationName}-integration`) + .description(`${this.integrationName} integration CLI`) + .version(this.version); + + this.setupSpecCommand(); + this.setupAccountCommands(); + this.setupDataCommands(); + this.setupSyncCommand(); + } + + private setupAccountCommands(): void { + const accountCmd = this.program + .command('account') + .description(`Manage ${this.integrationName} integration accounts`); + + accountCmd + .command('create') + .description(`Create a new ${this.integrationName} integration account`) + .requiredOption('--oauth-response ', 'OAuth response JSON') + .action(async (options) => { + try { + const oauthResponse = JSON.parse(options.oauthResponse); + const integrationDefinition = JSON.parse(options.integrationDefinition); + + const result = await this.handleEvent({ + event: 'INTEGRATION_ACCOUNT_CREATED', + eventBody: { oauthResponse }, + integrationDefinition, + }); + + console.log('Account created successfully:', JSON.stringify(result, null, 2)); + } catch (error) { + console.error('Error creating account:', error); + process.exit(1); + } + }); + } + + private setupDataCommands(): void { + this.program + .command('process') + .description(`Process ${this.integrationName} integration data`) + .requiredOption('--event-data ', 'Event data JSON') + .requiredOption('--config ', 'Integration configuration JSON') + .action(async (options) => { + try { + const eventData = JSON.parse(options.eventData); + const config = JSON.parse(options.config); + + const result = await this.handleEvent({ + event: 'PROCESS', + eventBody: { eventData }, + config, + }); + + const message: Message = { + type: 'data', + data: result + }; + console.log(JSON.stringify(message, null, 2)); + } catch (error) { + console.error('Error processing data:', error); + process.exit(1); + } + }); + + this.program + .command('identify') + .description('Identify webhook account') + .requiredOption('--webhook-data ', 'Webhook data JSON') + .action(async (options) => { + try { + const webhookData = JSON.parse(options.webhookData); + + const result = await this.handleEvent({ + event: 'IDENTIFY', + eventBody: webhookData, + }); + + const message: Message = { + type: 'identifier', + data: result + }; + console.log(JSON.stringify(message, null, 2)); + } catch (error) { + console.error('Error identifying account:', error); + process.exit(1); + } + }); + } + + private setupSpecCommand(): void { + this.program + .command('spec') + .description('Get integration specification') + .action(async () => { + try { + const spec = await this.getSpec(); + const message: Message = { + type: 'spec', + data: spec + }; + console.log(JSON.stringify(message, null, 2)); + } catch (error) { + console.error('Error getting spec:', error); + process.exit(1); + } + }); + } + + private setupSyncCommand(): void { + this.program + .command('sync') + .description('Perform scheduled sync') + .requiredOption('--config ', 'Integration configuration JSON') + .action(async (options) => { + try { + const config = JSON.parse(options.config); + + const result = await this.handleEvent({ + event: 'SYNC', + eventBody: {}, + config, + }); + + const message: Message = { + type: 'data', + data: result + }; + console.log(JSON.stringify(message, null, 2)); + } catch (error) { + console.error('Error during sync:', error); + process.exit(1); + } + }); + } + + /** + * Abstract method that must be implemented by each integration + * This method should handle the integration-specific logic for each event type + */ + protected abstract handleEvent(eventPayload: IntegrationEventPayload): Promise; + + /** + * Abstract method that must be implemented by each integration + * This method should return the integration specification + */ + protected abstract getSpec(): Promise; + + /** + * Parse and execute the CLI commands + */ + public parse(): void { + this.program.parse(); + } + + /** + * Get the commander program instance for additional customization + */ + public getProgram(): Command { + return this.program; + } +} diff --git a/integrations/slack/src/common/README.md b/integrations/slack/src/common/README.md new file mode 100644 index 0000000..efd21bc --- /dev/null +++ b/integrations/slack/src/common/README.md @@ -0,0 +1,65 @@ +# IntegrationCLI Base Class + +This is a common CLI base class that can be moved to the SDK and used by all integrations. + +## Usage + +### 1. Create your integration-specific CLI class: + +```typescript +import { IntegrationCLI, IntegrationEventPayload } from './common/IntegrationCLI'; + +export class MyIntegrationCLI extends IntegrationCLI { + constructor() { + super('my-integration', '1.0.0'); + } + + protected async handleEvent(eventPayload: IntegrationEventPayload): Promise { + // Your integration-specific logic here + return await processMyIntegrationEvent(eventPayload); + } +} +``` + +### 2. Create your CLI entry point: + +```typescript +#!/usr/bin/env node + +import { MyIntegrationCLI } from './MyIntegrationCLI'; + +const cli = new MyIntegrationCLI(); +cli.parse(); +``` + +### 3. Update your package.json: + +```json +{ + "bin": { + "my-integration": "./dist/cli.js" + }, + "dependencies": { + "commander": "^12.0.0" + } +} +``` + +## Available Commands + +The base class provides these commands automatically: + +- `account create --oauth-response --integration-definition ` +- `account delete --account-id ` +- `process --event-data --integration-account ` +- `identify --webhook-data ` +- `sync --integration-account ` + +## Moving to SDK + +To move this to the SDK: + +1. Move `IntegrationCLI.ts` to `@redplanethq/sol-sdk/src/cli/` +2. Export it from the SDK's index +3. Update imports in integrations to use the SDK version +4. Add commander as a dependency to the SDK \ No newline at end of file diff --git a/integrations/slack/src/create-activity.ts b/integrations/slack/src/create-activity.ts new file mode 100644 index 0000000..78bf7d3 --- /dev/null +++ b/integrations/slack/src/create-activity.ts @@ -0,0 +1,131 @@ +// import { IntegrationAccount } from '@redplanethq/sol-sdk'; +import axios from 'axios'; + +import { getUserDetails } from './utils'; + +async function getMessage(accessToken: string, channel: string, ts: string) { + const result = await axios.get('https://slack.com/api/conversations.history', { + headers: { + Authorization: `Bearer ${accessToken}`, + 'Content-Type': 'application/json', + }, + params: { + channel, + latest: ts, + inclusive: true, + limit: 1, + }, + }); + + return result.data.messages?.[0]; +} + +async function getConversationInfo(accessToken: string, channel: string) { + const result = await axios.get('https://slack.com/api/conversations.info', { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + params: { + channel, + }, + }); + + return result.data.channel; +} + +export const createActivityEvent = async ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + eventBody: any, + config: any, +) => { + const { eventData } = eventBody; + if (eventData.event.type === 'message' && eventData.event.channel === 'D06UAK42494') { + const event = eventData.event; + + if (!config) { + throw new Error('Integration configuration not found'); + } + + const accessToken = config.access_token; + + const text = `DM with Sigma channel Content: '${event.text}'`; + + const permalinkResponse = await axios.get( + `https://slack.com/api/chat.getPermalink?channel=${event.channel}&message_ts=${event.ts}`, + { + headers: { Authorization: `Bearer ${accessToken}` }, + }, + ); + + const activity = { + sourceURL: permalinkResponse.data.permalink, + text, + integrationAccountId: config.integrationAccountId, + taskId: null, + }; + + await axios.post('/api/v1/activity', activity); + } + + if (eventData.event.type === 'reaction_added' && eventData.event.reaction === 'eyes') { + const event = eventData.event; + + if (!config) { + throw new Error('Integration configuration not found'); + } + + const accessToken = config.access_token; + const channel = event.item.channel; + const ts = event.item.ts; + + const eventMessage = await getMessage(accessToken, channel, ts); + const mentionedUsers = getMentionUsers(eventMessage.text); + + const [userDetails, conversationInfo] = await Promise.all([ + getUserDetails([eventMessage.user, ...mentionedUsers], config.access_token), + getConversationInfo(accessToken, channel), + ]); + + const userIdMap = new Map(userDetails.map((user) => [user.id, user])); + + const eventMessageText = eventMessage.text.replace(/<@U\w+>/g, (match: string) => { + const userId = match.replace(/<@|>/g, ''); + const user = userIdMap.get(userId); + return user ? `@${user.real_name}|${userId}` : match; + }); + + let conversationContext; + if (conversationInfo.is_im) { + const dmUser = userIdMap.get(conversationInfo.user); + conversationContext = `direct message with ${dmUser?.real_name}(${conversationInfo.user})`; + } else if (conversationInfo.is_group) { + conversationContext = `private channel ${conversationInfo.name}(${conversationInfo.id})`; + } else { + conversationContext = `channel ${conversationInfo.name}(${conversationInfo.id})`; + } + + const text = `Message from user ${userIdMap.get(eventMessage.user)?.real_name}(${eventMessage.user}) in ${conversationContext} at ${eventMessage.ts}. Content: '${eventMessageText}'`; + + const permalinkResponse = await axios.get( + `https://slack.com/api/chat.getPermalink?channel=${channel}&message_ts=${ts}`, + { + headers: { Authorization: `Bearer ${accessToken}` }, + }, + ); + + const activity = { + sourceURL: permalinkResponse.data.permalink, + text, + integrationAccountId: config.integrationAccountId, + taskId: null, + }; + + await axios.post('/api/v1/activity', activity); + } + return { message: `Processed activity from slack` }; +}; + +function getMentionUsers(message: string): string[] { + const mentionUsers = message.matchAll(/<@U\w+>/g); + return Array.from(mentionUsers).map((match) => match[0].replace(/<@|>/g, '')); +} diff --git a/integrations/slack/src/index.ts b/integrations/slack/src/index.ts new file mode 100644 index 0000000..d66ee50 --- /dev/null +++ b/integrations/slack/src/index.ts @@ -0,0 +1,91 @@ +// import { IntegrationPayloadEventType } from '@redplanethq/sol-sdk'; + +import { integrationCreate } from './account-create'; +import { createActivityEvent } from './create-activity'; +import { IntegrationCLI } from './common/IntegrationCLI'; +import { IntegrationEventPayload, Spec } from '@echo/core-types'; + +export async function run(eventPayload: IntegrationEventPayload) { + switch (eventPayload.event) { + case 'SETUP': + return await integrationCreate(eventPayload.eventBody, eventPayload.integrationDefinition); + + case 'IDENTIFY': + return eventPayload.eventBody.event.user; + + case 'PROCESS': + return createActivityEvent(eventPayload.eventBody, eventPayload.config); + + case 'SYNC': + return { message: 'Scheduled sync completed successfully' }; + + default: + return { + message: `The event payload type is ${eventPayload.event}`, + }; + } +} + +// CLI implementation that extends the base class +class SlackCLI extends IntegrationCLI { + constructor() { + super('slack', '1.0.0'); + } + + protected async handleEvent(eventPayload: IntegrationEventPayload): Promise { + return await run(eventPayload); + } + + protected async getSpec(): Promise { + return { + name: "Slack extension", + key: "slack", + description: "Connect your workspace to Slack. Run your workflows from slack bookmarks", + icon: "slack", + mcp: { + command: "npx", + args: ["-y", "@modelcontextprotocol/server-slack"], + env: { + "SLACK_BOT_TOKEN": "${config:access_token}", + "SLACK_TEAM_ID": "${config:team_id}", + "SLACK_CHANNEL_IDS": "${config:channel_ids}" + } + }, + auth: { + OAuth2: { + token_url: "https://slack.com/api/oauth.v2.access", + authorization_url: "https://slack.com/oauth/v2/authorize", + scopes: [ + "stars:read", + "team:read", + "stars:write", + "users:read", + "channels:read", + "groups:read", + "im:read", + "im:history", + "mpim:read", + "mpim:write", + "mpim:history", + "channels:history", + "chat:write", + "reactions:read", + "reactions:write", + "users.profile:read" + ], + scope_identifier: "user_scope", + scope_separator: "," + } + } + }; + } +} + +// Define a main function and invoke it directly. +// This works after bundling to JS and running with `node index.js`. +function main() { + const slackCLI = new SlackCLI(); + slackCLI.parse(); +} + +main(); diff --git a/integrations/slack/src/utils.ts b/integrations/slack/src/utils.ts new file mode 100644 index 0000000..93a61a5 --- /dev/null +++ b/integrations/slack/src/utils.ts @@ -0,0 +1,32 @@ +import axios from 'axios'; + +export interface ActivityCreate { + url: string; + text: string; + sourceId: string; + sourceURL: string; + integrationAccountId: string; +} + +export async function getSlackTeamInfo(slackTeamId: string, accessToken: string) { + const response = await axios.get(`https://slack.com/api/team.info?team=${slackTeamId}`, { + headers: { + 'Content-Type': 'application/json; charset=utf-8', + Authorization: `Bearer ${accessToken}`, + }, + }); + + return response.data; +} + +export async function getUserDetails(userIds: string[], accessToken: string) { + return await Promise.all( + userIds.map(async (userId) => { + const userResponse = await axios.get(`https://slack.com/api/users.info?user=${userId}`, { + headers: { Authorization: `Bearer ${accessToken}` }, + }); + + return userResponse.data.user; + }), + ); +} diff --git a/integrations/slack/tsconfig.json b/integrations/slack/tsconfig.json new file mode 100644 index 0000000..81b2d79 --- /dev/null +++ b/integrations/slack/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "ES2022", + + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "outDir": "./dist", + "rootDir": "./src", + + "lib": ["dom", "dom.iterable", "esnext"], + "baseUrl": "frontend", + "allowJs": false, + + "allowSyntheticDefaultImports": true, + + "module": "esnext", + "moduleResolution": "node", + + "isolatedModules": true, + "strictNullChecks": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "noFallthroughCasesInSwitch": true, + "useUnknownInCatchVariables": false + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "build", "dist", "scripts", "acceptance-tests", "webpack", "jest"], + "types": ["typePatches"] +} diff --git a/integrations/slack/tsup.config.ts b/integrations/slack/tsup.config.ts new file mode 100644 index 0000000..431fcf8 --- /dev/null +++ b/integrations/slack/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsup'; +import { dependencies } from './package.json'; + +export default defineConfig({ + entry: ['src/index.ts'], + format: ['cjs'], // or esm if you're using that + bundle: true, + target: 'node16', + outDir: 'bin', + splitting: false, + shims: true, + clean: true, + name: 'slack', + platform: 'node', + legacyOutput: false, + noExternal: Object.keys(dependencies || {}), // ⬅️ bundle all deps + treeshake: { + preset: 'recommended', + }, +}); diff --git a/package.json b/package.json index 8432232..ba522b4 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "db:seed": "dotenv -- turbo run db:seed", "db:studio": "dotenv -- turbo run db:studio", "db:populate": "dotenv -- turbo run db:populate", - "generate": "dotenv -- turbo run generate" + "generate": "dotenv -- turbo run generate", + "trigger:dev": "dotenv -- turbo run trigger:dev" }, "devDependencies": { "dotenv-cli": "^7.4.4", diff --git a/packages/database/prisma/migrations/20250706093221_add_activity/migration.sql b/packages/database/prisma/migrations/20250706093221_add_activity/migration.sql new file mode 100644 index 0000000..d08043b --- /dev/null +++ b/packages/database/prisma/migrations/20250706093221_add_activity/migration.sql @@ -0,0 +1,119 @@ +-- CreateEnum +CREATE TYPE "WebhookDeliveryStatus" AS ENUM ('SUCCESS', 'FAILED'); + +-- CreateTable +CREATE TABLE "Activity" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "deleted" TIMESTAMP(3), + "text" TEXT NOT NULL, + "sourceURL" TEXT, + "integrationAccountId" TEXT, + "rejectionReason" TEXT, + "workspaceId" TEXT NOT NULL, + + CONSTRAINT "Activity_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "IntegrationAccount" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "deleted" TIMESTAMP(3), + "integrationConfiguration" JSONB NOT NULL, + "accountId" TEXT, + "settings" JSONB, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "integratedById" TEXT NOT NULL, + "integrationDefinitionId" TEXT NOT NULL, + "workspaceId" TEXT NOT NULL, + + CONSTRAINT "IntegrationAccount_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "IntegrationDefinitionV2" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "deleted" TIMESTAMP(3), + "name" TEXT NOT NULL, + "slug" TEXT NOT NULL, + "description" TEXT NOT NULL, + "icon" TEXT NOT NULL, + "config" JSONB, + "spec" JSONB NOT NULL DEFAULT '{}', + "version" TEXT, + "url" TEXT, + "workspaceId" TEXT, + + CONSTRAINT "IntegrationDefinitionV2_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "WebhookConfiguration" ( + "id" TEXT NOT NULL, + "url" TEXT NOT NULL, + "secret" TEXT, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "eventTypes" TEXT[], + "userId" TEXT, + "workspaceId" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "WebhookConfiguration_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "WebhookDeliveryLog" ( + "id" TEXT NOT NULL, + "webhookConfigurationId" TEXT NOT NULL, + "activityId" TEXT, + "status" "WebhookDeliveryStatus" NOT NULL, + "responseStatusCode" INTEGER, + "responseBody" TEXT, + "error" TEXT, + "deliveredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "WebhookDeliveryLog_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "IntegrationAccount_accountId_integrationDefinitionId_worksp_key" ON "IntegrationAccount"("accountId", "integrationDefinitionId", "workspaceId"); + +-- CreateIndex +CREATE UNIQUE INDEX "IntegrationDefinitionV2_name_key" ON "IntegrationDefinitionV2"("name"); + +-- AddForeignKey +ALTER TABLE "Activity" ADD CONSTRAINT "Activity_integrationAccountId_fkey" FOREIGN KEY ("integrationAccountId") REFERENCES "IntegrationAccount"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Activity" ADD CONSTRAINT "Activity_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "IntegrationAccount" ADD CONSTRAINT "IntegrationAccount_integratedById_fkey" FOREIGN KEY ("integratedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "IntegrationAccount" ADD CONSTRAINT "IntegrationAccount_integrationDefinitionId_fkey" FOREIGN KEY ("integrationDefinitionId") REFERENCES "IntegrationDefinitionV2"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "IntegrationAccount" ADD CONSTRAINT "IntegrationAccount_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "IntegrationDefinitionV2" ADD CONSTRAINT "IntegrationDefinitionV2_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "WebhookConfiguration" ADD CONSTRAINT "WebhookConfiguration_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "WebhookConfiguration" ADD CONSTRAINT "WebhookConfiguration_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "WebhookDeliveryLog" ADD CONSTRAINT "WebhookDeliveryLog_webhookConfigurationId_fkey" FOREIGN KEY ("webhookConfigurationId") REFERENCES "WebhookConfiguration"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "WebhookDeliveryLog" ADD CONSTRAINT "WebhookDeliveryLog_activityId_fkey" FOREIGN KEY ("activityId") REFERENCES "Activity"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/packages/database/prisma/migrations/20250707105400_add_preferences/migration.sql b/packages/database/prisma/migrations/20250707105400_add_preferences/migration.sql new file mode 100644 index 0000000..6841d3f --- /dev/null +++ b/packages/database/prisma/migrations/20250707105400_add_preferences/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "preferences" JSONB; + +-- AlterTable +ALTER TABLE "Workspace" ADD COLUMN "preferences" JSONB; diff --git a/packages/database/prisma/migrations/20250708000247_add_conversation/migration.sql b/packages/database/prisma/migrations/20250708000247_add_conversation/migration.sql new file mode 100644 index 0000000..4caae51 --- /dev/null +++ b/packages/database/prisma/migrations/20250708000247_add_conversation/migration.sql @@ -0,0 +1,70 @@ +-- CreateEnum +CREATE TYPE "UserType" AS ENUM ('Agent', 'User', 'System'); + +-- CreateTable +CREATE TABLE "Conversation" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "deleted" TIMESTAMP(3), + "unread" BOOLEAN NOT NULL DEFAULT false, + "title" TEXT, + "userId" TEXT NOT NULL, + "workspaceId" TEXT, + "status" TEXT NOT NULL DEFAULT 'pending', + + CONSTRAINT "Conversation_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "ConversationHistory" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "deleted" TIMESTAMP(3), + "message" TEXT NOT NULL, + "userType" "UserType" NOT NULL, + "activityId" TEXT, + "context" JSONB, + "thoughts" JSONB, + "userId" TEXT, + "conversationId" TEXT NOT NULL, + + CONSTRAINT "ConversationHistory_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "ConversationExecutionStep" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "deleted" TIMESTAMP(3), + "thought" TEXT NOT NULL, + "message" TEXT NOT NULL, + "actionId" TEXT, + "actionOutput" TEXT, + "actionInput" TEXT, + "actionStatus" TEXT, + "metadata" JSONB DEFAULT '{}', + "conversationHistoryId" TEXT NOT NULL, + + CONSTRAINT "ConversationExecutionStep_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Conversation" ADD CONSTRAINT "Conversation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Conversation" ADD CONSTRAINT "Conversation_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ConversationHistory" ADD CONSTRAINT "ConversationHistory_activityId_fkey" FOREIGN KEY ("activityId") REFERENCES "Activity"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ConversationHistory" ADD CONSTRAINT "ConversationHistory_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ConversationHistory" ADD CONSTRAINT "ConversationHistory_conversationId_fkey" FOREIGN KEY ("conversationId") REFERENCES "Conversation"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ConversationExecutionStep" ADD CONSTRAINT "ConversationExecutionStep_conversationHistoryId_fkey" FOREIGN KEY ("conversationHistoryId") REFERENCES "ConversationHistory"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma index 7035de3..2d80e73 100644 --- a/packages/database/prisma/schema.prisma +++ b/packages/database/prisma/schema.prisma @@ -10,6 +10,258 @@ generator client { previewFeatures = ["tracing"] } +model Activity { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + text String + // Used to link the task or activity to external apps + sourceURL String? + + integrationAccount IntegrationAccount? @relation(fields: [integrationAccountId], references: [id]) + integrationAccountId String? + + rejectionReason String? + + workspace Workspace @relation(fields: [workspaceId], references: [id]) + workspaceId String + + WebhookDeliveryLog WebhookDeliveryLog[] + + ConversationHistory ConversationHistory[] +} + +model AuthorizationCode { + id String @id @default(cuid()) + + code String @unique + + personalAccessToken PersonalAccessToken? @relation(fields: [personalAccessTokenId], references: [id], onDelete: Cascade, onUpdate: Cascade) + personalAccessTokenId String? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Conversation { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + unread Boolean @default(false) + + title String? + user User @relation(fields: [userId], references: [id]) + userId String + + workspace Workspace? @relation(fields: [workspaceId], references: [id]) + workspaceId String? + + status String @default("pending") // Can be "pending", "running", "completed", "failed", "need_attention" + + ConversationHistory ConversationHistory[] +} + +model ConversationExecutionStep { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + thought String + message String + + actionId String? + actionOutput String? + actionInput String? + actionStatus String? + + metadata Json? @default("{}") + + conversationHistory ConversationHistory @relation(fields: [conversationHistoryId], references: [id]) + conversationHistoryId String +} + +model ConversationHistory { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + message String + userType UserType + + activity Activity? @relation(fields: [activityId], references: [id]) + activityId String? + + context Json? + + thoughts Json? + user User? @relation(fields: [userId], references: [id]) + userId String? + + conversation Conversation @relation(fields: [conversationId], references: [id]) + conversationId String + ConversationExecutionStep ConversationExecutionStep[] +} + +model Entity { + id String @id @default(cuid()) + name String @unique // e.g., "User", "Issue", "Task", "Automation" + metadata Json // Store field definitions and their types + + // Relations + spaceEntities SpaceEntity[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model IngestionQueue { + id String @id @default(cuid()) + + // Relations + space Space? @relation(fields: [spaceId], references: [id]) + spaceId String? + + // Queue metadata + data Json // The actual data to be processed + output Json? // The processed output data + status IngestionStatus + priority Int @default(0) + + workspaceId String + workspace Workspace @relation(fields: [workspaceId], references: [id]) + + // Error handling + error String? + retryCount Int @default(0) + + // Timestamps + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + processedAt DateTime? +} + +model IntegrationAccount { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + integrationConfiguration Json + accountId String? + settings Json? + isActive Boolean @default(true) + + integratedBy User @relation(references: [id], fields: [integratedById]) + integratedById String + integrationDefinition IntegrationDefinitionV2 @relation(references: [id], fields: [integrationDefinitionId]) + integrationDefinitionId String + workspace Workspace @relation(references: [id], fields: [workspaceId]) + workspaceId String + Activity Activity[] + + @@unique([accountId, integrationDefinitionId, workspaceId]) +} + +model IntegrationDefinitionV2 { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deleted DateTime? + + name String @unique + slug String + description String + icon String + config Json? + spec Json @default("{}") + version String? + url String? + + workspace Workspace? @relation(references: [id], fields: [workspaceId]) + workspaceId String? + + IntegrationAccount IntegrationAccount[] +} + +model InvitationCode { + id String @id @default(cuid()) + code String @unique + + users User[] + + createdAt DateTime @default(now()) +} + +model PersonalAccessToken { + id String @id @default(cuid()) + + /// If generated by the CLI this will be "cli", otherwise user-provided + name String + + /// This is the token encrypted using the ENCRYPTION_KEY + encryptedToken Json + + /// This is shown in the UI, with ******** + obfuscatedToken String + + /// This is used to find the token in the database + hashedToken String @unique + + user User @relation(fields: [userId], references: [id]) + userId String + + revokedAt DateTime? + lastAccessedAt DateTime? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + authorizationCodes AuthorizationCode[] +} + +model Space { + id String @id @default(cuid()) + name String + description String? + autoMode Boolean @default(false) + + // Relations + user User @relation(fields: [userId], references: [id]) + userId String + + // Space's enabled entities + enabledEntities SpaceEntity[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + IngestionQueue IngestionQueue[] +} + +model SpaceEntity { + id String @id @default(cuid()) + + // Relations + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + entity Entity @relation(fields: [entityId], references: [id]) + entityId String + + // Custom settings for this entity in this space + settings Json? + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@unique([spaceId, entityId]) +} + model User { id String @id @default(cuid()) email String @unique @@ -36,10 +288,47 @@ model User { referralSource String? personalAccessTokens PersonalAccessToken[] - InvitationCode InvitationCode? @relation(fields: [invitationCodeId], references: [id]) + InvitationCode InvitationCode? @relation(fields: [invitationCodeId], references: [id]) invitationCodeId String? Space Space[] Workspace Workspace? + IntegrationAccount IntegrationAccount[] + WebhookConfiguration WebhookConfiguration[] + Conversation Conversation[] + ConversationHistory ConversationHistory[] +} + +model WebhookConfiguration { + id String @id @default(cuid()) + url String + secret String? + isActive Boolean @default(true) + eventTypes String[] // List of event types this webhook is interested in, e.g. ["activity.created"] + user User? @relation(fields: [userId], references: [id]) + userId String? + workspace Workspace? @relation(fields: [workspaceId], references: [id]) + workspaceId String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + WebhookDeliveryLog WebhookDeliveryLog[] +} + +model WebhookDeliveryLog { + id String @id @default(cuid()) + webhookConfiguration WebhookConfiguration @relation(fields: [webhookConfigurationId], references: [id]) + webhookConfigurationId String + + activity Activity? @relation(fields: [activityId], references: [id]) + activityId String? + + status WebhookDeliveryStatus + responseStatusCode Int? + responseBody String? + error String? + deliveredAt DateTime @default(now()) + + createdAt DateTime @default(now()) } model Workspace { @@ -54,9 +343,14 @@ model Workspace { integrations String[] - userId String? @unique - user User? @relation(fields: [userId], references: [id]) - IngestionQueue IngestionQueue[] + userId String? @unique + user User? @relation(fields: [userId], references: [id]) + IngestionQueue IngestionQueue[] + IntegrationAccount IntegrationAccount[] + IntegrationDefinitionV2 IntegrationDefinitionV2[] + Activity Activity[] + WebhookConfiguration WebhookConfiguration[] + Conversation Conversation[] } enum AuthenticationMethod { @@ -64,135 +358,6 @@ enum AuthenticationMethod { MAGIC_LINK } -/// Used to generate PersonalAccessTokens, they're one-time use -model AuthorizationCode { - id String @id @default(cuid()) - - code String @unique - - personalAccessToken PersonalAccessToken? @relation(fields: [personalAccessTokenId], references: [id], onDelete: Cascade, onUpdate: Cascade) - personalAccessTokenId String? - - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - -// Used by User's to perform API actions -model PersonalAccessToken { - id String @id @default(cuid()) - - /// If generated by the CLI this will be "cli", otherwise user-provided - name String - - /// This is the token encrypted using the ENCRYPTION_KEY - encryptedToken Json - - /// This is shown in the UI, with ******** - obfuscatedToken String - - /// This is used to find the token in the database - hashedToken String @unique - - user User @relation(fields: [userId], references: [id]) - userId String - - revokedAt DateTime? - lastAccessedAt DateTime? - - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - authorizationCodes AuthorizationCode[] -} - -model InvitationCode { - id String @id @default(cuid()) - code String @unique - - users User[] - - createdAt DateTime @default(now()) -} - -// Space model for user workspaces -model Space { - id String @id @default(cuid()) - name String - description String? - autoMode Boolean @default(false) - - // Relations - user User @relation(fields: [userId], references: [id]) - userId String - - // Space's enabled entities - enabledEntities SpaceEntity[] - - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - IngestionQueue IngestionQueue[] -} - -// Entity types that can be stored in the memory plane -model Entity { - id String @id @default(cuid()) - name String @unique // e.g., "User", "Issue", "Task", "Automation" - metadata Json // Store field definitions and their types - - // Relations - spaceEntities SpaceEntity[] - - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - -// Junction table for Space-Entity relationship (what entities are enabled in each space) -model SpaceEntity { - id String @id @default(cuid()) - - // Relations - space Space @relation(fields: [spaceId], references: [id]) - spaceId String - - entity Entity @relation(fields: [entityId], references: [id]) - entityId String - - // Custom settings for this entity in this space - settings Json? - - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - @@unique([spaceId, entityId]) -} - -// Queue for processing ingestion tasks -model IngestionQueue { - id String @id @default(cuid()) - - // Relations - space Space? @relation(fields: [spaceId], references: [id]) - spaceId String? - - // Queue metadata - data Json // The actual data to be processed - output Json? // The processed output data - status IngestionStatus - priority Int @default(0) - - workspaceId String - workspace Workspace @relation(fields: [workspaceId], references: [id]) - - // Error handling - error String? - retryCount Int @default(0) - - // Timestamps - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - processedAt DateTime? -} - enum IngestionStatus { PENDING PROCESSING @@ -200,3 +365,14 @@ enum IngestionStatus { FAILED CANCELLED } + +enum UserType { + Agent + User + System +} + +enum WebhookDeliveryStatus { + SUCCESS + FAILED +} diff --git a/packages/sdk/.eslintrc.js b/packages/sdk/.eslintrc.js new file mode 100644 index 0000000..bd58927 --- /dev/null +++ b/packages/sdk/.eslintrc.js @@ -0,0 +1,9 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + root: true, + extends: ['@redplanethq/eslint-config/internal.js'], + parser: '@typescript-eslint/parser', + rules: { + 'no-redeclare': 'off', + }, +}; diff --git a/packages/sdk/.prettierrc.json b/packages/sdk/.prettierrc.json new file mode 100644 index 0000000..dcb7279 --- /dev/null +++ b/packages/sdk/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/packages/sdk/package.json b/packages/sdk/package.json new file mode 100644 index 0000000..fed7b69 --- /dev/null +++ b/packages/sdk/package.json @@ -0,0 +1,49 @@ +{ + "name": "@redplanethq/sol-sdk", + "version": "0.2.18", + "description": "Sol Node.JS SDK", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "module": "./dist/index.mjs", + "publishConfig": { + "access": "public" + }, + "files": [ + "dist" + ], + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./package.json": "./package.json" + }, + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && npm run build:tsup", + "build:tsup": "tsup --dts-resolve", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + }, + "devDependencies": { + "@core/types": "workspace:*", + "@types/configstore": "^6.0.2", + "@types/debug": "^4.1.7", + "@types/node": "18", + "@types/slug": "^5.0.3", + "@types/uuid": "^9.0.0", + "encoding": "^0.1.13", + "rimraf": "^6.0.1", + "tsup": "^8.0.1", + "typescript": "^5.3.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "packageManager": "pnpm@10.3.0" +} \ No newline at end of file diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts new file mode 100644 index 0000000..d33aaa0 --- /dev/null +++ b/packages/sdk/src/index.ts @@ -0,0 +1 @@ +export * from '@core/types'; diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json new file mode 100644 index 0000000..baa0f20 --- /dev/null +++ b/packages/sdk/tsconfig.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "include": ["./src/**/*.ts", "tsup.config.ts"], + "compilerOptions": { + "baseUrl": "src", + + "moduleResolution": "node", + + "strictNullChecks": false, + "preserveConstEnums": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "noFallthroughCasesInSwitch": true, + "useUnknownInCatchVariables": false, + + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "sourceMap": true, + + "removeComments": true, + "module": "commonjs", + "target": "ES2022", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "lib": ["DOM", "DOM.Iterable"], + "declaration": false, + "declarationMap": false, + "stripInternal": true + }, + "exclude": ["node_modules", "dist"] +} diff --git a/packages/sdk/tsup.config.ts b/packages/sdk/tsup.config.ts new file mode 100644 index 0000000..81352e3 --- /dev/null +++ b/packages/sdk/tsup.config.ts @@ -0,0 +1,22 @@ +import { Options, defineConfig as defineConfigTSUP } from 'tsup'; + +const options: Options = { + name: 'main', + config: 'tsconfig.json', + entry: ['./src/index.ts'], + outDir: './dist', + platform: 'node', + format: ['cjs', 'esm'], + legacyOutput: false, + sourcemap: true, + clean: true, + bundle: true, + splitting: false, + dts: true, + treeshake: { + preset: 'recommended', + }, + external: ['axios'], +}; + +export default defineConfigTSUP(options); diff --git a/packages/types/package.json b/packages/types/package.json index c99387e..e27f62d 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -5,7 +5,9 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "dependencies": { - "@prisma/client": "5.4.1" + "@prisma/client": "5.4.1", + "class-transformer": "0.5.1", + "class-validator": "0.14.1" }, "devDependencies": { "prisma": "5.4.1", diff --git a/packages/types/src/conversation-execution-step/conversation-execution.entity.ts b/packages/types/src/conversation-execution-step/conversation-execution.entity.ts new file mode 100644 index 0000000..43bdeb5 --- /dev/null +++ b/packages/types/src/conversation-execution-step/conversation-execution.entity.ts @@ -0,0 +1,19 @@ +export enum ActionStatusEnum { + ACCEPT = "ACCEPT", + DECLINE = "DECLINE", + QUESTION = "QUESTION", + TOOL_REQUEST = "TOOL_REQUEST", + SUCCESS = "SUCCESS", + FAILED = "FAILED", +} + +export const ActionStatus = { + ACCEPT: "ACCEPT", + DECLINE: "DECLINE", + QUESTION: "QUESTION", + TOOL_REQUEST: "TOOL_REQUEST", + SUCCESS: "SUCCESS", + FAILED: "FAILED", +}; + +export type ActionStatus = (typeof ActionStatus)[keyof typeof ActionStatus]; diff --git a/packages/types/src/conversation-execution-step/index.ts b/packages/types/src/conversation-execution-step/index.ts new file mode 100644 index 0000000..cb952ac --- /dev/null +++ b/packages/types/src/conversation-execution-step/index.ts @@ -0,0 +1 @@ +export * from "./conversation-execution.entity"; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 555ffe9..6ce7200 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,2 +1,6 @@ export * from "./llm"; export * from "./graph"; +export * from "./conversation-execution-step"; +export * from "./oauth"; +export * from "./integration"; +export * from "./user"; diff --git a/packages/types/src/integration.ts b/packages/types/src/integration.ts new file mode 100644 index 0000000..e9036d8 --- /dev/null +++ b/packages/types/src/integration.ts @@ -0,0 +1,70 @@ +import { Spec } from "./oauth"; + +export enum IntegrationPayloadEventType { + /** + * When a webhook is received, this event is triggered to identify which integration + * account the webhook belongs to + */ + IDENTIFY_WEBHOOK_ACCOUNT = "identify_webhook_account", + + /** + * Lifecycle events for integration accounts + */ + INTEGRATION_ACCOUNT_CREATED = "integration_account_created", + + /** + * When data is received from the integration source (e.g. new Slack message) + */ + INTEGRATION_DATA_RECEIVED = "integration_data_received", + + /** + * For integrations without webhook support, this event is triggered at the + * configured frequency to sync data + */ + SCHEDULED_SYNC = "scheduled_sync", +} + +export interface IntegrationEventPayload { + event: IntegrationPayloadEventType; + [x: string]: any; +} + +export interface Activity { + id: string; + type: string; + timestamp: string; + data: any; +} + +export interface IntegrationAccountConfig { + access_token: string; + team_id?: string; + channel_ids?: string; + [key: string]: any; +} + +export interface IntegrationAccountIdentifier { + identifier: string; + type: string; +} + +export interface IntegrationAccountSettings { + [key: string]: any; +} + +export type MessageType = + | "Spec" + | "Activity" + | "IntegrationAccountConfig" + | "IntegrationAccountIdentifier" + | "IntegrationAccountSettings"; + +export interface Message { + type: MessageType; + data: + | Spec + | Activity + | IntegrationAccountConfig + | IntegrationAccountIdentifier + | IntegrationAccountSettings; +} diff --git a/packages/types/src/oauth/index.ts b/packages/types/src/oauth/index.ts new file mode 100644 index 0000000..83f99fb --- /dev/null +++ b/packages/types/src/oauth/index.ts @@ -0,0 +1 @@ +export * from "./params"; diff --git a/packages/types/src/oauth/params.ts b/packages/types/src/oauth/params.ts new file mode 100644 index 0000000..f2c423c --- /dev/null +++ b/packages/types/src/oauth/params.ts @@ -0,0 +1,25 @@ +export class OAuth2Params { + authorization_url: string; + authorization_params?: Record; + default_scopes?: string[]; + scope_separator?: string; + scope_identifier?: string; + token_url: string; + token_params?: Record; + redirect_uri_metadata?: string[]; + token_response_metadata?: string[]; + token_expiration_buffer?: number; // In seconds. + scopes?: string[]; +} + +export type AuthType = "OAuth2" | "APIKey"; + +export class APIKeyParams { + "header_name": string; + "format": string; +} + +export class Spec { + auth: Record; + other_data?: any; +} diff --git a/packages/types/src/user/index.ts b/packages/types/src/user/index.ts new file mode 100644 index 0000000..406fb3a --- /dev/null +++ b/packages/types/src/user/index.ts @@ -0,0 +1,5 @@ +export enum UserTypeEnum { + Agent = "Agent", + User = "User", + System = "System", +} diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json index 8783927..a759bff 100644 --- a/packages/types/tsconfig.json +++ b/packages/types/tsconfig.json @@ -12,7 +12,10 @@ "noEmit": false, "outDir": "./dist", "declaration": true, - "declarationDir": "./dist" + "declarationDir": "./dist", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "strictPropertyInitialization": false }, "exclude": ["node_modules", "dist"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d36452..7aa64c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.26.2 '@remix-run/changelog-github': specifier: ^0.0.5 - version: 0.0.5 + version: 0.0.5(encoding@0.1.13) devDependencies: dotenv-cli: specifier: ^7.4.4 @@ -30,6 +30,12 @@ importers: apps/webapp: dependencies: + '@ai-sdk/anthropic': + specifier: ^1.2.12 + version: 1.2.12(zod@3.23.8) + '@ai-sdk/google': + specifier: ^1.2.22 + version: 1.2.22(zod@3.23.8) '@ai-sdk/openai': specifier: ^1.3.21 version: 1.3.22(zod@3.23.8) @@ -51,6 +57,9 @@ importers: '@mjackson/headers': specifier: 0.11.1 version: 0.11.1 + '@modelcontextprotocol/sdk': + specifier: 1.13.2 + version: 1.13.2 '@nichtsam/remix-auth-email-link': specifier: 3.0.0 version: 3.0.0(remix-auth@4.2.0) @@ -147,12 +156,51 @@ importers: '@tanstack/react-table': specifier: ^8.13.2 version: 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tiptap/extension-document': + specifier: ^2.11.9 + version: 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-hard-break': + specifier: ^2.11.9 + version: 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-history': + specifier: ^2.11.9 + version: 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-paragraph': + specifier: ^2.11.9 + version: 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-text': + specifier: ^2.11.9 + version: 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/pm': + specifier: ^2.11.9 + version: 2.25.0 + '@tiptap/react': + specifier: ^2.11.9 + version: 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tiptap/starter-kit': + specifier: 2.11.9 + version: 2.11.9 + '@trigger.dev/react-hooks': + specifier: ^4.0.0-v4-beta.22 + version: 4.0.0-v4-beta.22(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@trigger.dev/sdk': + specifier: ^4.0.0-v4-beta.22 + version: 4.0.0-v4-beta.22(ai@4.3.14(react@18.3.1)(zod@3.23.8))(zod@3.23.8) ai: specifier: 4.3.14 version: 4.3.14(react@18.3.1)(zod@3.23.8) + axios: + specifier: ^1.10.0 + version: 1.10.0 bullmq: specifier: ^5.53.2 version: 5.53.2 + class-transformer: + specifier: 0.5.1 + version: 0.5.1 + class-validator: + specifier: 0.14.1 + version: 0.14.1 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -177,9 +225,30 @@ importers: emails: specifier: workspace:* version: link:../../packages/emails + execa: + specifier: ^9.6.0 + version: 9.6.0 express: specifier: ^4.18.1 version: 4.21.2 + fast-sort: + specifier: ^3.4.0 + version: 3.4.1 + graphology: + specifier: ^0.26.0 + version: 0.26.0(graphology-types@0.24.8) + graphology-layout-force: + specifier: ^0.2.4 + version: 0.2.4(graphology-types@0.24.8) + graphology-layout-forceatlas2: + specifier: ^0.10.1 + version: 0.10.1(graphology-types@0.24.8) + graphology-layout-noverlap: + specifier: ^0.4.2 + version: 0.4.2(graphology-types@0.24.8) + handlebars: + specifier: ^4.7.8 + version: 4.7.8 ioredis: specifier: ^5.6.1 version: 5.6.1 @@ -204,6 +273,9 @@ importers: non.geist: specifier: ^1.0.2 version: 1.0.4 + novel: + specifier: ^1.0.2 + version: 1.0.2(@tiptap/extension-code-block@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0))(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ollama-ai-provider: specifier: 1.2.0 version: 1.2.0(zod@3.23.8) @@ -237,6 +309,15 @@ importers: remix-utils: specifier: ^7.7.0 version: 7.7.0(@remix-run/node@2.1.0(typescript@5.8.3))(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/router@1.23.0)(crypto-js@4.2.0)(react@18.3.1)(zod@3.23.8) + sdk: + specifier: link:@modelcontextprotocol/sdk + version: link:@modelcontextprotocol/sdk + sigma: + specifier: ^3.0.2 + version: 3.0.2(graphology-types@0.24.8) + simple-oauth2: + specifier: ^5.1.0 + version: 5.1.0 tailwind-merge: specifier: ^2.6.0 version: 2.6.0 @@ -264,7 +345,7 @@ importers: devDependencies: '@remix-run/dev': specifier: 2.16.7 - version: 2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0) + version: 2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0) '@remix-run/eslint-config': specifier: 2.16.7 version: 2.16.7(eslint@8.57.1)(react@18.3.1)(typescript@5.8.3) @@ -279,7 +360,10 @@ importers: version: 0.5.16(tailwindcss@4.1.7) '@tailwindcss/vite': specifier: ^4.1.7 - version: 4.1.9(vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)) + version: 4.1.9(vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)) + '@trigger.dev/build': + specifier: ^4.0.0-v4-beta.22 + version: 4.0.0-v4-beta.22(typescript@5.8.3) '@types/compression': specifier: ^1.7.2 version: 1.8.1 @@ -298,6 +382,12 @@ importers: '@types/react-dom': specifier: ^18.2.7 version: 18.3.7(@types/react@18.2.69) + '@types/react-virtualized': + specifier: ^9.22.0 + version: 9.22.2 + '@types/simple-oauth2': + specifier: ^5.0.7 + version: 5.0.7 '@typescript-eslint/eslint-plugin': specifier: ^6.7.4 version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) @@ -366,10 +456,16 @@ importers: version: 5.8.3 vite: specifier: ^6.0.0 - version: 6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) vite-tsconfig-paths: specifier: ^4.2.1 - version: 4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)) + version: 4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)) + + core/types: + devDependencies: + typescript: + specifier: ^5.0.0 + version: 5.8.3 packages/database: dependencies: @@ -406,7 +502,7 @@ importers: version: 18.3.1 react-email: specifier: ^2.1.1 - version: 2.1.6(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.2)(eslint@8.57.1) + version: 2.1.6(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.17)(eslint@8.57.1) resend: specifier: ^3.2.0 version: 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -424,11 +520,50 @@ importers: specifier: 18.2.69 version: 18.2.69 + packages/sdk: + devDependencies: + '@core/types': + specifier: workspace:* + version: link:../types + '@types/configstore': + specifier: ^6.0.2 + version: 6.0.2 + '@types/debug': + specifier: ^4.1.7 + version: 4.1.12 + '@types/node': + specifier: '18' + version: 18.19.115 + '@types/slug': + specifier: ^5.0.3 + version: 5.0.9 + '@types/uuid': + specifier: ^9.0.0 + version: 9.0.8 + encoding: + specifier: ^0.1.13 + version: 0.1.13 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 + tsup: + specifier: ^8.0.1 + version: 8.5.0(@swc/core@1.3.101(@swc/helpers@0.5.17))(jiti@2.4.2)(postcss@8.5.5)(typescript@5.8.3)(yaml@2.8.0) + typescript: + specifier: ^5.3.0 + version: 5.8.3 + packages/types: dependencies: '@prisma/client': specifier: 5.4.1 version: 5.4.1(prisma@5.4.1) + class-transformer: + specifier: 0.5.1 + version: 0.5.1 + class-validator: + specifier: 0.14.1 + version: 0.14.1 devDependencies: esbuild: specifier: ^0.25.5 @@ -442,6 +577,18 @@ importers: packages: + '@ai-sdk/anthropic@1.2.12': + resolution: {integrity: sha512-YSzjlko7JvuiyQFmI9RN1tNZdEiZxc+6xld/0tq/VkJaHpEzGAb1yiNxxvmYVcjvfu/PcvCxAAYXmTYQQ63IHQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + + '@ai-sdk/google@1.2.22': + resolution: {integrity: sha512-Ppxu3DIieF1G9pyQ5O1Z646GYR0gkC57YdBqXJ82qvCdhEhZHu0TWhmnOoeIWe2olSbuDeoOY+MfJrW8dzS3Hw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + '@ai-sdk/openai@1.3.22': resolution: {integrity: sha512-QwA+2EkG0QyjVR+7h6FE7iOu2ivNqAVMm9UJZkVxxTk5OIq5fFJDTEI/zICEMuHImTTXR2JjsL6EirJ28Jc4cw==} engines: {node: '>=18'} @@ -778,6 +925,12 @@ packages: resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} + '@bugsnag/cuid@3.2.1': + resolution: {integrity: sha512-zpvN8xQ5rdRWakMd/BcVkdn2F8HKlDSbM3l7duueK590WmI1T0ObTLc1V/1e55r14WNjPd5AJTYX4yPEAFVi+Q==} + + '@cfcs/core@0.0.6': + resolution: {integrity: sha512-FxfJMwoLB8MEMConeXUCqtMGqxdtePQxRBOiGip9ULcYYam3WfCgoY6xdnMaSkYvRvmosp5iuG+TiPofm65+Pw==} + '@changesets/apply-release-plan@6.1.4': resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} @@ -850,10 +1003,28 @@ packages: '@conform-to/dom': 0.6.3 zod: ^3.21.0 + '@daybrush/utils@1.13.0': + resolution: {integrity: sha512-ALK12C6SQNNHw1enXK+UO8bdyQ+jaWNQ1Af7Z3FNxeAwjYhQT7do+TRE4RASAJ3ObaS2+TJ7TXR3oz2Gzbw0PQ==} + '@edgefirst-dev/data@0.0.4': resolution: {integrity: sha512-VLhlvEPDJ0Sd0pE6sAYTQkIqZCXVonaWlgRJIQQHzfjTXCadF77qqHj5NxaPSc4wCul0DJO/0MnejVqJAXUiRg==} engines: {node: '>=20.0.0'} + '@egjs/agent@2.4.4': + resolution: {integrity: sha512-cvAPSlUILhBBOakn2krdPnOGv5hAZq92f1YHxYcfu0p7uarix2C6Ia3AVizpS1SGRZGiEkIS5E+IVTLg1I2Iog==} + + '@egjs/children-differ@1.0.1': + resolution: {integrity: sha512-DRvyqMf+CPCOzAopQKHtW+X8iN6Hy6SFol+/7zCUiE5y4P/OB8JP8FtU4NxtZwtafvSL4faD5KoQYPj3JHzPFQ==} + + '@egjs/component@3.0.5': + resolution: {integrity: sha512-cLcGizTrrUNA2EYE3MBmEDt2tQv1joVP1Q3oDisZ5nw0MZDx2kcgEXM+/kZpfa/PAkFvYVhRUZwytIQWoN3V/w==} + + '@egjs/list-differ@1.0.1': + resolution: {integrity: sha512-OTFTDQcWS+1ZREOdCWuk5hCBgYO4OsD30lXcOCyVOAjXMhgL5rBRDnt/otb6Nz8CzU0L/igdcaQBDLWc4t9gvg==} + + '@electric-sql/client@1.0.0-beta.1': + resolution: {integrity: sha512-Ei9jN3pDoGzc+a/bGqnB5ajb52IvSv7/n2btuyzUlcOHIR2kM9fqtYTJXPwZYKLkGZlHWlpHgWyRtrinkP2nHg==} + '@emnapi/core@1.4.3': resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} @@ -1466,6 +1637,37 @@ packages: '@fullhuman/postcss-purgecss@2.3.0': resolution: {integrity: sha512-qnKm5dIOyPGJ70kPZ5jiz0I9foVOic0j+cOzNDoo8KoCf6HjicIZ99UfO2OmE7vCYSKAAepEwJtNzpiiZAh9xw==} + '@google-cloud/precise-date@4.0.0': + resolution: {integrity: sha512-1TUx3KdaU3cN7nfCdNf+UVqA/PSX29Cjcox3fZZBtINlRrXVTmUkQnCKv2MbBUbCopbK4olAT1IHl76uZyCiVA==} + engines: {node: '>=14.0.0'} + + '@grpc/grpc-js@1.13.4': + resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.15': + resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} + engines: {node: '>=6'} + hasBin: true + + '@hapi/boom@10.0.1': + resolution: {integrity: sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==} + + '@hapi/bourne@3.0.0': + resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} + + '@hapi/hoek@11.0.7': + resolution: {integrity: sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@hapi/wreck@18.1.0': + resolution: {integrity: sha512-0z6ZRCmFEfV/MQqkQomJ7sl/hyxvcZM7LtuVqN3vdAO4vM9eBbowl0kaqQj9EJJQab+3Uuh1GxbGIBFy4NfJ4w==} + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -1511,6 +1713,12 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@jsonhero/path@1.0.21': + resolution: {integrity: sha512-gVUDj/92acpVoJwsVJ/RuWOaHyG4oFzn898WNGQItLCTQ+hOaVlEaImhwE1WqOTf+l3dGOUkbSiVKlb3q1hd1Q==} + '@jspm/core@2.1.0': resolution: {integrity: sha512-3sRl+pkyFY/kLmHl0cgHiFp2xEqErA8N3ECjMs7serSUBmoJ70lBa0PG5t0IM6WJgdZNyyI0R8YFfi5wM8+mzg==} @@ -1532,6 +1740,10 @@ packages: '@mjackson/headers@0.9.0': resolution: {integrity: sha512-1WFCu2iRaqbez9hcYYI611vcH1V25R+fDfOge/CyKc8sdbzniGfy/FRhNd3DgvFF4ZEEX2ayBrvFHLtOpfvadw==} + '@modelcontextprotocol/sdk@1.13.2': + resolution: {integrity: sha512-Vx7qOcmoKkR3qhaQ9qf3GxiVKCEu+zfJddHv6x3dY/9P6+uIwJnmuAur5aB+4FDXf41rRrDnOEGkviX5oYZ67w==} + engines: {node: '>=18'} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} cpu: [arm64] @@ -1665,10 +1877,142 @@ packages: '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@opentelemetry/api-logs@0.52.1': + resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==} + engines: {node: '>=14'} + '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} + '@opentelemetry/context-async-hooks@1.25.1': + resolution: {integrity: sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@1.25.1': + resolution: {integrity: sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@1.30.1': + resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/exporter-logs-otlp-http@0.52.1': + resolution: {integrity: sha512-qKgywId2DbdowPZpOBXQKp0B8DfhfIArmSic15z13Nk/JAOccBUQdPwDjDnjsM5f0ckZFMVR2t/tijTUAqDZoA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/exporter-trace-otlp-grpc@0.52.1': + resolution: {integrity: sha512-pVkSH20crBwMTqB3nIN4jpQKUEoB0Z94drIHpYyEqs7UBr+I0cpYyOR3bqjA/UasQUMROb3GX8ZX4/9cVRqGBQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/exporter-trace-otlp-http@0.52.1': + resolution: {integrity: sha512-05HcNizx0BxcFKKnS5rwOV+2GevLTVIRA0tRgWYyw4yCgR53Ic/xk83toYKts7kbzcI+dswInUg/4s8oyA+tqg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/exporter-trace-otlp-proto@0.52.1': + resolution: {integrity: sha512-pt6uX0noTQReHXNeEslQv7x311/F1gJzMnp1HD2qgypLRPbXDeMzzeTngRTUaUbP6hqWNtPxuLr4DEoZG+TcEQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/exporter-zipkin@1.25.1': + resolution: {integrity: sha512-RmOwSvkimg7ETwJbUOPTMhJm9A9bG1U8s7Zo3ajDh4zM7eYcycQ0dM7FbLD6NXWbI2yj7UY4q8BKinKYBQksyw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation@0.52.1': + resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-exporter-base@0.52.1': + resolution: {integrity: sha512-z175NXOtX5ihdlshtYBe5RpGeBoTXVCKPPLiQlD6FHvpM4Ch+p2B0yWKYSrBfLH24H9zjJiBdTrtD+hLlfnXEQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/otlp-grpc-exporter-base@0.52.1': + resolution: {integrity: sha512-zo/YrSDmKMjG+vPeA9aBBrsQM9Q/f2zo6N04WMB3yNldJRsgpRBeLLwvAt/Ba7dpehDLOEFBd1i2JCoaFtpCoQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/otlp-transformer@0.52.1': + resolution: {integrity: sha512-I88uCZSZZtVa0XniRqQWKbjAUm73I8tpEy/uJYPPYw5d7BRdVk0RfTBQw8kSUl01oVWEuqxLDa802222MYyWHg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/propagator-b3@1.25.1': + resolution: {integrity: sha512-p6HFscpjrv7//kE+7L+3Vn00VEDUJB0n6ZrjkTYHrJ58QZ8B3ajSJhRbCcY6guQ3PDjTbxWklyvIN2ojVbIb1A==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/propagator-jaeger@1.25.1': + resolution: {integrity: sha512-nBprRf0+jlgxks78G/xq72PipVK+4or9Ypntw0gVZYNTCSK8rg5SeaGV19tV920CMqBD/9UIOiFr23Li/Q8tiA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/resources@1.25.1': + resolution: {integrity: sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/sdk-logs@0.52.1': + resolution: {integrity: sha512-MBYh+WcPPsN8YpRHRmK1Hsca9pVlyyKd4BxOC4SsgHACnl/bPp4Cri9hWhVm5+2tiQ9Zf4qSc1Jshw9tOLGWQA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.4.0 <1.10.0' + + '@opentelemetry/sdk-metrics@1.25.1': + resolution: {integrity: sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-node@0.52.1': + resolution: {integrity: sha512-uEG+gtEr6eKd8CVWeKMhH2olcCHM9dEK68pe0qE0be32BcCRsvYURhHaD1Srngh1SQcnQzZ4TP324euxqtBOJA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@1.25.1': + resolution: {integrity: sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/sdk-trace-node@1.25.1': + resolution: {integrity: sha512-nMcjFIKxnFqoez4gUmihdBrbpsEnAX/Xj16sGvZm+guceYE0NE00vLhpDVK6f3q8Q4VFI5xG8JjlXKMB/SkTTQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.25.1': + resolution: {integrity: sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==} + engines: {node: '>=14'} + + '@opentelemetry/semantic-conventions@1.28.0': + resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==} + engines: {node: '>=14'} + '@oslojs/asn1@1.0.0': resolution: {integrity: sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA==} @@ -1691,6 +2035,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@prisma/client@5.4.1': resolution: {integrity: sha512-xyD0DJ3gRNfLbPsC+YfMBBuLJtZKQfy1OD2qU/PZg+HKrr7SO+09174LMeTlWP0YF2wca9LxtVd4HnAiB5ketQ==} engines: {node: '>=16.13'} @@ -1706,6 +2053,36 @@ packages: '@prisma/engines@5.4.1': resolution: {integrity: sha512-vJTdY4la/5V3N7SFvWRmSMUh4mIQnyb/MNoDjzVbh9iLmEC+uEykj/1GPviVsorvfz7DbYSQC4RiwmlEpTEvGA==} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@radix-ui/colors@1.0.1': resolution: {integrity: sha512-xySw8f0ZVsAEP+e7iLl3EvcBXX7gsIlC1Zso/sPBW9gIWerBTgz6axrjU+MZ39wD+WFi5h5zdWpsg3+hwt2Qsg==} @@ -2665,6 +3042,9 @@ packages: peerDependencies: react: 18.2.0 + '@remirror/core-constants@3.0.0': + resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} + '@remix-run/changelog-github@0.0.5': resolution: {integrity: sha512-43tqwUqWqirbv6D9uzo55ASPsCJ61Ein1k/M8qn+Qpros0MmbmuzjLVPmtaxfxfe2ANX0LefLvCD0pAgr1tp4g==} @@ -2941,9 +3321,34 @@ packages: '@rushstack/eslint-patch@1.11.0': resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + '@scena/dragscroll@1.4.0': + resolution: {integrity: sha512-3O8daaZD9VXA9CP3dra6xcgt/qrm0mg0xJCwiX6druCteQ9FFsXffkF8PrqxY4Z4VJ58fFKEa0RlKqbsi/XnRA==} + + '@scena/event-emitter@1.0.5': + resolution: {integrity: sha512-AzY4OTb0+7ynefmWFQ6hxDdk0CySAq/D4efljfhtRHCOP7MBF9zUfhKG3TJiroVjASqVgkRJFdenS8ArZo6Olg==} + + '@scena/matrix@1.1.1': + resolution: {integrity: sha512-JVKBhN0tm2Srl+Yt+Ywqu0oLgLcdemDQlD1OxmN9jaCTwaFPZ7tY8n6dhVgMEaR9qcR7r+kAlMXnSfNyYdE+Vg==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@selderee/plugin-htmlparser2@0.11.0': resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@smithy/abort-controller@4.0.4': resolution: {integrity: sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==} engines: {node: '>=18.0.0'} @@ -3191,6 +3596,9 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/helpers@0.5.2': resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} @@ -3320,6 +3728,232 @@ packages: resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} engines: {node: '>=12'} + '@tiptap/core@2.25.0': + resolution: {integrity: sha512-pTLV0+g+SBL49/Y5A9ii7oHwlzIzpgroJVI3AcBk7/SeR7554ZzjxxtJmZkQ9/NxJO+k1jQp9grXaqqOLqC7cA==} + peerDependencies: + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-blockquote@2.25.0': + resolution: {integrity: sha512-W+sVPlV9XmaNPUkxV2BinNEbk2hr4zw8VgKjqKQS9O0k2YIVRCfQch+4DudSAwBVMrVW97zVAKRNfictGFQ8vQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-bold@2.25.0': + resolution: {integrity: sha512-3cBX2EtdFR3+EDTkIshhpQpXoZQbFUzxf6u86Qm0qD49JnVOjX9iexnUp8MydXPZA6NVsKeEfMhf18gV7oxTEw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-bubble-menu@2.25.0': + resolution: {integrity: sha512-BnbfQWRXJDDy9/x/0Atu2Nka5ZAMyXLDFqzSLMAXqXSQcG6CZRTSNRgOCnjpda6Hq2yCtq7l/YEoXkbHT1ZZdQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-bullet-list@2.25.0': + resolution: {integrity: sha512-KD+q/q6KIU2anedjtjG8vELkL5rYFdNHWc5XcUJgQoxbOCK3/sBuOgcn9mnFA2eAS6UkraN9Yx0BXEDbXX2HOw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-character-count@2.25.0': + resolution: {integrity: sha512-F+4DxJFptbX3oioqNwS38zOTi6gH9CumV/ISeOIvr4ao7Iija3tNonGDsHhxD05njjbYNIp1OKsxtnzbWukgMA==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-code-block-lowlight@2.25.0': + resolution: {integrity: sha512-RunmpexQ+sYNmQbBdjQq/6s1aYYx7lQxOzPO5Q64qx5FjVbekZkQI9c98jv4v0ez7qjRLZBcyG2ETD3bQuHs4Q==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/extension-code-block': ^2.7.0 + '@tiptap/pm': ^2.7.0 + highlight.js: ^11 + lowlight: ^2 || ^3 + + '@tiptap/extension-code-block@2.25.0': + resolution: {integrity: sha512-T4kXbZNZ/NyklzQ/FWmUnjD4hgmJPrIBazzCZ/E/rF/Ag2IvUsztBT0PN3vTa+DAZ+IbM61TjlIpyJs1R7OdbQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-code@2.25.0': + resolution: {integrity: sha512-rRp6X2aNNnvo7Fbqc3olZ0vLb52FlCPPfetr9gy6/M9uQdVYDhJcFOPuRuXtZ8M8X+WpCZBV29BvZFeDqfw8bw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-color@2.25.0': + resolution: {integrity: sha512-jZh7X71Kd8TVU/lexbosyeBseOj2jzxQ5/7DV/L6E2SHsXX9rIOeY61kf4xRqoQm5Z9t2vy8GzNGXhhNACd66w==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/extension-text-style': ^2.7.0 + + '@tiptap/extension-document@2.25.0': + resolution: {integrity: sha512-3gEZlQKUSIRrC6Az8QS7SJi4CvhMWrA7RBChM1aRl9vMNN8Ul7dZZk5StYJGPjL/koTiceMqx9pNmTCBprsbvQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-dropcursor@2.25.0': + resolution: {integrity: sha512-eSHqp+iUI2mGVwvIyENP02hi5TSyQ+bdwNwIck6bdzjRvXakm72+8uPfVSLGxRKAQZ0RFtmux8ISazgUqF/oSw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-floating-menu@2.25.0': + resolution: {integrity: sha512-hPZ5SNpI14smTz4GpWQXTnxmeICINYiABSgXcsU5V66tik9OtxKwoCSR/gpU35esaAFUVRdjW7+sGkACLZD5AQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-gapcursor@2.25.0': + resolution: {integrity: sha512-s/3WDbgkvLac88h5iYJLPJCDw8tMhlss1hk9GAo+zzP4h0xfazYie09KrA0CBdfaSOFyeJK3wedzjKZBtdgX4w==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-hard-break@2.25.0': + resolution: {integrity: sha512-h8be5Zdtsl5GQHxRXvYlGfIJsLvdbexflSTr12gr4kvcQqTdtrsqyu2eksfAK+p2szbiwP2G4VZlH0LNS47UXQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-heading@2.25.0': + resolution: {integrity: sha512-IrRKRRr7Bhpnq5aue1v5/e5N/eNdVV/THsgqqpLZO48pgN8Wv+TweOZe1Ntg/v8L4QSBC8iGMxxhiJZT8AzSkA==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-highlight@2.25.0': + resolution: {integrity: sha512-YuDZUFTil06wmuIMod1z2zbLGIwDwcoRV21f2wZBl3SryzppX/B1S1fGgLdnOo4M8ryykSKxWdpjMSOYCAdsjA==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-history@2.25.0': + resolution: {integrity: sha512-y3uJkJv+UngDaDYfcVJ4kx8ivc3Etk5ow6N+47AMCRjUUweQ/CLiJwJ2C7nL7L82zOzVbb/NoR/B3UeE4ts/wQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-horizontal-rule@2.25.0': + resolution: {integrity: sha512-bZovyhdOexB3Cv9ddUogWT+cd3KbnenMIZKhgrJ+R0J27rlOtzeUD9TeIjn4V8Of9mTxm3XDKUZGLgPiriN8Ww==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-image@2.25.0': + resolution: {integrity: sha512-+EJVxt61LzSK/2iaZLp8UN/jY4eohfn4SloJ1jHEobf4+XA6LwusXItQzQiJfaAL7kjrUih2RcCkOWa0BpLFLA==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-italic@2.25.0': + resolution: {integrity: sha512-FZHmNqvWJ5SHYlUi+Qg3b2C0ZBt82DUDUqM+bqcQqSQu6B0c4IEc3+VHhjAJwEUIO9wX7xk/PsdM4Z5Ex4Lr3w==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-link@2.25.0': + resolution: {integrity: sha512-jNd+1Fd7wiIbxlS51weBzyDtBEBSVzW0cgzdwOzBYQtPJueRyXNNVERksyinDuVgcfvEWgmNZUylgzu7mehnEg==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-list-item@2.25.0': + resolution: {integrity: sha512-HLstO/R+dNjIFMXN15bANc8i/+CDpEgtEQhZNHqvSUJH9xQ5op0S05m5VvFI10qnwXNjwwXdhxUYwwjIDCiAgg==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-ordered-list@2.25.0': + resolution: {integrity: sha512-Hlid16nQdDFOGOx6mJT+zPEae2t1dGlJ18pqCqaVMuDnIpNIWmQutJk5QYxGVxr9awd2SpHTpQtdBTqcufbHtw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-paragraph@2.25.0': + resolution: {integrity: sha512-53gpWMPedkWVDp3u/1sLt6vnr3BWz4vArGCmmabLucCI2Yl4R6S/AQ9yj/+jOHvWbXCroCbKtmmwxJl32uGN2w==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-placeholder@2.25.0': + resolution: {integrity: sha512-BUJnp/WQt/8iMJ9wn1xGlA+RiXCsP24u5n+ecxw+DBTgFq7RRL9I1nDQ/IJBrfWMJGOrMEq6tg8rmg1NVLGfWw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-strike@2.25.0': + resolution: {integrity: sha512-Z5YBKnv4N6MMD1LEo9XbmWnmdXavZKOOJt/OkXYFZ3KgzB52Z3q3DDfH+NyeCtKKSWqWVxbBHKLnsojDerSf2g==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-task-item@2.25.0': + resolution: {integrity: sha512-8F7Z7jbsyGrPLHQCn+n39zdqIgxwR1kJ1nL5ZwhEW3ZhJgkFF0WMJSv36mwIJwL08p8um/c6g72AYB/e8CD7eA==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@tiptap/extension-task-list@2.25.0': + resolution: {integrity: sha512-2mASqp8MJ0dyc1OK6c8P7m/zwoVDv8PV+XsRR9O3tpIz/zjUVrOl0W4IndjUPBMa7cpJX8fGj8iC3DaRNpSMcg==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-text-style@2.25.0': + resolution: {integrity: sha512-MKAXqDATEbuFEB1SeeAFy2VbefUMJ9jxQyybpaHjDX+Ik0Ddu+aYuJP/njvLuejXCqhrkS/AorxzmHUC4HNPbQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-text@2.25.0': + resolution: {integrity: sha512-HlZL86rihpP/R8+dqRrvzSRmiPpx6ctlAKM9PnWT/WRMeI4Y1AUq6PSHLz74wtYO1LH4PXys1ws3n+pLP4Mo6g==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-underline@2.25.0': + resolution: {integrity: sha512-RqXkWSMJyllfsDukugDzWEZfWRUOgcqzuMWC40BnuDUs4KgdRA0nhVUWJbLfUEmXI0UVqN5OwYTTAdhaiF7kjQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/extension-youtube@2.25.0': + resolution: {integrity: sha512-jVeBHhJZQ7upMMio/jVR/MisD0Xc0pOzMWMw8/82s6Dwkp9F5xRQXpofoYW2UlfAt9FwxyxdwJ6s9vZEyiyOkw==} + peerDependencies: + '@tiptap/core': ^2.7.0 + + '@tiptap/pm@2.25.0': + resolution: {integrity: sha512-vuzU0pLGQyHqtikAssHn9V61aXLSQERQtn3MUtaJ36fScQg7RClAK5gnIbBt3Ul3VFof8o4xYmcidARc0X/E5A==} + + '@tiptap/react@2.25.0': + resolution: {integrity: sha512-Fc7uj/+goEhvJkH2vYJxXLH1GsUkOcsIR3kUyL0vejNRvpzzd87CI/EiSD2ESJO43czQcsJkiYzY4EC+p8NF9w==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tiptap/starter-kit@2.11.9': + resolution: {integrity: sha512-UUx5t1PrwR+KVOjTkmGC1duOq6Ubz/fsetI1OieyegMT/2J1wkFFP1w3NFZarj5jo0GLBt3GMlBwS9GY8cJUxQ==} + + '@tiptap/suggestion@2.25.0': + resolution: {integrity: sha512-ykMwdyaHzqIg+jMI/zZ4TOjVxYkwVG7H6BD3gV9gV5tyRpedsKbvppm3aUlnMWC/OmDqQhlSD8iT8Vo3UWX2oQ==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + + '@trigger.dev/build@4.0.0-v4-beta.22': + resolution: {integrity: sha512-W+SfA7soXzD7f2GQQL2Q4x3+JQkJijcVjgKpNuwPdZcgI++YpJkPzJ5RlT98flErU8ZvuiL26SAur2tvObrZgA==} + engines: {node: '>=18.20.0'} + + '@trigger.dev/core@4.0.0-v4-beta.22': + resolution: {integrity: sha512-FVaVNsW3KQgYEWStr80Iu+1l4KMyHPVU4QbV55pLQp7d126jOuP+hXYp7LhnYVZtgcQLIZSC0VjJc/UYwr4D6g==} + engines: {node: '>=18.20.0'} + + '@trigger.dev/react-hooks@4.0.0-v4-beta.22': + resolution: {integrity: sha512-hWBoxEkNSM+IcFsUlFEJBcMZGmpaYGPy5k/o+iK9QNLURiQsKEYGYoBzKlA7iP0cVPwhIV1eNlsPediNRQyTsA==} + engines: {node: '>=18.20.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^18.0 || ^19.0 || ^19.0.0-rc + + '@trigger.dev/sdk@4.0.0-v4-beta.22': + resolution: {integrity: sha512-yRv9G/KODpItU16Iv6gCfLQ2SjhGq443zTlYKY3XZf4HHIuByOhkOKYPRpl82FmJprL8DxnT7V0pma4kfHBzPQ==} + engines: {node: '>=18.20.0'} + peerDependencies: + ai: ^4.2.0 + zod: ^3.0.0 + peerDependenciesMeta: + ai: + optional: true + '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -3335,6 +3969,9 @@ packages: '@types/compression@1.8.1': resolution: {integrity: sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==} + '@types/configstore@6.0.2': + resolution: {integrity: sha512-OS//b51j9uyR3zvwD04Kfs5kHpve2qalQ18JhY/ho3voGYUTPLEG90/ocfKPI48hyHH8T04f7KEEbK6Ue60oZQ==} + '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -3473,6 +4110,9 @@ packages: '@types/hast@2.3.10': resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} @@ -3485,9 +4125,21 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/mdx@2.0.13': resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} @@ -3506,6 +4158,12 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@18.19.115': + resolution: {integrity: sha512-kNrFiTgG4a9JAn1LMQeLOv3MvXIPokzXziohMrMsvpYgLpdEt/mMiVYc4sGKtDfyxM5gIDF4VgrPRyCw4fHOYg==} + + '@types/node@22.16.0': + resolution: {integrity: sha512-B2egV9wALML1JCpv3VQoQ+yesQKAmNMBIAY7OteVrikcOcAkWm+dGL6qpeCktPjAv6N1JLnhbNiqS35UpFyBsQ==} + '@types/node@24.0.0': resolution: {integrity: sha512-yZQa2zm87aRVcqDyH5+4Hv9KYgSdgwX1rFnGvpbzMaC7YAljmhBET93TPiTd3ObwTL+gSpIzPKg5BqVxdCvxKg==} @@ -3532,6 +4190,9 @@ packages: peerDependencies: '@types/react': ^18.0.0 + '@types/react-virtualized@9.22.2': + resolution: {integrity: sha512-0Eg/ME3OHYWGxs+/n4VelfYrhXssireZaa1Uqj5SEkTpSaBu5ctFGOCVxcOqpGXRiEdrk/7uho9tlZaryCIjHA==} + '@types/react@18.2.47': resolution: {integrity: sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==} @@ -3550,9 +4211,30 @@ packages: '@types/serve-static@1.15.8': resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} + '@types/shimmer@1.2.0': + resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} + + '@types/simple-oauth2@5.0.7': + resolution: {integrity: sha512-8JbWVJbiTSBQP/7eiyGKyXWAqp3dKQZpaA+pdW16FCi32ujkzRMG8JfjoAzdWt6W8U591ZNdHcPtP2D7ILTKuA==} + + '@types/slug@5.0.9': + resolution: {integrity: sha512-6Yp8BSplP35Esa/wOG1wLNKiqXevpQTEF/RcL/NV6BBQaMmZh4YlDwCgrrFSoUE4xAGvnKd5c+lkQJmPrBAzfQ==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + + '@types/validator@13.15.2': + resolution: {integrity: sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==} + '@types/webpack@5.28.5': resolution: {integrity: sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw==} @@ -3851,6 +4533,15 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -4018,6 +4709,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + autoprefixer@10.4.14: resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} @@ -4044,6 +4738,9 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -4077,6 +4774,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bintrees@1.0.2: + resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -4084,6 +4784,10 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + body-parser@2.2.0: + resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + engines: {node: '>=18'} + bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} @@ -4124,6 +4828,12 @@ packages: bullmq@5.53.2: resolution: {integrity: sha512-xHgxrP/yNJHD7VCw1h+eRBh+2TCPBCM39uC9gCyksYc6ufcJP+HTZ/A2lzB2x7qMFWrvsX7tM40AT2BmdkYL/Q==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -4209,6 +4919,10 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -4228,6 +4942,15 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + class-validator@0.14.1: + resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -4273,6 +4996,12 @@ packages: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} + cmdk@1.1.1: + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4292,6 +5021,10 @@ packages: color@3.2.1: resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -4318,6 +5051,10 @@ packages: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -4338,10 +5075,18 @@ packages: config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} @@ -4368,6 +5113,10 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + core-js@3.43.0: resolution: {integrity: sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==} @@ -4387,10 +5136,17 @@ packages: typescript: optional: true + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} + cronstrue@2.59.0: + resolution: {integrity: sha512-YKGmAy84hKH+hHIIER07VCAHf9u0Ldelx1uU6EBxsRPDXIA1m5fsKmJfyC3xBhw6cVC/1i83VdbL4PvepTrt8A==} + hasBin: true + cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -4422,6 +5178,12 @@ packages: webpack: optional: true + css-styled@1.0.8: + resolution: {integrity: sha512-tCpP7kLRI8dI95rCh3Syl7I+v7PP+2JYOzWkl0bUEoSbJM+u8ITbutjlQVf0NC2/g4ULROJPi16sfwDIO8/84g==} + + css-to-mat@1.1.1: + resolution: {integrity: sha512-kvpxFYZb27jRd2vium35G7q5XZ2WJ9rWjDUMNT36M3Hc41qCrLXFM5iEKMGXcrPsKfXEN+8l/riB4QzwwwiEyQ==} + css-unit-converter@1.1.2: resolution: {integrity: sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==} @@ -4693,6 +5455,10 @@ packages: delaunator@5.0.1: resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} @@ -4725,6 +5491,9 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -4824,6 +5593,9 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -5139,6 +5911,9 @@ packages: estree-util-is-identifier-name@2.1.0: resolution: {integrity: sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==} + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-util-to-js@1.2.0: resolution: {integrity: sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==} @@ -5172,18 +5947,47 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-parser@3.0.3: + resolution: {integrity: sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==} + engines: {node: '>=20.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + evt@2.5.9: + resolution: {integrity: sha512-GpjX476FSlttEGWHT8BdVMoI8wGXQGbEOtKcP4E+kggg+yJzXBZN2n4x7TS/zPBJ1DZqWI+rguZZApjjzQ0HpA==} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.6.0: + resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} + engines: {node: ^18.19.0 || >=20.5.0} + exit-hook@2.2.1: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} + express-rate-limit@7.5.1: + resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + express@4.21.2: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} + express@5.1.0: + resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + engines: {node: '>= 18'} + exsolve@1.0.5: resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} @@ -5213,6 +6017,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-sort@3.4.1: + resolution: {integrity: sha512-76uvGPsF6So53sZAqenP9UVT3p5l7cyTHkLWVCMinh41Y8NDrK1IYXJgaBMfc1gk7nJiSRZp676kddFG2Aa5+A==} + fast-uri@3.0.6: resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} @@ -5237,6 +6044,10 @@ packages: fflate@0.4.8: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5249,6 +6060,10 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} + finalhandler@2.1.0: + resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} + engines: {node: '>= 0.8'} + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -5260,6 +6075,9 @@ packages: find-yarn-workspace-root2@1.2.16: resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5267,6 +6085,15 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -5275,6 +6102,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + form-data@4.0.3: + resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==} + engines: {node: '>= 6'} + format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} @@ -5297,10 +6128,17 @@ packages: react-dom: optional: true + framework-utils@1.1.0: + resolution: {integrity: sha512-KAfqli5PwpFJ8o3psRNs8svpMGyCSAe8nmGcjQ0zZBWN2H6dZDnq+ABp3N3hdUmFeMrLtjOCTXD4yplUJIWceg==} + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -5349,6 +6187,9 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + gesto@1.19.4: + resolution: {integrity: sha512-hfr/0dWwh0Bnbb88s3QVJd1ZRJeOWcgHPPwmiH6NnafDYvhTsxg+SLYu+q/oPNh9JS3V+nlr6fNs8kvPAtcRDQ==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -5373,6 +6214,14 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -5441,10 +6290,43 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphology-layout-force@0.2.4: + resolution: {integrity: sha512-NYZz0YAnDkn5pkm30cvB0IScFoWGtbzJMrqaiH070dYlYJiag12Oc89dbVfaMaVR/w8DMIKxn/ix9Bqj+Umm9Q==} + peerDependencies: + graphology-types: '>=0.19.0' + + graphology-layout-forceatlas2@0.10.1: + resolution: {integrity: sha512-ogzBeF1FvWzjkikrIFwxhlZXvD2+wlY54lqhsrWprcdPjopM2J9HoMweUmIgwaTvY4bUYVimpSsOdvDv1gPRFQ==} + peerDependencies: + graphology-types: '>=0.19.0' + + graphology-layout-noverlap@0.4.2: + resolution: {integrity: sha512-13WwZSx96zim6l1dfZONcqLh3oqyRcjIBsqz2c2iJ3ohgs3605IDWjldH41Gnhh462xGB1j6VGmuGhZ2FKISXA==} + peerDependencies: + graphology-types: '>=0.19.0' + + graphology-types@0.24.8: + resolution: {integrity: sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==} + + graphology-utils@2.5.2: + resolution: {integrity: sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==} + peerDependencies: + graphology-types: '>=0.23.0' + + graphology@0.26.0: + resolution: {integrity: sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==} + peerDependencies: + graphology-types: '>=0.24.0' + gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} hasBin: true + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} @@ -5483,9 +6365,19 @@ packages: hast-util-to-estree@2.3.3: resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==} + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + hast-util-whitespace@2.0.1: resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -5501,6 +6393,9 @@ packages: resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==} engines: {node: '>=14'} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} @@ -5515,6 +6410,17 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + humanize-duration@3.33.0: + resolution: {integrity: sha512-vYJX7BSzn7EQ4SaP2lPYVy+icHDppB6k7myNeI3wrSRfwMS5+BHyGgzpHR0ptqJ2AQ6UuIKrclSg5ve6Ci4IAQ==} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -5540,6 +6446,9 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-in-the-middle@1.14.2: + resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -5561,6 +6470,9 @@ packages: inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -5709,6 +6621,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} @@ -5728,6 +6643,14 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -5748,6 +6671,10 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -5760,6 +6687,10 @@ packages: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -5807,9 +6738,28 @@ packages: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + jotai@2.12.5: + resolution: {integrity: sha512-G8m32HW3lSmcz/4mbqx0hgJIQ0ekndKWiYP7kWVKi0p6saLXdSoye+FZiOFyonnd7Q482LCzm8sMDl7Ar1NWDw==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=17.0.0' + react: '>=17.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -5884,6 +6834,16 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + katex@0.16.22: + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} + hasBin: true + + keycode@2.2.1: + resolution: {integrity: sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==} + + keycon@1.4.0: + resolution: {integrity: sha512-p1NAIxiRMH3jYfTeXRs2uWbVJ1WpEjpi8ktzUyBJsX7/wn2qu2VRXktneBLNtKNxJmlUYxRi9gOJt1DuthXR7A==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -5909,6 +6869,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libphonenumber-js@1.12.9: + resolution: {integrity: sha512-VWwAdNeJgN7jFOD+wN4qx83DTPMVPPAUyx9/TUkBXKLiNkuWWk6anV0439tgdtwaJDrEdqkvdN22iA6J4bUCZg==} + lightningcss-darwin-arm64@1.30.1: resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} engines: {node: '>= 12.0.0'} @@ -5984,10 +6947,20 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + linkifyjs@4.3.1: + resolution: {integrity: sha512-DRSlB9DKVW04c4SUdGvKK5FR6be45lTU9M76JnngqPeeGDqPwYc0zdUErtsNVMtxPXgUWV4HbXbnC4sNyBxkYg==} + load-json-file@4.0.0: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -6033,6 +7006,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} @@ -6043,6 +7019,9 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -6050,6 +7029,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lowlight@3.3.0: + resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -6095,6 +7077,10 @@ packages: resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} engines: {node: '>=0.10.0'} + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + marked@7.0.4: resolution: {integrity: sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ==} engines: {node: '>= 16'} @@ -6115,33 +7101,60 @@ packages: mdast-util-from-markdown@1.3.1: resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + mdast-util-frontmatter@1.0.1: resolution: {integrity: sha512-JjA2OjxRqAa8wEG8hloD0uTU0kdn8kbtOWpPP94NBkfAlbxn4S8gCGf/9DwFtEeGPXrDcNXdiDjVaRdUFqYokw==} mdast-util-mdx-expression@1.3.2: resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==} + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + mdast-util-mdx-jsx@2.1.4: resolution: {integrity: sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==} + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + mdast-util-mdx@2.0.1: resolution: {integrity: sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==} mdast-util-mdxjs-esm@1.3.1: resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==} + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + mdast-util-phrasing@3.0.1: resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + mdast-util-to-hast@12.3.0: resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdast-util-to-markdown@1.5.0: resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + mdast-util-to-string@3.2.0: resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-query-parser@2.0.2: resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} @@ -6149,6 +7162,10 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -6160,6 +7177,10 @@ packages: merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -6174,6 +7195,9 @@ packages: micromark-core-commonmark@1.1.0: resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + micromark-extension-frontmatter@1.1.1: resolution: {integrity: sha512-m2UH9a7n3W8VAH9JO9y01APpPKmNNNs71P0RbknEmYSaZU5Ghogv38BYO94AI5Xw6OYfxZRdHZZ2nYjs/Z+SZQ==} @@ -6195,69 +7219,129 @@ packages: micromark-factory-destination@1.1.0: resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + micromark-factory-label@1.1.0: resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + micromark-factory-mdx-expression@1.0.9: resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==} micromark-factory-space@1.1.0: resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + micromark-factory-title@1.1.0: resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + micromark-factory-whitespace@1.1.0: resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + micromark-util-character@1.2.0: resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + micromark-util-chunked@1.1.0: resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + micromark-util-classify-character@1.1.0: resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + micromark-util-combine-extensions@1.1.0: resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + micromark-util-decode-numeric-character-reference@1.1.0: resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + micromark-util-decode-string@1.1.0: resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + micromark-util-encode@1.1.0: resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-events-to-acorn@1.2.3: resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==} micromark-util-html-tag-name@1.2.0: resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + micromark-util-normalize-identifier@1.1.0: resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + micromark-util-resolve-all@1.1.0: resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + micromark-util-sanitize-uri@1.2.0: resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + micromark-util-subtokenize@1.1.0: resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + micromark-util-symbol@1.1.0: resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + micromark-util-types@1.1.0: resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromark@3.2.0: resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -6274,6 +7358,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -6283,6 +7371,10 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -6291,6 +7383,9 @@ packages: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true + minimal-polyfills@2.2.3: + resolution: {integrity: sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw==} + minimatch@10.0.2: resolution: {integrity: sha512-+9TJCIYXgZ2Dm5LxVCFsa8jOm+evMwXHFI0JM1XROmkfkpz8/iLLDh+TwSmyIBrs6C6Xu9294/fq8cBA+P6AqA==} engines: {node: 20 || >=22} @@ -6372,6 +7467,9 @@ packages: modern-ahocorasick@1.1.0: resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + morgan@1.10.0: resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} engines: {node: '>= 0.8.0'} @@ -6429,6 +7527,10 @@ packages: resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} engines: {node: '>= 0.6'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -6511,6 +7613,11 @@ packages: normalize.css@8.0.1: resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==} + novel@1.0.2: + resolution: {integrity: sha512-lyMtoBsRCqgrQaNhlc8Ngpp+npJEQjPoGBLcnYlEr8mEf+lXZV7/m6CbEpGRfma+HZQVlU3YJOs4gCmzbLG+ow==} + peerDependencies: + react: '>=18' + npm-install-checks@6.3.0: resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -6536,6 +7643,14 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + num2fraction@1.2.2: resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} @@ -6611,6 +7726,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -6619,6 +7738,9 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -6629,6 +7751,9 @@ packages: outdent@0.8.0: resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} + overlap-area@1.1.0: + resolution: {integrity: sha512-3dlJgJCaVeXH0/eZjYVJvQiLVVrPO4U1ZGqlATtx6QGO3b5eNM6+JgUKa7oStBTdYuGTk7gVoABCW6Tp+dhRdw==} + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -6690,6 +7815,10 @@ packages: resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} engines: {node: '>=6'} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parseley@0.12.1: resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} @@ -6716,6 +7845,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -6730,6 +7863,10 @@ packages: path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -6793,6 +7930,10 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pkce-challenge@5.0.0: + resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} + engines: {node: '>=16.20.0'} + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -6849,6 +7990,24 @@ packages: ts-node: optional: true + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postcss-loader@8.1.1: resolution: {integrity: sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==} engines: {node: '>= 18.12.0'} @@ -7041,6 +8200,10 @@ packages: resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} engines: {node: '>=10'} + pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} + engines: {node: '>=18'} + prism-react-renderer@2.1.0: resolution: {integrity: sha512-I5cvXHjA1PVGbGm1MsWCpvBCRrYyxEri0MC7/JbfIfYfcXAxHyO5PaUjs3A8H5GW6kJcLhTHxxMaOZZpRZD2iQ==} peerDependencies: @@ -7067,6 +8230,10 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + prom-client@15.1.3: + resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} + engines: {node: ^16 || ^18 || >=20} + promise-inflight@1.0.1: resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} peerDependencies: @@ -7085,13 +8252,81 @@ packages: property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + prosemirror-changeset@2.3.1: + resolution: {integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==} + + prosemirror-collab@1.3.1: + resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} + + prosemirror-commands@1.7.1: + resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} + + prosemirror-dropcursor@1.8.2: + resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} + + prosemirror-gapcursor@1.3.2: + resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==} + + prosemirror-history@1.4.1: + resolution: {integrity: sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==} + + prosemirror-inputrules@1.5.0: + resolution: {integrity: sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-markdown@1.13.2: + resolution: {integrity: sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==} + + prosemirror-menu@1.2.5: + resolution: {integrity: sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==} + + prosemirror-model@1.25.1: + resolution: {integrity: sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==} + + prosemirror-schema-basic@1.2.4: + resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.3: + resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} + + prosemirror-tables@1.7.1: + resolution: {integrity: sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==} + + prosemirror-trailing-node@3.0.0: + resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} + peerDependencies: + prosemirror-model: ^1.22.1 + prosemirror-state: ^1.4.2 + prosemirror-view: ^1.33.8 + + prosemirror-transform@1.10.4: + resolution: {integrity: sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==} + + prosemirror-view@1.40.0: + resolution: {integrity: sha512-2G3svX0Cr1sJjkD/DYWSe3cfV5VPVTBOxI9XQEGWJDFEpsZb/gh4MV29ctv+OJx2RFX4BLt09i+6zaGM/ldkCw==} + proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + protobufjs@7.5.3: + resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} + engines: {node: '>=12.0.0'} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} @@ -7104,6 +8339,10 @@ packages: pumpify@1.5.1: resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -7116,6 +8355,10 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + quansync@0.2.10: resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} @@ -7137,6 +8380,13 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + + react-css-styled@1.1.9: + resolution: {integrity: sha512-M7fJZ3IWFaIHcZEkoFOnkjdiUFmwd8d+gTh2bpqMOcnxy/0Gsykw4dsL4QBiKsxcGow6tETUa4NAUcmJF+/nfw==} + react-dom@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -7161,6 +8411,15 @@ packages: react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + react-markdown@9.1.0: + resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + + react-moveable@0.56.0: + resolution: {integrity: sha512-FmJNmIOsOA36mdxbrc/huiE4wuXSRlmon/o+/OrfNhSiYYYL0AV5oObtPluEhb2Yr/7EfYWBHTxF5aWAvjg1SA==} + react-promise-suspense@0.3.4: resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==} @@ -7217,6 +8476,9 @@ packages: peerDependencies: react: '>=16.8' + react-selecto@1.26.3: + resolution: {integrity: sha512-Ubik7kWSnZyQEBNro+1k38hZaI1tJarE+5aD/qsqCOA1uUBSjgKVBy3EWRzGIbdmVex7DcxznFZLec/6KZNvwQ==} + react-style-singleton@2.2.3: resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} engines: {node: '>=10'} @@ -7227,6 +8489,12 @@ packages: '@types/react': optional: true + react-tweet@3.2.2: + resolution: {integrity: sha512-hIkxAVPpN2RqWoDEbo3TTnN/pDcp9/Jb6pTgiA4EbXa9S+m2vHIvvZKHR+eS0PDIsYqe+zTmANRa5k6+/iwGog==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + react-virtualized@9.22.6: resolution: {integrity: sha512-U5j7KuUQt3AaMatlMJ0UJddqSiX+Km0YJxSqbAzIiGw5EmNz0khMyqP2hzgu4+QUtm+QPIrxzUX4raJxmVJnHg==} peerDependencies: @@ -7271,6 +8539,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -7311,9 +8583,15 @@ packages: remark-parse@10.0.2: resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + remark-rehype@10.1.0: resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + remix-auth-oauth2@3.4.1: resolution: {integrity: sha512-ZhGon1czdIsOw1/O9EcTCzapZB6FpT3u9vtXSVeEMwGNs+iWljRsibnUC1RtwJbzzCdLBSwIXTNTbiRmLZ4cZw==} engines: {node: ^20.0.0 || >=20.0.0} @@ -7378,6 +8656,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-in-the-middle@7.5.2: + resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} + engines: {node: '>=8.6.0'} + require-like@0.1.2: resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} @@ -7446,6 +8728,16 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-exclusive@2.2.19: + resolution: {integrity: sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -7493,6 +8785,9 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + selecto@1.26.3: + resolution: {integrity: sha512-gZHgqMy5uyB6/2YDjv3Qqaf7bd2hTDOpPdxXlrez4R3/L0GiEWDCFaUfrflomgqdb3SxHF2IXY0Jw0EamZi7cw==} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -7510,6 +8805,10 @@ packages: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -7517,6 +8816,10 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -7558,6 +8861,9 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} + shimmer@1.2.1: + resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -7574,6 +8880,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + sigma@3.0.2: + resolution: {integrity: sha512-/BUbeOwPGruiBOm0YQQ6ZMcLIZ6tf/W+Jcm7dxZyAX0tK3WP9/sq7/NAWBxPIxVahdGjCJoGwej0Gdrv0DxlQQ==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -7581,6 +8890,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-oauth2@5.1.0: + resolution: {integrity: sha512-gWDa38Ccm4MwlG5U7AlcJxPv3lvr80dU7ARJWrGdgvOKyzSj1gr3GBPN1rABTedAYvC/LsGYoFuFxwDBPtGEbw==} + simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -7588,6 +8900,9 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slug@6.1.0: + resolution: {integrity: sha512-x6vLHCMasg4DR2LPiyFGI0gJJhywY6DTiGhCrOMzb3SOk/0JVLIaL4UhyFSHu04SD3uAavrKY/K3zZ3i6iRcgA==} + smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} @@ -7600,6 +8915,10 @@ packages: resolution: {integrity: sha512-nU+ywttCyBitXIl9Xe0RSEfek4LneYkJxCeNnKCuhwoH4jGXO1ipIUw/VA/+Vvv2G1MTym11fzFC0SxkrcfXDw==} engines: {node: '>=10.0.0'} + socket.io-client@4.7.5: + resolution: {integrity: sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==} + engines: {node: '>=10.0.0'} + socket.io-parser@4.2.4: resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} engines: {node: '>=10.0.0'} @@ -7608,6 +8927,10 @@ packages: resolution: {integrity: sha512-SE+UIQXBQE+GPG2oszWMlsEmWtHVqw/h1VrYJGK5/MC7CH5p58N448HwIrtREcvR4jfdOJAY4ieQfxMr55qbbw==} engines: {node: '>=10.2.0'} + socket.io@4.7.4: + resolution: {integrity: sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==} + engines: {node: '>=10.2.0'} + sonner@1.3.1: resolution: {integrity: sha512-+rOAO56b2eI3q5BtgljERSn2umRk63KFIvgb2ohbZ5X+Eb5u+a/7/0ZgswYqgBMg8dyl7n6OXd9KasA8QF9ToA==} peerDependencies: @@ -7633,6 +8956,10 @@ packages: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} engines: {node: '>= 8'} + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -7672,6 +8999,9 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -7752,6 +9082,14 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -7763,9 +9101,15 @@ packages: strnum@1.1.2: resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} + style-to-js@1.1.17: + resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==} + style-to-object@0.4.4: resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} + style-to-object@1.0.9: + resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==} + styled-jsx@5.1.1: resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} @@ -7784,6 +9128,10 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -7869,6 +9217,9 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + tdigest@0.1.2: + resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} @@ -7914,10 +9265,19 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyglobby@0.2.14: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tippy.js@6.3.7: + resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + + tiptap-extension-global-drag-handle@0.1.18: + resolution: {integrity: sha512-jwFuy1K8DP3a4bFy76Hpc63w1Sil0B7uZ3mvhQomVvUFCU787Lg2FowNhn7NFzeyok761qY2VG+PZ/FDthWUdg==} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -7936,6 +9296,13 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -7955,6 +9322,19 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsafe@1.8.5: + resolution: {integrity: sha512-LFWTWQrW6rwSY+IBNFl2ridGfUzVsPwrZ26T4KUJww/py8rzaQ/SY+MIz6YROozpUCaRcuISqagmlwub9YT9kw==} + + tsconfck@3.1.3: + resolution: {integrity: sha512-ulNZP1SVpRDesxeMLON/LtWM8HIgAJEIVpVVhBM6gsmvQ8+Rh+ZG7FWGvHh7Ah3pRABwVJWklWCr/BTZSv0xnQ==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -7978,6 +9358,25 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.0: + resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + tsutils@3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -7989,6 +9388,9 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + tunnel-rat@0.1.2: + resolution: {integrity: sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==} + turbo-darwin-64@2.5.4: resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==} cpu: [x64] @@ -8058,6 +9460,10 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -8089,13 +9495,34 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + ulid@2.4.0: + resolution: {integrity: sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg==} + hasBin: true + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.8.0: resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} @@ -8103,9 +9530,16 @@ packages: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + unique-filename@3.0.0: resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -8120,24 +9554,39 @@ packages: unist-util-is@5.2.1: resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + unist-util-position-from-estree@1.1.2: resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==} unist-util-position@4.0.4: resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + unist-util-remove-position@4.0.2: resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==} unist-util-stringify-position@3.0.3: resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + unist-util-visit-parents@5.1.3: resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + unist-util-visit@4.1.2: resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -8221,6 +9670,10 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + validator@13.15.15: + resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} + engines: {node: '>= 0.10'} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -8228,9 +9681,15 @@ packages: vfile-message@3.1.4: resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@1.6.1: resolution: {integrity: sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8320,6 +9779,9 @@ packages: yaml: optional: true + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + watchpack@2.4.4: resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} @@ -8340,6 +9802,9 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + webpack-sources@3.3.2: resolution: {integrity: sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==} engines: {node: '>=10.13.0'} @@ -8357,6 +9822,9 @@ packages: whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -8398,6 +9866,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -8490,6 +9961,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + zod-error@1.5.0: resolution: {integrity: sha512-zzopKZ/skI9iXpqCEPj+iLCKl9b88E43ehcU+sbRoHuwGd9F1IDVGQ70TyO6kmfiRL1g4IXkjsXK+g1gLYl4WQ==} @@ -8507,11 +9982,38 @@ packages: zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zustand@4.5.7: + resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: + '@ai-sdk/anthropic@1.2.12(zod@3.23.8)': + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@3.23.8) + zod: 3.23.8 + + '@ai-sdk/google@1.2.22(zod@3.23.8)': + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@3.23.8) + zod: 3.23.8 + '@ai-sdk/openai@1.3.22(zod@3.23.8)': dependencies: '@ai-sdk/provider': 1.1.3 @@ -9184,6 +10686,12 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@bugsnag/cuid@3.2.1': {} + + '@cfcs/core@0.0.6': + dependencies: + '@egjs/component': 3.0.5 + '@changesets/apply-release-plan@6.1.4': dependencies: '@babel/runtime': 7.27.6 @@ -9271,10 +10779,10 @@ snapshots: fs-extra: 7.0.1 semver: 7.7.2 - '@changesets/get-github-info@0.5.2': + '@changesets/get-github-info@0.5.2(encoding@0.1.13)': dependencies: dataloader: 1.4.0 - node-fetch: 2.7.0 + node-fetch: 2.7.0(encoding@0.1.13) transitivePeerDependencies: - encoding @@ -9354,8 +10862,24 @@ snapshots: '@conform-to/dom': 0.6.3 zod: 3.23.8 + '@daybrush/utils@1.13.0': {} + '@edgefirst-dev/data@0.0.4': {} + '@egjs/agent@2.4.4': {} + + '@egjs/children-differ@1.0.1': + dependencies: + '@egjs/list-differ': 1.0.1 + + '@egjs/component@3.0.5': {} + + '@egjs/list-differ@1.0.1': {} + + '@electric-sql/client@1.0.0-beta.1': + optionalDependencies: + '@rollup/rollup-darwin-arm64': 4.43.0 + '@emnapi/core@1.4.3': dependencies: '@emnapi/wasi-threads': 1.0.2 @@ -9706,6 +11230,40 @@ snapshots: postcss: 7.0.32 purgecss: 2.3.0 + '@google-cloud/precise-date@4.0.0': {} + + '@grpc/grpc-js@1.13.4': + dependencies: + '@grpc/proto-loader': 0.7.15 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.7.15': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.5.3 + yargs: 17.7.2 + + '@hapi/boom@10.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/bourne@3.0.0': {} + + '@hapi/hoek@11.0.7': {} + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@hapi/wreck@18.1.0': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/bourne': 3.0.0 + '@hapi/hoek': 11.0.7 + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -9755,6 +11313,10 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@js-sdsl/ordered-map@4.4.2': {} + + '@jsonhero/path@1.0.21': {} + '@jspm/core@2.1.0': {} '@manypkg/find-root@1.1.0': @@ -9801,6 +11363,22 @@ snapshots: '@mjackson/headers@0.9.0': {} + '@modelcontextprotocol/sdk@1.13.2': + dependencies: + ajv: 6.12.6 + content-type: 1.0.5 + cors: 2.8.5 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + express: 5.1.0 + express-rate-limit: 7.5.1(express@5.1.0) + pkce-challenge: 5.0.0 + raw-body: 3.0.0 + zod: 3.23.8 + zod-to-json-schema: 3.24.5(zod@3.23.8) + transitivePeerDependencies: + - supports-color + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': optional: true @@ -9914,8 +11492,178 @@ snapshots: '@one-ini/wasm@0.1.1': {} + '@opentelemetry/api-logs@0.52.1': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api@1.9.0': {} + '@opentelemetry/context-async-hooks@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.25.1 + + '@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.28.0 + + '@opentelemetry/exporter-logs-otlp-http@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-grpc@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.13.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-http@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-proto@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-zipkin@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + + '@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@types/shimmer': 1.2.0 + import-in-the-middle: 1.14.2 + require-in-the-middle: 7.5.2 + semver: 7.7.2 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/otlp-exporter-base@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-grpc-exporter-base@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.13.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-transformer@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + protobufjs: 7.5.3 + + '@opentelemetry/propagator-b3@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/propagator-jaeger@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + + '@opentelemetry/sdk-logs@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + lodash.merge: 4.6.2 + + '@opentelemetry/sdk-node@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + + '@opentelemetry/sdk-trace-node@1.25.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + semver: 7.7.2 + + '@opentelemetry/semantic-conventions@1.25.1': {} + + '@opentelemetry/semantic-conventions@1.28.0': {} + '@oslojs/asn1@1.0.0': dependencies: '@oslojs/binary': 1.0.0 @@ -9938,6 +11686,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@popperjs/core@2.11.8': {} + '@prisma/client@5.4.1(prisma@5.4.1)': dependencies: '@prisma/engines-version': 5.4.1-1.2f302df92bd8945e20ad4595a73def5b96afa54f @@ -9948,6 +11698,29 @@ snapshots: '@prisma/engines@5.4.1': {} + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + '@radix-ui/colors@1.0.1': {} '@radix-ui/number@1.1.1': {} @@ -10896,16 +12669,18 @@ snapshots: dependencies: react: 18.3.1 - '@remix-run/changelog-github@0.0.5': + '@remirror/core-constants@3.0.0': {} + + '@remix-run/changelog-github@0.0.5(encoding@0.1.13)': dependencies: '@changesets/errors': 0.1.4 - '@changesets/get-github-info': 0.5.2 + '@changesets/get-github-info': 0.5.2(encoding@0.1.13) '@changesets/types': 5.2.1 dotenv: 8.6.0 transitivePeerDependencies: - encoding - '@remix-run/dev@2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0)': + '@remix-run/dev@2.16.7(@remix-run/react@2.16.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))(@remix-run/serve@2.16.7(typescript@5.8.3))(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))(yaml@2.8.0)': dependencies: '@babel/core': 7.27.4 '@babel/generator': 7.27.5 @@ -10922,7 +12697,7 @@ snapshots: '@remix-run/router': 1.23.0 '@remix-run/server-runtime': 2.16.7(typescript@5.8.3) '@types/mdx': 2.0.13 - '@vanilla-extract/integration': 6.5.0(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0) + '@vanilla-extract/integration': 6.5.0(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0) arg: 5.0.2 cacache: 17.1.4 chalk: 4.1.2 @@ -10962,12 +12737,12 @@ snapshots: tar-fs: 2.1.3 tsconfig-paths: 4.2.0 valibot: 0.41.0(typescript@5.8.3) - vite-node: 3.2.3(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) + vite-node: 3.2.3(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) ws: 7.5.10 optionalDependencies: '@remix-run/serve': 2.16.7(typescript@5.8.3) typescript: 5.8.3 - vite: 6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11249,11 +13024,36 @@ snapshots: '@rushstack/eslint-patch@1.11.0': {} + '@scena/dragscroll@1.4.0': + dependencies: + '@daybrush/utils': 1.13.0 + '@scena/event-emitter': 1.0.5 + + '@scena/event-emitter@1.0.5': + dependencies: + '@daybrush/utils': 1.13.0 + + '@scena/matrix@1.1.1': + dependencies: + '@daybrush/utils': 1.13.0 + + '@sec-ant/readable-stream@0.4.1': {} + '@selderee/plugin-htmlparser2@0.11.0': dependencies: domhandler: 5.0.3 selderee: 0.11.0 + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + '@smithy/abort-controller@4.0.4': dependencies: '@smithy/types': 4.3.1 @@ -11561,7 +13361,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.3.101': optional: true - '@swc/core@1.3.101(@swc/helpers@0.5.2)': + '@swc/core@1.3.101(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.23 @@ -11576,10 +13376,14 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.3.101 '@swc/core-win32-ia32-msvc': 1.3.101 '@swc/core-win32-x64-msvc': 1.3.101 - '@swc/helpers': 0.5.2 + '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + '@swc/helpers@0.5.2': dependencies: tslib: 2.8.1 @@ -11677,12 +13481,12 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.1.7 - '@tailwindcss/vite@4.1.9(vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))': + '@tailwindcss/vite@4.1.9(vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0))': dependencies: '@tailwindcss/node': 4.1.9 '@tailwindcss/oxide': 4.1.9 tailwindcss: 4.1.9 - vite: 6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) '@tanstack/react-table@8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -11703,6 +13507,304 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 + '@tiptap/core@2.25.0(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-blockquote@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-bold@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-bubble-menu@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + tippy.js: 6.3.7 + + '@tiptap/extension-bullet-list@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-character-count@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-code-block-lowlight@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/extension-code-block@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)(highlight.js@11.11.1)(lowlight@3.3.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/extension-code-block': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + highlight.js: 11.11.1 + lowlight: 3.3.0 + + '@tiptap/extension-code-block@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-code@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-color@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/extension-text-style@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/extension-text-style': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + + '@tiptap/extension-document@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-dropcursor@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-floating-menu@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + tippy.js: 6.3.7 + + '@tiptap/extension-gapcursor@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-hard-break@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-heading@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-highlight@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-history@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-horizontal-rule@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-image@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-italic@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-link@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + linkifyjs: 4.3.1 + + '@tiptap/extension-list-item@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-ordered-list@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-paragraph@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-placeholder@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-strike@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-task-item@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@tiptap/extension-task-list@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-text-style@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-text@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-underline@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/extension-youtube@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + + '@tiptap/pm@2.25.0': + dependencies: + prosemirror-changeset: 2.3.1 + prosemirror-collab: 1.3.1 + prosemirror-commands: 1.7.1 + prosemirror-dropcursor: 1.8.2 + prosemirror-gapcursor: 1.3.2 + prosemirror-history: 1.4.1 + prosemirror-inputrules: 1.5.0 + prosemirror-keymap: 1.2.3 + prosemirror-markdown: 1.13.2 + prosemirror-menu: 1.2.5 + prosemirror-model: 1.25.1 + prosemirror-schema-basic: 1.2.4 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.3 + prosemirror-tables: 1.7.1 + prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.40.0) + prosemirror-transform: 1.10.4 + prosemirror-view: 1.40.0 + + '@tiptap/react@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/extension-bubble-menu': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-floating-menu': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + '@types/use-sync-external-store': 0.0.6 + fast-deep-equal: 3.1.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.5.0(react@18.3.1) + + '@tiptap/starter-kit@2.11.9': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/extension-blockquote': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-bold': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-bullet-list': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-code': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-code-block': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-document': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-dropcursor': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-gapcursor': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-hard-break': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-heading': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-history': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-horizontal-rule': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-italic': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-list-item': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-ordered-list': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-paragraph': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-strike': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-text': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-text-style': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/pm': 2.25.0 + + '@tiptap/suggestion@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)': + dependencies: + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/pm': 2.25.0 + + '@trigger.dev/build@4.0.0-v4-beta.22(typescript@5.8.3)': + dependencies: + '@trigger.dev/core': 4.0.0-v4-beta.22 + pkg-types: 1.3.1 + tinyglobby: 0.2.14 + tsconfck: 3.1.3(typescript@5.8.3) + transitivePeerDependencies: + - bufferutil + - supports-color + - typescript + - utf-8-validate + + '@trigger.dev/core@4.0.0-v4-beta.22': + dependencies: + '@bugsnag/cuid': 3.2.1 + '@electric-sql/client': 1.0.0-beta.1 + '@google-cloud/precise-date': 4.0.0 + '@jsonhero/path': 1.0.21 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-node': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + dequal: 2.0.3 + eventsource: 3.0.7 + eventsource-parser: 3.0.3 + execa: 8.0.1 + humanize-duration: 3.33.0 + jose: 5.10.0 + nanoid: 3.3.8 + prom-client: 15.1.3 + socket.io: 4.7.4 + socket.io-client: 4.7.5 + std-env: 3.9.0 + superjson: 2.2.2 + tinyexec: 0.3.2 + zod: 3.23.8 + zod-error: 1.5.0 + zod-validation-error: 1.5.0(zod@3.23.8) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@trigger.dev/react-hooks@4.0.0-v4-beta.22(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@trigger.dev/core': 4.0.0-v4-beta.22 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + swr: 2.3.3(react@18.3.1) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@trigger.dev/sdk@4.0.0-v4-beta.22(ai@4.3.14(react@18.3.1)(zod@3.23.8))(zod@3.23.8)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.52.1 + '@opentelemetry/semantic-conventions': 1.25.1 + '@trigger.dev/core': 4.0.0-v4-beta.22 + chalk: 5.4.1 + cronstrue: 2.59.0 + debug: 4.4.1 + evt: 2.5.9 + slug: 6.1.0 + ulid: 2.4.0 + uncrypto: 0.1.3 + uuid: 9.0.1 + ws: 8.17.1 + zod: 3.23.8 + optionalDependencies: + ai: 4.3.14(react@18.3.1)(zod@3.23.8) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 @@ -11717,16 +13819,18 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 24.0.0 + '@types/node': 18.19.115 '@types/compression@1.8.1': dependencies: '@types/express': 4.17.23 '@types/node': 24.0.0 + '@types/configstore@6.0.2': {} + '@types/connect@3.4.38': dependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 '@types/cookie@0.4.1': {} @@ -11734,7 +13838,7 @@ snapshots: '@types/cors@2.8.19': dependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 '@types/d3-array@3.2.1': {} @@ -11879,7 +13983,7 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -11897,6 +14001,10 @@ snapshots: dependencies: '@types/unist': 2.0.11 + '@types/hast@3.0.4': + dependencies: + '@types/unist': 2.0.11 + '@types/http-errors@2.0.5': {} '@types/is-ci@3.0.4': @@ -11907,10 +14015,23 @@ snapshots: '@types/json5@0.0.29': {} + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + '@types/mdast@3.0.15': dependencies: '@types/unist': 2.0.11 + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 2.0.11 + + '@types/mdurl@2.0.0': {} + '@types/mdx@2.0.13': {} '@types/mime@1.3.5': {} @@ -11925,6 +14046,14 @@ snapshots: '@types/node@12.20.55': {} + '@types/node@18.19.115': + dependencies: + undici-types: 5.26.5 + + '@types/node@22.16.0': + dependencies: + undici-types: 6.21.0 + '@types/node@24.0.0': dependencies: undici-types: 7.8.0 @@ -11947,6 +14076,11 @@ snapshots: dependencies: '@types/react': 18.2.69 + '@types/react-virtualized@9.22.2': + dependencies: + '@types/prop-types': 15.7.15 + '@types/react': 18.2.69 + '@types/react@18.2.47': dependencies: '@types/prop-types': 15.7.15 @@ -11966,21 +14100,35 @@ snapshots: '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 24.0.0 + '@types/node': 18.19.115 '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 24.0.0 + '@types/node': 18.19.115 '@types/send': 0.17.5 + '@types/shimmer@1.2.0': {} + + '@types/simple-oauth2@5.0.7': {} + + '@types/slug@5.0.9': {} + '@types/unist@2.0.11': {} - '@types/webpack@5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)': + '@types/unist@3.0.3': {} + + '@types/use-sync-external-store@0.0.6': {} + + '@types/uuid@9.0.8': {} + + '@types/validator@13.15.2': {} + + '@types/webpack@5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)': dependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 tapable: 2.2.2 - webpack: 5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11) + webpack: 5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11) transitivePeerDependencies: - '@swc/core' - esbuild @@ -12241,7 +14389,7 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - '@vanilla-extract/integration@6.5.0(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0)': + '@vanilla-extract/integration@6.5.0(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0)': dependencies: '@babel/core': 7.27.4 '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) @@ -12254,8 +14402,8 @@ snapshots: lodash: 4.17.21 mlly: 1.7.4 outdent: 0.8.0 - vite: 5.4.19(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0) - vite-node: 1.6.1(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0) + vite: 5.4.19(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0) + vite-node: 1.6.1(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -12366,6 +14514,15 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + accepts@2.0.0: + dependencies: + mime-types: 3.0.1 + negotiator: 1.0.0 + + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -12550,6 +14707,8 @@ snapshots: async-function@1.0.0: {} + asynckit@0.4.0: {} + autoprefixer@10.4.14(postcss@8.4.38): dependencies: browserslist: 4.25.0 @@ -12586,6 +14745,14 @@ snapshots: axe-core@4.10.3: {} + axios@1.10.0: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.3 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@4.1.0: {} bail@2.0.2: {} @@ -12608,6 +14775,8 @@ snapshots: binary-extensions@2.3.0: {} + bintrees@1.0.2: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -12631,6 +14800,20 @@ snapshots: transitivePeerDependencies: - supports-color + body-parser@2.2.0: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.1 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + bowser@2.11.0: {} brace-expansion@1.1.12: @@ -12689,6 +14872,11 @@ snapshots: transitivePeerDependencies: - supports-color + bundle-require@5.1.0(esbuild@0.25.5): + dependencies: + esbuild: 0.25.5 + load-tsconfig: 0.2.5 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -12792,6 +14980,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chownr@1.1.4: {} chownr@2.0.0: {} @@ -12802,6 +14994,16 @@ snapshots: ci-info@3.9.0: {} + cjs-module-lexer@1.4.3: {} + + class-transformer@0.5.1: {} + + class-validator@0.14.1: + dependencies: + '@types/validator': 13.15.2 + libphonenumber-js: 1.12.9 + validator: 13.15.15 + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -12838,6 +15040,18 @@ snapshots: cluster-key-slot@1.1.2: {} + cmdk@1.1.1(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.2.69)(react@18.3.1) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.2.69)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -12860,6 +15074,10 @@ snapshots: color-convert: 1.9.3 color-string: 1.9.1 + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} commander@10.0.1: {} @@ -12874,6 +15092,8 @@ snapshots: commander@7.2.0: {} + commander@8.3.0: {} + compressible@2.0.18: dependencies: mime-db: 1.54.0 @@ -12901,10 +15121,16 @@ snapshots: ini: 1.3.8 proto-list: 1.2.4 + consola@3.4.2: {} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 + content-disposition@1.0.0: + dependencies: + safe-buffer: 5.2.1 + content-type@1.0.5: {} convert-source-map@2.0.0: {} @@ -12919,6 +15145,10 @@ snapshots: cookie@0.7.2: {} + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + core-js@3.43.0: {} core-util-is@1.0.3: {} @@ -12937,10 +15167,14 @@ snapshots: optionalDependencies: typescript: 5.8.3 + crelt@1.0.6: {} + cron-parser@4.9.0: dependencies: luxon: 3.6.1 + cronstrue@2.59.0: {} + cross-env@7.0.3: dependencies: cross-spawn: 7.0.6 @@ -12980,6 +15214,15 @@ snapshots: optionalDependencies: webpack: 5.99.9(esbuild@0.25.5) + css-styled@1.0.8: + dependencies: + '@daybrush/utils': 1.13.0 + + css-to-mat@1.1.1: + dependencies: + '@daybrush/utils': 1.13.0 + '@scena/matrix': 1.1.1 + css-unit-converter@1.1.2: {} css-what@6.1.0: {} @@ -13261,6 +15504,8 @@ snapshots: dependencies: robust-predicates: 3.0.2 + delayed-stream@1.0.0: {} + denque@2.1.0: {} depd@2.0.0: {} @@ -13281,6 +15526,10 @@ snapshots: defined: 1.0.1 minimist: 1.2.8 + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + didyoumean@1.2.2: {} diff-match-patch@1.0.5: {} @@ -13375,6 +15624,10 @@ snapshots: encodeurl@2.0.0: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -13397,7 +15650,7 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.19 - '@types/node': 24.0.0 + '@types/node': 18.19.115 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -13983,6 +16236,8 @@ snapshots: estree-util-is-identifier-name@2.1.0: {} + estree-util-is-identifier-name@3.0.0: {} + estree-util-to-js@1.2.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -14008,13 +16263,25 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 require-like: 0.1.2 event-target-shim@5.0.1: {} events@3.3.0: {} + eventsource-parser@3.0.3: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.3 + + evt@2.5.9: + dependencies: + minimal-polyfills: 2.2.3 + run-exclusive: 2.2.19 + tsafe: 1.8.5 + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -14027,8 +16294,39 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.6.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.2.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + exit-hook@2.2.1: {} + express-rate-limit@7.5.1(express@5.1.0): + dependencies: + express: 5.1.0 + express@4.21.2: dependencies: accepts: 1.3.8 @@ -14065,6 +16363,38 @@ snapshots: transitivePeerDependencies: - supports-color + express@5.1.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.0 + serve-static: 2.2.0 + statuses: 2.0.1 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + exsolve@1.0.5: {} extend@3.0.2: {} @@ -14093,6 +16423,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-sort@3.4.1: {} + fast-uri@3.0.6: {} fast-xml-parser@4.4.1: @@ -14113,6 +16445,10 @@ snapshots: fflate@0.4.8: {} + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -14133,6 +16469,17 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@2.1.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -14148,6 +16495,12 @@ snapshots: micromatch: 4.0.8 pkg-dir: 4.2.0 + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.17 + mlly: 1.7.4 + rollup: 4.43.0 + flat-cache@3.2.0: dependencies: flatted: 3.3.3 @@ -14156,6 +16509,8 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.9: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -14165,6 +16520,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data@4.0.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + format@0.2.2: {} forwarded@0.2.0: {} @@ -14179,8 +16542,12 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + framework-utils@1.1.0: {} + fresh@0.5.2: {} + fresh@2.0.0: {} + fs-constants@1.0.0: {} fs-extra@10.1.0: @@ -14233,6 +16600,11 @@ snapshots: gensync@1.0.0-beta.2: {} + gesto@1.19.4: + dependencies: + '@daybrush/utils': 1.13.0 + '@scena/event-emitter': 1.0.5 + get-caller-file@2.0.5: {} get-intrinsic@1.3.0: @@ -14259,6 +16631,13 @@ snapshots: get-stream@6.0.1: {} + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 @@ -14344,6 +16723,32 @@ snapshots: graphemer@1.4.0: {} + graphology-layout-force@0.2.4(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + + graphology-layout-forceatlas2@0.10.1(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + + graphology-layout-noverlap@0.4.2(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + graphology-utils: 2.5.2(graphology-types@0.24.8) + + graphology-types@0.24.8: {} + + graphology-utils@2.5.2(graphology-types@0.24.8): + dependencies: + graphology-types: 0.24.8 + + graphology@0.26.0(graphology-types@0.24.8): + dependencies: + events: 3.3.0 + graphology-types: 0.24.8 + gunzip-maybe@1.4.2: dependencies: browserify-zlib: 0.1.4 @@ -14353,6 +16758,15 @@ snapshots: pumpify: 1.5.1 through2: 2.0.5 + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + hard-rejection@2.1.0: {} has-bigints@1.1.0: {} @@ -14399,8 +16813,34 @@ snapshots: transitivePeerDependencies: - supports-color + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.17 + unist-util-position: 5.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + hast-util-whitespace@2.0.1: {} + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + highlight.js@11.11.1: {} + hosted-git-info@2.8.9: {} hosted-git-info@6.1.3: @@ -14417,6 +16857,8 @@ snapshots: htmlparser2: 8.0.2 selderee: 0.11.0 + html-url-attributes@3.0.1: {} + htmlparser2@8.0.2: dependencies: domelementtype: 2.3.0 @@ -14436,6 +16878,12 @@ snapshots: human-signals@2.1.0: {} + human-signals@5.0.0: {} + + human-signals@8.0.1: {} + + humanize-duration@3.33.0: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -14457,6 +16905,13 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + import-in-the-middle@1.14.2: + dependencies: + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + cjs-module-lexer: 1.4.3 + module-details-from-path: 1.0.4 + imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -14472,6 +16927,8 @@ snapshots: inline-style-parser@0.1.1: {} + inline-style-parser@0.2.4: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -14614,6 +17071,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-promise@4.0.0: {} + is-reference@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -14633,6 +17092,10 @@ snapshots: is-stream@2.0.1: {} + is-stream@3.0.0: {} + + is-stream@4.0.1: {} + is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -14654,6 +17117,8 @@ snapshots: is-unicode-supported@0.1.0: {} + is-unicode-supported@2.1.0: {} + is-weakmap@2.0.2: {} is-weakref@1.1.1: @@ -14665,6 +17130,8 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 + is-what@4.1.16: {} + is-windows@1.0.2: {} isarray@1.0.0: {} @@ -14704,7 +17171,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14712,8 +17179,23 @@ snapshots: jiti@2.4.2: {} + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + jose@5.10.0: {} + jotai@2.12.5(@types/react@18.2.69)(react@18.3.1): + optionalDependencies: + '@types/react': 18.2.69 + react: 18.3.1 + + joycon@3.1.1: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -14782,6 +17264,19 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 + katex@0.16.22: + dependencies: + commander: 8.3.0 + + keycode@2.2.1: {} + + keycon@1.4.0: + dependencies: + '@cfcs/core': 0.0.6 + '@daybrush/utils': 1.13.0 + '@scena/event-emitter': 1.0.5 + keycode: 2.2.1 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -14803,6 +17298,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + libphonenumber-js@1.12.9: {} + lightningcss-darwin-arm64@1.30.1: optional: true @@ -14854,6 +17351,12 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + linkifyjs@4.3.1: {} + load-json-file@4.0.0: dependencies: graceful-fs: 4.2.11 @@ -14861,6 +17364,8 @@ snapshots: pify: 3.0.0 strip-bom: 3.0.0 + load-tsconfig@0.2.5: {} + load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.11 @@ -14900,6 +17405,8 @@ snapshots: lodash.merge@4.6.2: {} + lodash.sortby@4.7.0: {} + lodash.startcase@4.4.0: {} lodash@4.17.21: {} @@ -14909,12 +17416,20 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + long@5.3.2: {} + longest-streak@3.1.0: {} loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 + lowlight@3.3.0: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + highlight.js: 11.11.1 + lru-cache@10.4.3: {} lru-cache@11.1.0: {} @@ -14948,6 +17463,15 @@ snapshots: markdown-extensions@1.1.1: {} + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + marked@7.0.4: {} math-intrinsics@1.1.0: {} @@ -14980,6 +17504,23 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.1.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-frontmatter@1.0.1: dependencies: '@types/mdast': 3.0.15 @@ -14996,6 +17537,17 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + mdast-util-mdx-jsx@2.1.4: dependencies: '@types/estree-jsx': 1.0.5 @@ -15013,6 +17565,23 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + mdast-util-mdx@2.0.1: dependencies: mdast-util-from-markdown: 1.3.1 @@ -15033,11 +17602,27 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + mdast-util-phrasing@3.0.1: dependencies: '@types/mdast': 3.0.15 unist-util-is: 5.2.1 + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + mdast-util-to-hast@12.3.0: dependencies: '@types/hast': 2.3.10 @@ -15049,6 +17634,18 @@ snapshots: unist-util-position: 4.0.4 unist-util-visit: 4.1.2 + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + mdast-util-to-markdown@1.5.0: dependencies: '@types/mdast': 3.0.15 @@ -15060,16 +17657,36 @@ snapshots: unist-util-visit: 4.1.2 zwitch: 2.0.4 + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + mdast-util-to-string@3.2.0: dependencies: '@types/mdast': 3.0.15 + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdurl@2.0.0: {} + media-query-parser@2.0.2: dependencies: '@babel/runtime': 7.27.6 media-typer@0.3.0: {} + media-typer@1.1.0: {} + memorystream@0.3.1: {} meow@6.1.1: @@ -15088,6 +17705,8 @@ snapshots: merge-descriptors@1.0.3: {} + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -15113,6 +17732,25 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.1.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-extension-frontmatter@1.1.1: dependencies: fault: 2.0.1 @@ -15177,6 +17815,12 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-label@1.1.0: dependencies: micromark-util-character: 1.2.0 @@ -15184,6 +17828,13 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-mdx-expression@1.0.9: dependencies: '@types/estree': 1.0.8 @@ -15200,6 +17851,11 @@ snapshots: micromark-util-character: 1.2.0 micromark-util-types: 1.1.0 + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + micromark-factory-title@1.1.0: dependencies: micromark-factory-space: 1.1.0 @@ -15207,6 +17863,13 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-whitespace@1.1.0: dependencies: micromark-factory-space: 1.1.0 @@ -15214,30 +17877,61 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-character@1.2.0: dependencies: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-chunked@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-classify-character@1.1.0: dependencies: micromark-util-character: 1.2.0 micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-combine-extensions@1.1.0: dependencies: micromark-util-chunked: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-decode-numeric-character-reference@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-decode-string@1.1.0: dependencies: decode-named-character-reference: 1.1.0 @@ -15245,8 +17939,17 @@ snapshots: micromark-util-decode-numeric-character-reference: 1.1.0 micromark-util-symbol: 1.1.0 + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-encode@1.1.0: {} + micromark-util-encode@2.0.1: {} + micromark-util-events-to-acorn@1.2.3: dependencies: '@types/acorn': 4.0.6 @@ -15260,20 +17963,36 @@ snapshots: micromark-util-html-tag-name@1.2.0: {} + micromark-util-html-tag-name@2.0.1: {} + micromark-util-normalize-identifier@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-resolve-all@1.1.0: dependencies: micromark-util-types: 1.1.0 + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + micromark-util-sanitize-uri@1.2.0: dependencies: micromark-util-character: 1.2.0 micromark-util-encode: 1.1.0 micromark-util-symbol: 1.1.0 + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-subtokenize@1.1.0: dependencies: micromark-util-chunked: 1.1.0 @@ -15281,10 +18000,21 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-symbol@1.1.0: {} + micromark-util-symbol@2.0.1: {} + micromark-util-types@1.1.0: {} + micromark-util-types@2.0.2: {} + micromark@3.2.0: dependencies: '@types/debug': 4.1.12 @@ -15307,6 +18037,28 @@ snapshots: transitivePeerDependencies: - supports-color + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.1 + decode-named-character-reference: 1.1.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -15320,14 +18072,22 @@ snapshots: dependencies: mime-db: 1.52.0 + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mimic-fn@2.1.0: {} + mimic-fn@4.0.0: {} + min-indent@1.0.1: {} mini-svg-data-uri@1.4.4: {} + minimal-polyfills@2.2.3: {} + minimatch@10.0.2: dependencies: brace-expansion: 4.0.1 @@ -15402,6 +18162,8 @@ snapshots: modern-ahocorasick@1.1.0: {} + module-details-from-path@1.0.4: {} + morgan@1.10.0: dependencies: basic-auth: 2.0.1 @@ -15456,6 +18218,8 @@ snapshots: negotiator@0.6.4: {} + negotiator@1.0.0: {} + neo-async@2.6.2: {} neo4j-driver-bolt-connection@5.28.1: @@ -15506,9 +18270,11 @@ snapshots: dependencies: lodash: 4.17.21 - node-fetch@2.7.0: + node-fetch@2.7.0(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 node-gyp-build-optional-packages@5.2.2: dependencies: @@ -15545,6 +18311,48 @@ snapshots: normalize.css@8.0.1: {} + novel@1.0.2(@tiptap/extension-code-block@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0))(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@18.2.69)(react@18.3.1) + '@tiptap/core': 2.25.0(@tiptap/pm@2.25.0) + '@tiptap/extension-character-count': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-code-block-lowlight': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/extension-code-block@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)(highlight.js@11.11.1)(lowlight@3.3.0) + '@tiptap/extension-color': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/extension-text-style@2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))) + '@tiptap/extension-highlight': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-horizontal-rule': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-image': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-link': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-placeholder': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-task-item': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@tiptap/extension-task-list': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-text-style': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-underline': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/extension-youtube': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0)) + '@tiptap/pm': 2.25.0 + '@tiptap/react': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tiptap/starter-kit': 2.11.9 + '@tiptap/suggestion': 2.25.0(@tiptap/core@2.25.0(@tiptap/pm@2.25.0))(@tiptap/pm@2.25.0) + '@types/node': 22.16.0 + cmdk: 1.1.1(@types/react-dom@18.3.7(@types/react@18.2.69))(@types/react@18.2.69)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + jotai: 2.12.5(@types/react@18.2.69)(react@18.3.1) + katex: 0.16.22 + react: 18.3.1 + react-markdown: 9.1.0(@types/react@18.2.69)(react@18.3.1) + react-moveable: 0.56.0 + react-tweet: 3.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tippy.js: 6.3.7 + tiptap-extension-global-drag-handle: 0.1.18 + tunnel-rat: 0.1.2(@types/react@18.2.69)(react@18.3.1) + transitivePeerDependencies: + - '@tiptap/extension-code-block' + - '@types/react' + - '@types/react-dom' + - highlight.js + - immer + - lowlight + - react-dom + - supports-color + npm-install-checks@6.3.0: dependencies: semver: 7.7.2 @@ -15581,6 +18389,15 @@ snapshots: dependencies: path-key: 3.1.1 + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + num2fraction@1.2.2: {} object-assign@4.1.1: {} @@ -15660,6 +18477,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -15681,12 +18502,18 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + orderedmap@2.1.1: {} + os-tmpdir@1.0.2: {} outdent@0.5.0: {} outdent@0.8.0: {} + overlap-area@1.1.0: + dependencies: + '@daybrush/utils': 1.13.0 + own-keys@1.0.1: dependencies: get-intrinsic: 1.3.0 @@ -15753,6 +18580,8 @@ snapshots: parse-ms@2.1.0: {} + parse-ms@4.0.0: {} + parseley@0.12.1: dependencies: leac: 0.6.0 @@ -15770,6 +18599,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -15784,6 +18615,8 @@ snapshots: path-to-regexp@0.1.12: {} + path-to-regexp@8.2.0: {} + path-type@3.0.0: dependencies: pify: 3.0.0 @@ -15828,6 +18661,8 @@ snapshots: pirates@4.0.7: {} + pkce-challenge@5.0.0: {} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -15895,6 +18730,14 @@ snapshots: optionalDependencies: postcss: 8.5.5 + postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.5.5)(yaml@2.8.0): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.4.2 + postcss: 8.5.5 + yaml: 2.8.0 + postcss-loader@8.1.1(postcss@8.5.5)(typescript@5.8.3)(webpack@5.99.9(esbuild@0.25.5)): dependencies: cosmiconfig: 9.0.0(typescript@5.8.3) @@ -16041,6 +18884,10 @@ snapshots: dependencies: parse-ms: 2.1.0 + pretty-ms@9.2.0: + dependencies: + parse-ms: 4.0.0 + prism-react-renderer@2.1.0(react@18.3.1): dependencies: '@types/prismjs': 1.26.5 @@ -16063,6 +18910,11 @@ snapshots: process-nextick-args@2.0.1: {} + prom-client@15.1.3: + dependencies: + '@opentelemetry/api': 1.9.0 + tdigest: 0.1.2 + promise-inflight@1.0.1: {} promise-retry@2.0.1: @@ -16078,13 +18930,135 @@ snapshots: property-information@6.5.0: {} + property-information@7.1.0: {} + + prosemirror-changeset@2.3.1: + dependencies: + prosemirror-transform: 1.10.4 + + prosemirror-collab@1.3.1: + dependencies: + prosemirror-state: 1.4.3 + + prosemirror-commands@1.7.1: + dependencies: + prosemirror-model: 1.25.1 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + + prosemirror-dropcursor@1.8.2: + dependencies: + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + prosemirror-view: 1.40.0 + + prosemirror-gapcursor@1.3.2: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.1 + prosemirror-state: 1.4.3 + prosemirror-view: 1.40.0 + + prosemirror-history@1.4.1: + dependencies: + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + prosemirror-view: 1.40.0 + rope-sequence: 1.3.4 + + prosemirror-inputrules@1.5.0: + dependencies: + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.3 + w3c-keyname: 2.2.8 + + prosemirror-markdown@1.13.2: + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + prosemirror-model: 1.25.1 + + prosemirror-menu@1.2.5: + dependencies: + crelt: 1.0.6 + prosemirror-commands: 1.7.1 + prosemirror-history: 1.4.1 + prosemirror-state: 1.4.3 + + prosemirror-model@1.25.1: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-basic@1.2.4: + dependencies: + prosemirror-model: 1.25.1 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.1 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + + prosemirror-state@1.4.3: + dependencies: + prosemirror-model: 1.25.1 + prosemirror-transform: 1.10.4 + prosemirror-view: 1.40.0 + + prosemirror-tables@1.7.1: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.1 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + prosemirror-view: 1.40.0 + + prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.40.0): + dependencies: + '@remirror/core-constants': 3.0.0 + escape-string-regexp: 4.0.0 + prosemirror-model: 1.25.1 + prosemirror-state: 1.4.3 + prosemirror-view: 1.40.0 + + prosemirror-transform@1.10.4: + dependencies: + prosemirror-model: 1.25.1 + + prosemirror-view@1.40.0: + dependencies: + prosemirror-model: 1.25.1 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.4 + proto-list@1.2.4: {} + protobufjs@7.5.3: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 18.19.115 + long: 5.3.2 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + pseudomap@1.0.2: {} pump@2.0.1: @@ -16103,6 +19077,8 @@ snapshots: inherits: 2.0.4 pump: 2.0.1 + punycode.js@2.3.1: {} + punycode@2.3.1: {} purgecss@2.3.0: @@ -16116,6 +19092,10 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + quansync@0.2.10: {} queue-microtask@1.2.3: {} @@ -16135,6 +19115,18 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + raw-body@3.0.0: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + + react-css-styled@1.1.9: + dependencies: + css-styled: 1.0.8 + framework-utils: 1.1.0 + react-dom@18.2.0(react@18.2.0): dependencies: loose-envify: 1.4.0 @@ -16147,7 +19139,7 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-email@2.1.6(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.2)(eslint@8.57.1): + react-email@2.1.6(@opentelemetry/api@1.9.0)(@swc/helpers@0.5.17)(eslint@8.57.1): dependencies: '@babel/core': 7.24.5 '@babel/parser': 7.24.5 @@ -16157,10 +19149,10 @@ snapshots: '@radix-ui/react-slot': 1.1.0(@types/react@18.2.47)(react@18.3.1) '@radix-ui/react-toggle-group': 1.1.0(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tooltip': 1.1.1(@types/react-dom@18.3.7(@types/react@18.2.47))(@types/react@18.2.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/core': 1.3.101(@swc/helpers@0.5.2) + '@swc/core': 1.3.101(@swc/helpers@0.5.17) '@types/react': 18.2.47 '@types/react-dom': 18.3.7(@types/react@18.2.69) - '@types/webpack': 5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11) + '@types/webpack': 5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11) autoprefixer: 10.4.14(postcss@8.4.38) chalk: 4.1.2 chokidar: 3.5.3 @@ -16208,6 +19200,40 @@ snapshots: react-lifecycles-compat@3.0.4: {} + react-markdown@9.1.0(@types/react@18.2.69)(react@18.3.1): + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/react': 18.2.69 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.0 + react: 18.3.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + react-moveable@0.56.0: + dependencies: + '@daybrush/utils': 1.13.0 + '@egjs/agent': 2.4.4 + '@egjs/children-differ': 1.0.1 + '@egjs/list-differ': 1.0.1 + '@scena/dragscroll': 1.4.0 + '@scena/event-emitter': 1.0.5 + '@scena/matrix': 1.1.1 + css-to-mat: 1.1.1 + framework-utils: 1.1.0 + gesto: 1.19.4 + overlap-area: 1.1.0 + react-css-styled: 1.1.9 + react-selecto: 1.26.3 + react-promise-suspense@0.3.4: dependencies: fast-deep-equal: 2.0.1 @@ -16269,6 +19295,10 @@ snapshots: '@remix-run/router': 1.23.0 react: 18.3.1 + react-selecto@1.26.3: + dependencies: + selecto: 1.26.3 + react-style-singleton@2.2.3(@types/react@18.2.47)(react@18.3.1): dependencies: get-nonce: 1.0.1 @@ -16285,6 +19315,14 @@ snapshots: optionalDependencies: '@types/react': 18.2.69 + react-tweet@3.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@swc/helpers': 0.5.17 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + swr: 2.3.3(react@18.3.1) + react-virtualized@9.22.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.27.6 @@ -16354,6 +19392,8 @@ snapshots: dependencies: picomatch: 2.3.1 + readdirp@4.1.2: {} + redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -16421,6 +19461,15 @@ snapshots: transitivePeerDependencies: - supports-color + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-rehype@10.1.0: dependencies: '@types/hast': 2.3.10 @@ -16428,6 +19477,14 @@ snapshots: mdast-util-to-hast: 12.3.0 unified: 10.1.2 + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 + remix-auth-oauth2@3.4.1(remix-auth@4.2.0): dependencies: '@edgefirst-dev/data': 0.0.4 @@ -16463,6 +19520,14 @@ snapshots: require-from-string@2.0.2: {} + require-in-the-middle@7.5.2: + dependencies: + debug: 4.4.1 + module-details-from-path: 1.0.4 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + require-like@0.1.2: {} require-main-filename@2.0.0: {} @@ -16542,6 +19607,22 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.43.0 fsevents: 2.3.3 + rope-sequence@1.3.4: {} + + router@2.2.0: + dependencies: + debug: 4.4.1 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + transitivePeerDependencies: + - supports-color + + run-exclusive@2.2.19: + dependencies: + minimal-polyfills: 2.2.3 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -16598,6 +19679,19 @@ snapshots: dependencies: parseley: 0.12.1 + selecto@1.26.3: + dependencies: + '@daybrush/utils': 1.13.0 + '@egjs/children-differ': 1.0.1 + '@scena/dragscroll': 1.4.0 + '@scena/event-emitter': 1.0.5 + css-styled: 1.0.8 + css-to-mat: 1.1.1 + framework-utils: 1.1.0 + gesto: 1.19.4 + keycon: 1.4.0 + overlap-area: 1.1.0 + semver@5.7.2: {} semver@6.3.1: {} @@ -16622,6 +19716,22 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -16635,6 +19745,15 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + set-blocking@2.0.0: {} set-cookie-parser@2.7.1: {} @@ -16677,6 +19796,8 @@ snapshots: shell-quote@1.8.3: {} + shimmer@1.2.1: {} + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -16705,16 +19826,34 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + sigma@3.0.2(graphology-types@0.24.8): + dependencies: + events: 3.3.0 + graphology-utils: 2.5.2(graphology-types@0.24.8) + transitivePeerDependencies: + - graphology-types + signal-exit@3.0.7: {} signal-exit@4.1.0: {} + simple-oauth2@5.1.0: + dependencies: + '@hapi/hoek': 11.0.7 + '@hapi/wreck': 18.1.0 + debug: 4.4.1 + joi: 17.13.3 + transitivePeerDependencies: + - supports-color + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 slash@3.0.0: {} + slug@6.1.0: {} + smartwrap@2.0.2: dependencies: array.prototype.flat: 1.3.3 @@ -16744,6 +19883,17 @@ snapshots: - supports-color - utf-8-validate + socket.io-client@4.7.5: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-client: 6.5.4 + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 @@ -16765,6 +19915,20 @@ snapshots: - supports-color - utf-8-validate + socket.io@4.7.4: + dependencies: + accepts: 1.3.8 + base64id: 2.0.0 + cors: 2.8.5 + debug: 4.3.7 + engine.io: 6.5.5 + socket.io-adapter: 2.5.5 + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + sonner@1.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 @@ -16783,6 +19947,10 @@ snapshots: source-map@0.7.4: {} + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + space-separated-tokens@2.0.2: {} spawndamnit@2.0.0: @@ -16820,6 +19988,8 @@ snapshots: statuses@2.0.1: {} + std-env@3.9.0: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -16931,6 +20101,10 @@ snapshots: strip-final-newline@2.0.0: {} + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -16939,10 +20113,18 @@ snapshots: strnum@1.1.2: {} + style-to-js@1.1.17: + dependencies: + style-to-object: 1.0.9 + style-to-object@0.4.4: dependencies: inline-style-parser: 0.1.1 + style-to-object@1.0.9: + dependencies: + inline-style-parser: 0.2.4 + styled-jsx@5.1.1(@babel/core@7.24.5)(react@18.3.1): dependencies: client-only: 0.0.1 @@ -16960,6 +20142,10 @@ snapshots: pirates: 4.0.7 ts-interface-checker: 0.1.13 + superjson@2.2.2: + dependencies: + copy-anything: 3.0.5 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -17100,18 +20286,22 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + tdigest@0.1.2: + dependencies: + bintrees: 1.0.2 + term-size@2.2.1: {} - terser-webpack-plugin@5.3.14(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)(webpack@5.99.9): + terser-webpack-plugin@5.3.14(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)(webpack@5.99.9): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 terser: 5.42.0 - webpack: 5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11) + webpack: 5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11) optionalDependencies: - '@swc/core': 1.3.101(@swc/helpers@0.5.2) + '@swc/core': 1.3.101(@swc/helpers@0.5.17) esbuild: 0.19.11 terser-webpack-plugin@5.3.14(esbuild@0.25.5)(webpack@5.99.9(esbuild@0.25.5)): @@ -17152,11 +20342,19 @@ snapshots: tiny-invariant@1.3.3: {} + tinyexec@0.3.2: {} + tinyglobby@0.2.14: dependencies: fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 + tippy.js@6.3.7: + dependencies: + '@popperjs/core': 2.11.8 + + tiptap-extension-global-drag-handle@0.1.18: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -17171,6 +20369,12 @@ snapshots: tr46@0.0.3: {} + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + trim-lines@3.0.1: {} trim-newlines@3.0.1: {} @@ -17183,6 +20387,12 @@ snapshots: ts-interface-checker@0.1.13: {} + tsafe@1.8.5: {} + + tsconfck@3.1.3(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + tsconfck@3.1.6(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 @@ -17204,6 +20414,35 @@ snapshots: tslib@2.8.1: {} + tsup@8.5.0(@swc/core@1.3.101(@swc/helpers@0.5.17))(jiti@2.4.2)(postcss@8.5.5)(typescript@5.8.3)(yaml@2.8.0): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.5) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.1 + esbuild: 0.25.5 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.5.5)(yaml@2.8.0) + resolve-from: 5.0.0 + rollup: 4.43.0 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.14 + tree-kill: 1.2.2 + optionalDependencies: + '@swc/core': 1.3.101(@swc/helpers@0.5.17) + postcss: 8.5.5 + typescript: 5.8.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsutils@3.21.0(typescript@5.8.3): dependencies: tslib: 1.14.1 @@ -17219,6 +20458,14 @@ snapshots: wcwidth: 1.0.1 yargs: 17.7.2 + tunnel-rat@0.1.2(@types/react@18.2.69)(react@18.3.1): + dependencies: + zustand: 4.5.7(@types/react@18.2.69)(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - immer + - react + turbo-darwin-64@2.5.4: optional: true @@ -17269,6 +20516,12 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.1 + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -17308,8 +20561,15 @@ snapshots: typescript@5.8.3: {} + uc.micro@2.1.0: {} + ufo@1.6.1: {} + uglify-js@3.19.3: + optional: true + + ulid@2.4.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -17317,10 +20577,18 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + uncrypto@0.1.3: {} + + undici-types@5.26.5: {} + + undici-types@6.21.0: {} + undici-types@7.8.0: {} undici@6.21.3: {} + unicorn-magic@0.3.0: {} + unified@10.1.2: dependencies: '@types/unist': 2.0.11 @@ -17331,6 +20599,16 @@ snapshots: trough: 2.2.0 vfile: 5.3.7 + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + unique-filename@3.0.0: dependencies: unique-slug: 4.0.0 @@ -17345,6 +20623,10 @@ snapshots: dependencies: '@types/unist': 2.0.11 + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-position-from-estree@1.1.2: dependencies: '@types/unist': 2.0.11 @@ -17353,6 +20635,10 @@ snapshots: dependencies: '@types/unist': 2.0.11 + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-remove-position@4.0.2: dependencies: '@types/unist': 2.0.11 @@ -17362,17 +20648,32 @@ snapshots: dependencies: '@types/unist': 2.0.11 + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit-parents@5.1.3: dependencies: '@types/unist': 2.0.11 unist-util-is: 5.2.1 + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit@4.1.2: dependencies: '@types/unist': 2.0.11 unist-util-is: 5.2.1 unist-util-visit-parents: 5.1.3 + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + universalify@0.1.2: {} universalify@2.0.1: {} @@ -17479,6 +20780,8 @@ snapshots: validate-npm-package-name@5.0.1: {} + validator@13.15.15: {} + vary@1.1.2: {} vfile-message@3.1.4: @@ -17486,6 +20789,11 @@ snapshots: '@types/unist': 2.0.11 unist-util-stringify-position: 3.0.3 + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + vfile@5.3.7: dependencies: '@types/unist': 2.0.11 @@ -17493,13 +20801,18 @@ snapshots: unist-util-stringify-position: 3.0.3 vfile-message: 3.1.4 - vite-node@1.6.1(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0): + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vite-node@1.6.1(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0): dependencies: cac: 6.7.14 debug: 4.4.1 pathe: 1.1.2 picocolors: 1.1.1 - vite: 5.4.19(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0) + vite: 5.4.19(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0) transitivePeerDependencies: - '@types/node' - less @@ -17511,13 +20824,13 @@ snapshots: - supports-color - terser - vite-node@3.2.3(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0): + vite-node@3.2.3(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -17532,29 +20845,29 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)): + vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0)): dependencies: debug: 4.4.1 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0) transitivePeerDependencies: - supports-color - typescript - vite@5.4.19(@types/node@24.0.0)(lightningcss@1.30.1)(terser@5.42.0): + vite@5.4.19(@types/node@18.19.115)(lightningcss@1.30.1)(terser@5.42.0): dependencies: esbuild: 0.21.5 postcss: 8.5.5 rollup: 4.43.0 optionalDependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 fsevents: 2.3.3 lightningcss: 1.30.1 terser: 5.42.0 - vite@6.3.5(@types/node@24.0.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0): + vite@6.3.5(@types/node@18.19.115)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.42.0)(yaml@2.8.0): dependencies: esbuild: 0.25.5 fdir: 6.4.6(picomatch@4.0.2) @@ -17563,13 +20876,15 @@ snapshots: rollup: 4.43.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 24.0.0 + '@types/node': 18.19.115 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.30.1 terser: 5.42.0 yaml: 2.8.0 + w3c-keyname@2.2.8: {} + watchpack@2.4.4: dependencies: glob-to-regexp: 0.4.1 @@ -17591,9 +20906,11 @@ snapshots: webidl-conversions@3.0.1: {} + webidl-conversions@4.0.2: {} + webpack-sources@3.3.2: {} - webpack@5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11): + webpack@5.99.9(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -17616,7 +20933,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.2 - terser-webpack-plugin: 5.3.14(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)(webpack@5.99.9) + terser-webpack-plugin: 5.3.14(@swc/core@1.3.101(@swc/helpers@0.5.17))(esbuild@0.19.11)(webpack@5.99.9) watchpack: 2.4.4 webpack-sources: 3.3.2 transitivePeerDependencies: @@ -17661,6 +20978,12 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -17723,6 +21046,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -17798,6 +21123,8 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors@2.1.1: {} + zod-error@1.5.0: dependencies: zod: 3.23.8 @@ -17812,4 +21139,11 @@ snapshots: zod@3.23.8: {} + zustand@4.5.7(@types/react@18.2.69)(react@18.3.1): + dependencies: + use-sync-external-store: 1.5.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.2.69 + react: 18.3.1 + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3ff5faa..868471a 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - "apps/*" - "packages/*" + - "core/*" diff --git a/trigger/.env.example b/trigger/.env.example new file mode 100644 index 0000000..67afd24 --- /dev/null +++ b/trigger/.env.example @@ -0,0 +1,138 @@ +# Trigger.dev self-hosting environment variables +# - These are the default values for the self-hosting stack +# - You should change them to suit your needs, especially the secrets +# - See the docs for more information: https://trigger.dev/docs/self-hosting/overview + +# Secrets +# - Do NOT use these defaults in production +# - Generate your own by running `openssl rand -hex 16` for each secret +SESSION_SECRET=2818143646516f6fffd707b36f334bbb +MAGIC_LINK_SECRET=44da78b7bbb0dfe709cf38931d25dcdd +ENCRYPTION_KEY=f686147ab967943ebbe9ed3b496e465a +MANAGED_WORKER_SECRET=447c29678f9eaf289e9c4b70d3dd8a7f + +# Worker token +# - This is the token for the worker to connect to the webapp +# - When running the combined stack, this is set automatically during bootstrap +# - For the split setup, you will have to set this manually. The token is available in the webapp logs but will only be shown once. +# - See the docs for more information: https://trigger.dev/docs/self-hosting/docker +# TRIGGER_WORKER_TOKEN= + +# Worker URLs +# - In split setups, uncomment and set to the public URL of your webapp +# TRIGGER_API_URL=https://trigger.example.com +# OTEL_EXPORTER_OTLP_ENDPOINT=https://trigger.example.com/otel + +# Postgres +# - Do NOT use these defaults in production +# - Especially if you decide to expose the database to the internet +# POSTGRES_USER=postgres +POSTGRES_USER=docker +POSTGRES_PASSWORD=docker +TRIGGER_DB=trigger + +DB_HOST=localhost +DB_PORT=5432 +DB_SCHEMA=sigma + + +# POSTGRES_DB=postgres +DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}:${DB_PORT}/${TRIGGER_DB}?schema=public&sslmode=disable +DIRECT_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}:${DB_PORT}/${TRIGGER_DB}?schema=public&sslmode=disable + +# Trigger image tag +# - This is the version of the webapp and worker images to use, they should be locked to a specific version in production +# - For example: TRIGGER_IMAGE_TAG=v4.0.0-v4-beta.21 +TRIGGER_IMAGE_TAG=v4-beta + +# Webapp +# - These should generally be set to the same value +# - In production, these should be set to the public URL of your webapp, e.g. https://trigger.example.com +APP_ORIGIN=http://localhost:8030 +LOGIN_ORIGIN=http://localhost:8030 +API_ORIGIN=http://localhost:8030 +DEV_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8030/otel +# You may need to set this when testing locally or when using the combined setup +# API_ORIGIN=http://webapp:3000 + +# Webapp - memory management +# - This sets the maximum memory allocation for Node.js heap in MiB (e.g. "4096" for 4GB) +# - It should be set according to your total webapp machine's memory or any container limits you have set +# - Setting this too high or low WILL cause crashes, inefficient memory utilization and high CPU usage +# - You should allow for some memory overhead, we suggest at least 20%, for example: +# - 2GB machine: NODE_MAX_OLD_SPACE_SIZE=1600 +# - 4GB machine: NODE_MAX_OLD_SPACE_SIZE=3200 +# - 6GB machine: NODE_MAX_OLD_SPACE_SIZE=4800 +# - 8GB machine: NODE_MAX_OLD_SPACE_SIZE=6400 +# NODE_MAX_OLD_SPACE_SIZE=8192 + +# ClickHouse +# - Do NOT use these defaults in production +CLICKHOUSE_USER=default +CLICKHOUSE_PASSWORD=password +CLICKHOUSE_URL=http://default:password@clickhouse:8123?secure=false +RUN_REPLICATION_CLICKHOUSE_URL=http://default:password@clickhouse:8123 + +# Docker Registry +# - When testing locally, the default values should be fine +# - When deploying to production, you will have to change these, especially the password and URL +# - See the docs for more information: https://trigger.dev/docs/self-hosting/docker#registry-setup +DOCKER_REGISTRY_URL=localhost:5000 +DOCKER_REGISTRY_USERNAME=registry-user +DOCKER_REGISTRY_PASSWORD=very-secure-indeed + +# Object store +# - You need to log into the Minio dashboard and create a bucket called "packets" +# - See the docs for more information: https://trigger.dev/docs/self-hosting/docker#object-storage +OBJECT_STORE_ACCESS_KEY_ID=admin +OBJECT_STORE_SECRET_ACCESS_KEY=very-safe-password +# You will have to uncomment and configure this for production +# OBJECT_STORE_BASE_URL=http://localhost:9000 +# Credentials to access the Minio dashboard at http://localhost:9001 +# - You should change these credentials and not use them for the `OBJECT_STORE_` env vars above +# - Instead, setup a non-root user with access the "packets" bucket +# MINIO_ROOT_USER=admin +# MINIO_ROOT_PASSWORD=very-safe-password + +# Other image tags +# - These are the versions of the other images to use +# - You should lock these to a specific version in production +# POSTGRES_IMAGE_TAG=14 +# REDIS_IMAGE_TAG=7 +# ELECTRIC_IMAGE_TAG=1.0.13 +# CLICKHOUSE_IMAGE_TAG=latest +# REGISTRY_IMAGE_TAG=2 +# MINIO_IMAGE_TAG=latest +# DOCKER_PROXY_IMAGE_TAG=latest +# TRAEFIK_IMAGE_TAG=v3.4 + +# Publish IPs +# - These are the IPs to publish the services to +# - Setting to 127.0.0.1 makes the service only accessible locally +# - When deploying to production, you will have to change these, depending on your setup +# WEBAPP_PUBLISH_IP=0.0.0.0 +# POSTGRES_PUBLISH_IP=127.0.0.1 +# REDIS_PUBLISH_IP=127.0.0.1 +# ELECTRIC_PUBLISH_IP=127.0.0.1 +# CLICKHOUSE_PUBLISH_IP=127.0.0.1 +# REGISTRY_PUBLISH_IP=127.0.0.1 +# MINIO_PUBLISH_IP=127.0.0.1 + +# Restart policy +# - Applies to all services, adjust as needed +# RESTART_POLICY=unless-stopped + +# Docker logging +# - See the official docs: https://docs.docker.com/engine/logging/configure/ +# LOGGING_DRIVER=local +# LOGGING_MAX_SIZE=20m +# LOGGING_MAX_FILES=5 +# LOGGING_COMPRESS=true + +# Traefik +# - Reverse proxy settings only serve as an example and require further configuration +# - See the partial overrides in docker-compose.traefik.yml for more details +# TRAEFIK_ENTRYPOINT=websecure +# TRAEFIK_HTTP_PUBLISH_IP=0.0.0.0 +# TRAEFIK_HTTPS_PUBLISH_IP=0.0.0.0 +# TRAEFIK_DASHBOARD_PUBLISH_IP=127.0.0.1 \ No newline at end of file diff --git a/trigger/docker-compose.yaml b/trigger/docker-compose.yaml new file mode 100644 index 0000000..c0aac8c --- /dev/null +++ b/trigger/docker-compose.yaml @@ -0,0 +1,262 @@ +x-logging: &logging-config + driver: ${LOGGING_DRIVER:-local} + options: + max-size: ${LOGGING_MAX_SIZE:-20m} + max-file: ${LOGGING_MAX_FILES:-5} + compress: ${LOGGING_COMPRESS:-true} + +services: + webapp: + image: ghcr.io/triggerdotdev/trigger.dev:${TRIGGER_IMAGE_TAG:-v4-beta} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + ports: + - ${WEBAPP_PUBLISH_IP:-0.0.0.0}:8030:3000 + depends_on: + - clickhouse + networks: + - webapp + - supervisor + volumes: + - shared:/home/node/shared + # Only needed for bootstrap + user: root + # Only needed for bootstrap + command: sh -c "chown -R node:node /home/node/shared && exec ./scripts/entrypoint.sh" + healthcheck: + test: + [ + "CMD", + "node", + "-e", + "http.get('http://localhost:3000/healthcheck', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))", + ] + interval: 30s + timeout: 10s + retries: 5 + start_period: 10s + environment: + APP_ORIGIN: ${APP_ORIGIN:-http://localhost:8030} + LOGIN_ORIGIN: ${LOGIN_ORIGIN:-http://localhost:8030} + API_ORIGIN: ${API_ORIGIN:-http://localhost:8030} + ELECTRIC_ORIGIN: http://electric:3000 + DATABASE_URL: ${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/main?schema=public&sslmode=disable} + DIRECT_URL: ${DIRECT_URL:-postgresql://postgres:postgres@postgres:5432/main?schema=public&sslmode=disable} + SESSION_SECRET: ${SESSION_SECRET} + MAGIC_LINK_SECRET: ${MAGIC_LINK_SECRET} + ENCRYPTION_KEY: ${ENCRYPTION_KEY} + MANAGED_WORKER_SECRET: ${MANAGED_WORKER_SECRET} + REDIS_HOST: host.docker.internal + REDIS_PORT: 6379 + REDIS_TLS_DISABLED: true + APP_LOG_LEVEL: info + DEV_OTEL_EXPORTER_OTLP_ENDPOINT: ${DEV_OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:8030/otel} + DEPLOY_REGISTRY_HOST: ${DOCKER_REGISTRY_URL:-localhost:5000} + OBJECT_STORE_BASE_URL: ${OBJECT_STORE_BASE_URL:-http://minio:9000} + OBJECT_STORE_ACCESS_KEY_ID: ${OBJECT_STORE_ACCESS_KEY_ID} + OBJECT_STORE_SECRET_ACCESS_KEY: ${OBJECT_STORE_SECRET_ACCESS_KEY} + GRACEFUL_SHUTDOWN_TIMEOUT: 1000 + # Bootstrap - this will automatically set up a worker group for you + # This will NOT work for split deployments + TRIGGER_BOOTSTRAP_ENABLED: 1 + TRIGGER_BOOTSTRAP_WORKER_GROUP_NAME: bootstrap + TRIGGER_BOOTSTRAP_WORKER_TOKEN_PATH: /home/node/shared/worker_token + # ClickHouse configuration + CLICKHOUSE_URL: ${CLICKHOUSE_URL:-http://default:password@clickhouse:8123?secure=false} + CLICKHOUSE_LOG_LEVEL: ${CLICKHOUSE_LOG_LEVEL:-info} + # Run replication + RUN_REPLICATION_ENABLED: ${RUN_REPLICATION_ENABLED:-1} + RUN_REPLICATION_CLICKHOUSE_URL: ${RUN_REPLICATION_CLICKHOUSE_URL:-http://default:password@clickhouse:8123} + RUN_REPLICATION_LOG_LEVEL: ${RUN_REPLICATION_LOG_LEVEL:-info} + # Limits + # TASK_PAYLOAD_OFFLOAD_THRESHOLD: 524288 # 512KB + # TASK_PAYLOAD_MAXIMUM_SIZE: 3145728 # 3MB + # BATCH_TASK_PAYLOAD_MAXIMUM_SIZE: 1000000 # 1MB + # TASK_RUN_METADATA_MAXIMUM_SIZE: 262144 # 256KB + # DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT: 100 + # DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT: 100 + # Internal OTEL configuration + INTERNAL_OTEL_TRACE_LOGGING_ENABLED: ${INTERNAL_OTEL_TRACE_LOGGING_ENABLED:-0} + + electric: + image: electricsql/electric:${ELECTRIC_IMAGE_TAG:-1.0.13} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + networks: + - webapp + environment: + DATABASE_URL: ${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/main?schema=public&sslmode=disable} + ELECTRIC_INSECURE: true + ELECTRIC_USAGE_REPORTING: false + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/v1/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + + clickhouse: + image: bitnami/clickhouse:${CLICKHOUSE_IMAGE_TAG:-latest} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + ports: + - ${CLICKHOUSE_PUBLISH_IP:-127.0.0.1}:9123:8123 + - ${CLICKHOUSE_PUBLISH_IP:-127.0.0.1}:9090:9000 + environment: + CLICKHOUSE_ADMIN_USER: ${CLICKHOUSE_USER:-default} + CLICKHOUSE_ADMIN_PASSWORD: ${CLICKHOUSE_PASSWORD:-password} + volumes: + - clickhouse:/bitnami/clickhouse + - ../clickhouse/override.xml:/bitnami/clickhouse/etc/config.d/override.xml:ro + networks: + - webapp + healthcheck: + test: + [ + "CMD", + "clickhouse-client", + "--host", + "localhost", + "--port", + "9000", + "--user", + "default", + "--password", + "password", + "--query", + "SELECT 1", + ] + interval: 5s + timeout: 5s + retries: 5 + start_period: 10s + + registry: + image: registry:${REGISTRY_IMAGE_TAG:-2} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + ports: + - ${REGISTRY_PUBLISH_IP:-127.0.0.1}:5000:5000 + networks: + - webapp + volumes: + # registry-user:very-secure-indeed + - ../registry/auth.htpasswd:/auth/htpasswd:ro + environment: + REGISTRY_AUTH: htpasswd + REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm + REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd + healthcheck: + test: ["CMD", "wget", "--spider", "-q", "http://localhost:5000/"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + + minio: + image: bitnami/minio:${MINIO_IMAGE_TAG:-latest} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + ports: + - ${MINIO_PUBLISH_IP:-127.0.0.1}:9000:9000 + - ${MINIO_PUBLISH_IP:-127.0.0.1}:9001:9001 + networks: + - webapp + volumes: + - minio:/bitnami/minio/data + environment: + MINIO_ROOT_USER: ${MINIO_ROOT_USER:-admin} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-very-safe-password} + MINIO_DEFAULT_BUCKETS: packets + MINIO_BROWSER: "on" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 5s + timeout: 10s + retries: 5 + start_period: 10s + + # Worker related + supervisor: + image: ghcr.io/triggerdotdev/supervisor:${TRIGGER_IMAGE_TAG:-v4-beta} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + depends_on: + - docker-proxy + networks: + - supervisor + - docker-proxy + - webapp + volumes: + - shared:/home/node/shared + # Only needed for bootstrap + user: root + # Only needed for bootstrap + command: sh -c "chown -R node:node /home/node/shared && exec /usr/bin/dumb-init -- pnpm run --filter supervisor start" + environment: + # This needs to match the token of the worker group you want to connect to + # TRIGGER_WORKER_TOKEN: ${TRIGGER_WORKER_TOKEN} + # Use the bootstrap token created by the webapp + TRIGGER_WORKER_TOKEN: file:///home/node/shared/worker_token + MANAGED_WORKER_SECRET: ${MANAGED_WORKER_SECRET} + TRIGGER_API_URL: ${TRIGGER_API_URL:-http://webapp:3000} + OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://webapp:3000/otel} + TRIGGER_WORKLOAD_API_DOMAIN: supervisor + TRIGGER_WORKLOAD_API_PORT_EXTERNAL: 8020 + # Optional settings + DEBUG: 1 + ENFORCE_MACHINE_PRESETS: 1 + TRIGGER_DEQUEUE_INTERVAL_MS: 1000 + DOCKER_HOST: tcp://docker-proxy:2375 + DOCKER_RUNNER_NETWORKS: webapp,supervisor + DOCKER_REGISTRY_URL: ${DOCKER_REGISTRY_URL:-localhost:5000} + DOCKER_REGISTRY_USERNAME: ${DOCKER_REGISTRY_USERNAME:-} + DOCKER_REGISTRY_PASSWORD: ${DOCKER_REGISTRY_PASSWORD:-} + DOCKER_AUTOREMOVE_EXITED_CONTAINERS: 0 + healthcheck: + test: + [ + "CMD", + "node", + "-e", + "http.get('http://localhost:8020/health', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))", + ] + interval: 30s + timeout: 10s + retries: 5 + start_period: 10s + + docker-proxy: + image: tecnativa/docker-socket-proxy:${DOCKER_PROXY_IMAGE_TAG:-latest} + restart: ${RESTART_POLICY:-unless-stopped} + logging: *logging-config + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - docker-proxy + environment: + - LOG_LEVEL=info + - POST=1 + - CONTAINERS=1 + - IMAGES=1 + - INFO=1 + - NETWORKS=1 + healthcheck: + test: ["CMD", "nc", "-z", "127.0.0.1", "2375"] + interval: 30s + timeout: 5s + retries: 5 + start_period: 5s + +volumes: + shared: + clickhouse: + minio: + +networks: + docker-proxy: + name: docker-proxy + supervisor: + name: supervisor + webapp: + name: webapp diff --git a/turbo.json b/turbo.json index 932032e..cad65a9 100644 --- a/turbo.json +++ b/turbo.json @@ -32,6 +32,10 @@ }, "generate": { "dependsOn": [ "^generate" ] + }, + "trigger:dev": { + "interactive": true, + "cache": false } }, "globalDependencies": [ ".env" ], @@ -60,6 +64,11 @@ "MAGIC_LINK_SECRET", "ENABLE_EMAIL_LOGIN", "MODEL", - "OLLAMA_URL" + "OLLAMA_URL", + "TRIGGER_PROJECT_ID", + "TRIGGER_API_URL", + "TRIGGER_SECRET_KEY", + "EMBEDDING_MODEL", + "MODEL" ] }