diff --git a/packages/matrix-bot-common/CLAUDE.md b/packages/matrix-bot-common/CLAUDE.md
new file mode 100644
index 000000000..47d38cbd2
--- /dev/null
+++ b/packages/matrix-bot-common/CLAUDE.md
@@ -0,0 +1,265 @@
+# @manacore/matrix-bot-common
+
+Shared utilities and base classes for Matrix bots.
+
+## Purpose
+
+This package consolidates common code patterns found across all 19 Matrix bots:
+
+- ~4,000 lines of duplicate code reduced to shared utilities
+- Consistent behavior across all bots
+- Easier maintenance and updates
+- Type-safe helpers for common patterns
+
+## Available Components
+
+### BaseMatrixService
+
+Abstract base class that handles Matrix client lifecycle:
+
+```typescript
+import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common';
+
+@Injectable()
+export class MyBotService extends BaseMatrixService {
+ constructor(configService: ConfigService) {
+ super(configService);
+ }
+
+ protected getConfig(): MatrixBotConfig {
+ return {
+ homeserverUrl: this.configService.get('matrix.homeserverUrl'),
+ accessToken: this.configService.get('matrix.accessToken'),
+ storagePath: this.configService.get('matrix.storagePath'),
+ allowedRooms: this.configService.get('matrix.allowedRooms') || [],
+ };
+ }
+
+ protected async handleTextMessage(
+ roomId: string,
+ event: MatrixRoomEvent,
+ message: string,
+ sender: string
+ ) {
+ if (message === '!hello') {
+ await this.sendReply(roomId, event, 'Hello!');
+ }
+ }
+
+ // Optional: Handle voice messages
+ protected async handleAudioMessage(roomId: string, event: MatrixRoomEvent, sender: string) {
+ // Transcribe and process
+ }
+
+ // Optional: Send intro on room join
+ protected getIntroductionMessage(): string | null {
+ return 'Hello! I am a bot.';
+ }
+}
+```
+
+**Provides:**
+
+- `onModuleInit()` - Client setup, storage, auto-join
+- `onModuleDestroy()` - Graceful shutdown
+- `sendMessage(roomId, message)` - Send markdown message
+- `sendReply(roomId, event, message)` - Reply to event
+- `sendNotice(roomId, message)` - Non-highlighted message
+- `downloadMedia(mxcUrl)` - Download from Matrix
+- `uploadMedia(buffer, contentType, filename)` - Upload to Matrix
+
+### HealthController
+
+Shared health endpoint:
+
+```typescript
+import { HealthController, createHealthProvider } from '@manacore/matrix-bot-common';
+
+@Module({
+ controllers: [HealthController],
+ providers: [createHealthProvider('matrix-todo-bot')],
+})
+export class AppModule {}
+```
+
+Returns:
+
+```json
+{
+ "status": "ok",
+ "service": "matrix-todo-bot",
+ "timestamp": "2026-02-01T12:00:00.000Z",
+ "uptime": 3600
+}
+```
+
+### MatrixMessageService
+
+Injectable service for message operations:
+
+```typescript
+import { MatrixMessageService } from '@manacore/matrix-bot-common';
+
+@Injectable()
+export class MyService {
+ constructor(private messageService: MatrixMessageService) {}
+
+ async doSomething(client: MatrixClient, roomId: string) {
+ await this.messageService.sendMessage(client, roomId, '**Bold** message');
+ await this.messageService.sendReaction(client, roomId, eventId, '👍');
+ await this.messageService.editMessage(client, roomId, eventId, 'Updated text');
+ }
+}
+```
+
+### KeywordCommandDetector
+
+Natural language command detection:
+
+```typescript
+import { KeywordCommandDetector, COMMON_KEYWORDS } from '@manacore/matrix-bot-common';
+
+const detector = new KeywordCommandDetector([
+ ...COMMON_KEYWORDS, // hilfe, help, status, etc.
+ { keywords: ['liste', 'list', 'zeige'], command: 'list' },
+ { keywords: ['neu', 'new', 'erstelle'], command: 'create' },
+]);
+
+const command = detector.detect('zeige mir alles'); // Returns 'list'
+const command2 = detector.detect('random text'); // Returns null
+```
+
+### Markdown Utilities
+
+```typescript
+import { markdownToHtml, formatNumberedList, formatBulletList } from '@manacore/matrix-bot-common';
+
+const html = markdownToHtml('**bold** and *italic*');
+// 'bold and italic'
+
+const list = formatNumberedList(items, (item, i) => `${item.name} - ${item.status}`);
+// '1. Item A - active\n2. Item B - done'
+```
+
+### SessionHelper
+
+Type-safe session data wrapper:
+
+```typescript
+import { SessionHelper } from '@manacore/matrix-bot-common';
+
+interface MySessionData {
+ currentItemId: string;
+ selectedModel: string;
+ itemList: string[];
+}
+
+const session = new SessionHelper(sessionService, matrixUserId);
+
+session.set('currentItemId', 'abc123');
+const itemId = session.get('currentItemId'); // string | null
+session.delete('currentItemId');
+
+if (session.isLoggedIn()) {
+ const token = session.getToken();
+}
+```
+
+### UserListMapper
+
+Number-based reference system:
+
+```typescript
+import { UserListMapper } from '@manacore/matrix-bot-common';
+
+const mapper = new UserListMapper();
+
+// After listing contacts to user
+mapper.setList(userId, contacts);
+
+// User says "!select 3"
+const contact = mapper.getByNumber(userId, 3);
+
+// For items with id field
+import { UserIdListMapper } from '@manacore/matrix-bot-common';
+const idMapper = new UserIdListMapper<{ id: string; name: string }>();
+const itemId = idMapper.getIdByNumber(userId, 2);
+```
+
+## Migration Guide
+
+### Before (duplicate code in each bot)
+
+```typescript
+// matrix.service.ts - 50+ lines duplicated across 12 bots
+private markdownToHtml(text: string): string {
+ return text
+ .replace(/\*\*(.+?)\*\*/g, '$1')
+ .replace(/\*(.+?)\*/g, '$1')
+ // ...
+}
+
+private async sendReply(roomId: string, event: any, message: string) {
+ const reply = RichReply.createFor(roomId, event, message, this.markdownToHtml(message));
+ reply.msgtype = 'm.text';
+ await this.client.sendMessage(roomId, reply);
+}
+```
+
+### After (using shared package)
+
+```typescript
+import { markdownToHtml } from '@manacore/matrix-bot-common';
+
+// Or extend BaseMatrixService which includes sendReply()
+await this.sendReply(roomId, event, message);
+```
+
+## Installation
+
+```bash
+pnpm --filter matrix-xxx-bot add @manacore/matrix-bot-common
+```
+
+## File Structure
+
+```
+packages/matrix-bot-common/
+├── src/
+│ ├── index.ts # Main exports
+│ ├── base/
+│ │ ├── base-matrix.service.ts
+│ │ ├── types.ts
+│ │ └── index.ts
+│ ├── health/
+│ │ ├── health.controller.ts
+│ │ └── index.ts
+│ ├── message/
+│ │ ├── message.service.ts
+│ │ └── index.ts
+│ ├── markdown/
+│ │ ├── markdown-formatter.ts
+│ │ └── index.ts
+│ ├── keywords/
+│ │ ├── keyword-detector.ts
+│ │ └── index.ts
+│ ├── session/
+│ │ ├── session-helper.ts
+│ │ └── index.ts
+│ └── list-mapper/
+│ ├── list-mapper.ts
+│ └── index.ts
+├── package.json
+├── tsconfig.json
+└── CLAUDE.md
+```
+
+## Development
+
+```bash
+# Type check
+pnpm --filter @manacore/matrix-bot-common type-check
+
+# Add to a bot
+pnpm --filter matrix-xxx-bot add @manacore/matrix-bot-common
+```
diff --git a/packages/matrix-bot-common/package.json b/packages/matrix-bot-common/package.json
new file mode 100644
index 000000000..15218c53b
--- /dev/null
+++ b/packages/matrix-bot-common/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "@manacore/matrix-bot-common",
+ "version": "0.1.0",
+ "private": true,
+ "description": "Shared utilities and base classes for Matrix bots",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "exports": {
+ ".": "./src/index.ts",
+ "./base": "./src/base/index.ts",
+ "./health": "./src/health/index.ts",
+ "./message": "./src/message/index.ts",
+ "./markdown": "./src/markdown/index.ts",
+ "./keywords": "./src/keywords/index.ts",
+ "./session": "./src/session/index.ts",
+ "./list-mapper": "./src/list-mapper/index.ts"
+ },
+ "scripts": {
+ "type-check": "tsc --noEmit",
+ "clean": "rm -rf dist",
+ "lint": "eslint ."
+ },
+ "dependencies": {
+ "@manacore/bot-services": "workspace:*",
+ "@nestjs/common": "^11.0.20",
+ "@nestjs/config": "^4.0.2",
+ "matrix-bot-sdk": "^0.7.1"
+ },
+ "peerDependencies": {
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
+ "@nestjs/config": "^3.0.0 || ^4.0.0",
+ "matrix-bot-sdk": "^0.7.0"
+ },
+ "devDependencies": {
+ "@types/node": "^24.10.1",
+ "typescript": "^5.9.3"
+ }
+}
diff --git a/packages/matrix-bot-common/src/base/base-matrix.service.ts b/packages/matrix-bot-common/src/base/base-matrix.service.ts
new file mode 100644
index 000000000..dbfa81333
--- /dev/null
+++ b/packages/matrix-bot-common/src/base/base-matrix.service.ts
@@ -0,0 +1,250 @@
+import { Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
+import { ConfigService } from '@nestjs/config';
+import {
+ MatrixClient,
+ SimpleFsStorageProvider,
+ AutojoinRoomsMixin,
+ RichReply,
+} from 'matrix-bot-sdk';
+import * as path from 'path';
+import * as fs from 'fs';
+import { MatrixBotConfig, MatrixRoomEvent, isTextMessage, isAudioMessage } from './types';
+import { markdownToHtml } from '../markdown/markdown-formatter';
+
+/**
+ * Abstract base class for Matrix bot services
+ *
+ * Provides common functionality:
+ * - Matrix client initialization
+ * - Room join handling
+ * - Message routing
+ * - Markdown message sending
+ * - Graceful shutdown
+ *
+ * @example
+ * ```typescript
+ * @Injectable()
+ * export class MyBotService extends BaseMatrixService {
+ * protected async handleTextMessage(roomId: string, event: MatrixRoomEvent, message: string) {
+ * if (message.startsWith('!hello')) {
+ * await this.sendReply(roomId, event, 'Hello!');
+ * }
+ * }
+ *
+ * protected getConfig(): MatrixBotConfig {
+ * return {
+ * homeserverUrl: this.configService.get('matrix.homeserverUrl'),
+ * accessToken: this.configService.get('matrix.accessToken'),
+ * storagePath: this.configService.get('matrix.storagePath'),
+ * allowedRooms: this.configService.get('matrix.allowedRooms'),
+ * };
+ * }
+ * }
+ * ```
+ */
+export abstract class BaseMatrixService implements OnModuleInit, OnModuleDestroy {
+ protected readonly logger = new Logger(this.constructor.name);
+ protected client!: MatrixClient;
+ protected botUserId: string = '';
+ protected readonly allowedRooms: string[];
+
+ constructor(protected configService: ConfigService) {
+ this.allowedRooms = this.getConfig().allowedRooms;
+ }
+
+ /**
+ * Get Matrix configuration - must be implemented by subclass
+ */
+ protected abstract getConfig(): MatrixBotConfig;
+
+ /**
+ * Handle a text message - must be implemented by subclass
+ */
+ protected abstract handleTextMessage(
+ roomId: string,
+ event: MatrixRoomEvent,
+ message: string,
+ sender: string
+ ): Promise;
+
+ /**
+ * Handle an audio message (optional override)
+ */
+ protected async handleAudioMessage(
+ _roomId: string,
+ _event: MatrixRoomEvent,
+ _sender: string
+ ): Promise {
+ // Default: no-op, override in subclass for voice support
+ }
+
+ /**
+ * Get welcome/introduction message (optional override)
+ */
+ protected getIntroductionMessage(): string | null {
+ return null;
+ }
+
+ /**
+ * Initialize the Matrix client
+ */
+ async onModuleInit(): Promise {
+ const config = this.getConfig();
+
+ if (!config.accessToken) {
+ this.logger.error('MATRIX_ACCESS_TOKEN is required');
+ return;
+ }
+
+ // Ensure storage directory exists
+ const storageDir = path.dirname(config.storagePath);
+ if (!fs.existsSync(storageDir)) {
+ fs.mkdirSync(storageDir, { recursive: true });
+ this.logger.log(`Created storage directory: ${storageDir}`);
+ }
+
+ // Initialize client
+ const storage = new SimpleFsStorageProvider(config.storagePath);
+ this.client = new MatrixClient(config.homeserverUrl, config.accessToken, storage);
+
+ // Setup auto-join for allowed rooms
+ AutojoinRoomsMixin.setupOnClient(this.client);
+
+ // Get bot user ID
+ this.botUserId = await this.client.getUserId();
+ this.logger.log(`Bot user ID: ${this.botUserId}`);
+
+ // Setup room join handler
+ this.client.on('room.join', async (roomId: string) => {
+ await this.onRoomJoin(roomId);
+ });
+
+ // Setup message handler
+ this.client.on('room.message', async (roomId: string, event: MatrixRoomEvent) => {
+ await this.onRoomMessage(roomId, event);
+ });
+
+ // Start the client
+ await this.client.start();
+ this.logger.log('Matrix client started');
+ }
+
+ /**
+ * Graceful shutdown
+ */
+ async onModuleDestroy(): Promise {
+ if (this.client) {
+ await this.client.stop();
+ this.logger.log('Matrix client stopped');
+ }
+ }
+
+ /**
+ * Handle room join event
+ */
+ protected async onRoomJoin(roomId: string): Promise {
+ this.logger.log(`Joined room: ${roomId}`);
+
+ // Send introduction message if defined
+ const intro = this.getIntroductionMessage();
+ if (intro) {
+ await this.sendMessage(roomId, intro);
+ }
+ }
+
+ /**
+ * Handle incoming room message
+ */
+ protected async onRoomMessage(roomId: string, event: MatrixRoomEvent): Promise {
+ // Ignore own messages
+ if (event.sender === this.botUserId) return;
+
+ // Check room permissions
+ if (this.allowedRooms.length > 0 && !this.allowedRooms.includes(roomId)) {
+ return;
+ }
+
+ try {
+ if (isTextMessage(event)) {
+ const message = event.content.body.trim();
+ await this.handleTextMessage(roomId, event, message, event.sender);
+ } else if (isAudioMessage(event)) {
+ await this.handleAudioMessage(roomId, event, event.sender);
+ }
+ } catch (error) {
+ this.logger.error(`Error handling message: ${error}`);
+ await this.sendReply(roomId, event, '❌ Ein Fehler ist aufgetreten.');
+ }
+ }
+
+ /**
+ * Send a message to a room
+ */
+ protected async sendMessage(roomId: string, message: string): Promise {
+ return this.client.sendMessage(roomId, {
+ msgtype: 'm.text',
+ body: message,
+ format: 'org.matrix.custom.html',
+ formatted_body: markdownToHtml(message),
+ });
+ }
+
+ /**
+ * Send a reply to an event
+ */
+ protected async sendReply(
+ roomId: string,
+ event: MatrixRoomEvent,
+ message: string
+ ): Promise {
+ const reply = RichReply.createFor(roomId, event, message, markdownToHtml(message));
+ reply.msgtype = 'm.text';
+ return this.client.sendMessage(roomId, reply);
+ }
+
+ /**
+ * Send a notice (non-highlighted message)
+ */
+ protected async sendNotice(roomId: string, message: string): Promise {
+ return this.client.sendMessage(roomId, {
+ msgtype: 'm.notice',
+ body: message,
+ format: 'org.matrix.custom.html',
+ formatted_body: markdownToHtml(message),
+ });
+ }
+
+ /**
+ * Download media from Matrix
+ */
+ protected async downloadMedia(mxcUrl: string): Promise {
+ const result = await this.client.downloadContent(mxcUrl);
+ return result.data;
+ }
+
+ /**
+ * Upload media to Matrix
+ */
+ protected async uploadMedia(
+ buffer: Buffer,
+ contentType: string,
+ filename: string
+ ): Promise {
+ return this.client.uploadContent(buffer, contentType, filename);
+ }
+
+ /**
+ * Get the Matrix client (for advanced operations)
+ */
+ protected getClient(): MatrixClient {
+ return this.client;
+ }
+
+ /**
+ * Check if a room is allowed
+ */
+ protected isRoomAllowed(roomId: string): boolean {
+ if (this.allowedRooms.length === 0) return true;
+ return this.allowedRooms.includes(roomId);
+ }
+}
diff --git a/packages/matrix-bot-common/src/base/index.ts b/packages/matrix-bot-common/src/base/index.ts
new file mode 100644
index 000000000..81669d5c1
--- /dev/null
+++ b/packages/matrix-bot-common/src/base/index.ts
@@ -0,0 +1,10 @@
+export { BaseMatrixService } from './base-matrix.service';
+export {
+ type MatrixBotConfig,
+ type MatrixRoomEvent,
+ type MatrixMessageEvent,
+ isTextMessage,
+ isAudioMessage,
+ isImageMessage,
+ isFileMessage,
+} from './types';
diff --git a/packages/matrix-bot-common/src/base/types.ts b/packages/matrix-bot-common/src/base/types.ts
new file mode 100644
index 000000000..d611feb0d
--- /dev/null
+++ b/packages/matrix-bot-common/src/base/types.ts
@@ -0,0 +1,75 @@
+/**
+ * Matrix bot configuration
+ */
+export interface MatrixBotConfig {
+ /** Matrix homeserver URL */
+ homeserverUrl: string;
+ /** Bot access token */
+ accessToken: string;
+ /** Path to store bot state */
+ storagePath: string;
+ /** Allowed room IDs (empty = all rooms) */
+ allowedRooms: string[];
+}
+
+/**
+ * Matrix room event
+ */
+export interface MatrixRoomEvent {
+ event_id: string;
+ type: string;
+ sender: string;
+ room_id: string;
+ origin_server_ts: number;
+ content: {
+ msgtype?: string;
+ body?: string;
+ format?: string;
+ formatted_body?: string;
+ url?: string;
+ info?: Record;
+ 'm.relates_to'?: {
+ 'm.in_reply_to'?: { event_id: string };
+ rel_type?: string;
+ event_id?: string;
+ };
+ };
+}
+
+/**
+ * Matrix message event (subset of room event)
+ */
+export interface MatrixMessageEvent extends MatrixRoomEvent {
+ content: MatrixRoomEvent['content'] & {
+ msgtype: string;
+ body: string;
+ };
+}
+
+/**
+ * Check if event is a text message
+ */
+export function isTextMessage(event: MatrixRoomEvent): event is MatrixMessageEvent {
+ return event.content?.msgtype === 'm.text' && typeof event.content?.body === 'string';
+}
+
+/**
+ * Check if event is an audio message
+ */
+export function isAudioMessage(event: MatrixRoomEvent): boolean {
+ return event.content?.msgtype === 'm.audio';
+}
+
+/**
+ * Check if event is an image message
+ */
+export function isImageMessage(event: MatrixRoomEvent): boolean {
+ return event.content?.msgtype === 'm.image';
+}
+
+/**
+ * Check if event is a file message
+ */
+export function isFileMessage(event: MatrixRoomEvent): boolean {
+ return event.content?.msgtype === 'm.file';
+}
diff --git a/packages/matrix-bot-common/src/health/health.controller.ts b/packages/matrix-bot-common/src/health/health.controller.ts
new file mode 100644
index 000000000..5412f564c
--- /dev/null
+++ b/packages/matrix-bot-common/src/health/health.controller.ts
@@ -0,0 +1,58 @@
+import { Controller, Get, Inject, Optional } from '@nestjs/common';
+
+export const HEALTH_SERVICE_NAME = 'HEALTH_SERVICE_NAME';
+
+export interface HealthResponse {
+ status: 'ok' | 'error';
+ service: string;
+ timestamp: string;
+ uptime?: number;
+ version?: string;
+}
+
+/**
+ * Shared health controller for Matrix bots
+ *
+ * Returns standardized health check response.
+ *
+ * @example
+ * ```typescript
+ * // In app.module.ts
+ * @Module({
+ * controllers: [HealthController],
+ * providers: [
+ * { provide: HEALTH_SERVICE_NAME, useValue: 'matrix-todo-bot' }
+ * ],
+ * })
+ * ```
+ */
+@Controller('health')
+export class HealthController {
+ private readonly startTime = Date.now();
+
+ constructor(
+ @Optional()
+ @Inject(HEALTH_SERVICE_NAME)
+ private readonly serviceName?: string
+ ) {}
+
+ @Get()
+ check(): HealthResponse {
+ return {
+ status: 'ok',
+ service: this.serviceName || 'matrix-bot',
+ timestamp: new Date().toISOString(),
+ uptime: Math.floor((Date.now() - this.startTime) / 1000),
+ };
+ }
+}
+
+/**
+ * Create a health controller provider with service name
+ */
+export function createHealthProvider(serviceName: string) {
+ return {
+ provide: HEALTH_SERVICE_NAME,
+ useValue: serviceName,
+ };
+}
diff --git a/packages/matrix-bot-common/src/health/index.ts b/packages/matrix-bot-common/src/health/index.ts
new file mode 100644
index 000000000..20e33addb
--- /dev/null
+++ b/packages/matrix-bot-common/src/health/index.ts
@@ -0,0 +1,6 @@
+export {
+ HealthController,
+ HEALTH_SERVICE_NAME,
+ createHealthProvider,
+ type HealthResponse,
+} from './health.controller';
diff --git a/packages/matrix-bot-common/src/index.ts b/packages/matrix-bot-common/src/index.ts
new file mode 100644
index 000000000..c77830fe0
--- /dev/null
+++ b/packages/matrix-bot-common/src/index.ts
@@ -0,0 +1,68 @@
+/**
+ * @manacore/matrix-bot-common
+ *
+ * Shared utilities and base classes for Matrix bots.
+ * Reduces code duplication across 19 Matrix bots.
+ *
+ * @example
+ * ```typescript
+ * import {
+ * BaseMatrixService,
+ * HealthController,
+ * MatrixMessageService,
+ * KeywordCommandDetector,
+ * markdownToHtml,
+ * SessionHelper,
+ * UserListMapper,
+ * } from '@manacore/matrix-bot-common';
+ * ```
+ */
+
+// Base Matrix Service
+export {
+ BaseMatrixService,
+ type MatrixBotConfig,
+ type MatrixRoomEvent,
+ type MatrixMessageEvent,
+ isTextMessage,
+ isAudioMessage,
+ isImageMessage,
+ isFileMessage,
+} from './base';
+
+// Health Controller
+export {
+ HealthController,
+ HEALTH_SERVICE_NAME,
+ createHealthProvider,
+ type HealthResponse,
+} from './health';
+
+// Message Service
+export {
+ MatrixMessageService,
+ type MatrixMessageContent,
+ type SendMessageOptions,
+} from './message';
+
+// Markdown Utilities
+export {
+ markdownToHtml,
+ escapeHtml,
+ formatNumberedList,
+ formatBulletList,
+} from './markdown';
+
+// Keyword Detection
+export {
+ KeywordCommandDetector,
+ COMMON_KEYWORDS,
+ type KeywordCommand,
+ type KeywordDetectorOptions,
+} from './keywords';
+
+// Session Helper
+export { SessionHelper, createSessionHelper } from './session';
+
+// List Mapper
+export { UserListMapper, UserIdListMapper } from './list-mapper';
diff --git a/packages/matrix-bot-common/src/keywords/index.ts b/packages/matrix-bot-common/src/keywords/index.ts
new file mode 100644
index 000000000..51e2686b9
--- /dev/null
+++ b/packages/matrix-bot-common/src/keywords/index.ts
@@ -0,0 +1,6 @@
+export {
+ KeywordCommandDetector,
+ COMMON_KEYWORDS,
+ type KeywordCommand,
+ type KeywordDetectorOptions,
+} from './keyword-detector';
diff --git a/packages/matrix-bot-common/src/keywords/keyword-detector.ts b/packages/matrix-bot-common/src/keywords/keyword-detector.ts
new file mode 100644
index 000000000..fb706c46a
--- /dev/null
+++ b/packages/matrix-bot-common/src/keywords/keyword-detector.ts
@@ -0,0 +1,118 @@
+/**
+ * Keyword command mapping
+ */
+export interface KeywordCommand {
+ /** Keywords that trigger this command (lowercase) */
+ keywords: string[];
+ /** Command name to return when matched */
+ command: string;
+}
+
+/**
+ * Options for keyword detection
+ */
+export interface KeywordDetectorOptions {
+ /** Maximum message length to check (default: 60) */
+ maxLength?: number;
+ /** Whether to match partial words (default: false) */
+ partialMatch?: boolean;
+}
+
+/**
+ * Detect commands from natural language keywords
+ *
+ * Used by Matrix bots to respond to natural language instead of just !commands.
+ *
+ * @example
+ * ```typescript
+ * const detector = new KeywordCommandDetector([
+ * { keywords: ['hilfe', 'help'], command: 'help' },
+ * { keywords: ['status', 'info'], command: 'status' },
+ * ]);
+ *
+ * detector.detect('hilfe bitte'); // Returns 'help'
+ * detector.detect('was ist los'); // Returns null
+ * ```
+ */
+export class KeywordCommandDetector {
+ private readonly maxLength: number;
+ private readonly partialMatch: boolean;
+
+ constructor(
+ private readonly commands: KeywordCommand[],
+ options: KeywordDetectorOptions = {}
+ ) {
+ this.maxLength = options.maxLength ?? 60;
+ this.partialMatch = options.partialMatch ?? false;
+ }
+
+ /**
+ * Detect a command from a message
+ *
+ * @param message - The user's message
+ * @returns The command name if matched, null otherwise
+ */
+ detect(message: string): string | null {
+ const lowerMessage = message.toLowerCase().trim();
+
+ // Skip long messages (likely not commands)
+ if (lowerMessage.length > this.maxLength) {
+ return null;
+ }
+
+ for (const { keywords, command } of this.commands) {
+ for (const keyword of keywords) {
+ if (this.matches(lowerMessage, keyword)) {
+ return command;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Check if message matches a keyword
+ */
+ private matches(message: string, keyword: string): boolean {
+ // Exact match
+ if (message === keyword) {
+ return true;
+ }
+
+ // Message starts with keyword followed by space
+ if (message.startsWith(keyword + ' ')) {
+ return true;
+ }
+
+ // Partial match (keyword appears anywhere)
+ if (this.partialMatch && message.includes(keyword)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Add more commands dynamically
+ */
+ addCommands(commands: KeywordCommand[]): void {
+ this.commands.push(...commands);
+ }
+
+ /**
+ * Get all registered commands
+ */
+ getCommands(): KeywordCommand[] {
+ return [...this.commands];
+ }
+}
+
+/**
+ * Common German/English keywords used across bots
+ */
+export const COMMON_KEYWORDS: KeywordCommand[] = [
+ { keywords: ['hilfe', 'help', 'befehle', 'commands', '?'], command: 'help' },
+ { keywords: ['status', 'info'], command: 'status' },
+ { keywords: ['abbrechen', 'cancel', 'stop'], command: 'cancel' },
+];
diff --git a/packages/matrix-bot-common/src/list-mapper/index.ts b/packages/matrix-bot-common/src/list-mapper/index.ts
new file mode 100644
index 000000000..f048338dd
--- /dev/null
+++ b/packages/matrix-bot-common/src/list-mapper/index.ts
@@ -0,0 +1 @@
+export { UserListMapper, UserIdListMapper } from './list-mapper';
diff --git a/packages/matrix-bot-common/src/list-mapper/list-mapper.ts b/packages/matrix-bot-common/src/list-mapper/list-mapper.ts
new file mode 100644
index 000000000..ba870430a
--- /dev/null
+++ b/packages/matrix-bot-common/src/list-mapper/list-mapper.ts
@@ -0,0 +1,113 @@
+/**
+ * User list mapper for number-based reference system
+ *
+ * Allows users to reference items by number after listing them.
+ * Used by Matrix bots for commands like "!select 3" or "!delete 2".
+ *
+ * @example
+ * ```typescript
+ * const mapper = new UserListMapper();
+ *
+ * // After showing a list to the user
+ * mapper.setList('@user:matrix.org', contacts);
+ *
+ * // User says "!select 3"
+ * const contact = mapper.getByNumber('@user:matrix.org', 3);
+ * ```
+ */
+export class UserListMapper {
+ private lists: Map = new Map();
+
+ /**
+ * Store a list for a user
+ */
+ setList(userId: string, items: T[]): void {
+ this.lists.set(userId, [...items]);
+ }
+
+ /**
+ * Get an item by its 1-based number
+ *
+ * @param userId - The user ID
+ * @param number - 1-based index (as shown to user)
+ * @returns The item or null if invalid
+ */
+ getByNumber(userId: string, number: number): T | null {
+ const items = this.lists.get(userId);
+ if (!items || number < 1 || number > items.length) {
+ return null;
+ }
+ return items[number - 1];
+ }
+
+ /**
+ * Get the full list for a user
+ */
+ getList(userId: string): T[] {
+ return this.lists.get(userId) || [];
+ }
+
+ /**
+ * Check if user has a stored list
+ */
+ hasList(userId: string): boolean {
+ return this.lists.has(userId) && this.lists.get(userId)!.length > 0;
+ }
+
+ /**
+ * Get the count of items in user's list
+ */
+ getCount(userId: string): number {
+ return this.lists.get(userId)?.length || 0;
+ }
+
+ /**
+ * Clear the list for a user
+ */
+ clearList(userId: string): void {
+ this.lists.delete(userId);
+ }
+
+ /**
+ * Clear all lists
+ */
+ clearAll(): void {
+ this.lists.clear();
+ }
+}
+
+/**
+ * Extended list mapper that also stores IDs separately
+ * Useful when items have an id field that needs quick lookup
+ */
+export class UserIdListMapper extends UserListMapper {
+ private idMaps: Map> = new Map();
+
+ override setList(userId: string, items: T[]): void {
+ super.setList(userId, items);
+
+ // Build ID map
+ const idMap = new Map();
+ items.forEach((item, index) => {
+ idMap.set(index + 1, item.id);
+ });
+ this.idMaps.set(userId, idMap);
+ }
+
+ /**
+ * Get just the ID by number (without loading full item)
+ */
+ getIdByNumber(userId: string, number: number): string | null {
+ return this.idMaps.get(userId)?.get(number) || null;
+ }
+
+ override clearList(userId: string): void {
+ super.clearList(userId);
+ this.idMaps.delete(userId);
+ }
+
+ override clearAll(): void {
+ super.clearAll();
+ this.idMaps.clear();
+ }
+}
diff --git a/packages/matrix-bot-common/src/markdown/index.ts b/packages/matrix-bot-common/src/markdown/index.ts
new file mode 100644
index 000000000..b985125a7
--- /dev/null
+++ b/packages/matrix-bot-common/src/markdown/index.ts
@@ -0,0 +1,6 @@
+export {
+ markdownToHtml,
+ escapeHtml,
+ formatNumberedList,
+ formatBulletList,
+} from './markdown-formatter';
diff --git a/packages/matrix-bot-common/src/markdown/markdown-formatter.ts b/packages/matrix-bot-common/src/markdown/markdown-formatter.ts
new file mode 100644
index 000000000..1aeff3949
--- /dev/null
+++ b/packages/matrix-bot-common/src/markdown/markdown-formatter.ts
@@ -0,0 +1,53 @@
+/**
+ * Convert Markdown text to HTML for Matrix messages
+ *
+ * Supports:
+ * - **bold** -> bold
+ * - *italic* -> italic
+ * - ~~strikethrough~~ -> strikethrough
+ * - `code` -> code
+ * - Newlines ->
+ *
+ * @example
+ * ```typescript
+ * const html = markdownToHtml('**Hello** *world*');
+ * // Returns: 'Hello world'
+ * ```
+ */
+export function markdownToHtml(text: string): string {
+ return text
+ .replace(/\*\*(.+?)\*\*/g, '$1')
+ .replace(/\*(.+?)\*/g, '$1')
+ .replace(/~~(.+?)~~/g, '$1')
+ .replace(/`(.+?)`/g, '$1')
+ .replace(/\n/g, '
');
+}
+
+/**
+ * Escape HTML special characters to prevent XSS
+ */
+export function escapeHtml(text: string): string {
+ return text
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+}
+
+/**
+ * Format a list of items as numbered markdown list
+ */
+export function formatNumberedList(
+ items: T[],
+ formatter: (item: T, index: number) => string
+): string {
+ return items.map((item, i) => `${i + 1}. ${formatter(item, i)}`).join('\n');
+}
+
+/**
+ * Format a list of items as bullet markdown list
+ */
+export function formatBulletList(items: T[], formatter: (item: T) => string): string {
+ return items.map((item) => `• ${formatter(item)}`).join('\n');
+}
diff --git a/packages/matrix-bot-common/src/message/index.ts b/packages/matrix-bot-common/src/message/index.ts
new file mode 100644
index 000000000..2fcea7736
--- /dev/null
+++ b/packages/matrix-bot-common/src/message/index.ts
@@ -0,0 +1,5 @@
+export {
+ MatrixMessageService,
+ type MatrixMessageContent,
+ type SendMessageOptions,
+} from './message.service';
diff --git a/packages/matrix-bot-common/src/message/message.service.ts b/packages/matrix-bot-common/src/message/message.service.ts
new file mode 100644
index 000000000..07b5b8d25
--- /dev/null
+++ b/packages/matrix-bot-common/src/message/message.service.ts
@@ -0,0 +1,227 @@
+import { Injectable, Logger } from '@nestjs/common';
+import { MatrixClient, RichReply } from 'matrix-bot-sdk';
+import { markdownToHtml } from '../markdown/markdown-formatter';
+
+/**
+ * Message content for Matrix
+ */
+export interface MatrixMessageContent {
+ msgtype: string;
+ body: string;
+ format?: string;
+ formatted_body?: string;
+ 'm.relates_to'?: {
+ 'm.in_reply_to'?: { event_id: string };
+ event_id?: string;
+ rel_type?: string;
+ };
+}
+
+/**
+ * Options for sending messages
+ */
+export interface SendMessageOptions {
+ /** Convert markdown to HTML (default: true) */
+ markdown?: boolean;
+ /** Message type (default: 'm.text') */
+ msgtype?: string;
+}
+
+/**
+ * Shared message service for Matrix bots
+ *
+ * Provides standardized methods for sending messages, replies, and reactions.
+ *
+ * @example
+ * ```typescript
+ * const messageService = new MatrixMessageService();
+ *
+ * // Send a simple message
+ * await messageService.sendMessage(client, roomId, 'Hello!');
+ *
+ * // Send a reply to an event
+ * await messageService.sendReply(client, roomId, event, 'Thanks!');
+ *
+ * // Send a reaction
+ * await messageService.sendReaction(client, roomId, eventId, '👍');
+ * ```
+ */
+@Injectable()
+export class MatrixMessageService {
+ private readonly logger = new Logger(MatrixMessageService.name);
+
+ /**
+ * Send a message to a room
+ */
+ async sendMessage(
+ client: MatrixClient,
+ roomId: string,
+ message: string,
+ options: SendMessageOptions = {}
+ ): Promise {
+ const { markdown = true, msgtype = 'm.text' } = options;
+
+ const content: MatrixMessageContent = {
+ msgtype,
+ body: message,
+ };
+
+ if (markdown) {
+ content.format = 'org.matrix.custom.html';
+ content.formatted_body = markdownToHtml(message);
+ }
+
+ return client.sendMessage(roomId, content);
+ }
+
+ /**
+ * Send a reply to a specific event
+ */
+ async sendReply(
+ client: MatrixClient,
+ roomId: string,
+ event: { event_id: string; content?: { body?: string } },
+ message: string,
+ options: SendMessageOptions = {}
+ ): Promise {
+ const { markdown = true, msgtype = 'm.text' } = options;
+
+ const htmlMessage = markdown ? markdownToHtml(message) : message;
+ const reply = RichReply.createFor(roomId, event, message, htmlMessage);
+ reply.msgtype = msgtype;
+
+ return client.sendMessage(roomId, reply);
+ }
+
+ /**
+ * Send a reaction to an event
+ */
+ async sendReaction(
+ client: MatrixClient,
+ roomId: string,
+ eventId: string,
+ emoji: string
+ ): Promise {
+ return client.sendEvent(roomId, 'm.reaction', {
+ 'm.relates_to': {
+ rel_type: 'm.annotation',
+ event_id: eventId,
+ key: emoji,
+ },
+ });
+ }
+
+ /**
+ * Send a notice (non-highlighted message)
+ */
+ async sendNotice(
+ client: MatrixClient,
+ roomId: string,
+ message: string,
+ options: Omit = {}
+ ): Promise {
+ return this.sendMessage(client, roomId, message, { ...options, msgtype: 'm.notice' });
+ }
+
+ /**
+ * Send an image to a room
+ */
+ async sendImage(
+ client: MatrixClient,
+ roomId: string,
+ mxcUrl: string,
+ filename: string,
+ info?: { w?: number; h?: number; mimetype?: string; size?: number }
+ ): Promise {
+ return client.sendMessage(roomId, {
+ msgtype: 'm.image',
+ body: filename,
+ url: mxcUrl,
+ info: info || {},
+ });
+ }
+
+ /**
+ * Send a file to a room
+ */
+ async sendFile(
+ client: MatrixClient,
+ roomId: string,
+ mxcUrl: string,
+ filename: string,
+ info?: { mimetype?: string; size?: number }
+ ): Promise {
+ return client.sendMessage(roomId, {
+ msgtype: 'm.file',
+ body: filename,
+ url: mxcUrl,
+ info: info || {},
+ });
+ }
+
+ /**
+ * Edit an existing message
+ */
+ async editMessage(
+ client: MatrixClient,
+ roomId: string,
+ originalEventId: string,
+ newMessage: string,
+ options: SendMessageOptions = {}
+ ): Promise {
+ const { markdown = true, msgtype = 'm.text' } = options;
+
+ const content: MatrixMessageContent = {
+ msgtype,
+ body: `* ${newMessage}`,
+ 'm.relates_to': {
+ rel_type: 'm.replace',
+ event_id: originalEventId,
+ },
+ };
+
+ if (markdown) {
+ content.format = 'org.matrix.custom.html';
+ content.formatted_body = `* ${markdownToHtml(newMessage)}`;
+ }
+
+ return client.sendMessage(roomId, {
+ ...content,
+ 'm.new_content': {
+ msgtype,
+ body: newMessage,
+ format: markdown ? 'org.matrix.custom.html' : undefined,
+ formatted_body: markdown ? markdownToHtml(newMessage) : undefined,
+ },
+ });
+ }
+
+ /**
+ * Set room topic
+ */
+ async setRoomTopic(client: MatrixClient, roomId: string, topic: string): Promise {
+ await client.sendStateEvent(roomId, 'm.room.topic', '', { topic });
+ }
+
+ /**
+ * Pin a message in a room
+ */
+ async pinMessage(client: MatrixClient, roomId: string, eventId: string): Promise {
+ try {
+ // Get current pinned events
+ const pinnedEvents = await client
+ .getRoomStateEvent(roomId, 'm.room.pinned_events', '')
+ .catch(() => ({ pinned: [] }));
+
+ const pinned: string[] = pinnedEvents?.pinned || [];
+
+ // Add new event if not already pinned
+ if (!pinned.includes(eventId)) {
+ pinned.push(eventId);
+ await client.sendStateEvent(roomId, 'm.room.pinned_events', '', { pinned });
+ }
+ } catch (error) {
+ this.logger.warn(`Failed to pin message: ${error}`);
+ }
+ }
+}
diff --git a/packages/matrix-bot-common/src/session/index.ts b/packages/matrix-bot-common/src/session/index.ts
new file mode 100644
index 000000000..ac6d69b3f
--- /dev/null
+++ b/packages/matrix-bot-common/src/session/index.ts
@@ -0,0 +1 @@
+export { SessionHelper, createSessionHelper } from './session-helper';
diff --git a/packages/matrix-bot-common/src/session/session-helper.ts b/packages/matrix-bot-common/src/session/session-helper.ts
new file mode 100644
index 000000000..3ed652824
--- /dev/null
+++ b/packages/matrix-bot-common/src/session/session-helper.ts
@@ -0,0 +1,85 @@
+import { SessionService } from '@manacore/bot-services';
+
+/**
+ * Typed session helper for bot-specific session data
+ *
+ * Provides type-safe access to session data stored in SessionService.
+ *
+ * @example
+ * ```typescript
+ * interface ChatSessionData {
+ * currentConversationId: string;
+ * selectedModelId: string;
+ * conversationList: string[];
+ * }
+ *
+ * const session = new SessionHelper(sessionService, matrixUserId);
+ * session.set('currentConversationId', 'abc123');
+ * const convId = session.get('currentConversationId'); // string | null
+ * ```
+ */
+export class SessionHelper> {
+ constructor(
+ private readonly sessionService: SessionService,
+ private readonly userId: string
+ ) {}
+
+ /**
+ * Set a session value
+ */
+ set(key: K, value: T[K]): void {
+ this.sessionService.setSessionData(this.userId, key as string, value);
+ }
+
+ /**
+ * Get a session value
+ */
+ get(key: K): T[K] | null {
+ return this.sessionService.getSessionData(this.userId, key as string);
+ }
+
+ /**
+ * Delete a session value
+ */
+ delete(key: K): void {
+ this.sessionService.setSessionData(this.userId, key as string, null);
+ }
+
+ /**
+ * Check if a session value exists
+ */
+ has(key: K): boolean {
+ return this.get(key) !== null;
+ }
+
+ /**
+ * Get the underlying user ID
+ */
+ getUserId(): string {
+ return this.userId;
+ }
+
+ /**
+ * Check if user is logged in
+ */
+ isLoggedIn(): boolean {
+ return this.sessionService.isLoggedIn(this.userId);
+ }
+
+ /**
+ * Get JWT token for API calls
+ */
+ getToken(): string | null {
+ return this.sessionService.getToken(this.userId);
+ }
+}
+
+/**
+ * Factory function to create session helper
+ */
+export function createSessionHelper>(
+ sessionService: SessionService,
+ userId: string
+): SessionHelper {
+ return new SessionHelper(sessionService, userId);
+}
diff --git a/packages/matrix-bot-common/tsconfig.json b/packages/matrix-bot-common/tsconfig.json
new file mode 100644
index 000000000..71802e564
--- /dev/null
+++ b/packages/matrix-bot-common/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "declaration": true,
+ "removeComments": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "allowSyntheticDefaultImports": true,
+ "target": "ES2022",
+ "sourceMap": true,
+ "outDir": "./dist",
+ "baseUrl": "./",
+ "incremental": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "strictNullChecks": true,
+ "noImplicitAny": true,
+ "strictBindCallApply": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "esModuleInterop": true
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4dac649d6..01c44264f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -137,7 +137,7 @@ importers:
devDependencies:
'@nestjs/cli':
specifier: ^10.4.9
- version: 10.4.9(esbuild@0.19.12)
+ version: 10.4.9
'@nestjs/schematics':
specifier: ^10.2.3
version: 10.2.3(chokidar@3.6.0)(typescript@5.9.3)
@@ -185,10 +185,10 @@ importers:
version: 0.5.21
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-loader:
specifier: ^9.5.1
- version: 9.5.4(typescript@5.9.3)(webpack@5.97.1(esbuild@0.19.12))
+ version: 9.5.4(typescript@5.9.3)(webpack@5.100.2)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3)
@@ -212,14 +212,14 @@ importers:
version: link:../../../../packages/shared-landing-ui
astro:
specifier: ^5.16.0
- version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
+ version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
typescript:
specifier: ^5.9.2
version: 5.9.3
devDependencies:
'@astrojs/tailwind':
specifier: ^6.0.2
- version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
+ version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
'@tailwindcss/typography':
specifier: ^0.5.18
version: 0.5.19(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))
@@ -228,13 +228,13 @@ importers:
version: 20.19.25
eslint:
specifier: ^9.0.0
- version: 9.39.1(jiti@1.21.7)
+ version: 9.39.1(jiti@2.6.1)
eslint-config-prettier:
specifier: ^9.1.0
- version: 9.1.2(eslint@9.39.1(jiti@1.21.7))
+ version: 9.1.2(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-astro:
specifier: ^1.0.0
- version: 1.5.0(eslint@9.39.1(jiti@1.21.7))
+ version: 1.5.0(eslint@9.39.1(jiti@2.6.1))
prettier:
specifier: ^3.6.2
version: 3.6.2
@@ -609,19 +609,19 @@ importers:
version: 18.3.27
'@typescript-eslint/eslint-plugin':
specifier: ^7.7.0
- version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser':
specifier: ^7.7.0
- version: 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ version: 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
dotenv:
specifier: ^16.4.7
version: 16.6.1
eslint:
specifier: ^9.39.1
- version: 9.39.1(jiti@2.6.1)
+ version: 9.39.1(jiti@1.21.7)
eslint-config-universe:
specifier: ^12.0.1
- version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)(typescript@5.3.3)
+ version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)(typescript@5.3.3)
prettier:
specifier: ^3.2.5
version: 3.6.2
@@ -2333,7 +2333,7 @@ importers:
version: 0.5.21
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-loader:
specifier: ^9.5.1
version: 9.5.4(typescript@5.9.3)(webpack@5.100.2)
@@ -4594,6 +4594,28 @@ importers:
specifier: ^5.7.3
version: 5.9.3
+ packages/matrix-bot-common:
+ dependencies:
+ '@manacore/bot-services':
+ specifier: workspace:*
+ version: link:../bot-services
+ '@nestjs/common':
+ specifier: ^11.0.20
+ version: 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
+ '@nestjs/config':
+ specifier: ^4.0.2
+ version: 4.0.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)
+ matrix-bot-sdk:
+ specifier: ^0.7.1
+ version: 0.7.1
+ devDependencies:
+ '@types/node':
+ specifier: ^24.10.1
+ version: 24.10.1
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+
packages/notify-client:
devDependencies:
'@nestjs/common':
@@ -5208,7 +5230,7 @@ importers:
version: 1.57.0
jest:
specifier: ^29.0.0
- version: 29.7.0(@types/node@24.10.1)
+ version: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
vitest:
specifier: ^3.0.0
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.2.0)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
@@ -5340,7 +5362,7 @@ importers:
version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3)
@@ -5500,7 +5522,7 @@ importers:
version: 7.1.4
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-loader:
specifier: ^9.5.1
version: 9.5.4(typescript@5.9.3)(webpack@5.100.2)
@@ -5612,7 +5634,7 @@ importers:
version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3)
@@ -5712,7 +5734,7 @@ importers:
version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3)
@@ -5785,7 +5807,7 @@ importers:
version: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
ts-jest:
specifier: ^29.2.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3)
@@ -8891,7 +8913,7 @@ packages:
'@expo/bunyan@4.0.1':
resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==}
- engines: {'0': node >=0.10.0}
+ engines: {node: '>=0.10.0'}
'@expo/cli@0.22.26':
resolution: {integrity: sha512-I689wc8Fn/AX7aUGiwrh3HnssiORMJtR2fpksX+JIe8Cj/EDleblYMSwRPd0025wrwOV9UN1KM/RuEt/QjCS3Q==}
@@ -23341,16 +23363,6 @@ snapshots:
transitivePeerDependencies:
- ts-node
- '@astrojs/tailwind@6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))':
- dependencies:
- astro: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
- autoprefixer: 10.4.22(postcss@8.5.6)
- postcss: 8.5.6
- postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
- tailwindcss: 3.4.18(tsx@4.20.6)(yaml@2.8.1)
- transitivePeerDependencies:
- - ts-node
-
'@astrojs/tailwind@6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))':
dependencies:
astro: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
@@ -26420,7 +26432,7 @@ snapshots:
wrap-ansi: 7.0.0
ws: 8.18.3
optionalDependencies:
- expo-router: 6.0.15(7mqaurqidri6vkknnsci36yp4e)
+ expo-router: 6.0.15(vmxlpuhz6xqbe2ee7fdabyqx3y)
react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0)
transitivePeerDependencies:
- '@modelcontextprotocol/sdk'
@@ -27728,7 +27740,7 @@ snapshots:
jest-util: 30.2.0
slash: 3.0.0
- '@jest/core@29.7.0':
+ '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))':
dependencies:
'@jest/console': 29.7.0
'@jest/reporters': 29.7.0
@@ -27742,7 +27754,7 @@ snapshots:
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@22.19.1)
+ jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -27763,7 +27775,7 @@ snapshots:
- supports-color
- ts-node
- '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))':
+ '@jest/core@29.7.0(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))':
dependencies:
'@jest/console': 29.7.0
'@jest/reporters': 29.7.0
@@ -27777,7 +27789,7 @@ snapshots:
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
+ jest-config: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -28316,32 +28328,6 @@ snapshots:
- uglify-js
- webpack-cli
- '@nestjs/cli@10.4.9(esbuild@0.19.12)':
- dependencies:
- '@angular-devkit/core': 17.3.11(chokidar@3.6.0)
- '@angular-devkit/schematics': 17.3.11(chokidar@3.6.0)
- '@angular-devkit/schematics-cli': 17.3.11(chokidar@3.6.0)
- '@nestjs/schematics': 10.2.3(chokidar@3.6.0)(typescript@5.7.2)
- chalk: 4.1.2
- chokidar: 3.6.0
- cli-table3: 0.6.5
- commander: 4.1.1
- fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.19.12))
- glob: 10.4.5
- inquirer: 8.2.6
- node-emoji: 1.11.0
- ora: 5.4.1
- tree-kill: 1.2.2
- tsconfig-paths: 4.2.0
- tsconfig-paths-webpack-plugin: 4.2.0
- typescript: 5.7.2
- webpack: 5.97.1(esbuild@0.19.12)
- webpack-node-externals: 3.0.0
- transitivePeerDependencies:
- - esbuild
- - uglify-js
- - webpack-cli
-
'@nestjs/cli@10.4.9(esbuild@0.27.0)':
dependencies:
'@angular-devkit/core': 17.3.11(chokidar@3.6.0)
@@ -31937,19 +31923,6 @@ snapshots:
picocolors: 1.1.1
pretty-format: 27.5.1
- '@testing-library/react-native@13.3.3(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0)':
- dependencies:
- jest-matcher-utils: 30.2.0
- picocolors: 1.1.1
- pretty-format: 30.2.0
- react: 19.1.0
- react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0)
- react-test-renderer: 19.1.0(react@19.1.0)
- redent: 3.0.0
- optionalDependencies:
- jest: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
- optional: true
-
'@testing-library/react-native@13.3.3(jest@30.2.0(@types/node@20.19.25)(esbuild-register@3.6.0(esbuild@0.27.0)))(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
jest-matcher-utils: 30.2.0
@@ -32520,16 +32493,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/scope-manager': 6.21.0
- '@typescript-eslint/type-utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
- '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/type-utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
+ '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.4.3
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@@ -32578,15 +32551,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/scope-manager': 7.18.0
- '@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
- '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
+ '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.18.0
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@@ -32678,14 +32651,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.4.3
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
optionalDependencies:
typescript: 5.3.3
transitivePeerDependencies:
@@ -32717,14 +32690,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.4.3
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
optionalDependencies:
typescript: 5.3.3
transitivePeerDependencies:
@@ -32850,12 +32823,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/type-utils@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/type-utils@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
- '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
debug: 4.4.3
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
ts-api-utils: 1.4.3(typescript@5.3.3)
optionalDependencies:
typescript: 5.3.3
@@ -32886,12 +32859,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
- '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
debug: 4.4.3
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
ts-api-utils: 1.4.3(typescript@5.3.3)
optionalDependencies:
typescript: 5.3.3
@@ -33073,15 +33046,15 @@ snapshots:
- supports-color
- typescript
- '@typescript-eslint/utils@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/utils@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1))
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
'@types/json-schema': 7.0.15
'@types/semver': 7.7.1
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
semver: 7.7.3
transitivePeerDependencies:
- supports-color
@@ -33112,13 +33085,13 @@ snapshots:
- supports-color
- typescript
- '@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
+ '@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1))
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
transitivePeerDependencies:
- supports-color
- typescript
@@ -34017,108 +33990,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1):
- dependencies:
- '@astrojs/compiler': 2.13.0
- '@astrojs/internal-helpers': 0.7.5
- '@astrojs/markdown-remark': 6.3.9
- '@astrojs/telemetry': 3.3.0
- '@capsizecss/unpack': 3.0.1
- '@oslojs/encoding': 1.1.0
- '@rollup/pluginutils': 5.3.0(rollup@4.53.3)
- acorn: 8.15.0
- aria-query: 5.3.2
- axobject-query: 4.1.0
- boxen: 8.0.1
- ci-info: 4.3.1
- clsx: 2.1.1
- common-ancestor-path: 1.0.1
- cookie: 1.1.0
- cssesc: 3.0.0
- debug: 4.4.3
- deterministic-object-hash: 2.0.2
- devalue: 5.5.0
- diff: 5.2.0
- dlv: 1.1.3
- dset: 3.1.4
- es-module-lexer: 1.7.0
- esbuild: 0.25.12
- estree-walker: 3.0.3
- flattie: 1.1.1
- fontace: 0.3.1
- github-slugger: 2.0.0
- html-escaper: 3.0.3
- http-cache-semantics: 4.2.0
- import-meta-resolve: 4.2.0
- js-yaml: 4.1.1
- magic-string: 0.30.21
- magicast: 0.5.1
- mrmime: 2.0.1
- neotraverse: 0.6.18
- p-limit: 6.2.0
- p-queue: 8.1.1
- package-manager-detector: 1.5.0
- piccolore: 0.1.3
- picomatch: 4.0.3
- prompts: 2.4.2
- rehype: 13.0.2
- semver: 7.7.3
- shiki: 3.15.0
- smol-toml: 1.5.2
- svgo: 4.0.0
- tinyexec: 1.0.2
- tinyglobby: 0.2.15
- tsconfck: 3.1.6(typescript@5.9.3)
- ultrahtml: 1.6.0
- unifont: 0.6.0
- unist-util-visit: 5.0.0
- unstorage: 1.17.3(@netlify/blobs@10.4.1)(ioredis@5.9.2)
- vfile: 6.0.3
- vite: 6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
- vitefu: 1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))
- xxhash-wasm: 1.1.0
- yargs-parser: 21.1.1
- yocto-spinner: 0.2.3
- zod: 3.25.76
- zod-to-json-schema: 3.25.0(zod@3.25.76)
- zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76)
- optionalDependencies:
- sharp: 0.34.5
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@types/node'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/functions'
- - '@vercel/kv'
- - aws4fetch
- - db0
- - idb-keyval
- - ioredis
- - jiti
- - less
- - lightningcss
- - rollup
- - sass
- - sass-embedded
- - stylus
- - sugarss
- - supports-color
- - terser
- - tsx
- - typescript
- - uploadthing
- - yaml
-
astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1):
dependencies:
'@astrojs/compiler': 2.13.0
@@ -35405,13 +35276,13 @@ snapshots:
- supports-color
- ts-node
- create-jest@29.7.0(@types/node@24.10.1):
+ create-jest@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)):
dependencies:
'@jest/types': 29.6.3
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
- jest-config: 29.7.0(@types/node@24.10.1)
+ jest-config: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@@ -36515,11 +36386,6 @@ snapshots:
escape-string-regexp@5.0.0: {}
- eslint-compat-utils@0.6.5(eslint@9.39.1(jiti@1.21.7)):
- dependencies:
- eslint: 9.39.1(jiti@1.21.7)
- semver: 7.7.3
-
eslint-compat-utils@0.6.5(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@@ -36530,9 +36396,9 @@ snapshots:
'@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.1(jiti@2.6.1)
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-expo: 1.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1(jiti@2.6.1))
globals: 16.5.0
@@ -36547,9 +36413,9 @@ snapshots:
'@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
eslint: 9.39.1(jiti@2.6.1)
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-expo: 0.1.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1(jiti@2.6.1))
globals: 16.5.0
@@ -36567,14 +36433,14 @@ snapshots:
dependencies:
eslint: 8.57.1
+ eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)):
+ dependencies:
+ eslint: 9.39.1(jiti@1.21.7)
+
eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
- eslint-config-prettier@9.1.2(eslint@9.39.1(jiti@1.21.7)):
- dependencies:
- eslint: 9.39.1(jiti@1.21.7)
-
eslint-config-prettier@9.1.2(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@@ -36599,17 +36465,17 @@ snapshots:
- supports-color
- typescript
- eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)(typescript@5.3.3):
+ eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)(typescript@5.3.3):
dependencies:
- '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
- '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
- eslint: 9.39.1(jiti@2.6.1)
- eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@2.6.1))
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))
- eslint-plugin-node: 11.1.0(eslint@9.39.1(jiti@2.6.1))
- eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)
- eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1))
- eslint-plugin-react-hooks: 4.6.2(eslint@9.39.1(jiti@2.6.1))
+ '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
+ '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
+ eslint: 9.39.1(jiti@1.21.7)
+ eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@1.21.7))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))
+ eslint-plugin-node: 11.1.0(eslint@9.39.1(jiti@1.21.7))
+ eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)))(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)
+ eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@1.21.7))
+ eslint-plugin-react-hooks: 4.6.2(eslint@9.39.1(jiti@1.21.7))
optionalDependencies:
prettier: 3.6.2
transitivePeerDependencies:
@@ -36647,7 +36513,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
+ eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.3
@@ -36658,22 +36524,7 @@ snapshots:
tinyglobby: 0.2.15
unrs-resolver: 1.11.1
optionalDependencies:
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
- transitivePeerDependencies:
- - supports-color
-
- eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
- dependencies:
- '@nolyfill/is-core-module': 1.0.39
- debug: 4.4.3
- eslint: 9.39.1(jiti@2.6.1)
- get-tsconfig: 4.13.0
- is-bun-module: 2.0.0
- stable-hash: 0.0.5
- tinyglobby: 0.2.15
- unrs-resolver: 1.11.1
- optionalDependencies:
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
@@ -36687,12 +36538,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1)):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@1.21.7)):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
- eslint: 9.39.1(jiti@2.6.1)
+ '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
+ eslint: 9.39.1(jiti@1.21.7)
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
@@ -36707,39 +36558,25 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
- transitivePeerDependencies:
- - supports-color
-
- eslint-plugin-astro@1.5.0(eslint@9.39.1(jiti@1.21.7)):
- dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
- '@jridgewell/sourcemap-codec': 1.5.5
- '@typescript-eslint/types': 8.48.0
- astro-eslint-parser: 1.2.2
- eslint: 9.39.1(jiti@1.21.7)
- eslint-compat-utils: 0.6.5(eslint@9.39.1(jiti@1.21.7))
- globals: 16.5.0
- postcss: 8.5.6
- postcss-selector-parser: 7.1.0
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
@@ -36763,6 +36600,12 @@ snapshots:
eslint-utils: 2.1.0
regexpp: 3.2.0
+ eslint-plugin-es@3.0.1(eslint@9.39.1(jiti@1.21.7)):
+ dependencies:
+ eslint: 9.39.1(jiti@1.21.7)
+ eslint-utils: 2.1.0
+ regexpp: 3.2.0
+
eslint-plugin-es@3.0.1(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@@ -36816,7 +36659,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1)):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -36825,9 +36668,9 @@ snapshots:
array.prototype.flatmap: 1.3.3
debug: 3.2.7
doctrine: 2.1.0
- eslint: 9.39.1(jiti@2.6.1)
+ eslint: 9.39.1(jiti@1.21.7)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1))
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@1.21.7))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -36839,7 +36682,7 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
+ '@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -36874,7 +36717,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -36885,7 +36728,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -36903,7 +36746,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -36914,7 +36757,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -36942,6 +36785,16 @@ snapshots:
resolve: 1.22.11
semver: 6.3.1
+ eslint-plugin-node@11.1.0(eslint@9.39.1(jiti@1.21.7)):
+ dependencies:
+ eslint: 9.39.1(jiti@1.21.7)
+ eslint-plugin-es: 3.0.1(eslint@9.39.1(jiti@1.21.7))
+ eslint-utils: 2.1.0
+ ignore: 5.3.2
+ minimatch: 3.1.2
+ resolve: 1.22.11
+ semver: 6.3.1
+
eslint-plugin-node@11.1.0(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@@ -36972,6 +36825,16 @@ snapshots:
'@types/eslint': 9.6.1
eslint-config-prettier: 8.10.2(eslint@8.57.1)
+ eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)))(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2):
+ dependencies:
+ eslint: 9.39.1(jiti@1.21.7)
+ prettier: 3.6.2
+ prettier-linter-helpers: 1.0.0
+ synckit: 0.11.11
+ optionalDependencies:
+ '@types/eslint': 9.6.1
+ eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@1.21.7))
+
eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@@ -36996,6 +36859,10 @@ snapshots:
dependencies:
eslint: 8.57.1
+ eslint-plugin-react-hooks@4.6.2(eslint@9.39.1(jiti@1.21.7)):
+ dependencies:
+ eslint: 9.39.1(jiti@1.21.7)
+
eslint-plugin-react-hooks@4.6.2(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@@ -37026,6 +36893,28 @@ snapshots:
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
+ eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@1.21.7)):
+ dependencies:
+ array-includes: 3.1.9
+ array.prototype.findlast: 1.2.5
+ array.prototype.flatmap: 1.3.3
+ array.prototype.tosorted: 1.1.4
+ doctrine: 2.1.0
+ es-iterator-helpers: 1.2.1
+ eslint: 9.39.1(jiti@1.21.7)
+ estraverse: 5.3.0
+ hasown: 2.0.2
+ jsx-ast-utils: 3.3.5
+ minimatch: 3.1.2
+ object.entries: 1.1.9
+ object.fromentries: 2.0.8
+ object.values: 1.2.1
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.5
+ semver: 6.3.1
+ string.prototype.matchall: 4.0.12
+ string.prototype.repeat: 1.0.0
+
eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@2.6.1)):
dependencies:
array-includes: 3.1.9
@@ -38168,53 +38057,6 @@ snapshots:
- react-native
- supports-color
- expo-router@6.0.15(7mqaurqidri6vkknnsci36yp4e):
- dependencies:
- '@expo/metro-runtime': 6.1.2(expo@54.0.25)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- '@expo/schema-utils': 0.1.7
- '@radix-ui/react-slot': 1.2.0(@types/react@19.2.7)(react@19.1.0)
- '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
- '@react-navigation/bottom-tabs': 7.8.6(@react-navigation/native@7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- '@react-navigation/native': 7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- '@react-navigation/native-stack': 7.8.0(@react-navigation/native@7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- client-only: 0.0.1
- debug: 4.4.3
- escape-string-regexp: 4.0.0
- expo: 54.0.25(@babel/core@7.28.5)(@expo/metro-runtime@6.1.2)(expo-router@6.0.15)(react-native-webview@13.12.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- expo-constants: 18.0.10(expo@54.0.25)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))
- expo-linking: 8.0.9(expo@54.0.25)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- expo-server: 1.0.4
- fast-deep-equal: 3.1.3
- invariant: 2.2.4
- nanoid: 3.3.11
- query-string: 7.1.3
- react: 19.1.0
- react-fast-compare: 3.2.2
- react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0)
- react-native-is-edge-to-edge: 1.2.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- react-native-safe-area-context: 5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- react-native-screens: 4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- semver: 7.6.3
- server-only: 0.0.1
- sf-symbols-typescript: 2.1.0
- shallowequal: 1.1.0
- use-latest-callback: 0.2.6(react@19.1.0)
- vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
- optionalDependencies:
- '@react-navigation/drawer': 7.7.4(@react-navigation/native@7.1.21(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-gesture-handler@2.28.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-reanimated@4.1.5(@babel/core@7.28.5)(react-native-worklets@0.6.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- '@testing-library/react-native': 13.3.3(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react-test-renderer@19.1.0(react@19.1.0))(react@19.1.0)
- react-dom: 19.1.0(react@19.1.0)
- react-native-gesture-handler: 2.28.0(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- react-native-reanimated: 4.1.5(@babel/core@7.28.5)(react-native-worklets@0.6.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0)
- react-native-web: 0.21.2(encoding@0.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
- react-server-dom-webpack: 19.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(webpack@5.97.1(esbuild@0.19.12))
- transitivePeerDependencies:
- - '@react-native-masked-view/masked-view'
- - '@types/react'
- - '@types/react-dom'
- - supports-color
- optional: true
-
expo-router@6.0.15(k2muy65dii4k2uiuhg4mwyy6ki):
dependencies:
'@expo/metro-runtime': 6.1.2(expo@54.0.25)(react-dom@19.1.0(react@18.3.1))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)
@@ -39337,23 +39179,6 @@ snapshots:
forever-agent@0.6.1: {}
- fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.19.12)):
- dependencies:
- '@babel/code-frame': 7.27.1
- chalk: 4.1.2
- chokidar: 3.6.0
- cosmiconfig: 8.3.6(typescript@5.7.2)
- deepmerge: 4.3.1
- fs-extra: 10.1.0
- memfs: 3.5.3
- minimatch: 3.1.2
- node-abort-controller: 3.1.1
- schema-utils: 3.3.0
- semver: 7.7.3
- tapable: 2.3.0
- typescript: 5.7.2
- webpack: 5.97.1(esbuild@0.19.12)
-
fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.27.0)):
dependencies:
'@babel/code-frame': 7.27.1
@@ -40809,16 +40634,16 @@ snapshots:
- supports-color
- ts-node
- jest-cli@29.7.0(@types/node@24.10.1):
+ jest-cli@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)):
dependencies:
- '@jest/core': 29.7.0
+ '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
- create-jest: 29.7.0(@types/node@24.10.1)
+ create-jest: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
exit: 0.1.2
import-local: 3.2.0
- jest-config: 29.7.0(@types/node@24.10.1)
+ jest-config: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@@ -40906,36 +40731,6 @@ snapshots:
- ts-node
optional: true
- jest-config@29.7.0(@types/node@22.19.1):
- dependencies:
- '@babel/core': 7.28.5
- '@jest/test-sequencer': 29.7.0
- '@jest/types': 29.6.3
- babel-jest: 29.7.0(@babel/core@7.28.5)
- chalk: 4.1.2
- ci-info: 3.9.0
- deepmerge: 4.3.1
- glob: 7.2.3
- graceful-fs: 4.2.11
- jest-circus: 29.7.0
- jest-environment-node: 29.7.0
- jest-get-type: 29.6.3
- jest-regex-util: 29.6.3
- jest-resolve: 29.7.0
- jest-runner: 29.7.0
- jest-util: 29.7.0
- jest-validate: 29.7.0
- micromatch: 4.0.8
- parse-json: 5.2.0
- pretty-format: 29.7.0
- slash: 3.0.0
- strip-json-comments: 3.1.1
- optionalDependencies:
- '@types/node': 22.19.1
- transitivePeerDependencies:
- - babel-plugin-macros
- - supports-color
-
jest-config@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)):
dependencies:
'@babel/core': 7.28.5
@@ -40967,7 +40762,38 @@ snapshots:
- babel-plugin-macros
- supports-color
- jest-config@29.7.0(@types/node@24.10.1):
+ jest-config@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)):
+ dependencies:
+ '@babel/core': 7.28.5
+ '@jest/test-sequencer': 29.7.0
+ '@jest/types': 29.6.3
+ babel-jest: 29.7.0(@babel/core@7.28.5)
+ chalk: 4.1.2
+ ci-info: 3.9.0
+ deepmerge: 4.3.1
+ glob: 7.2.3
+ graceful-fs: 4.2.11
+ jest-circus: 29.7.0
+ jest-environment-node: 29.7.0
+ jest-get-type: 29.6.3
+ jest-regex-util: 29.6.3
+ jest-resolve: 29.7.0
+ jest-runner: 29.7.0
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ micromatch: 4.0.8
+ parse-json: 5.2.0
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ strip-json-comments: 3.1.1
+ optionalDependencies:
+ '@types/node': 22.19.1
+ ts-node: 10.9.2(@types/node@24.10.1)(typescript@5.9.3)
+ transitivePeerDependencies:
+ - babel-plugin-macros
+ - supports-color
+
+ jest-config@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)):
dependencies:
'@babel/core': 7.28.5
'@jest/test-sequencer': 29.7.0
@@ -40993,6 +40819,7 @@ snapshots:
strip-json-comments: 3.1.1
optionalDependencies:
'@types/node': 24.10.1
+ ts-node: 10.9.2(@types/node@24.10.1)(typescript@5.9.3)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
@@ -41579,12 +41406,12 @@ snapshots:
- supports-color
- ts-node
- jest@29.7.0(@types/node@24.10.1):
+ jest@29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3)):
dependencies:
- '@jest/core': 29.7.0
+ '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
'@jest/types': 29.6.3
import-local: 3.2.0
- jest-cli: 29.7.0(@types/node@24.10.1)
+ jest-cli: 29.7.0(@types/node@24.10.1)(ts-node@10.9.2(@types/node@24.10.1)(typescript@5.9.3))
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -45958,16 +45785,6 @@ snapshots:
webpack-sources: 3.3.3
optional: true
- react-server-dom-webpack@19.0.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(webpack@5.97.1(esbuild@0.19.12)):
- dependencies:
- acorn-loose: 8.5.2
- neo-async: 2.6.2
- react: 19.1.0
- react-dom: 19.1.0(react@19.1.0)
- webpack: 5.97.1(esbuild@0.19.12)
- webpack-sources: 3.3.3
- optional: true
-
react-style-singleton@2.2.3(@types/react@18.3.27)(react@18.3.1):
dependencies:
get-nonce: 1.0.1
@@ -47429,17 +47246,6 @@ snapshots:
ansi-escapes: 4.3.2
supports-hyperlinks: 2.3.0
- terser-webpack-plugin@5.3.14(esbuild@0.19.12)(webpack@5.97.1(esbuild@0.19.12)):
- dependencies:
- '@jridgewell/trace-mapping': 0.3.31
- jest-worker: 27.5.1
- schema-utils: 4.3.3
- serialize-javascript: 6.0.2
- terser: 5.44.1
- webpack: 5.97.1(esbuild@0.19.12)
- optionalDependencies:
- esbuild: 0.19.12
-
terser-webpack-plugin@5.3.14(esbuild@0.27.0)(webpack@5.100.2(esbuild@0.27.0)):
dependencies:
'@jridgewell/trace-mapping': 0.3.31
@@ -47640,27 +47446,6 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.19.12)(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3):
- dependencies:
- bs-logger: 0.2.6
- fast-json-stable-stringify: 2.1.0
- handlebars: 4.7.8
- jest: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
- json5: 2.2.3
- lodash.memoize: 4.1.2
- make-error: 1.3.6
- semver: 7.7.3
- type-fest: 4.41.0
- typescript: 5.9.3
- yargs-parser: 21.1.1
- optionalDependencies:
- '@babel/core': 7.28.5
- '@jest/transform': 30.2.0
- '@jest/types': 30.2.0
- babel-jest: 30.2.0(@babel/core@7.28.5)
- esbuild: 0.19.12
- jest-util: 30.2.0
-
ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.27.0)(jest-util@30.2.0)(jest@30.2.0(@types/node@22.19.1)(esbuild-register@3.6.0(esbuild@0.27.0))(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3):
dependencies:
bs-logger: 0.2.6
@@ -47703,6 +47488,26 @@ snapshots:
esbuild: 0.27.0
jest-util: 30.2.0
+ ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3)))(typescript@5.9.3):
+ dependencies:
+ bs-logger: 0.2.6
+ fast-json-stable-stringify: 2.1.0
+ handlebars: 4.7.8
+ jest: 29.7.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3))
+ json5: 2.2.3
+ lodash.memoize: 4.1.2
+ make-error: 1.3.6
+ semver: 7.7.3
+ type-fest: 4.41.0
+ typescript: 5.9.3
+ yargs-parser: 21.1.1
+ optionalDependencies:
+ '@babel/core': 7.28.5
+ '@jest/transform': 30.2.0
+ '@jest/types': 30.2.0
+ babel-jest: 30.2.0(@babel/core@7.28.5)
+ jest-util: 30.2.0
+
ts-loader@9.5.4(typescript@5.9.3)(webpack@5.100.2(esbuild@0.27.0)):
dependencies:
chalk: 4.1.2
@@ -47723,16 +47528,6 @@ snapshots:
typescript: 5.9.3
webpack: 5.100.2
- ts-loader@9.5.4(typescript@5.9.3)(webpack@5.97.1(esbuild@0.19.12)):
- dependencies:
- chalk: 4.1.2
- enhanced-resolve: 5.18.3
- micromatch: 4.0.8
- semver: 7.7.3
- source-map: 0.7.6
- typescript: 5.9.3
- webpack: 5.97.1(esbuild@0.19.12)
-
ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
@@ -48413,23 +48208,6 @@ snapshots:
lightningcss: 1.30.2
terser: 5.44.1
- vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1):
- dependencies:
- esbuild: 0.25.12
- fdir: 6.5.0(picomatch@4.0.3)
- picomatch: 4.0.3
- postcss: 8.5.6
- rollup: 4.53.3
- tinyglobby: 0.2.15
- optionalDependencies:
- '@types/node': 20.19.25
- fsevents: 2.3.3
- jiti: 1.21.7
- lightningcss: 1.30.2
- terser: 5.44.1
- tsx: 4.20.6
- yaml: 2.8.1
-
vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1):
dependencies:
esbuild: 0.25.12
@@ -48533,10 +48311,6 @@ snapshots:
tsx: 4.20.6
yaml: 2.8.1
- vitefu@1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)):
- optionalDependencies:
- vite: 6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
-
vitefu@1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)):
optionalDependencies:
vite: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
@@ -48991,36 +48765,6 @@ snapshots:
- esbuild
- uglify-js
- webpack@5.97.1(esbuild@0.19.12):
- dependencies:
- '@types/eslint-scope': 3.7.7
- '@types/estree': 1.0.8
- '@webassemblyjs/ast': 1.14.1
- '@webassemblyjs/wasm-edit': 1.14.1
- '@webassemblyjs/wasm-parser': 1.14.1
- acorn: 8.15.0
- browserslist: 4.28.0
- chrome-trace-event: 1.0.4
- enhanced-resolve: 5.18.3
- es-module-lexer: 1.7.0
- eslint-scope: 5.1.1
- events: 3.3.0
- glob-to-regexp: 0.4.1
- graceful-fs: 4.2.11
- json-parse-even-better-errors: 2.3.1
- loader-runner: 4.3.1
- mime-types: 2.1.35
- neo-async: 2.6.2
- schema-utils: 3.3.0
- tapable: 2.3.0
- terser-webpack-plugin: 5.3.14(esbuild@0.19.12)(webpack@5.97.1(esbuild@0.19.12))
- watchpack: 2.4.4
- webpack-sources: 3.3.3
- transitivePeerDependencies:
- - '@swc/core'
- - esbuild
- - uglify-js
-
webpack@5.97.1(esbuild@0.27.0):
dependencies:
'@types/eslint-scope': 3.7.7