From 25383ea6451f538db7859916af2012d876089374 Mon Sep 17 00:00:00 2001 From: Jarvis Date: Thu, 2 Apr 2026 20:51:13 -0500 Subject: [PATCH] feat(storage): implement SQLite adapter with better-sqlite3 Co-Authored-By: Claude Opus 4.6 --- packages/storage/package.json | 4 +- packages/storage/src/adapters/sqlite.test.ts | 201 +++++++++++++ packages/storage/src/adapters/sqlite.ts | 283 ++++++++++++++++++ packages/storage/src/index.ts | 6 + pnpm-lock.yaml | 289 ++++++++++++++++++- 5 files changed, 768 insertions(+), 15 deletions(-) create mode 100644 packages/storage/src/adapters/sqlite.test.ts create mode 100644 packages/storage/src/adapters/sqlite.ts diff --git a/packages/storage/package.json b/packages/storage/package.json index 36d1661..b525008 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -17,9 +17,11 @@ }, "dependencies": { "@mosaic/db": "workspace:^", - "@mosaic/types": "workspace:*" + "@mosaic/types": "workspace:*", + "better-sqlite3": "^12.8.0" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.13", "typescript": "^5.8.0", "vitest": "^2.0.0" }, diff --git a/packages/storage/src/adapters/sqlite.test.ts b/packages/storage/src/adapters/sqlite.test.ts new file mode 100644 index 0000000..85f524b --- /dev/null +++ b/packages/storage/src/adapters/sqlite.test.ts @@ -0,0 +1,201 @@ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { SqliteAdapter } from './sqlite.js'; + +describe('SqliteAdapter', () => { + let adapter: SqliteAdapter; + + beforeEach(async () => { + adapter = new SqliteAdapter({ type: 'sqlite', path: ':memory:' }); + await adapter.migrate(); + }); + + afterEach(async () => { + await adapter.close(); + }); + + describe('CRUD', () => { + it('creates and reads a record', async () => { + const created = await adapter.create('users', { name: 'Alice', email: 'alice@test.com' }); + expect(created.id).toBeDefined(); + expect(created.name).toBe('Alice'); + + const read = await adapter.read('users', created.id); + expect(read).not.toBeNull(); + expect(read!.name).toBe('Alice'); + expect(read!.email).toBe('alice@test.com'); + }); + + it('returns null for non-existent record', async () => { + const result = await adapter.read('users', 'does-not-exist'); + expect(result).toBeNull(); + }); + + it('updates a record', async () => { + const created = await adapter.create('users', { name: 'Alice' }); + const updated = await adapter.update('users', created.id, { name: 'Bob' }); + expect(updated).toBe(true); + + const read = await adapter.read('users', created.id); + expect(read!.name).toBe('Bob'); + }); + + it('update returns false for non-existent record', async () => { + const result = await adapter.update('users', 'does-not-exist', { name: 'X' }); + expect(result).toBe(false); + }); + + it('deletes a record', async () => { + const created = await adapter.create('users', { name: 'Alice' }); + const deleted = await adapter.delete('users', created.id); + expect(deleted).toBe(true); + + const read = await adapter.read('users', created.id); + expect(read).toBeNull(); + }); + + it('delete returns false for non-existent record', async () => { + const result = await adapter.delete('users', 'does-not-exist'); + expect(result).toBe(false); + }); + }); + + describe('find', () => { + it('finds records with filter', async () => { + await adapter.create('users', { name: 'Alice', role: 'admin' }); + await adapter.create('users', { name: 'Bob', role: 'user' }); + await adapter.create('users', { name: 'Charlie', role: 'admin' }); + + const admins = await adapter.find('users', { role: 'admin' }); + expect(admins).toHaveLength(2); + expect(admins.map((u) => u.name).sort()).toEqual(['Alice', 'Charlie']); + }); + + it('finds all records without filter', async () => { + await adapter.create('users', { name: 'Alice' }); + await adapter.create('users', { name: 'Bob' }); + + const all = await adapter.find('users'); + expect(all).toHaveLength(2); + }); + + it('supports limit and offset', async () => { + for (let i = 0; i < 5; i++) { + await adapter.create('users', { name: `User${i}`, idx: i }); + } + + const page = await adapter.find('users', undefined, { + limit: 2, + offset: 1, + orderBy: 'created_at', + }); + expect(page).toHaveLength(2); + }); + + it('findOne returns first match', async () => { + await adapter.create('users', { name: 'Alice', role: 'admin' }); + await adapter.create('users', { name: 'Bob', role: 'user' }); + + const found = await adapter.findOne('users', { role: 'user' }); + expect(found).not.toBeNull(); + expect(found!.name).toBe('Bob'); + }); + + it('findOne returns null when no match', async () => { + const result = await adapter.findOne('users', { role: 'nonexistent' }); + expect(result).toBeNull(); + }); + }); + + describe('count', () => { + it('counts all records', async () => { + await adapter.create('users', { name: 'Alice' }); + await adapter.create('users', { name: 'Bob' }); + + const total = await adapter.count('users'); + expect(total).toBe(2); + }); + + it('counts with filter', async () => { + await adapter.create('users', { name: 'Alice', role: 'admin' }); + await adapter.create('users', { name: 'Bob', role: 'user' }); + await adapter.create('users', { name: 'Charlie', role: 'admin' }); + + const adminCount = await adapter.count('users', { role: 'admin' }); + expect(adminCount).toBe(2); + }); + + it('returns 0 for empty collection', async () => { + const count = await adapter.count('users'); + expect(count).toBe(0); + }); + }); + + describe('transaction', () => { + it('commits on success', async () => { + await adapter.transaction(async (tx) => { + await tx.create('users', { name: 'Alice' }); + await tx.create('users', { name: 'Bob' }); + }); + + const count = await adapter.count('users'); + expect(count).toBe(2); + }); + + it('rolls back on error', async () => { + await expect( + adapter.transaction(async (tx) => { + await tx.create('users', { name: 'Alice' }); + throw new Error('rollback test'); + }), + ).rejects.toThrow('rollback test'); + + const count = await adapter.count('users'); + expect(count).toBe(0); + }); + }); + + describe('migrate', () => { + it('creates all tables', async () => { + // migrate() was already called in beforeEach — verify tables exist + const collections = [ + 'users', + 'sessions', + 'accounts', + 'projects', + 'missions', + 'tasks', + 'agents', + 'conversations', + 'messages', + 'preferences', + 'insights', + 'skills', + 'events', + 'routing_rules', + 'provider_credentials', + 'agent_logs', + 'teams', + 'team_members', + 'mission_tasks', + 'tickets', + 'summarization_jobs', + 'appreciations', + 'verifications', + ]; + + for (const collection of collections) { + // Should not throw + const count = await adapter.count(collection); + expect(count).toBe(0); + } + }); + + it('is idempotent', async () => { + await adapter.migrate(); + await adapter.migrate(); + // Should not throw + const count = await adapter.count('users'); + expect(count).toBe(0); + }); + }); +}); diff --git a/packages/storage/src/adapters/sqlite.ts b/packages/storage/src/adapters/sqlite.ts new file mode 100644 index 0000000..e6752d8 --- /dev/null +++ b/packages/storage/src/adapters/sqlite.ts @@ -0,0 +1,283 @@ +import Database from 'better-sqlite3'; +import { randomUUID } from 'node:crypto'; +import type { StorageAdapter, StorageConfig } from '../types.js'; + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +const COLLECTIONS = [ + 'users', + 'sessions', + 'accounts', + 'projects', + 'missions', + 'tasks', + 'agents', + 'conversations', + 'messages', + 'preferences', + 'insights', + 'skills', + 'events', + 'routing_rules', + 'provider_credentials', + 'agent_logs', + 'teams', + 'team_members', + 'mission_tasks', + 'tickets', + 'summarization_jobs', + 'appreciations', + 'verifications', +] as const; + +function buildFilterClause(filter?: Record): { + clause: string; + params: unknown[]; +} { + if (!filter || Object.keys(filter).length === 0) return { clause: '', params: [] }; + const conditions: string[] = []; + const params: unknown[] = []; + for (const [key, value] of Object.entries(filter)) { + if (key === 'id') { + conditions.push('id = ?'); + params.push(value); + } else { + conditions.push(`json_extract(data_json, '$.${key}') = ?`); + params.push(typeof value === 'object' ? JSON.stringify(value) : value); + } + } + return { clause: ` WHERE ${conditions.join(' AND ')}`, params }; +} + +export class SqliteAdapter implements StorageAdapter { + readonly name = 'sqlite'; + private db: Database.Database; + + constructor(config: Extract) { + this.db = new Database(config.path); + this.db.pragma('journal_mode = WAL'); + this.db.pragma('foreign_keys = ON'); + } + + async create>( + collection: string, + data: T, + ): Promise { + const id = (data as any).id ?? randomUUID(); + const now = new Date().toISOString(); + const rest = Object.fromEntries(Object.entries(data).filter(([k]) => k !== 'id')); + this.db + .prepare( + `INSERT INTO ${collection} (id, data_json, created_at, updated_at) VALUES (?, ?, ?, ?)`, + ) + .run(id, JSON.stringify(rest), now, now); + return { ...data, id } as T & { id: string }; + } + + async read>(collection: string, id: string): Promise { + const row = this.db.prepare(`SELECT * FROM ${collection} WHERE id = ?`).get(id) as any; + if (!row) return null; + return { id: row.id, ...JSON.parse(row.data_json as string) } as T; + } + + async update(collection: string, id: string, data: Record): Promise { + const existing = this.db + .prepare(`SELECT data_json FROM ${collection} WHERE id = ?`) + .get(id) as any; + if (!existing) return false; + const merged = { ...JSON.parse(existing.data_json as string), ...data }; + const now = new Date().toISOString(); + const result = this.db + .prepare(`UPDATE ${collection} SET data_json = ?, updated_at = ? WHERE id = ?`) + .run(JSON.stringify(merged), now, id); + return result.changes > 0; + } + + async delete(collection: string, id: string): Promise { + const result = this.db.prepare(`DELETE FROM ${collection} WHERE id = ?`).run(id); + return result.changes > 0; + } + + async find>( + collection: string, + filter?: Record, + opts?: { limit?: number; offset?: number; orderBy?: string; order?: 'asc' | 'desc' }, + ): Promise { + const { clause, params } = buildFilterClause(filter); + let query = `SELECT * FROM ${collection}${clause}`; + if (opts?.orderBy) { + const dir = opts.order === 'desc' ? 'DESC' : 'ASC'; + const col = + opts.orderBy === 'id' || opts.orderBy === 'created_at' || opts.orderBy === 'updated_at' + ? opts.orderBy + : `json_extract(data_json, '$.${opts.orderBy}')`; + query += ` ORDER BY ${col} ${dir}`; + } + if (opts?.limit) { + query += ` LIMIT ?`; + params.push(opts.limit); + } + if (opts?.offset) { + query += ` OFFSET ?`; + params.push(opts.offset); + } + const rows = this.db.prepare(query).all(...params) as any[]; + return rows.map((row) => ({ id: row.id, ...JSON.parse(row.data_json as string) }) as T); + } + + async findOne>( + collection: string, + filter: Record, + ): Promise { + const results = await this.find(collection, filter, { limit: 1 }); + return results[0] ?? null; + } + + async count(collection: string, filter?: Record): Promise { + const { clause, params } = buildFilterClause(filter); + const row = this.db + .prepare(`SELECT COUNT(*) as count FROM ${collection}${clause}`) + .get(...params) as any; + return row?.count ?? 0; + } + + async transaction(fn: (tx: StorageAdapter) => Promise): Promise { + const txAdapter = new SqliteTxAdapter(this.db); + this.db.exec('BEGIN'); + try { + const result = await fn(txAdapter); + this.db.exec('COMMIT'); + return result; + } catch (err) { + this.db.exec('ROLLBACK'); + throw err; + } + } + + async migrate(): Promise { + const createTable = (name: string) => + this.db.exec(` + CREATE TABLE IF NOT EXISTS ${name} ( + id TEXT PRIMARY KEY, + data_json TEXT NOT NULL DEFAULT '{}', + created_at TEXT NOT NULL DEFAULT (datetime('now')), + updated_at TEXT NOT NULL DEFAULT (datetime('now')) + ) + `); + for (const collection of COLLECTIONS) { + createTable(collection); + } + } + + async close(): Promise { + this.db.close(); + } +} + +/** + * Transaction wrapper that uses the same db handle — better-sqlite3 transactions + * are connection-level, so all statements on the same Database instance within + * a db.transaction() callback participate in the transaction. + */ +class SqliteTxAdapter implements StorageAdapter { + readonly name = 'sqlite'; + private db: Database.Database; + + constructor(db: Database.Database) { + this.db = db; + } + + async create>( + collection: string, + data: T, + ): Promise { + const id = (data as any).id ?? randomUUID(); + const now = new Date().toISOString(); + const rest = Object.fromEntries(Object.entries(data).filter(([k]) => k !== 'id')); + this.db + .prepare( + `INSERT INTO ${collection} (id, data_json, created_at, updated_at) VALUES (?, ?, ?, ?)`, + ) + .run(id, JSON.stringify(rest), now, now); + return { ...data, id } as T & { id: string }; + } + + async read>(collection: string, id: string): Promise { + const row = this.db.prepare(`SELECT * FROM ${collection} WHERE id = ?`).get(id) as any; + if (!row) return null; + return { id: row.id, ...JSON.parse(row.data_json as string) } as T; + } + + async update(collection: string, id: string, data: Record): Promise { + const existing = this.db + .prepare(`SELECT data_json FROM ${collection} WHERE id = ?`) + .get(id) as any; + if (!existing) return false; + const merged = { ...JSON.parse(existing.data_json as string), ...data }; + const now = new Date().toISOString(); + const result = this.db + .prepare(`UPDATE ${collection} SET data_json = ?, updated_at = ? WHERE id = ?`) + .run(JSON.stringify(merged), now, id); + return result.changes > 0; + } + + async delete(collection: string, id: string): Promise { + const result = this.db.prepare(`DELETE FROM ${collection} WHERE id = ?`).run(id); + return result.changes > 0; + } + + async find>( + collection: string, + filter?: Record, + opts?: { limit?: number; offset?: number; orderBy?: string; order?: 'asc' | 'desc' }, + ): Promise { + const { clause, params } = buildFilterClause(filter); + let query = `SELECT * FROM ${collection}${clause}`; + if (opts?.orderBy) { + const dir = opts.order === 'desc' ? 'DESC' : 'ASC'; + const col = + opts.orderBy === 'id' || opts.orderBy === 'created_at' || opts.orderBy === 'updated_at' + ? opts.orderBy + : `json_extract(data_json, '$.${opts.orderBy}')`; + query += ` ORDER BY ${col} ${dir}`; + } + if (opts?.limit) { + query += ` LIMIT ?`; + params.push(opts.limit); + } + if (opts?.offset) { + query += ` OFFSET ?`; + params.push(opts.offset); + } + const rows = this.db.prepare(query).all(...params) as any[]; + return rows.map((row) => ({ id: row.id, ...JSON.parse(row.data_json as string) }) as T); + } + + async findOne>( + collection: string, + filter: Record, + ): Promise { + const results = await this.find(collection, filter, { limit: 1 }); + return results[0] ?? null; + } + + async count(collection: string, filter?: Record): Promise { + const { clause, params } = buildFilterClause(filter); + const row = this.db + .prepare(`SELECT COUNT(*) as count FROM ${collection}${clause}`) + .get(...params) as any; + return row?.count ?? 0; + } + + async transaction(fn: (tx: StorageAdapter) => Promise): Promise { + return fn(this); + } + + async migrate(): Promise { + // No-op inside transaction + } + + async close(): Promise { + // No-op inside transaction + } +} diff --git a/packages/storage/src/index.ts b/packages/storage/src/index.ts index 6974b07..9c624ea 100644 --- a/packages/storage/src/index.ts +++ b/packages/storage/src/index.ts @@ -1,11 +1,17 @@ export type { StorageAdapter, StorageConfig } from './types.js'; export { createStorageAdapter, registerStorageAdapter } from './factory.js'; export { PostgresAdapter } from './adapters/postgres.js'; +export { SqliteAdapter } from './adapters/sqlite.js'; import { registerStorageAdapter } from './factory.js'; import { PostgresAdapter } from './adapters/postgres.js'; +import { SqliteAdapter } from './adapters/sqlite.js'; import type { StorageConfig } from './types.js'; registerStorageAdapter('postgres', (config: StorageConfig) => { return new PostgresAdapter(config as Extract); }); + +registerStorageAdapter('sqlite', (config: StorageConfig) => { + return new SqliteAdapter(config as Extract); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5588d4f..e23bb05 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -133,7 +133,7 @@ importers: version: 0.34.48 better-auth: specifier: ^1.5.5 - version: 1.5.5(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)) + version: 1.5.5(better-sqlite3@12.8.0)(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)) bullmq: specifier: ^5.71.0 version: 5.71.0 @@ -197,7 +197,7 @@ importers: version: link:../../packages/design-tokens better-auth: specifier: ^1.5.5 - version: 1.5.5(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)) + version: 1.5.5(better-sqlite3@12.8.0)(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)) clsx: specifier: ^2.1.0 version: 2.1.1 @@ -268,7 +268,7 @@ importers: version: link:../db better-auth: specifier: ^1.5.5 - version: 1.5.5(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)) + version: 1.5.5(better-sqlite3@12.8.0)(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)) devDependencies: '@types/node': specifier: ^22.0.0 @@ -371,7 +371,7 @@ importers: dependencies: drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8) + version: 0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8) postgres: specifier: ^3.4.8 version: 3.4.8 @@ -427,7 +427,7 @@ importers: version: link:../db drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8) + version: 0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8) devDependencies: typescript: specifier: ^5.8.0 @@ -461,7 +461,7 @@ importers: version: link:../types drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8) + version: 0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8) devDependencies: typescript: specifier: ^5.8.0 @@ -581,7 +581,13 @@ importers: '@mosaic/types': specifier: workspace:* version: link:../types + better-sqlite3: + specifier: ^12.8.0 + version: 12.8.0 devDependencies: + '@types/better-sqlite3': + specifier: ^7.6.13 + version: 7.6.13 typescript: specifier: ^5.8.0 version: 5.9.3 @@ -628,10 +634,10 @@ importers: dependencies: '@mariozechner/pi-agent-core': specifier: ^0.63.1 - version: 0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + version: 0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@3.25.76) '@mariozechner/pi-ai': specifier: ^0.63.1 - version: 0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + version: 0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@3.25.76) '@sinclair/typebox': specifier: ^0.34.41 version: 0.34.48 @@ -3418,6 +3424,9 @@ packages: '@types/aws-lambda@8.10.161': resolution: {integrity: sha512-rUYdp+MQwSFocxIOcSsYSF3YYYC/uUpMbCY/mbO21vGqfrEYvNSoPyKYDj6RhXXpPfS0KstW9RwG3qXh9sL7FQ==} + '@types/better-sqlite3@7.6.13': + resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} + '@types/bunyan@1.8.11': resolution: {integrity: sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==} @@ -3830,12 +3839,22 @@ packages: zod: optional: true + better-sqlite3@12.8.0: + resolution: {integrity: sha512-RxD2Vd96sQDjQr20kdP+F+dK/1OUNiVOl200vKBZY8u0vTwysfolF6Hq+3ZK2+h8My9YvZhHsF+RSGZW2VYrPQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + body-parser@2.2.2: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} @@ -3885,6 +3904,9 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bullmq@5.71.0: resolution: {integrity: sha512-aeNWh4drsafSKnAJeiNH/nZP/5O8ZdtdMbnOPZmpjXj7NZUP5YC901U3bIH41iZValm7d1i3c34ojv7q31m30w==} @@ -3946,6 +3968,9 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} @@ -4129,10 +4154,18 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -4505,6 +4538,10 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -4605,6 +4642,9 @@ packages: resolution: {integrity: sha512-cmBmnYo8Zymabm2+qAP7jTFbKF10bQpYmxoGfuZbRFRcq00BRddJdGNH/P7GA1EMpJy5yQbqa9B7yROb3z8Ziw==} engines: {node: '>=22'} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -4660,6 +4700,9 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -4724,6 +4767,9 @@ packages: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} engines: {node: '>= 14'} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} @@ -4883,6 +4929,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ink-spinner@5.0.0: resolution: {integrity: sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==} engines: {node: '>=14.16'} @@ -5450,6 +5499,10 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} @@ -5461,6 +5514,9 @@ packages: resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -5469,6 +5525,9 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} @@ -5529,6 +5588,9 @@ packages: resolution: {integrity: sha512-EYJqS25r2iBeTtGQCHidXl1VfZ1jXM7Q04zXJOrMlxVVmD0ptxJaNux92n1mJ7c5lN3zTq12MhH/8x59nP+qmg==} engines: {node: ^20.0.0 || >=22.0.0} + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -5565,6 +5627,10 @@ packages: sass: optional: true + node-abi@3.89.0: + resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} + engines: {node: '>=10'} + node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} @@ -5888,6 +5954,12 @@ packages: resolution: {integrity: sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==} engines: {node: '>=12'} + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -5961,6 +6033,10 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + react-dom@19.2.4: resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: @@ -5989,6 +6065,10 @@ packages: readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@5.0.0: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} @@ -6183,6 +6263,12 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -6324,6 +6410,10 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -6375,6 +6465,13 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + tar@7.5.13: resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} engines: {node: '>=18'} @@ -6489,6 +6586,9 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + turbo-darwin-64@2.8.16: resolution: {integrity: sha512-KWa4hUMWrpADC6Q/wIHRkBLw6X6MV9nx6X7hSXbTrrMz0KdaKhmfudUZ3sS76bJFmgArBU25cSc0AUyyrswYxg==} cpu: [x64] @@ -6899,6 +6999,12 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + '@anthropic-ai/sdk@0.73.0(zod@3.25.76)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 3.25.76 + '@anthropic-ai/sdk@0.73.0(zod@4.3.6)': dependencies: json-schema-to-ts: 3.1.1 @@ -7637,12 +7743,12 @@ snapshots: nanostores: 1.1.1 zod: 4.3.6 - '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8))': + '@better-auth/drizzle-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8))': dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1) '@better-auth/utils': 0.3.1 optionalDependencies: - drizzle-orm: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8) + drizzle-orm: 0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8) '@better-auth/kysely-adapter@1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(kysely@0.28.11)': dependencies: @@ -8483,6 +8589,18 @@ snapshots: - ws - zod + '@mariozechner/pi-agent-core@0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@3.25.76)': + dependencies: + '@mariozechner/pi-ai': 0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@3.25.76) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - aws-crt + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + '@mariozechner/pi-agent-core@0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: '@mariozechner/pi-ai': 0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) @@ -8543,6 +8661,30 @@ snapshots: - ws - zod + '@mariozechner/pi-ai@0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@3.25.76)': + dependencies: + '@anthropic-ai/sdk': 0.73.0(zod@3.25.76) + '@aws-sdk/client-bedrock-runtime': 3.1008.0 + '@google/genai': 1.45.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6)) + '@mistralai/mistralai': 1.14.1 + '@sinclair/typebox': 0.34.48 + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + chalk: 5.6.2 + openai: 6.26.0(ws@8.20.0)(zod@3.25.76) + partial-json: 0.1.7 + proxy-agent: 6.5.0 + undici: 7.24.3 + zod-to-json-schema: 3.25.1(zod@3.25.76) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - aws-crt + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + '@mariozechner/pi-ai@0.63.2(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: '@anthropic-ai/sdk': 0.73.0(zod@4.3.6) @@ -10193,6 +10335,10 @@ snapshots: '@types/aws-lambda@8.10.161': {} + '@types/better-sqlite3@7.6.13': + dependencies: + '@types/node': 22.19.15 + '@types/bunyan@1.8.11': dependencies: '@types/node': 22.19.15 @@ -10579,10 +10725,10 @@ snapshots: basic-ftp@5.2.0: {} - better-auth@1.5.5(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)): + better-auth@1.5.5(better-sqlite3@12.8.0)(drizzle-kit@0.31.9)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8))(mongodb@7.1.0(socks@2.8.7))(next@16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@2.1.9(@types/node@22.19.15)(jsdom@29.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)): dependencies: '@better-auth/core': 1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1) - '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8)) + '@better-auth/drizzle-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8)) '@better-auth/kysely-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(kysely@0.28.11) '@better-auth/memory-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1) '@better-auth/mongo-adapter': 1.5.5(@better-auth/core@1.5.5(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-call@1.3.2(zod@4.3.6))(jose@6.2.1)(kysely@0.28.11)(nanostores@1.1.1))(@better-auth/utils@0.3.1)(mongodb@7.1.0(socks@2.8.7)) @@ -10599,8 +10745,9 @@ snapshots: nanostores: 1.1.1 zod: 4.3.6 optionalDependencies: + better-sqlite3: 12.8.0 drizzle-kit: 0.31.9 - drizzle-orm: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8) + drizzle-orm: 0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8) mongodb: 7.1.0(socks@2.8.7) next: 16.1.6(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 @@ -10618,12 +10765,27 @@ snapshots: optionalDependencies: zod: 4.3.6 + better-sqlite3@12.8.0: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 bignumber.js@9.3.1: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + body-parser@2.2.2: dependencies: bytes: 3.1.2 @@ -10680,6 +10842,11 @@ snapshots: buffer-from@1.1.2: {} + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bullmq@5.71.0: dependencies: cron-parser: 4.9.0 @@ -10741,6 +10908,8 @@ snapshots: dependencies: readdirp: 5.0.0 + chownr@1.1.4: {} + chownr@3.0.0: {} cjs-module-lexer@2.2.0: {} @@ -10897,8 +11066,14 @@ snapshots: dependencies: character-entities: 2.0.2 + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + deep-eql@5.0.2: {} + deep-extend@0.6.0: {} + deep-is@0.1.4: {} defu@6.1.4: {} @@ -10979,10 +11154,12 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(kysely@0.28.11)(postgres@3.4.8): + drizzle-orm@0.45.1(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.8.0)(kysely@0.28.11)(postgres@3.4.8): optionalDependencies: '@opentelemetry/api': 1.9.0 + '@types/better-sqlite3': 7.6.13 '@types/pg': 8.15.6 + better-sqlite3: 12.8.0 kysely: 0.28.11 postgres: 3.4.8 @@ -11312,6 +11489,8 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + expand-template@2.0.3: {} + expect-type@1.3.0: {} express-rate-limit@8.3.1(express@5.2.1): @@ -11485,6 +11664,8 @@ snapshots: transitivePeerDependencies: - supports-color + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -11545,6 +11726,8 @@ snapshots: fresh@2.0.0: {} + fs-constants@1.0.0: {} + fsevents@2.3.2: optional: true @@ -11638,6 +11821,8 @@ snapshots: transitivePeerDependencies: - supports-color + github-from-package@0.0.0: {} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 @@ -11822,6 +12007,8 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + ink-spinner@5.0.0(ink@5.2.1(@types/react@18.3.28)(react@18.3.1))(react@18.3.1): dependencies: cli-spinners: 2.9.2 @@ -12530,6 +12717,8 @@ snapshots: mimic-function@5.0.1: {} + mimic-response@3.1.0: {} + minimatch@10.2.4: dependencies: brace-expansion: 5.0.4 @@ -12542,12 +12731,16 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimist@1.2.8: {} + minipass@7.1.3: {} minizlib@3.1.0: dependencies: minipass: 7.1.3 + mkdirp-classic@0.5.3: {} + module-details-from-path@1.0.4: {} mongodb-connection-string-url@7.0.1: @@ -12593,6 +12786,8 @@ snapshots: nanostores@1.1.1: {} + napi-build-utils@2.0.0: {} + natural-compare@1.4.0: {} negotiator@0.6.3: {} @@ -12627,6 +12822,10 @@ snapshots: - '@babel/core' - babel-plugin-macros + node-abi@3.89.0: + dependencies: + semver: 7.7.4 + node-abort-controller@3.1.1: {} node-cron@4.2.1: {} @@ -12704,6 +12903,11 @@ snapshots: dependencies: mimic-function: 5.0.1 + openai@6.26.0(ws@8.20.0)(zod@3.25.76): + optionalDependencies: + ws: 8.20.0 + zod: 3.25.76 + openai@6.26.0(ws@8.20.0)(zod@4.3.6): optionalDependencies: ws: 8.20.0 @@ -12977,6 +13181,21 @@ snapshots: postgres@3.4.8: {} + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.89.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + prelude-ls@1.2.1: {} prettier@3.8.1: {} @@ -13059,6 +13278,13 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + react-dom@19.2.4(react@19.2.4): dependencies: react: 19.2.4 @@ -13104,6 +13330,12 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readdirp@5.0.0: {} real-require@0.2.0: {} @@ -13357,6 +13589,14 @@ snapshots: signal-exit@4.1.0: {} + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + sisteransi@1.0.5: {} slice-ansi@5.0.0: @@ -13520,6 +13760,8 @@ snapshots: strip-final-newline@3.0.0: {} + strip-json-comments@2.0.1: {} + strip-json-comments@3.1.1: {} strnum@2.2.0: {} @@ -13557,6 +13799,21 @@ snapshots: tapable@2.3.0: {} + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + tar@7.5.13: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -13669,6 +13926,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + turbo-darwin-64@2.8.16: optional: true