diff --git a/apps/x/apps/main/bundle.mjs b/apps/x/apps/main/bundle.mjs index 976e8db3..a03bdb15 100644 --- a/apps/x/apps/main/bundle.mjs +++ b/apps/x/apps/main/bundle.mjs @@ -24,7 +24,7 @@ await esbuild.build({ platform: 'node', target: 'node20', outfile: './.package/dist/main.cjs', - external: ['electron'], // Provided by Electron runtime + external: ['electron', 'better-sqlite3'], // Provided by Electron/runtime node_modules // Use CommonJS format - many dependencies use require() which doesn't work // well with esbuild's ESM shim. CJS handles dynamic requires natively. format: 'cjs', diff --git a/apps/x/apps/main/forge.config.cjs b/apps/x/apps/main/forge.config.cjs index 7806f6cd..358a6160 100644 --- a/apps/x/apps/main/forge.config.cjs +++ b/apps/x/apps/main/forge.config.cjs @@ -33,13 +33,17 @@ module.exports = { // These settings prevent Forge's dependency walker (flora-colossus) from trying // to analyze/copy node_modules, which fails with pnpm's symlinked workspaces. prune: false, - ignore: [ - /src\//, - /node_modules\//, - /.gitignore/, - /bundle\.mjs/, - /tsconfig.json/, - ], + ignore: (file) => { + const normalized = file.split(path.sep).join('/'); + if (normalized.includes('/.package/node_modules/')) return false; + return [ + /\/src\//, + /\/node_modules\//, + /\.gitignore$/, + /\/bundle\.mjs$/, + /\/tsconfig\.json$/, + ].some((pattern) => pattern.test(normalized)); + }, }, makers: [ { @@ -164,6 +168,44 @@ module.exports = { stdio: 'inherit' }); + // Copy native runtime dependencies that cannot be bundled by esbuild. + console.log('Copying native runtime dependencies...'); + const stagedNodeModules = path.join(packageDir, 'node_modules'); + fs.mkdirSync(stagedNodeModules, { recursive: true }); + fs.writeFileSync(path.join(packageDir, 'package.json'), JSON.stringify({ + name: `${pkg.name}-native-runtime`, + version: pkg.version, + private: true, + dependencies: { + 'better-sqlite3': require(require.resolve('better-sqlite3/package.json', { + paths: [path.join(__dirname, '../../packages/core')], + })).version, + }, + }, null, 2)); + const copyRuntimePackage = (packageName) => { + const packageJsonPath = require.resolve(`${packageName}/package.json`, { + paths: [path.join(__dirname, '../../packages/core')], + }); + const packageSrc = path.dirname(packageJsonPath); + const packageDest = path.join(stagedNodeModules, packageName); + fs.rmSync(packageDest, { recursive: true, force: true }); + fs.cpSync(packageSrc, packageDest, { recursive: true }); + }; + for (const packageName of ['better-sqlite3', 'bindings', 'file-uri-to-path']) { + copyRuntimePackage(packageName); + } + const { rebuild } = require(path.join(__dirname, '../../node_modules/.pnpm/node_modules/@electron/rebuild')); + const electronVersion = require(require.resolve('electron/package.json', { paths: [__dirname] })).version; + await rebuild({ + buildPath: packageDir, + electronVersion, + platform, + arch, + onlyModules: ['better-sqlite3'], + force: true, + buildFromSource: true, + }); + // Copy preload dist into staging directory console.log('Copying preload...'); const preloadSrc = path.join(__dirname, '../preload/dist'); @@ -181,4 +223,4 @@ module.exports = { console.log('✅ All assets staged in .package/'); }, } -}; \ No newline at end of file +}; diff --git a/apps/x/apps/main/src/main.ts b/apps/x/apps/main/src/main.ts index f4415b5d..8af67fdd 100644 --- a/apps/x/apps/main/src/main.ts +++ b/apps/x/apps/main/src/main.ts @@ -33,6 +33,7 @@ import { backgroundTaskEventConsumer } from "@x/core/dist/background-tasks/event import { init as initLocalSites, shutdown as shutdownLocalSites } from "@x/core/dist/local-sites/server.js"; import { shutdown as shutdownAnalytics } from "@x/core/dist/analytics/posthog.js"; import { identifyIfSignedIn } from "@x/core/dist/analytics/identify.js"; +import { initStorage, shutdownStorage } from "@x/core/dist/storage/index.js"; import { initConfigs } from "@x/core/dist/config/initConfigs.js"; import { resolveWorkspacePath } from "@x/core/dist/workspace/workspace.js"; @@ -307,6 +308,9 @@ app.whenReady().then(async () => { // Initialize all config files before UI can access them await initConfigs(); + // Initialize SQLite storage before any DB-backed services or repos are used. + await initStorage(); + // PostHog identify() is idempotent — call it on every startup so existing // signed-in installs (and every cold start of v0.3.4+) get re-identified. // Otherwise main-process events stay anonymous until the user re-signs-in. @@ -430,4 +434,7 @@ app.on("before-quit", () => { shutdownAnalytics().catch((error) => { console.error('[Analytics] Failed to flush on quit:', error); }); + shutdownStorage().catch((error) => { + console.error('[storage] Failed to close SQLite storage:', error); + }); }); diff --git a/apps/x/packages/core/package.json b/apps/x/packages/core/package.json index 08c2644d..147f6e12 100644 --- a/apps/x/packages/core/package.json +++ b/apps/x/packages/core/package.json @@ -28,6 +28,7 @@ "@x/shared": "workspace:*", "ai": "^5.0.133", "awilix": "^12.0.5", + "better-sqlite3": "^12.10.0", "chokidar": "^4.0.3", "cors": "^2.8.6", "cron-parser": "^5.5.0", @@ -36,6 +37,7 @@ "google-auth-library": "^10.5.0", "googleapis": "^169.0.0", "isomorphic-git": "^1.29.0", + "kysely": "^0.29.2", "mammoth": "^1.11.0", "node-html-markdown": "^2.0.0", "ollama-ai-provider-v2": "^1.5.4", @@ -49,6 +51,7 @@ "zod": "^4.2.1" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.13", "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/node": "^25.0.3", diff --git a/apps/x/packages/core/src/index.ts b/apps/x/packages/core/src/index.ts index 894279b6..f81ec594 100644 --- a/apps/x/packages/core/src/index.ts +++ b/apps/x/packages/core/src/index.ts @@ -12,3 +12,6 @@ export * as versionHistory from './knowledge/version_history.js'; // Voice mode (config + TTS) export * as voice from './voice/voice.js'; + +// SQLite storage +export * as storage from './storage/index.js'; diff --git a/apps/x/packages/core/src/storage/database.ts b/apps/x/packages/core/src/storage/database.ts new file mode 100644 index 00000000..4e76dc4d --- /dev/null +++ b/apps/x/packages/core/src/storage/database.ts @@ -0,0 +1,82 @@ +import fs from "node:fs"; +import { createRequire } from "node:module"; +import path from "node:path"; +import { Kysely, SqliteDialect, type SqliteDatabase } from "kysely"; +import { WorkDir } from "../config/config.js"; +import type { Database } from "./schema.js"; +import { migrateToLatest } from "./migrations.js"; + +type BetterSqliteDatabase = SqliteDatabase & { + pragma(source: string, options?: { simple?: boolean }): unknown; +}; + +type BetterSqliteConstructor = new ( + filename?: string, + options?: { timeout?: number }, +) => BetterSqliteDatabase; + +const require = createRequire(import.meta.url); +const BetterSqlite = require("better-sqlite3") as BetterSqliteConstructor; + +let db: Kysely | null = null; +let initPromise: Promise | null = null; + +export function getDatabasePath(): string { + return path.join(WorkDir, "db", "rowboat.sqlite"); +} + +function createDatabase(): Kysely { + const databasePath = getDatabasePath(); + fs.mkdirSync(path.dirname(databasePath), { recursive: true }); + + const sqlite = new BetterSqlite(databasePath, { timeout: 5_000 }); + sqlite.pragma("foreign_keys = ON"); + sqlite.pragma("journal_mode = WAL"); + sqlite.pragma("busy_timeout = 5000"); + + return new Kysely({ + dialect: new SqliteDialect({ + database: sqlite, + }), + }); +} + +export async function initStorage(): Promise { + if (db) return; + if (initPromise) return initPromise; + + initPromise = (async () => { + const nextDb = createDatabase(); + try { + await migrateToLatest(nextDb); + db = nextDb; + } catch (error) { + await nextDb.destroy().catch((destroyError: unknown) => { + console.error("[storage] failed to close SQLite after init failure:", destroyError); + }); + throw error; + } finally { + initPromise = null; + } + })(); + + return initPromise; +} + +export function getDb(): Kysely { + if (!db) { + throw new Error("SQLite storage has not been initialized. Call initStorage() first."); + } + + return db; +} + +export async function shutdownStorage(): Promise { + const currentDb = db; + db = null; + initPromise = null; + + if (currentDb) { + await currentDb.destroy(); + } +} diff --git a/apps/x/packages/core/src/storage/index.ts b/apps/x/packages/core/src/storage/index.ts new file mode 100644 index 00000000..c0327e93 --- /dev/null +++ b/apps/x/packages/core/src/storage/index.ts @@ -0,0 +1,2 @@ +export { getDatabasePath, getDb, initStorage, shutdownStorage } from "./database.js"; +export type { Database, StorageMetadataTable, TimestampColumn } from "./schema.js"; diff --git a/apps/x/packages/core/src/storage/migrations.ts b/apps/x/packages/core/src/storage/migrations.ts new file mode 100644 index 00000000..6620d99f --- /dev/null +++ b/apps/x/packages/core/src/storage/migrations.ts @@ -0,0 +1,50 @@ +import type { Kysely } from "kysely"; +import { Migrator, type Migration, type MigrationProvider } from "kysely/migration"; + +// Kysely migrations are intentionally schema-agnostic and frozen in time. +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type MigrationDb = Kysely; + +const migrations: Record = { + "2026-06-09_0001_initial_storage": { + async up(db: MigrationDb): Promise { + await db.schema + .createTable("storage_metadata") + .ifNotExists() + .addColumn("key", "text", (col) => col.primaryKey()) + .addColumn("value", "text", (col) => col.notNull()) + .addColumn("updated_at", "text", (col) => col.notNull()) + .execute(); + }, + async down(db: MigrationDb): Promise { + await db.schema.dropTable("storage_metadata").ifExists().execute(); + }, + }, +}; + +class InCodeMigrationProvider implements MigrationProvider { + async getMigrations(): Promise> { + return migrations; + } +} + +export async function migrateToLatest(db: MigrationDb): Promise { + const migrator = new Migrator({ + db, + provider: new InCodeMigrationProvider(), + }); + + const { error, results } = await migrator.migrateToLatest(); + + for (const result of results ?? []) { + if (result.status === "Success") { + console.log(`[storage] migration applied: ${result.migrationName}`); + } else if (result.status === "Error") { + console.error(`[storage] migration failed: ${result.migrationName}`); + } + } + + if (error) { + throw new Error("Failed to migrate SQLite storage", { cause: error }); + } +} diff --git a/apps/x/packages/core/src/storage/schema.ts b/apps/x/packages/core/src/storage/schema.ts new file mode 100644 index 00000000..7a348fe0 --- /dev/null +++ b/apps/x/packages/core/src/storage/schema.ts @@ -0,0 +1,13 @@ +import type { ColumnType } from "kysely"; + +export type TimestampColumn = ColumnType; + +export interface StorageMetadataTable { + key: string; + value: string; + updated_at: TimestampColumn; +} + +export interface Database { + storage_metadata: StorageMetadataTable; +} diff --git a/apps/x/packages/core/src/storage/storage.test.ts b/apps/x/packages/core/src/storage/storage.test.ts new file mode 100644 index 00000000..d553f800 --- /dev/null +++ b/apps/x/packages/core/src/storage/storage.test.ts @@ -0,0 +1,90 @@ +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { sql } from "kysely"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +let tmpDir: string; +let workspaceDir: string; +let storageModule: typeof import("./index.js") | null = null; + +beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "rowboat-storage-test-")); + workspaceDir = path.join(tmpDir, "workspace"); + process.env.ROWBOAT_WORKDIR = workspaceDir; + vi.resetModules(); + vi.doMock("../knowledge/version_history.js", () => ({ + initRepo: vi.fn(async () => undefined), + })); + vi.doMock("../knowledge/deprecate_today_note.js", () => ({ + deprecateTodayNote: vi.fn(async () => undefined), + })); +}); + +afterEach(async () => { + if (storageModule) { + await storageModule.shutdownStorage().catch(() => undefined); + storageModule = null; + } + delete process.env.ROWBOAT_WORKDIR; + vi.doUnmock("../knowledge/version_history.js"); + vi.doUnmock("../knowledge/deprecate_today_note.js"); + vi.resetModules(); + await fs.rm(tmpDir, { recursive: true, force: true }); +}); + +async function loadStorage() { + storageModule = await import("./index.js"); + return storageModule; +} + +describe("SQLite storage", () => { + it("throws clearly when accessed before initialization", async () => { + const storage = await loadStorage(); + + expect(() => storage.getDb()).toThrow("SQLite storage has not been initialized"); + }); + + it("creates the database under ROWBOAT_WORKDIR/db", async () => { + const storage = await loadStorage(); + + await storage.initStorage(); + + expect(storage.getDatabasePath()).toBe(path.join(workspaceDir, "db", "rowboat.sqlite")); + await expect(fs.access(storage.getDatabasePath())).resolves.toBeUndefined(); + }); + + it("runs the initial migration", async () => { + const storage = await loadStorage(); + await storage.initStorage(); + + const result = await sql<{ name: string }>` + select name + from sqlite_master + where type = 'table' + and name in ('storage_metadata', 'kysely_migration') + order by name + `.execute(storage.getDb()); + + expect(result.rows.map((row) => row.name)).toEqual(["kysely_migration", "storage_metadata"]); + }); + + it("is idempotent", async () => { + const storage = await loadStorage(); + + await storage.initStorage(); + const firstDb = storage.getDb(); + await storage.initStorage(); + + expect(storage.getDb()).toBe(firstDb); + }); + + it("resets the singleton on shutdown", async () => { + const storage = await loadStorage(); + + await storage.initStorage(); + await storage.shutdownStorage(); + + expect(() => storage.getDb()).toThrow("SQLite storage has not been initialized"); + }); +}); diff --git a/apps/x/packages/core/src/workspace/watcher.test.ts b/apps/x/packages/core/src/workspace/watcher.test.ts new file mode 100644 index 00000000..51982dff --- /dev/null +++ b/apps/x/packages/core/src/workspace/watcher.test.ts @@ -0,0 +1,39 @@ +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +let tmpDir: string; +let workspaceDir: string; + +beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "rowboat-watcher-test-")); + workspaceDir = path.join(tmpDir, "workspace"); + process.env.ROWBOAT_WORKDIR = workspaceDir; + vi.resetModules(); + vi.doMock("../knowledge/version_history.js", () => ({ + initRepo: vi.fn(async () => undefined), + })); + vi.doMock("../knowledge/deprecate_today_note.js", () => ({ + deprecateTodayNote: vi.fn(async () => undefined), + })); +}); + +afterEach(async () => { + delete process.env.ROWBOAT_WORKDIR; + vi.doUnmock("../knowledge/version_history.js"); + vi.doUnmock("../knowledge/deprecate_today_note.js"); + vi.resetModules(); + await fs.rm(tmpDir, { recursive: true, force: true }); +}); + +describe("workspace watcher ignores", () => { + it("ignores SQLite storage files under db", async () => { + const watcher = await import("./watcher.js"); + + expect(watcher.shouldIgnoreWorkspacePath(path.join(workspaceDir, "db"))).toBe(true); + expect(watcher.shouldIgnoreWorkspacePath(path.join(workspaceDir, "db", "rowboat.sqlite"))).toBe(true); + expect(watcher.shouldIgnoreWorkspacePath(path.join(workspaceDir, "db", "rowboat.sqlite-wal"))).toBe(true); + expect(watcher.shouldIgnoreWorkspacePath(path.join(workspaceDir, "knowledge", "note.md"))).toBe(false); + }); +}); diff --git a/apps/x/packages/core/src/workspace/watcher.ts b/apps/x/packages/core/src/workspace/watcher.ts index 3460f014..e0eed3a5 100644 --- a/apps/x/packages/core/src/workspace/watcher.ts +++ b/apps/x/packages/core/src/workspace/watcher.ts @@ -8,6 +8,11 @@ import { Stats } from 'node:fs'; export type WorkspaceChangeCallback = (event: z.infer) => void; +export function shouldIgnoreWorkspacePath(absPath: string): boolean { + const relPath = absToRelPosix(absPath); + return relPath === 'db' || relPath?.startsWith('db/') === true; +} + /** * Create a workspace watcher * Watches the configured workspace root recursively and emits change events via callback @@ -23,6 +28,7 @@ export async function createWorkspaceWatcher( const watcher = chokidar.watch(WorkDir, { ignoreInitial: true, + ignored: shouldIgnoreWorkspacePath, awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 50, diff --git a/apps/x/pnpm-lock.yaml b/apps/x/pnpm-lock.yaml index c4e5a8d5..3202e658 100644 --- a/apps/x/pnpm-lock.yaml +++ b/apps/x/pnpm-lock.yaml @@ -206,16 +206,16 @@ importers: version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) '@tiptap/extension-placeholder': specifier: 3.22.4 - version: 3.22.4(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)) + version: 3.22.4(@tiptap/extensions@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)) '@tiptap/extension-table': specifier: 3.22.4 version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) '@tiptap/extension-task-item': specifier: 3.22.4 - version: 3.22.4(@tiptap/extension-list@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)) + version: 3.22.4(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)) '@tiptap/extension-task-list': specifier: 3.22.4 - version: 3.22.4(@tiptap/extension-list@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)) + version: 3.22.4(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)) '@tiptap/pm': specifier: 3.22.4 version: 3.22.4 @@ -424,6 +424,9 @@ importers: awilix: specifier: ^12.0.5 version: 12.0.5 + better-sqlite3: + specifier: ^12.10.0 + version: 12.10.0 chokidar: specifier: ^4.0.3 version: 4.0.3 @@ -448,6 +451,9 @@ importers: isomorphic-git: specifier: ^1.29.0 version: 1.37.2 + kysely: + specifier: ^0.29.2 + version: 0.29.2 mammoth: specifier: ^1.11.0 version: 1.11.0 @@ -482,6 +488,9 @@ importers: specifier: ^4.2.1 version: 4.2.1 devDependencies: + '@types/better-sqlite3': + specifier: ^7.6.13 + version: 7.6.13 '@types/cors': specifier: ^2.8.19 version: 2.8.19 @@ -596,25 +605,21 @@ packages: resolution: {integrity: sha512-R7KEVjxkR4rYgIQoHGBzwPdUJYxRTO8I4vHjRbMLH1eW4FS7BJvVs7ogfKR/NnHFBvMVqtC+l6jHLQv8bobUiw==} cpu: [arm64] os: [linux] - libc: [musl] '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.156': resolution: {integrity: sha512-H0Nfd41iw5isto9uQI1FlVSZ0eaDttr8rBpJMR25oK/mj3egMO5EmZ6aAxeeUYSLn2mSU50HA5VNxlGUE118TQ==} cpu: [arm64] os: [linux] - libc: [glibc] '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.156': resolution: {integrity: sha512-/Q6WUizI6a+hqZZ6ElwRU0PEuFhOoN4v6CuU35HHbiZ/7uaocGht4A8ZIgK1Fw6wOGtZzGLbc00CA1OU1Zg8EA==} cpu: [x64] os: [linux] - libc: [musl] '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.156': resolution: {integrity: sha512-ymhrdlbWoYvTACUdaGdhrEv+ZMfwXLsf0BRLkr/IvY5aqybP7URzWmmZGOtDQpqkT/8xu/UCGqUYH3woJwUxfg==} cpu: [x64] os: [linux] - libc: [glibc] '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.156': resolution: {integrity: sha512-5sAeNObQQrMy4NF9HwxewrMnU7mVxZDHh+/MfJVQSz0GSTvXQ6gOuRH8helMlfspoU6VOdekPxVLRooX/3foEw==} @@ -1677,35 +1682,30 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [glibc] '@napi-rs/canvas-linux-arm64-musl@0.1.80': resolution: {integrity: sha512-1XbCOz/ymhj24lFaIXtWnwv/6eFHXDrjP0jYkc6iHQ9q8oXKzUX1Lc6bu+wuGiLhGh2GS/2JlfORC5ZcXimRcg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [musl] '@napi-rs/canvas-linux-riscv64-gnu@0.1.80': resolution: {integrity: sha512-XTzR125w5ZMs0lJcxRlS1K3P5RaZ9RmUsPtd1uGt+EfDyYMu4c6SEROYsxyatbbu/2+lPe7MPHOO/0a0x7L/gw==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] - libc: [glibc] '@napi-rs/canvas-linux-x64-gnu@0.1.80': resolution: {integrity: sha512-BeXAmhKg1kX3UCrJsYbdQd3hIMDH/K6HnP/pG2LuITaXhXBiNdh//TVVVVCBbJzVQaV5gK/4ZOCMrQW9mvuTqA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [glibc] '@napi-rs/canvas-linux-x64-musl@0.1.80': resolution: {integrity: sha512-x0XvZWdHbkgdgucJsRxprX/4o4sEed7qo9rCQA9ugiS9qE2QvP0RIiEugtZhfLH3cyI+jIRFJHV4Fuz+1BHHMg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [musl] '@napi-rs/canvas-win32-x64-msvc@0.1.80': resolution: {integrity: sha512-Z8jPsM6df5V8B1HrCHB05+bDiCxjE9QA//3YrkKIdVDEwn5RKaqOxCJDRJkl48cJbylcrJbW4HxZbTte8juuPg==} @@ -2869,67 +2869,56 @@ packages: resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.54.0': resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.54.0': resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.54.0': resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.54.0': resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.54.0': resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.54.0': resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.54.0': resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.54.0': resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.54.0': resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.54.0': resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openharmony-arm64@4.54.0': resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} @@ -3251,28 +3240,24 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.18': resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.18': resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.18': resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.18': resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} @@ -3408,12 +3393,6 @@ packages: peerDependencies: '@tiptap/extension-list': 3.22.5 - '@tiptap/extension-list@3.22.4': - resolution: {integrity: sha512-Xe8UFvvHmyp/c/TJsFwlwU9CWACYbBirNsluJ3U1+H8BTu1wqdrT/AXR5uIXeyCl5kiWKgX5q71eHWbYFOrqrg==} - peerDependencies: - '@tiptap/core': 3.22.4 - '@tiptap/pm': 3.22.4 - '@tiptap/extension-list@3.22.5': resolution: {integrity: sha512-cVO3ZHCgxAWZ4zrFSs81FO2nyCk1wb2EHkpLpW98FzbJLkN9rDkazhW99P3HRWy/CvUldOT+8ecI1YrQtBojMg==} peerDependencies: @@ -3466,12 +3445,6 @@ packages: peerDependencies: '@tiptap/core': 3.22.5 - '@tiptap/extensions@3.22.4': - resolution: {integrity: sha512-fOe8VptJvLPs32bNdUYo8SRyljwqKNQVXWW056VoXIc5en/59OdJlJQVeHI0jRRciH3MtrqODi/gfJR0VHNZ8A==} - peerDependencies: - '@tiptap/core': 3.22.4 - '@tiptap/pm': 3.22.4 - '@tiptap/extensions@3.22.5': resolution: {integrity: sha512-Ifg4MzKCj3uRqe3ieTwYnomu2y4p7EXr2avVSKZYfh12i2dyWe2Gkn1KuZDREANVE+gHqFlQjJRYzhJFwzSCrg==} peerDependencies: @@ -3525,6 +3498,9 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/better-sqlite3@7.6.13': + resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} + '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -4126,12 +4102,19 @@ packages: before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + better-sqlite3@12.10.0: + resolution: {integrity: sha512-CyzaZRQKyHkB2ZInfTTl2nvT33EbDpjkLEbE8/Zck3Ll6O0qqvuGdrJ45HgtH+HykRg88ITY3AdreBGN70aBSQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x || 26.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==} @@ -4291,6 +4274,9 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -4684,6 +4670,10 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} + 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==} @@ -5059,6 +5049,10 @@ packages: resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} engines: {node: '>=6'} + 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'} @@ -5141,6 +5135,9 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + filename-reserved-regex@2.0.0: resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} engines: {node: '>=4'} @@ -5233,6 +5230,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==} + fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -5346,6 +5346,9 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + github-url-to-object@4.0.6: resolution: {integrity: sha512-NaqbYHMUAlPcmWFdrAB7bcxrNIiiJWJe8s/2+iOc9vlcHlwHqSGrPk+Yi3nu6ebTwgsZEa7igz+NH2vEq3gYwQ==} @@ -5653,6 +5656,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ini@2.0.0: resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} engines: {node: '>=10'} @@ -5921,6 +5927,10 @@ packages: khroma@2.1.0: resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kysely@0.29.2: + resolution: {integrity: sha512-s6WVJyEZrbm6jhBpiKHsGHyePMrVQKJ85wZCFCr9W4QHv6WTjWIrdvTmO9hDEA3bNK0xkrE2DqrHsXMLWuZpQg==} + engines: {node: '>=22.0.0'} + langium@4.2.2: resolution: {integrity: sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} @@ -5973,28 +5983,24 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -6440,6 +6446,9 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -6498,6 +6507,9 @@ packages: engines: {node: ^18 || >=20} hasBin: true + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -6878,6 +6890,12 @@ packages: preact@10.28.2: resolution: {integrity: sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==} + 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'} @@ -7031,6 +7049,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.3: resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} peerDependencies: @@ -7563,6 +7585,10 @@ packages: resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} engines: {node: '>=0.10.0'} + 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'} @@ -7617,6 +7643,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@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} @@ -7742,6 +7775,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tw-animate-css@1.4.0: resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} @@ -11783,11 +11819,6 @@ snapshots: dependencies: '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) - '@tiptap/extension-list@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': - dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 - '@tiptap/extension-list@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': dependencies: '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) @@ -11801,9 +11832,9 @@ snapshots: dependencies: '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/extension-placeholder@3.22.4(@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))': + '@tiptap/extension-placeholder@3.22.4(@tiptap/extensions@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))': dependencies: - '@tiptap/extensions': 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + '@tiptap/extensions': 3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) '@tiptap/extension-strike@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': dependencies: @@ -11814,13 +11845,13 @@ snapshots: '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) '@tiptap/pm': 3.22.4 - '@tiptap/extension-task-item@3.22.4(@tiptap/extension-list@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))': + '@tiptap/extension-task-item@3.22.4(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))': dependencies: - '@tiptap/extension-list': 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) - '@tiptap/extension-task-list@3.22.4(@tiptap/extension-list@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))': + '@tiptap/extension-task-list@3.22.4(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4))': dependencies: - '@tiptap/extension-list': 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4) '@tiptap/extension-text@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))': dependencies: @@ -11830,11 +11861,6 @@ snapshots: dependencies: '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/extensions@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': - dependencies: - '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) - '@tiptap/pm': 3.22.4 - '@tiptap/extensions@3.22.5(@tiptap/core@3.22.4(@tiptap/pm@3.22.4))(@tiptap/pm@3.22.4)': dependencies: '@tiptap/core': 3.22.4(@tiptap/pm@3.22.4) @@ -11942,6 +11968,10 @@ snapshots: dependencies: '@babel/types': 7.28.5 + '@types/better-sqlite3@7.6.13': + dependencies: + '@types/node': 25.0.3 + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 @@ -12651,12 +12681,21 @@ snapshots: before-after-hook@2.2.3: {} + better-sqlite3@12.10.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 @@ -12857,6 +12896,8 @@ snapshots: dependencies: readdirp: 4.1.2 + chownr@1.1.4: {} + chownr@2.0.0: {} chrome-trace-event@1.0.4: {} @@ -13243,6 +13284,8 @@ snapshots: dependencies: mimic-response: 3.1.0 + deep-extend@0.6.0: {} + deep-is@0.1.4: {} default-browser-id@5.0.1: {} @@ -13729,6 +13772,8 @@ snapshots: signal-exit: 3.0.7 strip-eof: 1.0.0 + expand-template@2.0.3: {} + expect-type@1.3.0: {} exponential-backoff@3.1.3: {} @@ -13835,6 +13880,8 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} + filename-reserved-regex@2.0.0: {} filenamify@4.3.0: @@ -13936,6 +13983,8 @@ snapshots: fresh@2.0.0: {} + fs-constants@1.0.0: {} + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -14094,6 +14143,8 @@ snapshots: dependencies: pump: 3.0.3 + github-from-package@0.0.0: {} + github-url-to-object@4.0.6: dependencies: is-url: 1.2.4 @@ -14546,6 +14597,8 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + ini@2.0.0: {} inline-style-parser@0.2.7: {} @@ -14786,6 +14839,8 @@ snapshots: khroma@2.1.0: {} + kysely@0.29.2: {} + langium@4.2.2: dependencies: '@chevrotain/regexp-to-ast': 12.0.0 @@ -15557,6 +15612,8 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + mkdirp-classic@0.5.3: {} + mkdirp@0.5.6: dependencies: minimist: 1.2.8 @@ -15605,6 +15662,8 @@ snapshots: nanoid@5.1.6: {} + napi-build-utils@2.0.0: {} + natural-compare@1.4.0: {} negotiator@0.6.4: {} @@ -15969,6 +16028,21 @@ snapshots: preact@10.28.2: {} + 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.86.0 + pump: 3.0.3 + 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.0: {} @@ -16204,6 +16278,13 @@ snapshots: iconv-lite: 0.7.1 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.3(react@19.2.3): dependencies: react: 19.2.3 @@ -16874,6 +16955,8 @@ snapshots: strip-eof@1.0.0: {} + strip-json-comments@2.0.1: {} + strip-json-comments@3.1.1: {} strip-outer@1.0.1: @@ -16922,6 +17005,21 @@ snapshots: tapable@2.3.0: {} + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.3 + 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@6.2.1: dependencies: chownr: 2.0.0 @@ -17042,6 +17140,10 @@ snapshots: tslib@2.8.1: {} + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + tw-animate-css@1.4.0: {} tweetnacl@1.0.3: {} diff --git a/apps/x/pnpm-workspace.yaml b/apps/x/pnpm-workspace.yaml index f5cdd141..19189e62 100644 --- a/apps/x/pnpm-workspace.yaml +++ b/apps/x/pnpm-workspace.yaml @@ -10,6 +10,7 @@ onlyBuiltDependencies: - electron - electron-winstaller - esbuild + - better-sqlite3 - fs-xattr - macos-alias - protobufjs