@tearleads/cli 0.0.1 → 0.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
+ import { createRequire } from "module";
4
5
  import { Command as Command8 } from "commander";
5
6
 
6
7
  // src/commands/backup.ts
@@ -1307,8 +1308,10 @@ async function runUnlock() {
1307
1308
  var unlockCommand = new Command7("unlock").description("Unlock the database").action(runUnlock);
1308
1309
 
1309
1310
  // src/index.ts
1311
+ var require2 = createRequire(import.meta.url);
1312
+ var pkg = require2("../package.json");
1310
1313
  var program = new Command8();
1311
- program.name("tearleads").description("Tearleads CLI for database management").version("0.0.1");
1314
+ program.name("tearleads").description("Tearleads CLI for database management").version(pkg.version);
1312
1315
  program.addCommand(setupCommand);
1313
1316
  program.addCommand(unlockCommand);
1314
1317
  program.addCommand(lockCommand);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/backup.ts","../src/backup/constants.ts","../src/backup/compression.ts","../src/backup/crypto.ts","../src/backup/types.ts","../src/backup/decoder.ts","../src/backup/encoder.ts","../src/crypto/key-manager.ts","../../shared/dist/crypto/asymmetric.js","../../shared/dist/crypto/web-crypto.js","../../shared/dist/index.js","../src/config/index.ts","../src/db/index.ts","../src/db/adapter.ts","../src/utils/prompt.ts","../src/commands/dump.ts","../src/commands/lock.ts","../src/commands/password.ts","../src/commands/restore.ts","../src/commands/setup.ts","../src/commands/unlock.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Tearleads CLI - Database management for Tearleads.\n */\n\nimport { Command } from 'commander';\nimport { backupCommand } from './commands/backup.js';\nimport { dumpCommand } from './commands/dump.js';\nimport { lockCommand } from './commands/lock.js';\nimport { passwordCommand } from './commands/password.js';\nimport { restoreCommand } from './commands/restore.js';\nimport { setupCommand } from './commands/setup.js';\nimport { unlockCommand } from './commands/unlock.js';\n\nconst program = new Command();\n\nprogram\n .name('tearleads')\n .description('Tearleads CLI for database management')\n .version('0.0.1');\n\nprogram.addCommand(setupCommand);\nprogram.addCommand(unlockCommand);\nprogram.addCommand(lockCommand);\nprogram.addCommand(backupCommand);\nprogram.addCommand(dumpCommand);\nprogram.addCommand(restoreCommand);\nprogram.addCommand(passwordCommand);\n\nprogram.parse();\n","/**\n * Backup command - Export database to a JSON file.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { encode } from '../backup/index.js';\nimport type { BackupManifest } from '../backup/types.js';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n exportBackupDatabase,\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession\n} from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\ninterface BackupOptions {\n password?: string;\n}\n\nasync function resolveBackupPassword(options: BackupOptions): Promise<string> {\n if (options.password) {\n return options.password;\n }\n\n const password = await promptPassword('Backup password: ');\n const confirm = await promptPassword('Confirm backup password: ');\n if (password !== confirm) {\n console.error('Passwords do not match.');\n process.exit(1);\n }\n return password;\n}\n\nexport async function runBackup(\n file: string,\n options: BackupOptions\n): Promise<void> {\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n // Try to restore session if not unlocked\n if (!isDatabaseUnlocked()) {\n if (await hasPersistedSession()) {\n const restored = await restoreDatabaseSession();\n if (!restored) {\n console.error('Session expired. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n } else {\n console.error('Database not unlocked. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n }\n\n const password = await resolveBackupPassword(options);\n const database = exportBackupDatabase();\n const manifest: BackupManifest = {\n createdAt: new Date().toISOString(),\n platform: 'cli',\n appVersion: 'cli',\n blobCount: 0,\n blobTotalSize: 0\n };\n\n const data = await encode({\n password,\n manifest,\n database,\n blobs: [],\n readBlob: async () => {\n throw new Error('No blob storage configured for CLI');\n }\n });\n const filePath = path.resolve(file);\n await fs.writeFile(filePath, data);\n console.log(`Backup saved to ${filePath}`);\n}\n\nexport const backupCommand = new Command('backup')\n .description('Export database to an encrypted .rbu backup file')\n .argument('<file>', 'Output file path')\n .option('-p, --password <password>', 'Backup password')\n .action(runBackup);\n","/**\n * Constants for the Universal Backup Format (.rbu)\n */\n\n/** Magic bytes identifying a valid .rbu file: \"RAPIDBAK\" */\nexport const MAGIC_BYTES = new Uint8Array([\n 0x52, 0x41, 0x50, 0x49, 0x44, 0x42, 0x41, 0x4b\n]);\n\n/** Current format version */\nexport const FORMAT_VERSION = 1;\n\n/** Total header size in bytes */\nexport const HEADER_SIZE = 32;\n\n/** Size of the magic bytes */\nexport const MAGIC_SIZE = 8;\n\n/** Size of the salt for PBKDF2 */\nexport const SALT_SIZE = 16;\n\n/** Size of the IV for AES-GCM */\nexport const IV_SIZE = 12;\n\n/** Size of the GCM authentication tag (included in ciphertext) */\nexport const AUTH_TAG_SIZE = 16;\n\n/** Chunk header size: 4 (length) + 1 (type) + 3 (reserved) + 12 (IV) = 20 bytes */\nexport const CHUNK_HEADER_SIZE = 20;\n\n/** PBKDF2 iterations for key derivation */\nexport const PBKDF2_ITERATIONS: number = 600_000;\n\n/** AES key size in bits */\nexport const AES_KEY_BITS = 256;\n\n/** Maximum blob size before splitting into multiple chunks (10 MB) */\nexport const MAX_BLOB_CHUNK_SIZE = 10 * 1024 * 1024;\n\n/** File extension for backup files */\nexport const BACKUP_EXTENSION = '.rbu';\n","/**\n * Compression utilities for backup data.\n *\n * Uses gzip compression with platform-appropriate implementation:\n * - Node.js: Native zlib module\n */\n\n/**\n * Compress data using gzip (Node.js implementation).\n */\nasync function compressNode(data: Uint8Array): Promise<Uint8Array> {\n const { gzipSync } = await import('node:zlib');\n return new Uint8Array(gzipSync(data));\n}\n\n/**\n * Decompress gzip data (Node.js implementation).\n */\nasync function decompressNode(data: Uint8Array): Promise<Uint8Array> {\n const { gunzipSync } = await import('node:zlib');\n return new Uint8Array(gunzipSync(data));\n}\n\n/**\n * Compress data using gzip.\n *\n * @param data - Uncompressed data\n * @returns Compressed data\n */\nexport async function compress(data: Uint8Array): Promise<Uint8Array> {\n return compressNode(data);\n}\n\n/**\n * Decompress gzip data.\n *\n * @param data - Compressed data\n * @returns Decompressed data\n * @throws Error if data is not valid gzip\n */\nexport async function decompress(data: Uint8Array): Promise<Uint8Array> {\n return decompressNode(data);\n}\n\n/**\n * Compress a string (UTF-8 encoded) using gzip.\n *\n * @param text - String to compress\n * @returns Compressed data\n */\nexport async function compressString(text: string): Promise<Uint8Array> {\n const encoder = new TextEncoder();\n return compress(encoder.encode(text));\n}\n\n/**\n * Decompress gzip data to a string (UTF-8 decoded).\n *\n * @param data - Compressed data\n * @returns Decompressed string\n */\nexport async function decompressString(data: Uint8Array): Promise<string> {\n const decompressed = await decompress(data);\n const decoder = new TextDecoder();\n return decoder.decode(decompressed);\n}\n","/**\n * Cryptographic utilities for backup encryption/decryption.\n *\n * Uses Web Crypto API for cross-platform compatibility:\n * - PBKDF2 for key derivation from password\n * - AES-256-GCM for authenticated encryption\n */\n\nimport {\n AES_KEY_BITS,\n AUTH_TAG_SIZE,\n IV_SIZE,\n PBKDF2_ITERATIONS,\n SALT_SIZE\n} from './constants.js';\n\n/**\n * Generate a random salt for PBKDF2 key derivation.\n */\nexport function generateSalt(): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(SALT_SIZE));\n}\n\n/**\n * Generate a random IV for AES-GCM encryption.\n */\nexport function generateIv(): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(IV_SIZE));\n}\n\n/**\n * Derive an AES-256 key from a password using PBKDF2.\n *\n * @param password - User-provided password\n * @param salt - Random salt (must be stored with encrypted data)\n * @returns CryptoKey suitable for AES-GCM operations\n */\nexport async function deriveKey(\n password: string,\n salt: Uint8Array,\n iterations: number = PBKDF2_ITERATIONS\n): Promise<CryptoKey> {\n const encoder = new TextEncoder();\n const passwordBytes = encoder.encode(password);\n\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n passwordBytes,\n 'PBKDF2',\n false,\n ['deriveBits', 'deriveKey']\n );\n\n const saltBuffer = new Uint8Array(salt).buffer;\n\n return crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: saltBuffer,\n iterations,\n hash: 'SHA-256'\n },\n keyMaterial,\n { name: 'AES-GCM', length: AES_KEY_BITS },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Encrypt data using AES-256-GCM.\n *\n * @param data - Plaintext data to encrypt\n * @param key - AES key derived from password\n * @returns Object containing IV and ciphertext (includes auth tag)\n */\nexport async function encrypt(\n data: Uint8Array,\n key: CryptoKey\n): Promise<{ iv: Uint8Array; ciphertext: Uint8Array }> {\n const iv = generateIv();\n\n const dataBuffer = new Uint8Array(data).buffer;\n const ivBuffer = new Uint8Array(iv).buffer;\n\n const ciphertext = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv: ivBuffer },\n key,\n dataBuffer\n );\n\n return {\n iv,\n ciphertext: new Uint8Array(ciphertext)\n };\n}\n\n/**\n * Decrypt data using AES-256-GCM.\n *\n * @param ciphertext - Encrypted data (includes auth tag)\n * @param key - AES key derived from password\n * @param iv - Initialization vector used during encryption\n * @returns Decrypted plaintext\n * @throws Error if decryption fails (wrong password or tampered data)\n */\nexport async function decrypt(\n ciphertext: Uint8Array,\n key: CryptoKey,\n iv: Uint8Array\n): Promise<Uint8Array> {\n const ciphertextBuffer = new Uint8Array(ciphertext).buffer;\n const ivBuffer = new Uint8Array(iv).buffer;\n\n const plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: ivBuffer },\n key,\n ciphertextBuffer\n );\n\n return new Uint8Array(plaintext);\n}\n\n/**\n * Calculate the encrypted size for a given plaintext size.\n * AES-GCM adds a 16-byte authentication tag.\n */\nexport function encryptedSize(plaintextSize: number): number {\n return plaintextSize + AUTH_TAG_SIZE;\n}\n\n/**\n * Calculate the plaintext size for a given ciphertext size.\n */\nexport function plaintextSize(ciphertextSize: number): number {\n return ciphertextSize - AUTH_TAG_SIZE;\n}\n","/**\n * Universal Backup Format Types\n *\n * Defines the structure of .rbu backup files that work across\n * all platforms (Web, Electron, iOS, Android, CLI).\n */\n\nexport type ChunkTypeValue = 0 | 1 | 2;\n\n/** Chunk types in the backup file */\nexport const ChunkType: {\n MANIFEST: ChunkTypeValue;\n DATABASE: ChunkTypeValue;\n BLOB: ChunkTypeValue;\n} = {\n MANIFEST: 0,\n DATABASE: 1,\n BLOB: 2\n};\n\n/** Backup file header (plaintext, 32 bytes) */\nexport interface BackupHeader {\n /** Magic bytes: \"RAPIDBAK\" */\n magic: Uint8Array;\n /** Format version (currently 1) */\n version: number;\n /** Flags for future use */\n flags: number;\n /** Salt for PBKDF2 key derivation */\n salt: Uint8Array;\n}\n\n/** Manifest chunk - metadata about the backup */\nexport interface BackupManifest {\n /** ISO timestamp when backup was created */\n createdAt: string;\n /** Platform that created the backup */\n platform: 'web' | 'electron' | 'ios' | 'android' | 'cli';\n /** App version that created the backup */\n appVersion: string;\n /** Total number of blob chunks */\n blobCount: number;\n /** Total size of all blobs in bytes */\n blobTotalSize: number;\n /** Instance name from source */\n instanceName?: string;\n}\n\n/** Database chunk - schema and row data */\nexport interface BackupDatabase {\n /** Table definitions from sqlite_master */\n tables: TableSchema[];\n /** Index definitions from sqlite_master */\n indexes: IndexSchema[];\n /** Row data keyed by table name */\n data: Record<string, unknown[]>;\n}\n\n/** Table schema extracted from sqlite_master */\nexport interface TableSchema {\n name: string;\n sql: string;\n}\n\n/** Index schema extracted from sqlite_master */\nexport interface IndexSchema {\n name: string;\n tableName: string;\n sql: string;\n}\n\n/** Blob entry header (stored before binary data in blob chunks) */\nexport interface BlobHeader {\n /** Relative path within the blob storage */\n path: string;\n /** MIME type of the blob */\n mimeType: string;\n /** Original size in bytes */\n size: number;\n /** For split blobs: which part this is (0-indexed) */\n partIndex?: number;\n /** For split blobs: total number of parts */\n totalParts?: number;\n}\n\n/** Chunk header structure (20 bytes) */\nexport interface ChunkHeader {\n /** Length of the encrypted payload */\n payloadLength: number;\n /** Type of chunk (manifest, database, blob) */\n chunkType: ChunkTypeValue;\n /** Reserved bytes for future use */\n reserved: Uint8Array;\n /** Initialization vector for AES-GCM */\n iv: Uint8Array;\n}\n\n/** Progress event during backup/restore */\nexport interface BackupProgressEvent {\n /** Current phase of the operation */\n phase: 'preparing' | 'database' | 'blobs' | 'finalizing';\n /** Current item number */\n current: number;\n /** Total items in this phase */\n total: number;\n /** Current item being processed */\n currentItem?: string | undefined;\n}\n\n/** Decoded blob data from a backup. */\nexport interface DecodedBlob {\n header: BlobHeader;\n data: Uint8Array;\n}\n\n/** Result of decoding a backup file. */\nexport interface DecodeResult {\n manifest: BackupManifest;\n database: BackupDatabase;\n blobs: DecodedBlob[];\n}\n\n/** Options for decoding a backup file. */\nexport interface DecodeOptions {\n data: Uint8Array;\n password: string;\n onProgress?: (event: BackupProgressEvent) => void;\n}\n\n/** Options for encoding a backup file. */\nexport interface EncodeOptions {\n password: string;\n manifest: BackupManifest;\n database: BackupDatabase;\n blobs: BlobEntry[];\n readBlob: (path: string) => Promise<Uint8Array>;\n onProgress?: (event: BackupProgressEvent) => void;\n}\n\n/** Entry in the blob listing */\nexport interface BlobEntry {\n path: string;\n mimeType: string;\n size: number;\n}\n","/**\n * Decoder for the Universal Backup Format (.rbu)\n *\n * Reads backup files with the following structure:\n * - Header (32 bytes, plaintext): magic, version, flags, salt\n * - Chunks (variable, encrypted): manifest, database, blobs\n */\n\nimport { decompress } from './compression.js';\nimport {\n CHUNK_HEADER_SIZE,\n FORMAT_VERSION,\n HEADER_SIZE,\n MAGIC_BYTES,\n MAGIC_SIZE,\n PBKDF2_ITERATIONS,\n SALT_SIZE\n} from './constants.js';\nimport { decrypt, deriveKey } from './crypto.js';\nimport {\n type BackupHeader,\n type BackupManifest,\n type BackupProgressEvent,\n type BlobHeader,\n ChunkType,\n type ChunkTypeValue,\n type DecodedBlob,\n type DecodeOptions,\n type DecodeResult\n} from './types.js';\n\n/**\n * Error thrown when backup file is invalid or corrupted.\n */\nexport class BackupDecodeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'BackupDecodeError';\n }\n}\n\n/**\n * Error thrown when password is incorrect.\n */\nexport class InvalidPasswordError extends Error {\n constructor() {\n super('Invalid password or corrupted backup');\n this.name = 'InvalidPasswordError';\n }\n}\n\n/**\n * Read a 32-bit unsigned integer from a buffer in little-endian format.\n */\nfunction readUint32LE(buffer: Uint8Array, offset: number): number {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n return view.getUint32(offset, true);\n}\n\n/**\n * Read a 16-bit unsigned integer from a buffer in little-endian format.\n */\nfunction readUint16LE(buffer: Uint8Array, offset: number): number {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n return view.getUint16(offset, true);\n}\n\n/**\n * Parse the backup file header.\n */\nfunction parseHeader(data: Uint8Array): BackupHeader {\n if (data.length < HEADER_SIZE) {\n throw new BackupDecodeError('File too small to be a valid backup');\n }\n\n const magic = data.slice(0, MAGIC_SIZE);\n for (let i = 0; i < MAGIC_SIZE; i++) {\n if (magic[i] !== MAGIC_BYTES[i]) {\n throw new BackupDecodeError('Invalid backup file: wrong magic bytes');\n }\n }\n\n const version = readUint16LE(data, MAGIC_SIZE);\n if (version > FORMAT_VERSION) {\n throw new BackupDecodeError(\n `Unsupported backup version: ${version} (max supported: ${FORMAT_VERSION})`\n );\n }\n\n const flags = readUint16LE(data, MAGIC_SIZE + 2);\n const salt = data.slice(MAGIC_SIZE + 4, MAGIC_SIZE + 4 + SALT_SIZE);\n\n return { magic, version, flags, salt };\n}\n\n/**\n * Parse a chunk header.\n */\nfunction parseChunkHeader(data: Uint8Array, offset: number) {\n if (offset + CHUNK_HEADER_SIZE > data.length) {\n throw new BackupDecodeError(\n 'Unexpected end of file while reading chunk header'\n );\n }\n\n const payloadLength = readUint32LE(data, offset);\n const chunkTypeValue = data[offset + 4] ?? -1;\n if (!isChunkTypeValue(chunkTypeValue)) {\n throw new BackupDecodeError(`Unknown chunk type: ${chunkTypeValue}`);\n }\n const reserved = data.slice(offset + 5, offset + 8);\n const iv = data.slice(offset + 8, offset + CHUNK_HEADER_SIZE);\n\n return { payloadLength, chunkType: chunkTypeValue, reserved, iv };\n}\n\nfunction isChunkTypeValue(value: number): value is ChunkTypeValue {\n return (\n value === ChunkType.MANIFEST ||\n value === ChunkType.DATABASE ||\n value === ChunkType.BLOB\n );\n}\n\n/**\n * Decrypt and decompress a chunk payload.\n */\nasync function decryptChunk(\n data: Uint8Array,\n offset: number,\n header: { payloadLength: number; iv: Uint8Array },\n key: CryptoKey\n): Promise<Uint8Array> {\n const payloadStart = offset + CHUNK_HEADER_SIZE;\n const payloadEnd = payloadStart + header.payloadLength;\n\n if (payloadEnd > data.length) {\n throw new BackupDecodeError(\n 'Unexpected end of file while reading chunk payload'\n );\n }\n\n const ciphertext = data.slice(payloadStart, payloadEnd);\n\n try {\n const compressed = await decrypt(ciphertext, key, header.iv);\n return decompress(compressed);\n } catch {\n throw new InvalidPasswordError();\n }\n}\n\n/**\n * Parse a JSON chunk (manifest or database).\n */\nfunction parseJsonChunk<T>(data: Uint8Array): T {\n const json = new TextDecoder().decode(data);\n return JSON.parse(json);\n}\n\n/**\n * Parse a blob chunk.\n */\nfunction parseBlobChunk(data: Uint8Array): DecodedBlob {\n const separatorIndex = data.indexOf(0);\n\n if (separatorIndex === -1) {\n throw new BackupDecodeError('Invalid blob chunk: missing separator');\n }\n\n const headerBytes = data.slice(0, separatorIndex);\n const blobData = data.slice(separatorIndex + 1);\n\n const header: BlobHeader = JSON.parse(new TextDecoder().decode(headerBytes));\n\n return { header, data: blobData };\n}\n\n/**\n * Decode a backup file.\n *\n * @param options - Decode options\n * @returns Decoded backup content\n */\nexport async function decode(options: DecodeOptions): Promise<DecodeResult> {\n const { data, password, onProgress } = options;\n\n const header = parseHeader(data);\n const decodeWithKey = async (key: CryptoKey): Promise<DecodeResult> => {\n let offset = HEADER_SIZE;\n let manifest: BackupManifest | null = null;\n let database: DecodeResult['database'] | null = null;\n const blobs: DecodedBlob[] = [];\n\n const totalChunks = Math.max(\n 1,\n Math.floor((data.length - HEADER_SIZE) / CHUNK_HEADER_SIZE)\n );\n let currentChunk = 0;\n\n const reportProgress = (\n phase: BackupProgressEvent['phase'],\n item?: string\n ) => {\n if (!onProgress) return;\n const event: BackupProgressEvent = {\n phase,\n current: currentChunk,\n total: totalChunks,\n currentItem: item\n };\n onProgress(event);\n };\n\n while (offset < data.length) {\n const chunkHeader = parseChunkHeader(data, offset);\n const chunkData = await decryptChunk(data, offset, chunkHeader, key);\n\n switch (chunkHeader.chunkType) {\n case ChunkType.MANIFEST:\n reportProgress('preparing', 'manifest');\n manifest = parseJsonChunk<BackupManifest>(chunkData);\n break;\n case ChunkType.DATABASE:\n reportProgress('database', 'database');\n database = parseJsonChunk<DecodeResult['database']>(chunkData);\n break;\n case ChunkType.BLOB:\n reportProgress('blobs', 'blob');\n blobs.push(parseBlobChunk(chunkData));\n break;\n default:\n throw new BackupDecodeError(\n `Unknown chunk type: ${chunkHeader.chunkType}`\n );\n }\n\n offset += CHUNK_HEADER_SIZE + chunkHeader.payloadLength;\n currentChunk++;\n }\n\n if (!manifest || !database) {\n throw new BackupDecodeError('Backup missing required chunks');\n }\n\n reportProgress('finalizing', 'complete');\n\n return { manifest, database, blobs };\n };\n\n const key = await deriveKey(password, header.salt, PBKDF2_ITERATIONS);\n return decodeWithKey(key);\n}\n\n/**\n * Read just the header from a backup file without decrypting.\n */\nexport function readHeader(data: Uint8Array): BackupHeader {\n return parseHeader(data);\n}\n\n/**\n * Validate a backup file without fully decoding it.\n */\nexport function validateBackup(data: Uint8Array): {\n valid: boolean;\n error?: string;\n} {\n try {\n const header = parseHeader(data);\n if (header.version > FORMAT_VERSION) {\n return {\n valid: false,\n error: `Unsupported backup version: ${header.version}`\n };\n }\n return { valid: true };\n } catch (err) {\n return {\n valid: false,\n error: err instanceof Error ? err.message : 'Invalid backup file'\n };\n }\n}\n","/**\n * Encoder for the Universal Backup Format (.rbu)\n *\n * Writes backup files with the following structure:\n * - Header (32 bytes, plaintext): magic, version, flags, salt\n * - Chunks (variable, encrypted): manifest, database, blobs\n */\n\nimport { compress } from './compression.js';\nimport {\n CHUNK_HEADER_SIZE,\n FORMAT_VERSION,\n HEADER_SIZE,\n MAGIC_BYTES,\n MAGIC_SIZE,\n MAX_BLOB_CHUNK_SIZE\n} from './constants.js';\nimport { deriveKey, encrypt, generateSalt } from './crypto.js';\nimport {\n type BackupProgressEvent,\n type BlobEntry,\n type BlobHeader,\n ChunkType,\n type ChunkTypeValue,\n type EncodeOptions\n} from './types.js';\n\n/**\n * Write a 32-bit unsigned integer to a buffer in little-endian format.\n */\nfunction writeUint32LE(\n buffer: Uint8Array,\n value: number,\n offset: number\n): void {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n view.setUint32(offset, value, true);\n}\n\n/**\n * Write a 16-bit unsigned integer to a buffer in little-endian format.\n */\nfunction writeUint16LE(\n buffer: Uint8Array,\n value: number,\n offset: number\n): void {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n view.setUint16(offset, value, true);\n}\n\n/**\n * Create the backup file header.\n */\nfunction createHeader(salt: Uint8Array, flags: number = 0): Uint8Array {\n const header = new Uint8Array(HEADER_SIZE);\n\n header.set(MAGIC_BYTES, 0);\n writeUint16LE(header, FORMAT_VERSION, MAGIC_SIZE);\n writeUint16LE(header, flags, MAGIC_SIZE + 2);\n header.set(salt, MAGIC_SIZE + 4);\n\n return header;\n}\n\n/**\n * Create a chunk with header and encrypted payload.\n */\nasync function createChunk(\n data: Uint8Array,\n chunkType: ChunkTypeValue,\n key: CryptoKey\n): Promise<Uint8Array> {\n const compressed = await compress(data);\n const { iv, ciphertext } = await encrypt(compressed, key);\n const chunk = new Uint8Array(CHUNK_HEADER_SIZE + ciphertext.length);\n\n writeUint32LE(chunk, ciphertext.length, 0);\n chunk[4] = chunkType;\n chunk.set(iv, 8);\n chunk.set(ciphertext, CHUNK_HEADER_SIZE);\n\n return chunk;\n}\n\n/**\n * Encode JSON data as a chunk.\n */\nasync function encodeJsonChunk(\n data: unknown,\n chunkType: ChunkTypeValue,\n key: CryptoKey\n): Promise<Uint8Array> {\n const json = JSON.stringify(data);\n const bytes = new TextEncoder().encode(json);\n return createChunk(bytes, chunkType, key);\n}\n\n/**\n * Encode a blob as one or more chunks.\n * Large blobs (>10MB) are split into multiple chunks.\n */\nasync function* encodeBlobChunks(\n blob: BlobEntry,\n data: Uint8Array,\n key: CryptoKey\n): AsyncGenerator<Uint8Array> {\n const totalParts = Math.ceil(data.length / MAX_BLOB_CHUNK_SIZE) || 1;\n\n for (let partIndex = 0; partIndex < totalParts; partIndex++) {\n const start = partIndex * MAX_BLOB_CHUNK_SIZE;\n const end = Math.min(start + MAX_BLOB_CHUNK_SIZE, data.length);\n const partData = data.slice(start, end);\n\n const header: BlobHeader = {\n path: blob.path,\n mimeType: blob.mimeType,\n size: blob.size,\n ...(totalParts > 1 && { partIndex, totalParts })\n };\n\n const headerBytes = new TextEncoder().encode(JSON.stringify(header));\n const chunkData = new Uint8Array(headerBytes.length + 1 + partData.length);\n chunkData.set(headerBytes, 0);\n chunkData[headerBytes.length] = 0;\n chunkData.set(partData, headerBytes.length + 1);\n\n yield createChunk(chunkData, ChunkType.BLOB, key);\n }\n}\n\n/**\n * Encode a complete backup file.\n *\n * @param options - Encoding options\n * @returns Complete backup file as Uint8Array\n */\nexport async function encode(options: EncodeOptions): Promise<Uint8Array> {\n const { password, manifest, database, blobs, readBlob, onProgress } = options;\n\n const salt = generateSalt();\n const key = await deriveKey(password, salt);\n\n const header = createHeader(salt);\n const chunks: Uint8Array[] = [header];\n\n const totalSteps = 2 + blobs.length;\n let currentStep = 0;\n\n const reportProgress = (\n phase: BackupProgressEvent['phase'],\n item?: string\n ) => {\n onProgress?.({\n phase,\n current: currentStep,\n total: totalSteps,\n currentItem: item\n });\n };\n\n reportProgress('preparing', 'manifest');\n const manifestChunk = await encodeJsonChunk(\n manifest,\n ChunkType.MANIFEST,\n key\n );\n chunks.push(manifestChunk);\n currentStep++;\n\n reportProgress('database', 'database');\n const databaseChunk = await encodeJsonChunk(\n database,\n ChunkType.DATABASE,\n key\n );\n chunks.push(databaseChunk);\n currentStep++;\n\n for (const blob of blobs) {\n reportProgress('blobs', blob.path);\n const blobData = await readBlob(blob.path);\n\n for await (const chunk of encodeBlobChunks(blob, blobData, key)) {\n chunks.push(chunk);\n }\n currentStep++;\n }\n\n const totalSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const output = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.length;\n }\n\n reportProgress('finalizing', 'complete');\n\n return output;\n}\n","/**\n * File-based key management for CLI.\n * Stores encryption keys and session data in ~/.tearleads\n */\n\nimport fs from 'node:fs/promises';\nimport {\n deriveKeyFromPassword,\n exportKey,\n exportWrappingKey,\n generateExtractableWrappingKey,\n generateSalt,\n importKey,\n importWrappingKey,\n secureZero,\n unwrapKey,\n wrapKey\n} from '@rapid/shared';\nimport {\n clearSession as clearSessionFile,\n ensureConfigDir,\n getConfigPaths,\n hasSession as hasSessionFile\n} from '../config/index.js';\n\nexport interface StoredKeyData {\n salt: number[];\n keyCheckValue: string;\n}\n\nexport interface SessionData {\n wrappedKey: number[];\n wrappingKey: number[];\n}\n\nlet currentKey: Uint8Array | null = null;\n\n/**\n * Check if a database key has been set up.\n */\nexport async function hasExistingKey(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.keyData);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Read stored key data from file.\n */\nasync function readKeyData(): Promise<StoredKeyData | null> {\n const paths = getConfigPaths();\n try {\n const content = await fs.readFile(paths.keyData, 'utf-8');\n return JSON.parse(content) as StoredKeyData;\n } catch {\n return null;\n }\n}\n\n/**\n * Write key data to file with restrictive permissions.\n */\nasync function writeKeyData(data: StoredKeyData): Promise<void> {\n await ensureConfigDir();\n const paths = getConfigPaths();\n await fs.writeFile(paths.keyData, JSON.stringify(data), {\n mode: 0o600\n });\n}\n\n/**\n * Read session data from file.\n */\nasync function readSessionData(): Promise<SessionData | null> {\n const paths = getConfigPaths();\n try {\n const content = await fs.readFile(paths.session, 'utf-8');\n return JSON.parse(content) as SessionData;\n } catch {\n return null;\n }\n}\n\n/**\n * Write session data to file with restrictive permissions.\n */\nasync function writeSessionData(data: SessionData): Promise<void> {\n await ensureConfigDir();\n const paths = getConfigPaths();\n await fs.writeFile(paths.session, JSON.stringify(data), {\n mode: 0o600\n });\n}\n\n/**\n * Create a key check value for password verification.\n */\nasync function createKeyCheckValue(keyBytes: Uint8Array): Promise<string> {\n const checkData = new TextEncoder().encode('TEARLEADS_KEY_CHECK');\n const key = await importKey(keyBytes);\n\n const iv = new Uint8Array(12);\n const encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n checkData\n );\n\n const bytes = new Uint8Array(encrypted).slice(0, 16);\n return btoa(String.fromCharCode(...bytes));\n}\n\n/**\n * Set up a new encryption key from a password.\n */\nexport async function setupNewKey(password: string): Promise<Uint8Array> {\n const salt = generateSalt();\n const key = await deriveKeyFromPassword(password, salt);\n const keyBytes = await exportKey(key);\n\n const kcv = await createKeyCheckValue(keyBytes);\n\n await writeKeyData({\n salt: Array.from(salt),\n keyCheckValue: kcv\n });\n\n currentKey = new Uint8Array(keyBytes);\n return keyBytes;\n}\n\n/**\n * Unlock with a password. Returns null if password is incorrect.\n */\nexport async function unlockWithPassword(\n password: string\n): Promise<Uint8Array | null> {\n const keyData = await readKeyData();\n if (!keyData) {\n throw new Error('No existing key found. Use setupNewKey instead.');\n }\n\n const salt = new Uint8Array(keyData.salt);\n const key = await deriveKeyFromPassword(password, salt);\n const keyBytes = await exportKey(key);\n\n const computedKcv = await createKeyCheckValue(keyBytes);\n\n if (keyData.keyCheckValue !== computedKcv) {\n secureZero(keyBytes);\n return null;\n }\n\n currentKey = new Uint8Array(keyBytes);\n return keyBytes;\n}\n\n/**\n * Change the encryption password.\n */\nexport async function changePassword(\n oldPassword: string,\n newPassword: string\n): Promise<{ oldKey: Uint8Array; newKey: Uint8Array } | null> {\n const oldKeyResult = await unlockWithPassword(oldPassword);\n if (!oldKeyResult) return null;\n\n // Clone the old key before we change currentKey\n const oldKey = new Uint8Array(oldKeyResult);\n\n const newSalt = generateSalt();\n const newCryptoKey = await deriveKeyFromPassword(newPassword, newSalt);\n const newKey = await exportKey(newCryptoKey);\n const newKcv = await createKeyCheckValue(newKey);\n\n await writeKeyData({\n salt: Array.from(newSalt),\n keyCheckValue: newKcv\n });\n\n currentKey = new Uint8Array(newKey);\n\n return { oldKey, newKey };\n}\n\n/**\n * Get the current key (must be unlocked first).\n */\nexport function getCurrentKey(): Uint8Array | null {\n return currentKey;\n}\n\n/**\n * Clear the current key from memory.\n */\nexport function clearKey(): void {\n if (currentKey) {\n secureZero(currentKey);\n currentKey = null;\n }\n}\n\n/**\n * Reset everything (for testing or complete wipe).\n */\nexport async function reset(): Promise<void> {\n clearKey();\n const paths = getConfigPaths();\n try {\n await fs.unlink(paths.keyData);\n } catch {\n // Ignore\n }\n await clearSessionFile();\n}\n\n/**\n * Persist the current key for session restoration.\n */\nexport async function persistSession(): Promise<boolean> {\n if (!currentKey) return false;\n\n try {\n const wrappingKey = await generateExtractableWrappingKey();\n const wrappedKey = await wrapKey(currentKey, wrappingKey);\n const wrappingKeyBytes = await exportWrappingKey(wrappingKey);\n\n await writeSessionData({\n wrappedKey: Array.from(wrappedKey),\n wrappingKey: Array.from(wrappingKeyBytes)\n });\n\n return true;\n } catch (err) {\n console.error('Failed to persist session:', err);\n return false;\n }\n}\n\n/**\n * Check if a persisted session exists.\n */\nexport async function hasPersistedSession(): Promise<boolean> {\n return hasSessionFile();\n}\n\n/**\n * Restore a persisted session.\n */\nexport async function restoreSession(): Promise<Uint8Array | null> {\n try {\n const sessionData = await readSessionData();\n if (!sessionData) return null;\n\n const wrappingKeyBytes = new Uint8Array(sessionData.wrappingKey);\n const wrappedKey = new Uint8Array(sessionData.wrappedKey);\n\n const wrappingKey = await importWrappingKey(wrappingKeyBytes);\n const keyBytes = await unwrapKey(wrappedKey, wrappingKey);\n\n currentKey = new Uint8Array(keyBytes);\n return keyBytes;\n } catch (err) {\n console.error('Failed to restore session:', err);\n await clearPersistedSession();\n return null;\n }\n}\n\n/**\n * Clear any persisted session data.\n */\nexport async function clearPersistedSession(): Promise<void> {\n await clearSessionFile();\n}\n","/**\n * Asymmetric cryptography for VFS key exchange.\n *\n * Implements a hybrid post-quantum encryption scheme:\n * - X25519: Classical elliptic curve Diffie-Hellman (fast, well-tested)\n * - ML-KEM-768: Post-quantum Key Encapsulation Mechanism (NIST standardized)\n *\n * The hybrid approach ensures security even if one algorithm is broken:\n * - If quantum computers break X25519, ML-KEM protects you\n * - If ML-KEM has an undiscovered flaw, X25519 protects you\n */\nimport { gcm } from '@noble/ciphers/aes.js';\nimport { randomBytes } from '@noble/ciphers/utils.js';\nimport { x25519 } from '@noble/curves/ed25519.js';\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n// Constants\nconst HKDF_INFO = new TextEncoder().encode('rapid-vfs-hybrid-v1');\nconst DERIVED_KEY_LENGTH = 32; // 256 bits for AES-256\nconst NONCE_LENGTH = 12; // 96 bits for AES-GCM\n/**\n * Generate a new VFS keypair for a user.\n * This should be done once during account setup.\n */\nexport function generateKeyPair() {\n // Generate X25519 keypair\n const x25519PrivateKey = x25519.utils.randomSecretKey();\n const x25519PublicKey = x25519.getPublicKey(x25519PrivateKey);\n // Generate ML-KEM-768 keypair\n const mlKemKeys = ml_kem768.keygen();\n return {\n x25519PublicKey,\n x25519PrivateKey,\n mlKemPublicKey: mlKemKeys.publicKey,\n mlKemPrivateKey: mlKemKeys.secretKey\n };\n}\n/**\n * Extract only the public keys from a keypair.\n */\nexport function extractPublicKey(keyPair) {\n return {\n x25519PublicKey: keyPair.x25519PublicKey,\n mlKemPublicKey: keyPair.mlKemPublicKey\n };\n}\n/**\n * Encrypt data for a recipient using their public key.\n * Uses hybrid X25519 + ML-KEM encryption.\n *\n * @param plaintext The data to encrypt\n * @param recipientPublicKey The recipient's public key\n * @returns Encapsulated key material and ciphertext\n */\nexport function encryptForRecipient(plaintext, recipientPublicKey) {\n // Generate ephemeral X25519 keypair for this message\n const x25519EphemeralPrivate = x25519.utils.randomSecretKey();\n const x25519EphemeralPublic = x25519.getPublicKey(x25519EphemeralPrivate);\n // X25519 key exchange\n const x25519SharedSecret = x25519.getSharedSecret(x25519EphemeralPrivate, recipientPublicKey.x25519PublicKey);\n // ML-KEM encapsulation\n const { cipherText: mlKemCiphertext, sharedSecret: mlKemSharedSecret } = ml_kem768.encapsulate(recipientPublicKey.mlKemPublicKey);\n // Combine shared secrets using HKDF\n const combinedSecret = new Uint8Array(x25519SharedSecret.length + mlKemSharedSecret.length);\n combinedSecret.set(x25519SharedSecret, 0);\n combinedSecret.set(mlKemSharedSecret, x25519SharedSecret.length);\n const derivedKey = hkdf(sha256, combinedSecret, undefined, HKDF_INFO, DERIVED_KEY_LENGTH);\n // Encrypt with AES-256-GCM\n const nonce = randomBytes(NONCE_LENGTH);\n const cipher = gcm(derivedKey, nonce);\n const ciphertext = cipher.encrypt(plaintext);\n // Zero out sensitive data\n x25519EphemeralPrivate.fill(0);\n x25519SharedSecret.fill(0);\n mlKemSharedSecret.fill(0);\n combinedSecret.fill(0);\n return {\n x25519EphemeralPublic,\n mlKemCiphertext,\n nonce,\n ciphertext\n };\n}\n/**\n * Decrypt data using your private key.\n *\n * @param encapsulation The encapsulated key material and ciphertext\n * @param recipientKeyPair Your keypair (with private keys)\n * @returns Decrypted plaintext\n */\nexport function decryptWithKeyPair(encapsulation, recipientKeyPair) {\n // X25519 key exchange (using ephemeral public from sender)\n const x25519SharedSecret = x25519.getSharedSecret(recipientKeyPair.x25519PrivateKey, encapsulation.x25519EphemeralPublic);\n // ML-KEM decapsulation\n const mlKemSharedSecret = ml_kem768.decapsulate(encapsulation.mlKemCiphertext, recipientKeyPair.mlKemPrivateKey);\n // Combine shared secrets using HKDF (same as encryption)\n const combinedSecret = new Uint8Array(x25519SharedSecret.length + mlKemSharedSecret.length);\n combinedSecret.set(x25519SharedSecret, 0);\n combinedSecret.set(mlKemSharedSecret, x25519SharedSecret.length);\n const derivedKey = hkdf(sha256, combinedSecret, undefined, HKDF_INFO, DERIVED_KEY_LENGTH);\n // Decrypt with AES-256-GCM\n const cipher = gcm(derivedKey, encapsulation.nonce);\n const plaintext = cipher.decrypt(encapsulation.ciphertext);\n // Zero out sensitive data\n x25519SharedSecret.fill(0);\n mlKemSharedSecret.fill(0);\n combinedSecret.fill(0);\n return plaintext;\n}\n/**\n * Wrap a symmetric key for a recipient.\n * This is the primary use case for VFS: sharing item session keys.\n *\n * @param sessionKey The symmetric key to wrap (typically 32 bytes for AES-256)\n * @param recipientPublicKey The recipient's public key\n * @returns Serialized encapsulation (base64-encoded for database storage)\n */\nexport function wrapKeyForRecipient(sessionKey, recipientPublicKey) {\n const encapsulation = encryptForRecipient(sessionKey, recipientPublicKey);\n return serializeEncapsulation(encapsulation);\n}\n/**\n * Unwrap a symmetric key using your private key.\n *\n * @param wrappedKey Serialized encapsulation from wrapKeyForRecipient\n * @param recipientKeyPair Your keypair\n * @returns The original symmetric key\n */\nexport function unwrapKeyWithKeyPair(wrappedKey, recipientKeyPair) {\n const encapsulation = deserializeEncapsulation(wrappedKey);\n return decryptWithKeyPair(encapsulation, recipientKeyPair);\n}\n// =============================================================================\n// Serialization helpers (for database storage)\n// =============================================================================\nfunction toBase64(data) {\n let binary = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < data.length; i += chunkSize) {\n binary += String.fromCharCode(...data.subarray(i, i + chunkSize));\n }\n return btoa(binary);\n}\nfunction fromBase64(base64) {\n return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));\n}\n/**\n * Serialize a keypair to base64 for storage or transmission.\n *\n * IMPORTANT: This returns RAW (unencrypted) private keys in base64 format.\n * The private keys MUST be encrypted (e.g., with a password-derived key via Argon2)\n * before being stored in the database's `encrypted_private_keys` field.\n *\n * Usage flow:\n * 1. Generate keypair with generateKeyPair()\n * 2. Serialize with serializeKeyPair() -> raw base64 keys\n * 3. Encrypt the serialized private keys with user's password-derived key\n * 4. Store encrypted blob in encrypted_private_keys, public keys stored as-is\n */\nexport function serializeKeyPair(keyPair) {\n return {\n x25519PublicKey: toBase64(keyPair.x25519PublicKey),\n x25519PrivateKey: toBase64(keyPair.x25519PrivateKey),\n mlKemPublicKey: toBase64(keyPair.mlKemPublicKey),\n mlKemPrivateKey: toBase64(keyPair.mlKemPrivateKey)\n };\n}\n/**\n * Deserialize a keypair from storage.\n */\nexport function deserializeKeyPair(serialized) {\n return {\n x25519PublicKey: fromBase64(serialized.x25519PublicKey),\n x25519PrivateKey: fromBase64(serialized.x25519PrivateKey),\n mlKemPublicKey: fromBase64(serialized.mlKemPublicKey),\n mlKemPrivateKey: fromBase64(serialized.mlKemPrivateKey)\n };\n}\n/**\n * Serialize a public key for storage/transmission.\n */\nexport function serializePublicKey(publicKey) {\n return {\n x25519PublicKey: toBase64(publicKey.x25519PublicKey),\n mlKemPublicKey: toBase64(publicKey.mlKemPublicKey)\n };\n}\n/**\n * Deserialize a public key from storage.\n */\nexport function deserializePublicKey(serialized) {\n return {\n x25519PublicKey: fromBase64(serialized.x25519PublicKey),\n mlKemPublicKey: fromBase64(serialized.mlKemPublicKey)\n };\n}\n/**\n * Serialize an encapsulation for storage.\n */\nexport function serializeEncapsulation(encapsulation) {\n return {\n x25519EphemeralPublic: toBase64(encapsulation.x25519EphemeralPublic),\n mlKemCiphertext: toBase64(encapsulation.mlKemCiphertext),\n nonce: toBase64(encapsulation.nonce),\n ciphertext: toBase64(encapsulation.ciphertext)\n };\n}\n/**\n * Deserialize an encapsulation from storage.\n */\nexport function deserializeEncapsulation(serialized) {\n return {\n x25519EphemeralPublic: fromBase64(serialized.x25519EphemeralPublic),\n mlKemCiphertext: fromBase64(serialized.mlKemCiphertext),\n nonce: fromBase64(serialized.nonce),\n ciphertext: fromBase64(serialized.ciphertext)\n };\n}\n/**\n * Combine serialized public key parts into a single string for database storage.\n * Format: base64(x25519) + \".\" + base64(mlKem)\n */\nexport function combinePublicKey(publicKey) {\n return `${publicKey.x25519PublicKey}.${publicKey.mlKemPublicKey}`;\n}\n/**\n * Split a combined public key string back into parts.\n */\nexport function splitPublicKey(combined) {\n const [x25519PublicKey, mlKemPublicKey] = combined.split('.');\n if (!x25519PublicKey || !mlKemPublicKey) {\n throw new Error('Invalid combined public key format');\n }\n return { x25519PublicKey, mlKemPublicKey };\n}\n/**\n * Combine encapsulation into a single string for database storage.\n * Format: base64(x25519Eph) + \".\" + base64(mlKemCt) + \".\" + base64(nonce) + \".\" + base64(ct)\n */\nexport function combineEncapsulation(encapsulation) {\n return [\n encapsulation.x25519EphemeralPublic,\n encapsulation.mlKemCiphertext,\n encapsulation.nonce,\n encapsulation.ciphertext\n ].join('.');\n}\n/**\n * Split a combined encapsulation string back into parts.\n */\nexport function splitEncapsulation(combined) {\n const parts = combined.split('.');\n if (parts.length !== 4) {\n throw new Error('Invalid combined encapsulation format');\n }\n const x25519EphemeralPublic = parts[0];\n const mlKemCiphertext = parts[1];\n const nonce = parts[2];\n const ciphertext = parts[3];\n if (!x25519EphemeralPublic || !mlKemCiphertext || !nonce || !ciphertext) {\n throw new Error('Invalid combined encapsulation format');\n }\n return {\n x25519EphemeralPublic,\n mlKemCiphertext,\n nonce,\n ciphertext\n };\n}\n","/**\n * Web Crypto API utilities for database encryption.\n * Uses AES-256-GCM for authenticated encryption.\n *\n * This module is compatible with both Node.js and browser environments.\n */\nimport { assertPlainArrayBuffer } from '../index.js';\nconst ALGORITHM = 'AES-GCM';\nconst KEY_LENGTH = 256;\nconst IV_LENGTH = 12;\nconst TAG_LENGTH = 128;\nconst SALT_LENGTH = 32;\nconst PBKDF2_ITERATIONS = 600000;\n/**\n * Generate a cryptographically secure random salt.\n */\nexport function generateSalt() {\n return crypto.getRandomValues(new Uint8Array(SALT_LENGTH));\n}\n/**\n * Generate a random encryption key.\n */\nexport async function generateRandomKey() {\n const key = await crypto.subtle.generateKey({ name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n const exported = await crypto.subtle.exportKey('raw', key);\n return new Uint8Array(exported);\n}\n/**\n * Derive an encryption key from a password using PBKDF2.\n */\nexport async function deriveKeyFromPassword(password, salt) {\n const encoder = new TextEncoder();\n const passwordBuffer = encoder.encode(password);\n const keyMaterial = await crypto.subtle.importKey('raw', passwordBuffer, 'PBKDF2', false, ['deriveBits', 'deriveKey']);\n assertPlainArrayBuffer(salt);\n return crypto.subtle.deriveKey({\n name: 'PBKDF2',\n salt,\n iterations: PBKDF2_ITERATIONS,\n hash: 'SHA-256'\n }, keyMaterial, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n}\n/**\n * Export a CryptoKey to raw bytes.\n */\nexport async function exportKey(key) {\n const exported = await crypto.subtle.exportKey('raw', key);\n return new Uint8Array(exported);\n}\n/**\n * Import raw key bytes as a CryptoKey.\n */\nexport async function importKey(keyBytes) {\n assertPlainArrayBuffer(keyBytes);\n return crypto.subtle.importKey('raw', keyBytes, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n}\n/**\n * Encrypt data using AES-GCM.\n * Returns IV prepended to ciphertext.\n */\nexport async function encrypt(data, key, additionalData) {\n const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));\n assertPlainArrayBuffer(data);\n const algorithm = {\n name: ALGORITHM,\n iv,\n tagLength: TAG_LENGTH\n };\n if (additionalData) {\n assertPlainArrayBuffer(additionalData);\n algorithm.additionalData = additionalData;\n }\n const ciphertext = await crypto.subtle.encrypt(algorithm, key, data);\n const result = new Uint8Array(IV_LENGTH + ciphertext.byteLength);\n result.set(iv, 0);\n result.set(new Uint8Array(ciphertext), IV_LENGTH);\n return result;\n}\n/**\n * Decrypt data using AES-GCM.\n * Expects IV prepended to ciphertext.\n */\nexport async function decrypt(encryptedData, key, additionalData) {\n const iv = encryptedData.slice(0, IV_LENGTH);\n const ciphertext = encryptedData.slice(IV_LENGTH);\n const algorithm = {\n name: ALGORITHM,\n iv,\n tagLength: TAG_LENGTH\n };\n if (additionalData) {\n assertPlainArrayBuffer(additionalData);\n algorithm.additionalData = additionalData;\n }\n const decrypted = await crypto.subtle.decrypt(algorithm, key, ciphertext);\n return new Uint8Array(decrypted);\n}\n/**\n * Securely zero out a buffer to prevent key leakage.\n */\nexport function secureZero(buffer) {\n crypto.getRandomValues(buffer);\n buffer.fill(0);\n}\n/**\n * Encrypt a string value (for storing secrets).\n */\nexport async function encryptString(value, key) {\n const encoder = new TextEncoder();\n const data = encoder.encode(value);\n const encrypted = await encrypt(data, key);\n return btoa(String.fromCharCode(...encrypted));\n}\n/**\n * Decrypt a string value.\n */\nexport async function decryptString(encryptedValue, key) {\n const encrypted = Uint8Array.from(atob(encryptedValue), (c) => c.charCodeAt(0));\n const decrypted = await decrypt(encrypted, key);\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n}\n/**\n * Generate a non-extractable wrapping key for session persistence.\n * This key can be stored in IndexedDB but its raw bytes cannot be exported.\n */\nexport async function generateWrappingKey() {\n return crypto.subtle.generateKey({ name: 'AES-KW', length: 256 }, false, [\n 'wrapKey',\n 'unwrapKey'\n ]);\n}\n/**\n * Generate an extractable wrapping key for platforms that need it.\n * This key can be exported to raw bytes for storage.\n */\nexport async function generateExtractableWrappingKey() {\n return crypto.subtle.generateKey({ name: 'AES-KW', length: 256 }, true, [\n 'wrapKey',\n 'unwrapKey'\n ]);\n}\n/**\n * Export a wrapping key to raw bytes.\n */\nexport async function exportWrappingKey(key) {\n const exported = await crypto.subtle.exportKey('raw', key);\n return new Uint8Array(exported);\n}\n/**\n * Import raw bytes as a wrapping key.\n */\nexport async function importWrappingKey(keyBytes) {\n assertPlainArrayBuffer(keyBytes);\n return crypto.subtle.importKey('raw', keyBytes, { name: 'AES-KW', length: 256 }, true, ['wrapKey', 'unwrapKey']);\n}\n/**\n * Wrap (encrypt) a key using a wrapping key.\n */\nexport async function wrapKey(keyToWrap, wrappingKey) {\n assertPlainArrayBuffer(keyToWrap);\n const cryptoKey = await crypto.subtle.importKey('raw', keyToWrap, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n const wrapped = await crypto.subtle.wrapKey('raw', cryptoKey, wrappingKey, {\n name: 'AES-KW'\n });\n return new Uint8Array(wrapped);\n}\n/**\n * Unwrap (decrypt) a wrapped key using a wrapping key.\n */\nexport async function unwrapKey(wrappedKey, wrappingKey) {\n assertPlainArrayBuffer(wrappedKey);\n const unwrappedCryptoKey = await crypto.subtle.unwrapKey('raw', wrappedKey, wrappingKey, { name: 'AES-KW' }, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n const exported = await crypto.subtle.exportKey('raw', unwrappedCryptoKey);\n return new Uint8Array(exported);\n}\n","/**\n * Shared types and utilities\n */\nexport * from './crypto/asymmetric.js';\n// Crypto utilities\nexport * from './crypto/web-crypto.js';\n// AI conversations\nexport * from './ai-conversations.js';\n// Chat validation helpers\nexport * from './chat.js';\n// OpenRouter model options\nexport * from './openrouter.js';\n// Tree utilities\nexport * from './tree/index.js';\n// =============================================================================\n// MLS (RFC 9420) Encrypted Chat Types\n// =============================================================================\n// =============================================================================\n// MLS (RFC 9420) Encrypted Chat Types\n// =============================================================================\n/** MLS ciphersuites - X-Wing hybrid (ML-KEM + X25519) for post-quantum security */\nexport const MLS_CIPHERSUITES = {\n /** MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 */\n X25519_AES128GCM: 1,\n /** MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519 */\n X25519_CHACHA20_SHA256_ED25519: 3,\n /** X-Wing hybrid: ML-KEM-768 + X25519 for post-quantum security */\n XWING_HYBRID: 65535\n};\n// Utilities\nexport function formatDate(date) {\n return date.toISOString();\n}\n// Type Guards\n/**\n * Type guard to check if a value is a non-null object (record).\n */\nexport function isRecord(value) {\n return typeof value === 'object' && value !== null;\n}\n/**\n * Assertion function to narrow Uint8Array<ArrayBufferLike> to Uint8Array<ArrayBuffer>.\n *\n * With @tsconfig/strictest, Uint8Array is typed as Uint8Array<ArrayBufferLike>\n * where ArrayBufferLike = ArrayBuffer | SharedArrayBuffer. Web Crypto API and\n * Blob constructor expect plain ArrayBuffer, not ArrayBufferLike.\n *\n * In practice, Uint8Arrays always use plain ArrayBuffer - SharedArrayBuffer\n * requires explicit opt-in and specific headers. This assertion narrows the type\n * by checking for SharedArrayBuffer rather than ArrayBuffer (since instanceof\n * ArrayBuffer can fail across realms in test environments).\n */\nexport function assertPlainArrayBuffer(arr) {\n if (typeof SharedArrayBuffer !== 'undefined' &&\n arr.buffer instanceof SharedArrayBuffer) {\n throw new Error('Unexpected SharedArrayBuffer backing Uint8Array. This should never occur in normal operation.');\n }\n}\n/**\n * Safely extract an error code from an unknown error value.\n * Returns undefined if the error doesn't have a string code property.\n */\nexport function getErrorCode(error) {\n if (!isRecord(error)) {\n return undefined;\n }\n const code = error['code'];\n return typeof code === 'string' ? code : undefined;\n}\n/**\n * Safely convert a value to a finite number, returning null if not possible.\n * Handles both numbers and numeric strings (useful for SQLite query results).\n */\nexport function toFiniteNumber(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return null;\n}\n","/**\n * Configuration directory management for ~/.tearleads\n */\n\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport interface ConfigPaths {\n root: string;\n database: string;\n keyData: string;\n session: string;\n}\n\nlet configRoot: string | null = null;\n\n/**\n * Set a custom config root (for testing).\n */\nexport function setConfigRoot(root: string | null): void {\n configRoot = root;\n}\n\n/**\n * Get the configuration directory paths.\n */\nexport function getConfigPaths(): ConfigPaths {\n const root = configRoot ?? path.join(os.homedir(), '.tearleads');\n return {\n root,\n database: path.join(root, 'tearleads.db'),\n keyData: path.join(root, 'keydata.json'),\n session: path.join(root, '.session')\n };\n}\n\n/**\n * Ensure the config directory exists with proper permissions.\n */\nexport async function ensureConfigDir(): Promise<void> {\n const paths = getConfigPaths();\n await fs.mkdir(paths.root, { recursive: true, mode: 0o700 });\n}\n\n/**\n * Check if the config directory exists.\n */\nexport async function configExists(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.root);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if the database is set up (keydata.json exists).\n */\nexport async function isDatabaseSetUp(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.keyData);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a session file exists.\n */\nexport async function hasSession(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.session);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Clear the session file.\n */\nexport async function clearSession(): Promise<void> {\n const paths = getConfigPaths();\n try {\n await fs.unlink(paths.session);\n } catch {\n // Ignore if file doesn't exist\n }\n}\n\n/**\n * Remove all config files (for reset).\n */\nexport async function clearConfig(): Promise<void> {\n const paths = getConfigPaths();\n try {\n await fs.rm(paths.root, { recursive: true, force: true });\n } catch {\n // Ignore errors\n }\n}\n","/**\n * Database operations for the CLI.\n */\n\nimport fs from 'node:fs/promises';\nimport type { BackupDatabase } from '../backup/types.js';\nimport { getConfigPaths } from '../config/index.js';\nimport {\n changePassword as changeKeyPassword,\n clearKey,\n getCurrentKey,\n hasExistingKey,\n hasPersistedSession,\n persistSession,\n restoreSession,\n setupNewKey,\n unlockWithPassword\n} from '../crypto/key-manager.js';\nimport { NativeSqliteAdapter } from './adapter.js';\n\nlet adapter: NativeSqliteAdapter | null = null;\n\n/**\n * Check if a database has been set up.\n */\nexport async function isDatabaseSetUp(): Promise<boolean> {\n return hasExistingKey();\n}\n\n/**\n * Check if the database is currently unlocked.\n */\nexport function isDatabaseUnlocked(): boolean {\n return adapter?.isOpen() ?? false;\n}\n\n/**\n * Set up a new database with a password.\n */\nexport async function setupDatabase(password: string): Promise<void> {\n const key = await setupNewKey(password);\n\n adapter = new NativeSqliteAdapter();\n await adapter.initialize(key);\n\n // Persist session for convenience\n await persistSession();\n}\n\n/**\n * Unlock an existing database with a password.\n */\nexport async function unlockDatabase(password: string): Promise<boolean> {\n const key = await unlockWithPassword(password);\n if (!key) {\n return false;\n }\n\n adapter = new NativeSqliteAdapter();\n await adapter.open(key);\n\n // Persist session for convenience\n await persistSession();\n\n return true;\n}\n\n/**\n * Restore a database session from persisted key.\n */\nexport async function restoreDatabaseSession(): Promise<boolean> {\n const key = await restoreSession();\n if (!key) {\n return false;\n }\n\n adapter = new NativeSqliteAdapter();\n await adapter.open(key);\n\n return true;\n}\n\n/**\n * Lock the database (close and clear key).\n */\nexport function lockDatabase(): void {\n if (adapter) {\n adapter.close();\n adapter = null;\n }\n clearKey();\n}\n\n/**\n * Export the database to JSON.\n */\nexport function exportDatabase(): Record<string, unknown[]> {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n return adapter.exportToJson();\n}\n\n/**\n * Export the database to a backup-ready structure.\n */\nexport function exportBackupDatabase(): BackupDatabase {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n return adapter.exportToBackupDatabase();\n}\n\n/**\n * Import data into the database from JSON.\n */\nexport function importDatabase(data: Record<string, unknown[]>): void {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n adapter.importFromJson(data);\n}\n\n/**\n * Import a backup database structure.\n */\nexport function importBackupDatabase(database: BackupDatabase): void {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n adapter.importFromBackupDatabase(database);\n}\n\n/**\n * Change the database password.\n */\nexport async function changePassword(\n oldPassword: string,\n newPassword: string\n): Promise<boolean> {\n const result = await changeKeyPassword(oldPassword, newPassword);\n if (!result) {\n return false;\n }\n\n // Re-key the database if it's open\n if (adapter?.isOpen()) {\n await adapter.rekeyDatabase(result.newKey);\n } else {\n // Open with old key, re-key, close\n adapter = new NativeSqliteAdapter();\n await adapter.open(result.oldKey);\n await adapter.rekeyDatabase(result.newKey);\n }\n\n // Update persisted session\n await persistSession();\n\n return true;\n}\n\n/**\n * Get the current encryption key (for testing).\n */\nexport function getKey(): Uint8Array | null {\n return getCurrentKey();\n}\n\n/**\n * Reset the database (delete all data).\n */\nexport async function resetDatabase(): Promise<void> {\n lockDatabase();\n\n const paths = getConfigPaths();\n try {\n await fs.unlink(paths.database);\n } catch {\n // Ignore if file doesn't exist\n }\n}\n\n// Re-export for convenience\nexport { hasPersistedSession };\n","/**\n * Native SQLite adapter using better-sqlite3-multiple-ciphers.\n * Provides on-disk encrypted SQLite database persistence.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Database as DatabaseType } from 'better-sqlite3';\nimport Database from 'better-sqlite3-multiple-ciphers';\nimport type {\n BackupDatabase,\n IndexSchema,\n TableSchema\n} from '../backup/types.js';\nimport { getConfigPaths } from '../config/index.js';\n\n/**\n * Schema for the tearleads database.\n */\nconst SCHEMA = `\n CREATE TABLE IF NOT EXISTS contacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n email TEXT,\n phone TEXT,\n notes TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contact_id INTEGER REFERENCES contacts(id),\n type TEXT NOT NULL,\n description TEXT,\n event_date TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n CREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n`;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction getStringField(\n value: Record<string, unknown>,\n key: string\n): string | null {\n const field = value[key];\n return typeof field === 'string' ? field : null;\n}\n\n/**\n * Convert Uint8Array key to hex string for SQLCipher PRAGMA.\n */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Native SQLite adapter with SQLCipher encryption.\n */\nexport class NativeSqliteAdapter {\n private db: DatabaseType | null = null;\n private dbPath: string;\n\n constructor() {\n const configPaths = getConfigPaths();\n this.dbPath = configPaths.database;\n }\n\n /**\n * Initialize a new encrypted database with the given key.\n * Creates the database file and schema.\n */\n async initialize(key: Uint8Array): Promise<void> {\n // Ensure directory exists\n await fs.mkdir(path.dirname(this.dbPath), { recursive: true, mode: 0o700 });\n\n // Create new database file\n this.db = new Database(this.dbPath);\n\n // Apply encryption\n this.db.pragma(`key = \"x'${bytesToHex(key)}'\"`);\n this.db.pragma('cipher_compatibility = 4');\n\n // Create schema\n this.db.exec(SCHEMA);\n }\n\n /**\n * Open an existing encrypted database with the given key.\n */\n async open(key: Uint8Array): Promise<void> {\n // Check if database file exists\n try {\n await fs.access(this.dbPath);\n } catch {\n throw new Error('Database file not found');\n }\n\n // Open existing database\n this.db = new Database(this.dbPath);\n\n // Apply encryption key\n this.db.pragma(`key = \"x'${bytesToHex(key)}'\"`);\n this.db.pragma('cipher_compatibility = 4');\n\n // Verify the key by running a simple query\n try {\n this.db.prepare('SELECT count(*) FROM sqlite_master').get();\n } catch {\n this.db.close();\n this.db = null;\n throw new Error('Invalid encryption key');\n }\n }\n\n /**\n * Check if the database is currently open.\n */\n isOpen(): boolean {\n return this.db !== null;\n }\n\n /**\n * Close the database connection.\n */\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n /**\n * Re-key the database with a new encryption key.\n */\n async rekeyDatabase(newKey: Uint8Array): Promise<void> {\n if (!this.db) {\n throw new Error('Database not open');\n }\n this.db.pragma(`rekey = \"x'${bytesToHex(newKey)}'\"`);\n }\n\n /**\n * Export the database to a JSON structure for backup.\n */\n exportToJson(): Record<string, unknown[]> {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n const result: Record<string, unknown[]> = {};\n\n // Get all table names\n const tables = this.db\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n )\n .all() as { name: string }[];\n\n for (const { name } of tables) {\n const rows = this.db.prepare(`SELECT * FROM ${name}`).all();\n result[name] = rows;\n }\n\n return result;\n }\n\n /**\n * Export the database to a backup-friendly structure with schema and data.\n */\n exportToBackupDatabase(): BackupDatabase {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n const tables = this.db\n .prepare(\n \"SELECT name, sql FROM sqlite_master WHERE type='table' AND sql IS NOT NULL ORDER BY name\"\n )\n .all();\n\n const tableSchemas: TableSchema[] = [];\n for (const row of tables) {\n if (!isRecord(row)) continue;\n const name = getStringField(row, 'name');\n const sql = getStringField(row, 'sql');\n if (!name || !sql) continue;\n if (name.startsWith('sqlite_') || name === '__drizzle_migrations') {\n continue;\n }\n tableSchemas.push({ name, sql });\n }\n\n const indexes = this.db\n .prepare(\n \"SELECT name, tbl_name, sql FROM sqlite_master WHERE type='index' AND sql IS NOT NULL ORDER BY name\"\n )\n .all();\n\n const indexSchemas: IndexSchema[] = [];\n for (const row of indexes) {\n if (!isRecord(row)) continue;\n const name = getStringField(row, 'name');\n const tableName = getStringField(row, 'tbl_name');\n const sql = getStringField(row, 'sql');\n if (!name || !tableName || !sql) continue;\n if (name.startsWith('sqlite_')) continue;\n indexSchemas.push({ name, tableName, sql });\n }\n\n const data: Record<string, unknown[]> = {};\n for (const table of tableSchemas) {\n const rows = this.db.prepare(`SELECT * FROM \"${table.name}\"`).all();\n data[table.name] = rows;\n }\n\n return { tables: tableSchemas, indexes: indexSchemas, data };\n }\n\n /**\n * Import data from a JSON structure (restore from backup).\n */\n importFromJson(data: Record<string, unknown[]>): void {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n // Capture db reference for use in transaction callback\n const db = this.db;\n\n // Start transaction\n const transaction = db.transaction(() => {\n for (const [tableName, rows] of Object.entries(data)) {\n if (!Array.isArray(rows) || rows.length === 0) continue;\n\n // Clear existing data\n db.prepare(`DELETE FROM ${tableName}`).run();\n\n // Get column names from first row\n const firstRow = rows[0] as Record<string, unknown>;\n const columns = Object.keys(firstRow);\n const placeholders = columns.map(() => '?').join(', ');\n const insertStmt = db.prepare(\n `INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (${placeholders})`\n );\n\n // Insert each row\n for (const row of rows) {\n const rowData = row as Record<string, unknown>;\n const values = columns.map((col) => rowData[col]);\n insertStmt.run(...values);\n }\n }\n });\n\n transaction();\n }\n\n /**\n * Import a backup database structure, recreating schema and data.\n */\n importFromBackupDatabase(database: BackupDatabase): void {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n const db = this.db;\n\n const transaction = db.transaction(() => {\n const existingTables = db\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n )\n .all();\n\n for (const row of existingTables) {\n if (!isRecord(row)) continue;\n const name = getStringField(row, 'name');\n if (!name) continue;\n db.exec(`DROP TABLE IF EXISTS \"${name}\"`);\n }\n\n for (const table of database.tables) {\n db.exec(table.sql);\n }\n\n for (const [tableName, rows] of Object.entries(database.data)) {\n if (!Array.isArray(rows) || rows.length === 0) continue;\n\n const firstRow = rows[0];\n if (!isRecord(firstRow)) continue;\n const columns = Object.keys(firstRow);\n if (columns.length === 0) continue;\n\n const placeholders = columns.map(() => '?').join(', ');\n const insertStmt = db.prepare(\n `INSERT INTO \"${tableName}\" (${columns.join(', ')}) VALUES (${placeholders})`\n );\n\n for (const row of rows) {\n if (!isRecord(row)) continue;\n const values = columns.map((col) => row[col]);\n insertStmt.run(...values);\n }\n }\n\n for (const index of database.indexes) {\n if (index.sql.trim().length > 0) {\n db.exec(index.sql);\n }\n }\n });\n\n transaction();\n }\n\n /**\n * Execute a raw SQL query.\n */\n exec(sql: string): void {\n if (!this.db) {\n throw new Error('Database not open');\n }\n this.db.exec(sql);\n }\n\n /**\n * Get the database file path.\n */\n getPath(): string {\n return this.dbPath;\n }\n}\n","/**\n * Terminal prompt utilities.\n */\n\nimport { stdin, stdout } from 'node:process';\nimport * as readline from 'node:readline/promises';\n\n/**\n * Prompt for password input (hidden).\n */\nexport async function promptPassword(prompt: string): Promise<string> {\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n stdout.write(prompt);\n return await new Promise((resolve) => {\n let input = '';\n\n if (stdin.isTTY) {\n stdin.setRawMode(true);\n }\n stdin.resume();\n stdin.setEncoding('utf8');\n\n const onData = (char: string): void => {\n if (char === '\\n' || char === '\\r' || char === '\\u0004') {\n stdin.removeListener('data', onData);\n if (stdin.isTTY) {\n stdin.setRawMode(false);\n }\n stdout.write('\\n');\n resolve(input);\n } else if (char === '\\u0003') {\n process.exit(1);\n } else if (char === '\\u007F' || char === '\\b') {\n if (input.length > 0) {\n input = input.slice(0, -1);\n }\n } else {\n input += char;\n }\n };\n\n stdin.on('data', onData);\n });\n } finally {\n rl.close();\n }\n}\n\n/**\n * Prompt for yes/no confirmation.\n */\nexport async function promptConfirm(prompt: string): Promise<boolean> {\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n const answer = await rl.question(prompt);\n return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';\n } finally {\n rl.close();\n }\n}\n","/**\n * Dump command - Export database to unencrypted JSON files.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { decode } from '../backup/index.js';\nimport type { BackupDatabase } from '../backup/types.js';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n exportBackupDatabase,\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession\n} from '../db/index.js';\nimport { promptConfirm, promptPassword } from '../utils/prompt.js';\n\ninterface DumpOptions {\n force?: boolean;\n blobs?: boolean;\n inputFile?: string;\n password?: string;\n}\n\nexport async function runDump(\n folder: string,\n options: DumpOptions\n): Promise<void> {\n let database: BackupDatabase;\n\n if (options.inputFile) {\n // Dump from .rbu backup file\n const filePath = path.resolve(options.inputFile);\n const password = options.password\n ? options.password\n : await promptPassword('Backup password: ');\n\n try {\n const backupData = await fs.readFile(filePath);\n const decoded = await decode({\n data: new Uint8Array(backupData),\n password\n });\n database = decoded.database;\n\n if (decoded.blobs.length > 0) {\n console.warn(\n `Warning: backup contains ${decoded.blobs.length} blobs that will be ignored.`\n );\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n console.error(`File not found: ${filePath}`);\n } else {\n console.error(\n err instanceof Error\n ? err.message\n : 'Failed to read or decode backup file.'\n );\n }\n process.exit(1);\n }\n } else {\n // Dump from live database\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n if (!isDatabaseUnlocked()) {\n const canRestore = await hasPersistedSession();\n if (!canRestore || !(await restoreDatabaseSession())) {\n const message = canRestore\n ? 'Session expired. Run \"tearleads unlock\" first.'\n : 'Database not unlocked. Run \"tearleads unlock\" first.';\n console.error(message);\n process.exit(1);\n }\n }\n\n database = exportBackupDatabase();\n }\n\n const outputPath = path.resolve(folder);\n\n try {\n const stat = await fs.stat(outputPath);\n if (stat.isDirectory()) {\n if (!options.force) {\n const confirmed = await promptConfirm(\n `Folder ${outputPath} exists. Overwrite? (y/n): `\n );\n if (!confirmed) {\n console.log('Dump cancelled.');\n return;\n }\n }\n await fs.rm(outputPath, { recursive: true });\n } else {\n console.error(`${outputPath} exists and is not a directory.`);\n process.exit(1);\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error(\n `Error checking output path \"${outputPath}\": ${(err as Error).message}`\n );\n process.exit(1);\n }\n // Folder doesn't exist, which is fine\n }\n\n await fs.mkdir(outputPath, { recursive: true });\n await fs.mkdir(path.join(outputPath, 'tables'), { recursive: true });\n if (options.blobs !== false) {\n await fs.mkdir(path.join(outputPath, 'files'), { recursive: true });\n }\n\n const manifest = {\n createdAt: new Date().toISOString(),\n platform: 'cli' as const,\n appVersion: 'cli',\n exportedTables: database.tables.map((t) => t.name),\n blobCount: 0,\n blobTotalSize: 0\n };\n await fs.writeFile(\n path.join(outputPath, 'manifest.json'),\n JSON.stringify(manifest, null, 2)\n );\n\n const schema = {\n tables: database.tables,\n indexes: database.indexes\n };\n await fs.writeFile(\n path.join(outputPath, 'schema.json'),\n JSON.stringify(schema, null, 2)\n );\n\n for (const table of database.tables) {\n const tableData = database.data[table.name] ?? [];\n await fs.writeFile(\n path.join(outputPath, 'tables', `${table.name}.json`),\n JSON.stringify(tableData, null, 2)\n );\n }\n\n console.log(`Database dumped to ${outputPath}`);\n console.log(` Tables: ${database.tables.length}`);\n}\n\nexport const dumpCommand = new Command('dump')\n .description('Export database to unencrypted JSON files')\n .argument('<folder>', 'Output folder path')\n .option(\n '-f, --input-file <file>',\n 'Read from .rbu backup file instead of live database'\n )\n .option(\n '-p, --password <password>',\n 'Backup file password (used with --input-file)'\n )\n .option('--force', 'Overwrite existing folder without confirmation')\n .option('--no-blobs', 'Skip files directory')\n .action(runDump);\n","/**\n * Lock command - Lock the database and clear session.\n */\n\nimport { Command } from 'commander';\nimport { lockDatabase } from '../db/index.js';\n\nexport async function runLock(): Promise<void> {\n await lockDatabase();\n console.log('Database locked.');\n}\n\nexport const lockCommand = new Command('lock')\n .description('Lock the database')\n .action(runLock);\n","/**\n * Password command - Change the database password.\n */\n\nimport { Command } from 'commander';\nimport { changePassword, isDatabaseSetUp } from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\nexport async function runPassword(): Promise<void> {\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n const oldPassword = await promptPassword('Current password: ');\n const newPassword = await promptPassword('New password: ');\n\n if (!newPassword) {\n console.error('Password cannot be empty.');\n process.exit(1);\n }\n\n const confirm = await promptPassword('Confirm new password: ');\n\n if (newPassword !== confirm) {\n console.error('Passwords do not match.');\n process.exit(1);\n }\n\n const success = await changePassword(oldPassword, newPassword);\n\n if (!success) {\n console.error('Incorrect current password.');\n process.exit(1);\n }\n\n console.log('Password changed successfully.');\n}\n\nexport const passwordCommand = new Command('password')\n .description('Change database password')\n .action(runPassword);\n","/**\n * Restore command - Import database from a JSON file.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { decode } from '../backup/index.js';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n importBackupDatabase,\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession\n} from '../db/index.js';\nimport { promptConfirm, promptPassword } from '../utils/prompt.js';\n\ninterface RestoreOptions {\n force?: boolean;\n password?: string;\n}\n\nexport async function runRestore(\n file: string,\n options: RestoreOptions\n): Promise<void> {\n const filePath = path.resolve(file);\n\n try {\n await fs.access(filePath);\n } catch {\n console.error(`File not found: ${filePath}`);\n process.exit(1);\n }\n\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n // Try to restore session if not unlocked\n if (!isDatabaseUnlocked()) {\n if (await hasPersistedSession()) {\n const restored = await restoreDatabaseSession();\n if (!restored) {\n console.error('Session expired. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n } else {\n console.error('Database not unlocked. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n }\n\n if (!options.force) {\n const confirmed = await promptConfirm(\n 'This will overwrite existing data. Continue? (y/n): '\n );\n if (!confirmed) {\n console.log('Restore cancelled.');\n return;\n }\n }\n\n const password = options.password\n ? options.password\n : await promptPassword('Backup password: ');\n\n const backupData = await fs.readFile(filePath);\n let decoded: Awaited<ReturnType<typeof decode>>;\n try {\n decoded = await decode({ data: new Uint8Array(backupData), password });\n } catch (err) {\n console.error(\n err instanceof Error ? err.message : 'Failed to decode backup file.'\n );\n process.exit(1);\n }\n\n if (decoded.blobs.length > 0) {\n console.warn(\n `Warning: backup contains ${decoded.blobs.length} blobs that will be ignored in the CLI restore.`\n );\n }\n\n importBackupDatabase(decoded.database);\n console.log('Database restored successfully.');\n}\n\nexport const restoreCommand = new Command('restore')\n .description('Restore database from a backup file')\n .argument('<file>', 'Backup file path')\n .option('-f, --force', 'Overwrite without confirmation')\n .option('-p, --password <password>', 'Backup password')\n .action(runRestore);\n","/**\n * Setup command - Initialize a new encrypted database.\n */\n\nimport { Command } from 'commander';\nimport { isDatabaseSetUp, setupDatabase } from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\nexport async function runSetup(): Promise<void> {\n if (await isDatabaseSetUp()) {\n console.error(\n 'Database already set up. Use \"tearleads password\" to change password.'\n );\n process.exit(1);\n }\n\n const password = await promptPassword('Enter password: ');\n if (!password) {\n console.error('Password cannot be empty.');\n process.exit(1);\n }\n\n const confirm = await promptPassword('Confirm password: ');\n if (password !== confirm) {\n console.error('Passwords do not match.');\n process.exit(1);\n }\n\n await setupDatabase(password);\n console.log('Database initialized successfully.');\n}\n\nexport const setupCommand = new Command('setup')\n .description('Initialize a new encrypted database')\n .action(runSetup);\n","/**\n * Unlock command - Unlock the database with a password.\n */\n\nimport { Command } from 'commander';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession,\n unlockDatabase\n} from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\nexport async function runUnlock(): Promise<void> {\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n if (isDatabaseUnlocked()) {\n console.log('Database already unlocked.');\n return;\n }\n\n // Try to restore session first\n if (await hasPersistedSession()) {\n const restored = await restoreDatabaseSession();\n if (restored) {\n console.log('Database unlocked (session restored).');\n return;\n }\n }\n\n const password = await promptPassword('Enter password: ');\n const success = await unlockDatabase(password);\n\n if (!success) {\n console.error('Incorrect password.');\n process.exit(1);\n }\n\n console.log('Database unlocked.');\n}\n\nexport const unlockCommand = new Command('unlock')\n .description('Unlock the database')\n .action(runUnlock);\n"],"mappings":"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","names":["Command","fs","path","key","fs","PBKDF2_ITERATIONS","generateSalt","PBKDF2_ITERATIONS","fs","generateSalt","fs","fs","path","isRecord","fs","path","changePassword","path","fs","fs","path","Command","path","fs","Command","Command","Command","Command","changePassword","Command","fs","path","Command","path","fs","Command","Command","Command","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/backup.ts","../src/backup/constants.ts","../src/backup/compression.ts","../src/backup/crypto.ts","../src/backup/types.ts","../src/backup/decoder.ts","../src/backup/encoder.ts","../src/crypto/key-manager.ts","../../shared/dist/crypto/asymmetric.js","../../shared/dist/crypto/web-crypto.js","../../shared/dist/index.js","../src/config/index.ts","../src/db/index.ts","../src/db/adapter.ts","../src/utils/prompt.ts","../src/commands/dump.ts","../src/commands/lock.ts","../src/commands/password.ts","../src/commands/restore.ts","../src/commands/setup.ts","../src/commands/unlock.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Tearleads CLI - Database management for Tearleads.\n */\n\nimport { createRequire } from 'node:module';\nimport { Command } from 'commander';\nimport { backupCommand } from './commands/backup.js';\nimport { dumpCommand } from './commands/dump.js';\nimport { lockCommand } from './commands/lock.js';\nimport { passwordCommand } from './commands/password.js';\nimport { restoreCommand } from './commands/restore.js';\nimport { setupCommand } from './commands/setup.js';\nimport { unlockCommand } from './commands/unlock.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('tearleads')\n .description('Tearleads CLI for database management')\n .version(pkg.version);\n\nprogram.addCommand(setupCommand);\nprogram.addCommand(unlockCommand);\nprogram.addCommand(lockCommand);\nprogram.addCommand(backupCommand);\nprogram.addCommand(dumpCommand);\nprogram.addCommand(restoreCommand);\nprogram.addCommand(passwordCommand);\n\nprogram.parse();\n","/**\n * Backup command - Export database to a JSON file.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { encode } from '../backup/index.js';\nimport type { BackupManifest } from '../backup/types.js';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n exportBackupDatabase,\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession\n} from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\ninterface BackupOptions {\n password?: string;\n}\n\nasync function resolveBackupPassword(options: BackupOptions): Promise<string> {\n if (options.password) {\n return options.password;\n }\n\n const password = await promptPassword('Backup password: ');\n const confirm = await promptPassword('Confirm backup password: ');\n if (password !== confirm) {\n console.error('Passwords do not match.');\n process.exit(1);\n }\n return password;\n}\n\nexport async function runBackup(\n file: string,\n options: BackupOptions\n): Promise<void> {\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n // Try to restore session if not unlocked\n if (!isDatabaseUnlocked()) {\n if (await hasPersistedSession()) {\n const restored = await restoreDatabaseSession();\n if (!restored) {\n console.error('Session expired. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n } else {\n console.error('Database not unlocked. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n }\n\n const password = await resolveBackupPassword(options);\n const database = exportBackupDatabase();\n const manifest: BackupManifest = {\n createdAt: new Date().toISOString(),\n platform: 'cli',\n appVersion: 'cli',\n blobCount: 0,\n blobTotalSize: 0\n };\n\n const data = await encode({\n password,\n manifest,\n database,\n blobs: [],\n readBlob: async () => {\n throw new Error('No blob storage configured for CLI');\n }\n });\n const filePath = path.resolve(file);\n await fs.writeFile(filePath, data);\n console.log(`Backup saved to ${filePath}`);\n}\n\nexport const backupCommand = new Command('backup')\n .description('Export database to an encrypted .rbu backup file')\n .argument('<file>', 'Output file path')\n .option('-p, --password <password>', 'Backup password')\n .action(runBackup);\n","/**\n * Constants for the Universal Backup Format (.rbu)\n */\n\n/** Magic bytes identifying a valid .rbu file: \"RAPIDBAK\" */\nexport const MAGIC_BYTES = new Uint8Array([\n 0x52, 0x41, 0x50, 0x49, 0x44, 0x42, 0x41, 0x4b\n]);\n\n/** Current format version */\nexport const FORMAT_VERSION = 1;\n\n/** Total header size in bytes */\nexport const HEADER_SIZE = 32;\n\n/** Size of the magic bytes */\nexport const MAGIC_SIZE = 8;\n\n/** Size of the salt for PBKDF2 */\nexport const SALT_SIZE = 16;\n\n/** Size of the IV for AES-GCM */\nexport const IV_SIZE = 12;\n\n/** Size of the GCM authentication tag (included in ciphertext) */\nexport const AUTH_TAG_SIZE = 16;\n\n/** Chunk header size: 4 (length) + 1 (type) + 3 (reserved) + 12 (IV) = 20 bytes */\nexport const CHUNK_HEADER_SIZE = 20;\n\n/** PBKDF2 iterations for key derivation */\nexport const PBKDF2_ITERATIONS: number = 600_000;\n\n/** AES key size in bits */\nexport const AES_KEY_BITS = 256;\n\n/** Maximum blob size before splitting into multiple chunks (10 MB) */\nexport const MAX_BLOB_CHUNK_SIZE = 10 * 1024 * 1024;\n\n/** File extension for backup files */\nexport const BACKUP_EXTENSION = '.rbu';\n","/**\n * Compression utilities for backup data.\n *\n * Uses gzip compression with platform-appropriate implementation:\n * - Node.js: Native zlib module\n */\n\n/**\n * Compress data using gzip (Node.js implementation).\n */\nasync function compressNode(data: Uint8Array): Promise<Uint8Array> {\n const { gzipSync } = await import('node:zlib');\n return new Uint8Array(gzipSync(data));\n}\n\n/**\n * Decompress gzip data (Node.js implementation).\n */\nasync function decompressNode(data: Uint8Array): Promise<Uint8Array> {\n const { gunzipSync } = await import('node:zlib');\n return new Uint8Array(gunzipSync(data));\n}\n\n/**\n * Compress data using gzip.\n *\n * @param data - Uncompressed data\n * @returns Compressed data\n */\nexport async function compress(data: Uint8Array): Promise<Uint8Array> {\n return compressNode(data);\n}\n\n/**\n * Decompress gzip data.\n *\n * @param data - Compressed data\n * @returns Decompressed data\n * @throws Error if data is not valid gzip\n */\nexport async function decompress(data: Uint8Array): Promise<Uint8Array> {\n return decompressNode(data);\n}\n\n/**\n * Compress a string (UTF-8 encoded) using gzip.\n *\n * @param text - String to compress\n * @returns Compressed data\n */\nexport async function compressString(text: string): Promise<Uint8Array> {\n const encoder = new TextEncoder();\n return compress(encoder.encode(text));\n}\n\n/**\n * Decompress gzip data to a string (UTF-8 decoded).\n *\n * @param data - Compressed data\n * @returns Decompressed string\n */\nexport async function decompressString(data: Uint8Array): Promise<string> {\n const decompressed = await decompress(data);\n const decoder = new TextDecoder();\n return decoder.decode(decompressed);\n}\n","/**\n * Cryptographic utilities for backup encryption/decryption.\n *\n * Uses Web Crypto API for cross-platform compatibility:\n * - PBKDF2 for key derivation from password\n * - AES-256-GCM for authenticated encryption\n */\n\nimport {\n AES_KEY_BITS,\n AUTH_TAG_SIZE,\n IV_SIZE,\n PBKDF2_ITERATIONS,\n SALT_SIZE\n} from './constants.js';\n\n/**\n * Generate a random salt for PBKDF2 key derivation.\n */\nexport function generateSalt(): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(SALT_SIZE));\n}\n\n/**\n * Generate a random IV for AES-GCM encryption.\n */\nexport function generateIv(): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(IV_SIZE));\n}\n\n/**\n * Derive an AES-256 key from a password using PBKDF2.\n *\n * @param password - User-provided password\n * @param salt - Random salt (must be stored with encrypted data)\n * @returns CryptoKey suitable for AES-GCM operations\n */\nexport async function deriveKey(\n password: string,\n salt: Uint8Array,\n iterations: number = PBKDF2_ITERATIONS\n): Promise<CryptoKey> {\n const encoder = new TextEncoder();\n const passwordBytes = encoder.encode(password);\n\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n passwordBytes,\n 'PBKDF2',\n false,\n ['deriveBits', 'deriveKey']\n );\n\n const saltBuffer = new Uint8Array(salt).buffer;\n\n return crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: saltBuffer,\n iterations,\n hash: 'SHA-256'\n },\n keyMaterial,\n { name: 'AES-GCM', length: AES_KEY_BITS },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Encrypt data using AES-256-GCM.\n *\n * @param data - Plaintext data to encrypt\n * @param key - AES key derived from password\n * @returns Object containing IV and ciphertext (includes auth tag)\n */\nexport async function encrypt(\n data: Uint8Array,\n key: CryptoKey\n): Promise<{ iv: Uint8Array; ciphertext: Uint8Array }> {\n const iv = generateIv();\n\n const dataBuffer = new Uint8Array(data).buffer;\n const ivBuffer = new Uint8Array(iv).buffer;\n\n const ciphertext = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv: ivBuffer },\n key,\n dataBuffer\n );\n\n return {\n iv,\n ciphertext: new Uint8Array(ciphertext)\n };\n}\n\n/**\n * Decrypt data using AES-256-GCM.\n *\n * @param ciphertext - Encrypted data (includes auth tag)\n * @param key - AES key derived from password\n * @param iv - Initialization vector used during encryption\n * @returns Decrypted plaintext\n * @throws Error if decryption fails (wrong password or tampered data)\n */\nexport async function decrypt(\n ciphertext: Uint8Array,\n key: CryptoKey,\n iv: Uint8Array\n): Promise<Uint8Array> {\n const ciphertextBuffer = new Uint8Array(ciphertext).buffer;\n const ivBuffer = new Uint8Array(iv).buffer;\n\n const plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: ivBuffer },\n key,\n ciphertextBuffer\n );\n\n return new Uint8Array(plaintext);\n}\n\n/**\n * Calculate the encrypted size for a given plaintext size.\n * AES-GCM adds a 16-byte authentication tag.\n */\nexport function encryptedSize(plaintextSize: number): number {\n return plaintextSize + AUTH_TAG_SIZE;\n}\n\n/**\n * Calculate the plaintext size for a given ciphertext size.\n */\nexport function plaintextSize(ciphertextSize: number): number {\n return ciphertextSize - AUTH_TAG_SIZE;\n}\n","/**\n * Universal Backup Format Types\n *\n * Defines the structure of .rbu backup files that work across\n * all platforms (Web, Electron, iOS, Android, CLI).\n */\n\nexport type ChunkTypeValue = 0 | 1 | 2;\n\n/** Chunk types in the backup file */\nexport const ChunkType: {\n MANIFEST: ChunkTypeValue;\n DATABASE: ChunkTypeValue;\n BLOB: ChunkTypeValue;\n} = {\n MANIFEST: 0,\n DATABASE: 1,\n BLOB: 2\n};\n\n/** Backup file header (plaintext, 32 bytes) */\nexport interface BackupHeader {\n /** Magic bytes: \"RAPIDBAK\" */\n magic: Uint8Array;\n /** Format version (currently 1) */\n version: number;\n /** Flags for future use */\n flags: number;\n /** Salt for PBKDF2 key derivation */\n salt: Uint8Array;\n}\n\n/** Manifest chunk - metadata about the backup */\nexport interface BackupManifest {\n /** ISO timestamp when backup was created */\n createdAt: string;\n /** Platform that created the backup */\n platform: 'web' | 'electron' | 'ios' | 'android' | 'cli';\n /** App version that created the backup */\n appVersion: string;\n /** Total number of blob chunks */\n blobCount: number;\n /** Total size of all blobs in bytes */\n blobTotalSize: number;\n /** Instance name from source */\n instanceName?: string;\n}\n\n/** Database chunk - schema and row data */\nexport interface BackupDatabase {\n /** Table definitions from sqlite_master */\n tables: TableSchema[];\n /** Index definitions from sqlite_master */\n indexes: IndexSchema[];\n /** Row data keyed by table name */\n data: Record<string, unknown[]>;\n}\n\n/** Table schema extracted from sqlite_master */\nexport interface TableSchema {\n name: string;\n sql: string;\n}\n\n/** Index schema extracted from sqlite_master */\nexport interface IndexSchema {\n name: string;\n tableName: string;\n sql: string;\n}\n\n/** Blob entry header (stored before binary data in blob chunks) */\nexport interface BlobHeader {\n /** Relative path within the blob storage */\n path: string;\n /** MIME type of the blob */\n mimeType: string;\n /** Original size in bytes */\n size: number;\n /** For split blobs: which part this is (0-indexed) */\n partIndex?: number;\n /** For split blobs: total number of parts */\n totalParts?: number;\n}\n\n/** Chunk header structure (20 bytes) */\nexport interface ChunkHeader {\n /** Length of the encrypted payload */\n payloadLength: number;\n /** Type of chunk (manifest, database, blob) */\n chunkType: ChunkTypeValue;\n /** Reserved bytes for future use */\n reserved: Uint8Array;\n /** Initialization vector for AES-GCM */\n iv: Uint8Array;\n}\n\n/** Progress event during backup/restore */\nexport interface BackupProgressEvent {\n /** Current phase of the operation */\n phase: 'preparing' | 'database' | 'blobs' | 'finalizing';\n /** Current item number */\n current: number;\n /** Total items in this phase */\n total: number;\n /** Current item being processed */\n currentItem?: string | undefined;\n}\n\n/** Decoded blob data from a backup. */\nexport interface DecodedBlob {\n header: BlobHeader;\n data: Uint8Array;\n}\n\n/** Result of decoding a backup file. */\nexport interface DecodeResult {\n manifest: BackupManifest;\n database: BackupDatabase;\n blobs: DecodedBlob[];\n}\n\n/** Options for decoding a backup file. */\nexport interface DecodeOptions {\n data: Uint8Array;\n password: string;\n onProgress?: (event: BackupProgressEvent) => void;\n}\n\n/** Options for encoding a backup file. */\nexport interface EncodeOptions {\n password: string;\n manifest: BackupManifest;\n database: BackupDatabase;\n blobs: BlobEntry[];\n readBlob: (path: string) => Promise<Uint8Array>;\n onProgress?: (event: BackupProgressEvent) => void;\n}\n\n/** Entry in the blob listing */\nexport interface BlobEntry {\n path: string;\n mimeType: string;\n size: number;\n}\n","/**\n * Decoder for the Universal Backup Format (.rbu)\n *\n * Reads backup files with the following structure:\n * - Header (32 bytes, plaintext): magic, version, flags, salt\n * - Chunks (variable, encrypted): manifest, database, blobs\n */\n\nimport { decompress } from './compression.js';\nimport {\n CHUNK_HEADER_SIZE,\n FORMAT_VERSION,\n HEADER_SIZE,\n MAGIC_BYTES,\n MAGIC_SIZE,\n PBKDF2_ITERATIONS,\n SALT_SIZE\n} from './constants.js';\nimport { decrypt, deriveKey } from './crypto.js';\nimport {\n type BackupHeader,\n type BackupManifest,\n type BackupProgressEvent,\n type BlobHeader,\n ChunkType,\n type ChunkTypeValue,\n type DecodedBlob,\n type DecodeOptions,\n type DecodeResult\n} from './types.js';\n\n/**\n * Error thrown when backup file is invalid or corrupted.\n */\nexport class BackupDecodeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'BackupDecodeError';\n }\n}\n\n/**\n * Error thrown when password is incorrect.\n */\nexport class InvalidPasswordError extends Error {\n constructor() {\n super('Invalid password or corrupted backup');\n this.name = 'InvalidPasswordError';\n }\n}\n\n/**\n * Read a 32-bit unsigned integer from a buffer in little-endian format.\n */\nfunction readUint32LE(buffer: Uint8Array, offset: number): number {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n return view.getUint32(offset, true);\n}\n\n/**\n * Read a 16-bit unsigned integer from a buffer in little-endian format.\n */\nfunction readUint16LE(buffer: Uint8Array, offset: number): number {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n return view.getUint16(offset, true);\n}\n\n/**\n * Parse the backup file header.\n */\nfunction parseHeader(data: Uint8Array): BackupHeader {\n if (data.length < HEADER_SIZE) {\n throw new BackupDecodeError('File too small to be a valid backup');\n }\n\n const magic = data.slice(0, MAGIC_SIZE);\n for (let i = 0; i < MAGIC_SIZE; i++) {\n if (magic[i] !== MAGIC_BYTES[i]) {\n throw new BackupDecodeError('Invalid backup file: wrong magic bytes');\n }\n }\n\n const version = readUint16LE(data, MAGIC_SIZE);\n if (version > FORMAT_VERSION) {\n throw new BackupDecodeError(\n `Unsupported backup version: ${version} (max supported: ${FORMAT_VERSION})`\n );\n }\n\n const flags = readUint16LE(data, MAGIC_SIZE + 2);\n const salt = data.slice(MAGIC_SIZE + 4, MAGIC_SIZE + 4 + SALT_SIZE);\n\n return { magic, version, flags, salt };\n}\n\n/**\n * Parse a chunk header.\n */\nfunction parseChunkHeader(data: Uint8Array, offset: number) {\n if (offset + CHUNK_HEADER_SIZE > data.length) {\n throw new BackupDecodeError(\n 'Unexpected end of file while reading chunk header'\n );\n }\n\n const payloadLength = readUint32LE(data, offset);\n const chunkTypeValue = data[offset + 4] ?? -1;\n if (!isChunkTypeValue(chunkTypeValue)) {\n throw new BackupDecodeError(`Unknown chunk type: ${chunkTypeValue}`);\n }\n const reserved = data.slice(offset + 5, offset + 8);\n const iv = data.slice(offset + 8, offset + CHUNK_HEADER_SIZE);\n\n return { payloadLength, chunkType: chunkTypeValue, reserved, iv };\n}\n\nfunction isChunkTypeValue(value: number): value is ChunkTypeValue {\n return (\n value === ChunkType.MANIFEST ||\n value === ChunkType.DATABASE ||\n value === ChunkType.BLOB\n );\n}\n\n/**\n * Decrypt and decompress a chunk payload.\n */\nasync function decryptChunk(\n data: Uint8Array,\n offset: number,\n header: { payloadLength: number; iv: Uint8Array },\n key: CryptoKey\n): Promise<Uint8Array> {\n const payloadStart = offset + CHUNK_HEADER_SIZE;\n const payloadEnd = payloadStart + header.payloadLength;\n\n if (payloadEnd > data.length) {\n throw new BackupDecodeError(\n 'Unexpected end of file while reading chunk payload'\n );\n }\n\n const ciphertext = data.slice(payloadStart, payloadEnd);\n\n try {\n const compressed = await decrypt(ciphertext, key, header.iv);\n return decompress(compressed);\n } catch {\n throw new InvalidPasswordError();\n }\n}\n\n/**\n * Parse a JSON chunk (manifest or database).\n */\nfunction parseJsonChunk<T>(data: Uint8Array): T {\n const json = new TextDecoder().decode(data);\n return JSON.parse(json);\n}\n\n/**\n * Parse a blob chunk.\n */\nfunction parseBlobChunk(data: Uint8Array): DecodedBlob {\n const separatorIndex = data.indexOf(0);\n\n if (separatorIndex === -1) {\n throw new BackupDecodeError('Invalid blob chunk: missing separator');\n }\n\n const headerBytes = data.slice(0, separatorIndex);\n const blobData = data.slice(separatorIndex + 1);\n\n const header: BlobHeader = JSON.parse(new TextDecoder().decode(headerBytes));\n\n return { header, data: blobData };\n}\n\n/**\n * Decode a backup file.\n *\n * @param options - Decode options\n * @returns Decoded backup content\n */\nexport async function decode(options: DecodeOptions): Promise<DecodeResult> {\n const { data, password, onProgress } = options;\n\n const header = parseHeader(data);\n const decodeWithKey = async (key: CryptoKey): Promise<DecodeResult> => {\n let offset = HEADER_SIZE;\n let manifest: BackupManifest | null = null;\n let database: DecodeResult['database'] | null = null;\n const blobs: DecodedBlob[] = [];\n\n const totalChunks = Math.max(\n 1,\n Math.floor((data.length - HEADER_SIZE) / CHUNK_HEADER_SIZE)\n );\n let currentChunk = 0;\n\n const reportProgress = (\n phase: BackupProgressEvent['phase'],\n item?: string\n ) => {\n if (!onProgress) return;\n const event: BackupProgressEvent = {\n phase,\n current: currentChunk,\n total: totalChunks,\n currentItem: item\n };\n onProgress(event);\n };\n\n while (offset < data.length) {\n const chunkHeader = parseChunkHeader(data, offset);\n const chunkData = await decryptChunk(data, offset, chunkHeader, key);\n\n switch (chunkHeader.chunkType) {\n case ChunkType.MANIFEST:\n reportProgress('preparing', 'manifest');\n manifest = parseJsonChunk<BackupManifest>(chunkData);\n break;\n case ChunkType.DATABASE:\n reportProgress('database', 'database');\n database = parseJsonChunk<DecodeResult['database']>(chunkData);\n break;\n case ChunkType.BLOB:\n reportProgress('blobs', 'blob');\n blobs.push(parseBlobChunk(chunkData));\n break;\n default:\n throw new BackupDecodeError(\n `Unknown chunk type: ${chunkHeader.chunkType}`\n );\n }\n\n offset += CHUNK_HEADER_SIZE + chunkHeader.payloadLength;\n currentChunk++;\n }\n\n if (!manifest || !database) {\n throw new BackupDecodeError('Backup missing required chunks');\n }\n\n reportProgress('finalizing', 'complete');\n\n return { manifest, database, blobs };\n };\n\n const key = await deriveKey(password, header.salt, PBKDF2_ITERATIONS);\n return decodeWithKey(key);\n}\n\n/**\n * Read just the header from a backup file without decrypting.\n */\nexport function readHeader(data: Uint8Array): BackupHeader {\n return parseHeader(data);\n}\n\n/**\n * Validate a backup file without fully decoding it.\n */\nexport function validateBackup(data: Uint8Array): {\n valid: boolean;\n error?: string;\n} {\n try {\n const header = parseHeader(data);\n if (header.version > FORMAT_VERSION) {\n return {\n valid: false,\n error: `Unsupported backup version: ${header.version}`\n };\n }\n return { valid: true };\n } catch (err) {\n return {\n valid: false,\n error: err instanceof Error ? err.message : 'Invalid backup file'\n };\n }\n}\n","/**\n * Encoder for the Universal Backup Format (.rbu)\n *\n * Writes backup files with the following structure:\n * - Header (32 bytes, plaintext): magic, version, flags, salt\n * - Chunks (variable, encrypted): manifest, database, blobs\n */\n\nimport { compress } from './compression.js';\nimport {\n CHUNK_HEADER_SIZE,\n FORMAT_VERSION,\n HEADER_SIZE,\n MAGIC_BYTES,\n MAGIC_SIZE,\n MAX_BLOB_CHUNK_SIZE\n} from './constants.js';\nimport { deriveKey, encrypt, generateSalt } from './crypto.js';\nimport {\n type BackupProgressEvent,\n type BlobEntry,\n type BlobHeader,\n ChunkType,\n type ChunkTypeValue,\n type EncodeOptions\n} from './types.js';\n\n/**\n * Write a 32-bit unsigned integer to a buffer in little-endian format.\n */\nfunction writeUint32LE(\n buffer: Uint8Array,\n value: number,\n offset: number\n): void {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n view.setUint32(offset, value, true);\n}\n\n/**\n * Write a 16-bit unsigned integer to a buffer in little-endian format.\n */\nfunction writeUint16LE(\n buffer: Uint8Array,\n value: number,\n offset: number\n): void {\n const view = new DataView(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength\n );\n view.setUint16(offset, value, true);\n}\n\n/**\n * Create the backup file header.\n */\nfunction createHeader(salt: Uint8Array, flags: number = 0): Uint8Array {\n const header = new Uint8Array(HEADER_SIZE);\n\n header.set(MAGIC_BYTES, 0);\n writeUint16LE(header, FORMAT_VERSION, MAGIC_SIZE);\n writeUint16LE(header, flags, MAGIC_SIZE + 2);\n header.set(salt, MAGIC_SIZE + 4);\n\n return header;\n}\n\n/**\n * Create a chunk with header and encrypted payload.\n */\nasync function createChunk(\n data: Uint8Array,\n chunkType: ChunkTypeValue,\n key: CryptoKey\n): Promise<Uint8Array> {\n const compressed = await compress(data);\n const { iv, ciphertext } = await encrypt(compressed, key);\n const chunk = new Uint8Array(CHUNK_HEADER_SIZE + ciphertext.length);\n\n writeUint32LE(chunk, ciphertext.length, 0);\n chunk[4] = chunkType;\n chunk.set(iv, 8);\n chunk.set(ciphertext, CHUNK_HEADER_SIZE);\n\n return chunk;\n}\n\n/**\n * Encode JSON data as a chunk.\n */\nasync function encodeJsonChunk(\n data: unknown,\n chunkType: ChunkTypeValue,\n key: CryptoKey\n): Promise<Uint8Array> {\n const json = JSON.stringify(data);\n const bytes = new TextEncoder().encode(json);\n return createChunk(bytes, chunkType, key);\n}\n\n/**\n * Encode a blob as one or more chunks.\n * Large blobs (>10MB) are split into multiple chunks.\n */\nasync function* encodeBlobChunks(\n blob: BlobEntry,\n data: Uint8Array,\n key: CryptoKey\n): AsyncGenerator<Uint8Array> {\n const totalParts = Math.ceil(data.length / MAX_BLOB_CHUNK_SIZE) || 1;\n\n for (let partIndex = 0; partIndex < totalParts; partIndex++) {\n const start = partIndex * MAX_BLOB_CHUNK_SIZE;\n const end = Math.min(start + MAX_BLOB_CHUNK_SIZE, data.length);\n const partData = data.slice(start, end);\n\n const header: BlobHeader = {\n path: blob.path,\n mimeType: blob.mimeType,\n size: blob.size,\n ...(totalParts > 1 && { partIndex, totalParts })\n };\n\n const headerBytes = new TextEncoder().encode(JSON.stringify(header));\n const chunkData = new Uint8Array(headerBytes.length + 1 + partData.length);\n chunkData.set(headerBytes, 0);\n chunkData[headerBytes.length] = 0;\n chunkData.set(partData, headerBytes.length + 1);\n\n yield createChunk(chunkData, ChunkType.BLOB, key);\n }\n}\n\n/**\n * Encode a complete backup file.\n *\n * @param options - Encoding options\n * @returns Complete backup file as Uint8Array\n */\nexport async function encode(options: EncodeOptions): Promise<Uint8Array> {\n const { password, manifest, database, blobs, readBlob, onProgress } = options;\n\n const salt = generateSalt();\n const key = await deriveKey(password, salt);\n\n const header = createHeader(salt);\n const chunks: Uint8Array[] = [header];\n\n const totalSteps = 2 + blobs.length;\n let currentStep = 0;\n\n const reportProgress = (\n phase: BackupProgressEvent['phase'],\n item?: string\n ) => {\n onProgress?.({\n phase,\n current: currentStep,\n total: totalSteps,\n currentItem: item\n });\n };\n\n reportProgress('preparing', 'manifest');\n const manifestChunk = await encodeJsonChunk(\n manifest,\n ChunkType.MANIFEST,\n key\n );\n chunks.push(manifestChunk);\n currentStep++;\n\n reportProgress('database', 'database');\n const databaseChunk = await encodeJsonChunk(\n database,\n ChunkType.DATABASE,\n key\n );\n chunks.push(databaseChunk);\n currentStep++;\n\n for (const blob of blobs) {\n reportProgress('blobs', blob.path);\n const blobData = await readBlob(blob.path);\n\n for await (const chunk of encodeBlobChunks(blob, blobData, key)) {\n chunks.push(chunk);\n }\n currentStep++;\n }\n\n const totalSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const output = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.length;\n }\n\n reportProgress('finalizing', 'complete');\n\n return output;\n}\n","/**\n * File-based key management for CLI.\n * Stores encryption keys and session data in ~/.tearleads\n */\n\nimport fs from 'node:fs/promises';\nimport {\n deriveKeyFromPassword,\n exportKey,\n exportWrappingKey,\n generateExtractableWrappingKey,\n generateSalt,\n importKey,\n importWrappingKey,\n secureZero,\n unwrapKey,\n wrapKey\n} from '@rapid/shared';\nimport {\n clearSession as clearSessionFile,\n ensureConfigDir,\n getConfigPaths,\n hasSession as hasSessionFile\n} from '../config/index.js';\n\nexport interface StoredKeyData {\n salt: number[];\n keyCheckValue: string;\n}\n\nexport interface SessionData {\n wrappedKey: number[];\n wrappingKey: number[];\n}\n\nlet currentKey: Uint8Array | null = null;\n\n/**\n * Check if a database key has been set up.\n */\nexport async function hasExistingKey(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.keyData);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Read stored key data from file.\n */\nasync function readKeyData(): Promise<StoredKeyData | null> {\n const paths = getConfigPaths();\n try {\n const content = await fs.readFile(paths.keyData, 'utf-8');\n return JSON.parse(content) as StoredKeyData;\n } catch {\n return null;\n }\n}\n\n/**\n * Write key data to file with restrictive permissions.\n */\nasync function writeKeyData(data: StoredKeyData): Promise<void> {\n await ensureConfigDir();\n const paths = getConfigPaths();\n await fs.writeFile(paths.keyData, JSON.stringify(data), {\n mode: 0o600\n });\n}\n\n/**\n * Read session data from file.\n */\nasync function readSessionData(): Promise<SessionData | null> {\n const paths = getConfigPaths();\n try {\n const content = await fs.readFile(paths.session, 'utf-8');\n return JSON.parse(content) as SessionData;\n } catch {\n return null;\n }\n}\n\n/**\n * Write session data to file with restrictive permissions.\n */\nasync function writeSessionData(data: SessionData): Promise<void> {\n await ensureConfigDir();\n const paths = getConfigPaths();\n await fs.writeFile(paths.session, JSON.stringify(data), {\n mode: 0o600\n });\n}\n\n/**\n * Create a key check value for password verification.\n */\nasync function createKeyCheckValue(keyBytes: Uint8Array): Promise<string> {\n const checkData = new TextEncoder().encode('TEARLEADS_KEY_CHECK');\n const key = await importKey(keyBytes);\n\n const iv = new Uint8Array(12);\n const encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n checkData\n );\n\n const bytes = new Uint8Array(encrypted).slice(0, 16);\n return btoa(String.fromCharCode(...bytes));\n}\n\n/**\n * Set up a new encryption key from a password.\n */\nexport async function setupNewKey(password: string): Promise<Uint8Array> {\n const salt = generateSalt();\n const key = await deriveKeyFromPassword(password, salt);\n const keyBytes = await exportKey(key);\n\n const kcv = await createKeyCheckValue(keyBytes);\n\n await writeKeyData({\n salt: Array.from(salt),\n keyCheckValue: kcv\n });\n\n currentKey = new Uint8Array(keyBytes);\n return keyBytes;\n}\n\n/**\n * Unlock with a password. Returns null if password is incorrect.\n */\nexport async function unlockWithPassword(\n password: string\n): Promise<Uint8Array | null> {\n const keyData = await readKeyData();\n if (!keyData) {\n throw new Error('No existing key found. Use setupNewKey instead.');\n }\n\n const salt = new Uint8Array(keyData.salt);\n const key = await deriveKeyFromPassword(password, salt);\n const keyBytes = await exportKey(key);\n\n const computedKcv = await createKeyCheckValue(keyBytes);\n\n if (keyData.keyCheckValue !== computedKcv) {\n secureZero(keyBytes);\n return null;\n }\n\n currentKey = new Uint8Array(keyBytes);\n return keyBytes;\n}\n\n/**\n * Change the encryption password.\n */\nexport async function changePassword(\n oldPassword: string,\n newPassword: string\n): Promise<{ oldKey: Uint8Array; newKey: Uint8Array } | null> {\n const oldKeyResult = await unlockWithPassword(oldPassword);\n if (!oldKeyResult) return null;\n\n // Clone the old key before we change currentKey\n const oldKey = new Uint8Array(oldKeyResult);\n\n const newSalt = generateSalt();\n const newCryptoKey = await deriveKeyFromPassword(newPassword, newSalt);\n const newKey = await exportKey(newCryptoKey);\n const newKcv = await createKeyCheckValue(newKey);\n\n await writeKeyData({\n salt: Array.from(newSalt),\n keyCheckValue: newKcv\n });\n\n currentKey = new Uint8Array(newKey);\n\n return { oldKey, newKey };\n}\n\n/**\n * Get the current key (must be unlocked first).\n */\nexport function getCurrentKey(): Uint8Array | null {\n return currentKey;\n}\n\n/**\n * Clear the current key from memory.\n */\nexport function clearKey(): void {\n if (currentKey) {\n secureZero(currentKey);\n currentKey = null;\n }\n}\n\n/**\n * Reset everything (for testing or complete wipe).\n */\nexport async function reset(): Promise<void> {\n clearKey();\n const paths = getConfigPaths();\n try {\n await fs.unlink(paths.keyData);\n } catch {\n // Ignore\n }\n await clearSessionFile();\n}\n\n/**\n * Persist the current key for session restoration.\n */\nexport async function persistSession(): Promise<boolean> {\n if (!currentKey) return false;\n\n try {\n const wrappingKey = await generateExtractableWrappingKey();\n const wrappedKey = await wrapKey(currentKey, wrappingKey);\n const wrappingKeyBytes = await exportWrappingKey(wrappingKey);\n\n await writeSessionData({\n wrappedKey: Array.from(wrappedKey),\n wrappingKey: Array.from(wrappingKeyBytes)\n });\n\n return true;\n } catch (err) {\n console.error('Failed to persist session:', err);\n return false;\n }\n}\n\n/**\n * Check if a persisted session exists.\n */\nexport async function hasPersistedSession(): Promise<boolean> {\n return hasSessionFile();\n}\n\n/**\n * Restore a persisted session.\n */\nexport async function restoreSession(): Promise<Uint8Array | null> {\n try {\n const sessionData = await readSessionData();\n if (!sessionData) return null;\n\n const wrappingKeyBytes = new Uint8Array(sessionData.wrappingKey);\n const wrappedKey = new Uint8Array(sessionData.wrappedKey);\n\n const wrappingKey = await importWrappingKey(wrappingKeyBytes);\n const keyBytes = await unwrapKey(wrappedKey, wrappingKey);\n\n currentKey = new Uint8Array(keyBytes);\n return keyBytes;\n } catch (err) {\n console.error('Failed to restore session:', err);\n await clearPersistedSession();\n return null;\n }\n}\n\n/**\n * Clear any persisted session data.\n */\nexport async function clearPersistedSession(): Promise<void> {\n await clearSessionFile();\n}\n","/**\n * Asymmetric cryptography for VFS key exchange.\n *\n * Implements a hybrid post-quantum encryption scheme:\n * - X25519: Classical elliptic curve Diffie-Hellman (fast, well-tested)\n * - ML-KEM-768: Post-quantum Key Encapsulation Mechanism (NIST standardized)\n *\n * The hybrid approach ensures security even if one algorithm is broken:\n * - If quantum computers break X25519, ML-KEM protects you\n * - If ML-KEM has an undiscovered flaw, X25519 protects you\n */\nimport { gcm } from '@noble/ciphers/aes.js';\nimport { randomBytes } from '@noble/ciphers/utils.js';\nimport { x25519 } from '@noble/curves/ed25519.js';\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { ml_kem768 } from '@noble/post-quantum/ml-kem.js';\n// Constants\nconst HKDF_INFO = new TextEncoder().encode('rapid-vfs-hybrid-v1');\nconst DERIVED_KEY_LENGTH = 32; // 256 bits for AES-256\nconst NONCE_LENGTH = 12; // 96 bits for AES-GCM\n/**\n * Generate a new VFS keypair for a user.\n * This should be done once during account setup.\n */\nexport function generateKeyPair() {\n // Generate X25519 keypair\n const x25519PrivateKey = x25519.utils.randomSecretKey();\n const x25519PublicKey = x25519.getPublicKey(x25519PrivateKey);\n // Generate ML-KEM-768 keypair\n const mlKemKeys = ml_kem768.keygen();\n return {\n x25519PublicKey,\n x25519PrivateKey,\n mlKemPublicKey: mlKemKeys.publicKey,\n mlKemPrivateKey: mlKemKeys.secretKey\n };\n}\n/**\n * Extract only the public keys from a keypair.\n */\nexport function extractPublicKey(keyPair) {\n return {\n x25519PublicKey: keyPair.x25519PublicKey,\n mlKemPublicKey: keyPair.mlKemPublicKey\n };\n}\n/**\n * Encrypt data for a recipient using their public key.\n * Uses hybrid X25519 + ML-KEM encryption.\n *\n * @param plaintext The data to encrypt\n * @param recipientPublicKey The recipient's public key\n * @returns Encapsulated key material and ciphertext\n */\nexport function encryptForRecipient(plaintext, recipientPublicKey) {\n // Generate ephemeral X25519 keypair for this message\n const x25519EphemeralPrivate = x25519.utils.randomSecretKey();\n const x25519EphemeralPublic = x25519.getPublicKey(x25519EphemeralPrivate);\n // X25519 key exchange\n const x25519SharedSecret = x25519.getSharedSecret(x25519EphemeralPrivate, recipientPublicKey.x25519PublicKey);\n // ML-KEM encapsulation\n const { cipherText: mlKemCiphertext, sharedSecret: mlKemSharedSecret } = ml_kem768.encapsulate(recipientPublicKey.mlKemPublicKey);\n // Combine shared secrets using HKDF\n const combinedSecret = new Uint8Array(x25519SharedSecret.length + mlKemSharedSecret.length);\n combinedSecret.set(x25519SharedSecret, 0);\n combinedSecret.set(mlKemSharedSecret, x25519SharedSecret.length);\n const derivedKey = hkdf(sha256, combinedSecret, undefined, HKDF_INFO, DERIVED_KEY_LENGTH);\n // Encrypt with AES-256-GCM\n const nonce = randomBytes(NONCE_LENGTH);\n const cipher = gcm(derivedKey, nonce);\n const ciphertext = cipher.encrypt(plaintext);\n // Zero out sensitive data\n x25519EphemeralPrivate.fill(0);\n x25519SharedSecret.fill(0);\n mlKemSharedSecret.fill(0);\n combinedSecret.fill(0);\n return {\n x25519EphemeralPublic,\n mlKemCiphertext,\n nonce,\n ciphertext\n };\n}\n/**\n * Decrypt data using your private key.\n *\n * @param encapsulation The encapsulated key material and ciphertext\n * @param recipientKeyPair Your keypair (with private keys)\n * @returns Decrypted plaintext\n */\nexport function decryptWithKeyPair(encapsulation, recipientKeyPair) {\n // X25519 key exchange (using ephemeral public from sender)\n const x25519SharedSecret = x25519.getSharedSecret(recipientKeyPair.x25519PrivateKey, encapsulation.x25519EphemeralPublic);\n // ML-KEM decapsulation\n const mlKemSharedSecret = ml_kem768.decapsulate(encapsulation.mlKemCiphertext, recipientKeyPair.mlKemPrivateKey);\n // Combine shared secrets using HKDF (same as encryption)\n const combinedSecret = new Uint8Array(x25519SharedSecret.length + mlKemSharedSecret.length);\n combinedSecret.set(x25519SharedSecret, 0);\n combinedSecret.set(mlKemSharedSecret, x25519SharedSecret.length);\n const derivedKey = hkdf(sha256, combinedSecret, undefined, HKDF_INFO, DERIVED_KEY_LENGTH);\n // Decrypt with AES-256-GCM\n const cipher = gcm(derivedKey, encapsulation.nonce);\n const plaintext = cipher.decrypt(encapsulation.ciphertext);\n // Zero out sensitive data\n x25519SharedSecret.fill(0);\n mlKemSharedSecret.fill(0);\n combinedSecret.fill(0);\n return plaintext;\n}\n/**\n * Wrap a symmetric key for a recipient.\n * This is the primary use case for VFS: sharing item session keys.\n *\n * @param sessionKey The symmetric key to wrap (typically 32 bytes for AES-256)\n * @param recipientPublicKey The recipient's public key\n * @returns Serialized encapsulation (base64-encoded for database storage)\n */\nexport function wrapKeyForRecipient(sessionKey, recipientPublicKey) {\n const encapsulation = encryptForRecipient(sessionKey, recipientPublicKey);\n return serializeEncapsulation(encapsulation);\n}\n/**\n * Unwrap a symmetric key using your private key.\n *\n * @param wrappedKey Serialized encapsulation from wrapKeyForRecipient\n * @param recipientKeyPair Your keypair\n * @returns The original symmetric key\n */\nexport function unwrapKeyWithKeyPair(wrappedKey, recipientKeyPair) {\n const encapsulation = deserializeEncapsulation(wrappedKey);\n return decryptWithKeyPair(encapsulation, recipientKeyPair);\n}\n// =============================================================================\n// Serialization helpers (for database storage)\n// =============================================================================\nfunction toBase64(data) {\n let binary = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < data.length; i += chunkSize) {\n binary += String.fromCharCode(...data.subarray(i, i + chunkSize));\n }\n return btoa(binary);\n}\nfunction fromBase64(base64) {\n return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));\n}\n/**\n * Serialize a keypair to base64 for storage or transmission.\n *\n * IMPORTANT: This returns RAW (unencrypted) private keys in base64 format.\n * The private keys MUST be encrypted (e.g., with a password-derived key via Argon2)\n * before being stored in the database's `encrypted_private_keys` field.\n *\n * Usage flow:\n * 1. Generate keypair with generateKeyPair()\n * 2. Serialize with serializeKeyPair() -> raw base64 keys\n * 3. Encrypt the serialized private keys with user's password-derived key\n * 4. Store encrypted blob in encrypted_private_keys, public keys stored as-is\n */\nexport function serializeKeyPair(keyPair) {\n return {\n x25519PublicKey: toBase64(keyPair.x25519PublicKey),\n x25519PrivateKey: toBase64(keyPair.x25519PrivateKey),\n mlKemPublicKey: toBase64(keyPair.mlKemPublicKey),\n mlKemPrivateKey: toBase64(keyPair.mlKemPrivateKey)\n };\n}\n/**\n * Deserialize a keypair from storage.\n */\nexport function deserializeKeyPair(serialized) {\n return {\n x25519PublicKey: fromBase64(serialized.x25519PublicKey),\n x25519PrivateKey: fromBase64(serialized.x25519PrivateKey),\n mlKemPublicKey: fromBase64(serialized.mlKemPublicKey),\n mlKemPrivateKey: fromBase64(serialized.mlKemPrivateKey)\n };\n}\n/**\n * Serialize a public key for storage/transmission.\n */\nexport function serializePublicKey(publicKey) {\n return {\n x25519PublicKey: toBase64(publicKey.x25519PublicKey),\n mlKemPublicKey: toBase64(publicKey.mlKemPublicKey)\n };\n}\n/**\n * Deserialize a public key from storage.\n */\nexport function deserializePublicKey(serialized) {\n return {\n x25519PublicKey: fromBase64(serialized.x25519PublicKey),\n mlKemPublicKey: fromBase64(serialized.mlKemPublicKey)\n };\n}\n/**\n * Serialize an encapsulation for storage.\n */\nexport function serializeEncapsulation(encapsulation) {\n return {\n x25519EphemeralPublic: toBase64(encapsulation.x25519EphemeralPublic),\n mlKemCiphertext: toBase64(encapsulation.mlKemCiphertext),\n nonce: toBase64(encapsulation.nonce),\n ciphertext: toBase64(encapsulation.ciphertext)\n };\n}\n/**\n * Deserialize an encapsulation from storage.\n */\nexport function deserializeEncapsulation(serialized) {\n return {\n x25519EphemeralPublic: fromBase64(serialized.x25519EphemeralPublic),\n mlKemCiphertext: fromBase64(serialized.mlKemCiphertext),\n nonce: fromBase64(serialized.nonce),\n ciphertext: fromBase64(serialized.ciphertext)\n };\n}\n/**\n * Combine serialized public key parts into a single string for database storage.\n * Format: base64(x25519) + \".\" + base64(mlKem)\n */\nexport function combinePublicKey(publicKey) {\n return `${publicKey.x25519PublicKey}.${publicKey.mlKemPublicKey}`;\n}\n/**\n * Split a combined public key string back into parts.\n */\nexport function splitPublicKey(combined) {\n const [x25519PublicKey, mlKemPublicKey] = combined.split('.');\n if (!x25519PublicKey || !mlKemPublicKey) {\n throw new Error('Invalid combined public key format');\n }\n return { x25519PublicKey, mlKemPublicKey };\n}\n/**\n * Combine encapsulation into a single string for database storage.\n * Format: base64(x25519Eph) + \".\" + base64(mlKemCt) + \".\" + base64(nonce) + \".\" + base64(ct)\n */\nexport function combineEncapsulation(encapsulation) {\n return [\n encapsulation.x25519EphemeralPublic,\n encapsulation.mlKemCiphertext,\n encapsulation.nonce,\n encapsulation.ciphertext\n ].join('.');\n}\n/**\n * Split a combined encapsulation string back into parts.\n */\nexport function splitEncapsulation(combined) {\n const parts = combined.split('.');\n if (parts.length !== 4) {\n throw new Error('Invalid combined encapsulation format');\n }\n const x25519EphemeralPublic = parts[0];\n const mlKemCiphertext = parts[1];\n const nonce = parts[2];\n const ciphertext = parts[3];\n if (!x25519EphemeralPublic || !mlKemCiphertext || !nonce || !ciphertext) {\n throw new Error('Invalid combined encapsulation format');\n }\n return {\n x25519EphemeralPublic,\n mlKemCiphertext,\n nonce,\n ciphertext\n };\n}\n","/**\n * Web Crypto API utilities for database encryption.\n * Uses AES-256-GCM for authenticated encryption.\n *\n * This module is compatible with both Node.js and browser environments.\n */\nimport { assertPlainArrayBuffer } from '../index.js';\nconst ALGORITHM = 'AES-GCM';\nconst KEY_LENGTH = 256;\nconst IV_LENGTH = 12;\nconst TAG_LENGTH = 128;\nconst SALT_LENGTH = 32;\nconst PBKDF2_ITERATIONS = 600000;\n/**\n * Generate a cryptographically secure random salt.\n */\nexport function generateSalt() {\n return crypto.getRandomValues(new Uint8Array(SALT_LENGTH));\n}\n/**\n * Generate a random encryption key.\n */\nexport async function generateRandomKey() {\n const key = await crypto.subtle.generateKey({ name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n const exported = await crypto.subtle.exportKey('raw', key);\n return new Uint8Array(exported);\n}\n/**\n * Derive an encryption key from a password using PBKDF2.\n */\nexport async function deriveKeyFromPassword(password, salt) {\n const encoder = new TextEncoder();\n const passwordBuffer = encoder.encode(password);\n const keyMaterial = await crypto.subtle.importKey('raw', passwordBuffer, 'PBKDF2', false, ['deriveBits', 'deriveKey']);\n assertPlainArrayBuffer(salt);\n return crypto.subtle.deriveKey({\n name: 'PBKDF2',\n salt,\n iterations: PBKDF2_ITERATIONS,\n hash: 'SHA-256'\n }, keyMaterial, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n}\n/**\n * Export a CryptoKey to raw bytes.\n */\nexport async function exportKey(key) {\n const exported = await crypto.subtle.exportKey('raw', key);\n return new Uint8Array(exported);\n}\n/**\n * Import raw key bytes as a CryptoKey.\n */\nexport async function importKey(keyBytes) {\n assertPlainArrayBuffer(keyBytes);\n return crypto.subtle.importKey('raw', keyBytes, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n}\n/**\n * Encrypt data using AES-GCM.\n * Returns IV prepended to ciphertext.\n */\nexport async function encrypt(data, key, additionalData) {\n const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));\n assertPlainArrayBuffer(data);\n const algorithm = {\n name: ALGORITHM,\n iv,\n tagLength: TAG_LENGTH\n };\n if (additionalData) {\n assertPlainArrayBuffer(additionalData);\n algorithm.additionalData = additionalData;\n }\n const ciphertext = await crypto.subtle.encrypt(algorithm, key, data);\n const result = new Uint8Array(IV_LENGTH + ciphertext.byteLength);\n result.set(iv, 0);\n result.set(new Uint8Array(ciphertext), IV_LENGTH);\n return result;\n}\n/**\n * Decrypt data using AES-GCM.\n * Expects IV prepended to ciphertext.\n */\nexport async function decrypt(encryptedData, key, additionalData) {\n const iv = encryptedData.slice(0, IV_LENGTH);\n const ciphertext = encryptedData.slice(IV_LENGTH);\n const algorithm = {\n name: ALGORITHM,\n iv,\n tagLength: TAG_LENGTH\n };\n if (additionalData) {\n assertPlainArrayBuffer(additionalData);\n algorithm.additionalData = additionalData;\n }\n const decrypted = await crypto.subtle.decrypt(algorithm, key, ciphertext);\n return new Uint8Array(decrypted);\n}\n/**\n * Securely zero out a buffer to prevent key leakage.\n */\nexport function secureZero(buffer) {\n crypto.getRandomValues(buffer);\n buffer.fill(0);\n}\n/**\n * Encrypt a string value (for storing secrets).\n */\nexport async function encryptString(value, key) {\n const encoder = new TextEncoder();\n const data = encoder.encode(value);\n const encrypted = await encrypt(data, key);\n return btoa(String.fromCharCode(...encrypted));\n}\n/**\n * Decrypt a string value.\n */\nexport async function decryptString(encryptedValue, key) {\n const encrypted = Uint8Array.from(atob(encryptedValue), (c) => c.charCodeAt(0));\n const decrypted = await decrypt(encrypted, key);\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n}\n/**\n * Generate a non-extractable wrapping key for session persistence.\n * This key can be stored in IndexedDB but its raw bytes cannot be exported.\n */\nexport async function generateWrappingKey() {\n return crypto.subtle.generateKey({ name: 'AES-KW', length: 256 }, false, [\n 'wrapKey',\n 'unwrapKey'\n ]);\n}\n/**\n * Generate an extractable wrapping key for platforms that need it.\n * This key can be exported to raw bytes for storage.\n */\nexport async function generateExtractableWrappingKey() {\n return crypto.subtle.generateKey({ name: 'AES-KW', length: 256 }, true, [\n 'wrapKey',\n 'unwrapKey'\n ]);\n}\n/**\n * Export a wrapping key to raw bytes.\n */\nexport async function exportWrappingKey(key) {\n const exported = await crypto.subtle.exportKey('raw', key);\n return new Uint8Array(exported);\n}\n/**\n * Import raw bytes as a wrapping key.\n */\nexport async function importWrappingKey(keyBytes) {\n assertPlainArrayBuffer(keyBytes);\n return crypto.subtle.importKey('raw', keyBytes, { name: 'AES-KW', length: 256 }, true, ['wrapKey', 'unwrapKey']);\n}\n/**\n * Wrap (encrypt) a key using a wrapping key.\n */\nexport async function wrapKey(keyToWrap, wrappingKey) {\n assertPlainArrayBuffer(keyToWrap);\n const cryptoKey = await crypto.subtle.importKey('raw', keyToWrap, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n const wrapped = await crypto.subtle.wrapKey('raw', cryptoKey, wrappingKey, {\n name: 'AES-KW'\n });\n return new Uint8Array(wrapped);\n}\n/**\n * Unwrap (decrypt) a wrapped key using a wrapping key.\n */\nexport async function unwrapKey(wrappedKey, wrappingKey) {\n assertPlainArrayBuffer(wrappedKey);\n const unwrappedCryptoKey = await crypto.subtle.unwrapKey('raw', wrappedKey, wrappingKey, { name: 'AES-KW' }, { name: ALGORITHM, length: KEY_LENGTH }, true, ['encrypt', 'decrypt']);\n const exported = await crypto.subtle.exportKey('raw', unwrappedCryptoKey);\n return new Uint8Array(exported);\n}\n","/**\n * Shared types and utilities\n */\nexport * from './crypto/asymmetric.js';\n// Crypto utilities\nexport * from './crypto/web-crypto.js';\n// AI conversations\nexport * from './ai-conversations.js';\n// Chat validation helpers\nexport * from './chat.js';\n// OpenRouter model options\nexport * from './openrouter.js';\n// Tree utilities\nexport * from './tree/index.js';\n// =============================================================================\n// MLS (RFC 9420) Encrypted Chat Types\n// =============================================================================\n// =============================================================================\n// MLS (RFC 9420) Encrypted Chat Types\n// =============================================================================\n/** MLS ciphersuites - X-Wing hybrid (ML-KEM + X25519) for post-quantum security */\nexport const MLS_CIPHERSUITES = {\n /** MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 */\n X25519_AES128GCM: 1,\n /** MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519 */\n X25519_CHACHA20_SHA256_ED25519: 3,\n /** X-Wing hybrid: ML-KEM-768 + X25519 for post-quantum security */\n XWING_HYBRID: 65535\n};\n// Utilities\nexport function formatDate(date) {\n return date.toISOString();\n}\n// Type Guards\n/**\n * Type guard to check if a value is a non-null object (record).\n */\nexport function isRecord(value) {\n return typeof value === 'object' && value !== null;\n}\n/**\n * Assertion function to narrow Uint8Array<ArrayBufferLike> to Uint8Array<ArrayBuffer>.\n *\n * With @tsconfig/strictest, Uint8Array is typed as Uint8Array<ArrayBufferLike>\n * where ArrayBufferLike = ArrayBuffer | SharedArrayBuffer. Web Crypto API and\n * Blob constructor expect plain ArrayBuffer, not ArrayBufferLike.\n *\n * In practice, Uint8Arrays always use plain ArrayBuffer - SharedArrayBuffer\n * requires explicit opt-in and specific headers. This assertion narrows the type\n * by checking for SharedArrayBuffer rather than ArrayBuffer (since instanceof\n * ArrayBuffer can fail across realms in test environments).\n */\nexport function assertPlainArrayBuffer(arr) {\n if (typeof SharedArrayBuffer !== 'undefined' &&\n arr.buffer instanceof SharedArrayBuffer) {\n throw new Error('Unexpected SharedArrayBuffer backing Uint8Array. This should never occur in normal operation.');\n }\n}\n/**\n * Safely extract an error code from an unknown error value.\n * Returns undefined if the error doesn't have a string code property.\n */\nexport function getErrorCode(error) {\n if (!isRecord(error)) {\n return undefined;\n }\n const code = error['code'];\n return typeof code === 'string' ? code : undefined;\n}\n/**\n * Safely convert a value to a finite number, returning null if not possible.\n * Handles both numbers and numeric strings (useful for SQLite query results).\n */\nexport function toFiniteNumber(value) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return null;\n}\n","/**\n * Configuration directory management for ~/.tearleads\n */\n\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport interface ConfigPaths {\n root: string;\n database: string;\n keyData: string;\n session: string;\n}\n\nlet configRoot: string | null = null;\n\n/**\n * Set a custom config root (for testing).\n */\nexport function setConfigRoot(root: string | null): void {\n configRoot = root;\n}\n\n/**\n * Get the configuration directory paths.\n */\nexport function getConfigPaths(): ConfigPaths {\n const root = configRoot ?? path.join(os.homedir(), '.tearleads');\n return {\n root,\n database: path.join(root, 'tearleads.db'),\n keyData: path.join(root, 'keydata.json'),\n session: path.join(root, '.session')\n };\n}\n\n/**\n * Ensure the config directory exists with proper permissions.\n */\nexport async function ensureConfigDir(): Promise<void> {\n const paths = getConfigPaths();\n await fs.mkdir(paths.root, { recursive: true, mode: 0o700 });\n}\n\n/**\n * Check if the config directory exists.\n */\nexport async function configExists(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.root);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if the database is set up (keydata.json exists).\n */\nexport async function isDatabaseSetUp(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.keyData);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a session file exists.\n */\nexport async function hasSession(): Promise<boolean> {\n const paths = getConfigPaths();\n try {\n await fs.access(paths.session);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Clear the session file.\n */\nexport async function clearSession(): Promise<void> {\n const paths = getConfigPaths();\n try {\n await fs.unlink(paths.session);\n } catch {\n // Ignore if file doesn't exist\n }\n}\n\n/**\n * Remove all config files (for reset).\n */\nexport async function clearConfig(): Promise<void> {\n const paths = getConfigPaths();\n try {\n await fs.rm(paths.root, { recursive: true, force: true });\n } catch {\n // Ignore errors\n }\n}\n","/**\n * Database operations for the CLI.\n */\n\nimport fs from 'node:fs/promises';\nimport type { BackupDatabase } from '../backup/types.js';\nimport { getConfigPaths } from '../config/index.js';\nimport {\n changePassword as changeKeyPassword,\n clearKey,\n getCurrentKey,\n hasExistingKey,\n hasPersistedSession,\n persistSession,\n restoreSession,\n setupNewKey,\n unlockWithPassword\n} from '../crypto/key-manager.js';\nimport { NativeSqliteAdapter } from './adapter.js';\n\nlet adapter: NativeSqliteAdapter | null = null;\n\n/**\n * Check if a database has been set up.\n */\nexport async function isDatabaseSetUp(): Promise<boolean> {\n return hasExistingKey();\n}\n\n/**\n * Check if the database is currently unlocked.\n */\nexport function isDatabaseUnlocked(): boolean {\n return adapter?.isOpen() ?? false;\n}\n\n/**\n * Set up a new database with a password.\n */\nexport async function setupDatabase(password: string): Promise<void> {\n const key = await setupNewKey(password);\n\n adapter = new NativeSqliteAdapter();\n await adapter.initialize(key);\n\n // Persist session for convenience\n await persistSession();\n}\n\n/**\n * Unlock an existing database with a password.\n */\nexport async function unlockDatabase(password: string): Promise<boolean> {\n const key = await unlockWithPassword(password);\n if (!key) {\n return false;\n }\n\n adapter = new NativeSqliteAdapter();\n await adapter.open(key);\n\n // Persist session for convenience\n await persistSession();\n\n return true;\n}\n\n/**\n * Restore a database session from persisted key.\n */\nexport async function restoreDatabaseSession(): Promise<boolean> {\n const key = await restoreSession();\n if (!key) {\n return false;\n }\n\n adapter = new NativeSqliteAdapter();\n await adapter.open(key);\n\n return true;\n}\n\n/**\n * Lock the database (close and clear key).\n */\nexport function lockDatabase(): void {\n if (adapter) {\n adapter.close();\n adapter = null;\n }\n clearKey();\n}\n\n/**\n * Export the database to JSON.\n */\nexport function exportDatabase(): Record<string, unknown[]> {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n return adapter.exportToJson();\n}\n\n/**\n * Export the database to a backup-ready structure.\n */\nexport function exportBackupDatabase(): BackupDatabase {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n return adapter.exportToBackupDatabase();\n}\n\n/**\n * Import data into the database from JSON.\n */\nexport function importDatabase(data: Record<string, unknown[]>): void {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n adapter.importFromJson(data);\n}\n\n/**\n * Import a backup database structure.\n */\nexport function importBackupDatabase(database: BackupDatabase): void {\n if (!adapter || !adapter.isOpen()) {\n throw new Error('Database not open');\n }\n adapter.importFromBackupDatabase(database);\n}\n\n/**\n * Change the database password.\n */\nexport async function changePassword(\n oldPassword: string,\n newPassword: string\n): Promise<boolean> {\n const result = await changeKeyPassword(oldPassword, newPassword);\n if (!result) {\n return false;\n }\n\n // Re-key the database if it's open\n if (adapter?.isOpen()) {\n await adapter.rekeyDatabase(result.newKey);\n } else {\n // Open with old key, re-key, close\n adapter = new NativeSqliteAdapter();\n await adapter.open(result.oldKey);\n await adapter.rekeyDatabase(result.newKey);\n }\n\n // Update persisted session\n await persistSession();\n\n return true;\n}\n\n/**\n * Get the current encryption key (for testing).\n */\nexport function getKey(): Uint8Array | null {\n return getCurrentKey();\n}\n\n/**\n * Reset the database (delete all data).\n */\nexport async function resetDatabase(): Promise<void> {\n lockDatabase();\n\n const paths = getConfigPaths();\n try {\n await fs.unlink(paths.database);\n } catch {\n // Ignore if file doesn't exist\n }\n}\n\n// Re-export for convenience\nexport { hasPersistedSession };\n","/**\n * Native SQLite adapter using better-sqlite3-multiple-ciphers.\n * Provides on-disk encrypted SQLite database persistence.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Database as DatabaseType } from 'better-sqlite3';\nimport Database from 'better-sqlite3-multiple-ciphers';\nimport type {\n BackupDatabase,\n IndexSchema,\n TableSchema\n} from '../backup/types.js';\nimport { getConfigPaths } from '../config/index.js';\n\n/**\n * Schema for the tearleads database.\n */\nconst SCHEMA = `\n CREATE TABLE IF NOT EXISTS contacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n email TEXT,\n phone TEXT,\n notes TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n contact_id INTEGER REFERENCES contacts(id),\n type TEXT NOT NULL,\n description TEXT,\n event_date TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n CREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n`;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction getStringField(\n value: Record<string, unknown>,\n key: string\n): string | null {\n const field = value[key];\n return typeof field === 'string' ? field : null;\n}\n\n/**\n * Convert Uint8Array key to hex string for SQLCipher PRAGMA.\n */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Native SQLite adapter with SQLCipher encryption.\n */\nexport class NativeSqliteAdapter {\n private db: DatabaseType | null = null;\n private dbPath: string;\n\n constructor() {\n const configPaths = getConfigPaths();\n this.dbPath = configPaths.database;\n }\n\n /**\n * Initialize a new encrypted database with the given key.\n * Creates the database file and schema.\n */\n async initialize(key: Uint8Array): Promise<void> {\n // Ensure directory exists\n await fs.mkdir(path.dirname(this.dbPath), { recursive: true, mode: 0o700 });\n\n // Create new database file\n this.db = new Database(this.dbPath);\n\n // Apply encryption\n this.db.pragma(`key = \"x'${bytesToHex(key)}'\"`);\n this.db.pragma('cipher_compatibility = 4');\n\n // Create schema\n this.db.exec(SCHEMA);\n }\n\n /**\n * Open an existing encrypted database with the given key.\n */\n async open(key: Uint8Array): Promise<void> {\n // Check if database file exists\n try {\n await fs.access(this.dbPath);\n } catch {\n throw new Error('Database file not found');\n }\n\n // Open existing database\n this.db = new Database(this.dbPath);\n\n // Apply encryption key\n this.db.pragma(`key = \"x'${bytesToHex(key)}'\"`);\n this.db.pragma('cipher_compatibility = 4');\n\n // Verify the key by running a simple query\n try {\n this.db.prepare('SELECT count(*) FROM sqlite_master').get();\n } catch {\n this.db.close();\n this.db = null;\n throw new Error('Invalid encryption key');\n }\n }\n\n /**\n * Check if the database is currently open.\n */\n isOpen(): boolean {\n return this.db !== null;\n }\n\n /**\n * Close the database connection.\n */\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n /**\n * Re-key the database with a new encryption key.\n */\n async rekeyDatabase(newKey: Uint8Array): Promise<void> {\n if (!this.db) {\n throw new Error('Database not open');\n }\n this.db.pragma(`rekey = \"x'${bytesToHex(newKey)}'\"`);\n }\n\n /**\n * Export the database to a JSON structure for backup.\n */\n exportToJson(): Record<string, unknown[]> {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n const result: Record<string, unknown[]> = {};\n\n // Get all table names\n const tables = this.db\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n )\n .all() as { name: string }[];\n\n for (const { name } of tables) {\n const rows = this.db.prepare(`SELECT * FROM ${name}`).all();\n result[name] = rows;\n }\n\n return result;\n }\n\n /**\n * Export the database to a backup-friendly structure with schema and data.\n */\n exportToBackupDatabase(): BackupDatabase {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n const tables = this.db\n .prepare(\n \"SELECT name, sql FROM sqlite_master WHERE type='table' AND sql IS NOT NULL ORDER BY name\"\n )\n .all();\n\n const tableSchemas: TableSchema[] = [];\n for (const row of tables) {\n if (!isRecord(row)) continue;\n const name = getStringField(row, 'name');\n const sql = getStringField(row, 'sql');\n if (!name || !sql) continue;\n if (name.startsWith('sqlite_') || name === '__drizzle_migrations') {\n continue;\n }\n tableSchemas.push({ name, sql });\n }\n\n const indexes = this.db\n .prepare(\n \"SELECT name, tbl_name, sql FROM sqlite_master WHERE type='index' AND sql IS NOT NULL ORDER BY name\"\n )\n .all();\n\n const indexSchemas: IndexSchema[] = [];\n for (const row of indexes) {\n if (!isRecord(row)) continue;\n const name = getStringField(row, 'name');\n const tableName = getStringField(row, 'tbl_name');\n const sql = getStringField(row, 'sql');\n if (!name || !tableName || !sql) continue;\n if (name.startsWith('sqlite_')) continue;\n indexSchemas.push({ name, tableName, sql });\n }\n\n const data: Record<string, unknown[]> = {};\n for (const table of tableSchemas) {\n const rows = this.db.prepare(`SELECT * FROM \"${table.name}\"`).all();\n data[table.name] = rows;\n }\n\n return { tables: tableSchemas, indexes: indexSchemas, data };\n }\n\n /**\n * Import data from a JSON structure (restore from backup).\n */\n importFromJson(data: Record<string, unknown[]>): void {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n // Capture db reference for use in transaction callback\n const db = this.db;\n\n // Start transaction\n const transaction = db.transaction(() => {\n for (const [tableName, rows] of Object.entries(data)) {\n if (!Array.isArray(rows) || rows.length === 0) continue;\n\n // Clear existing data\n db.prepare(`DELETE FROM ${tableName}`).run();\n\n // Get column names from first row\n const firstRow = rows[0] as Record<string, unknown>;\n const columns = Object.keys(firstRow);\n const placeholders = columns.map(() => '?').join(', ');\n const insertStmt = db.prepare(\n `INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (${placeholders})`\n );\n\n // Insert each row\n for (const row of rows) {\n const rowData = row as Record<string, unknown>;\n const values = columns.map((col) => rowData[col]);\n insertStmt.run(...values);\n }\n }\n });\n\n transaction();\n }\n\n /**\n * Import a backup database structure, recreating schema and data.\n */\n importFromBackupDatabase(database: BackupDatabase): void {\n if (!this.db) {\n throw new Error('Database not open');\n }\n\n const db = this.db;\n\n const transaction = db.transaction(() => {\n const existingTables = db\n .prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n )\n .all();\n\n for (const row of existingTables) {\n if (!isRecord(row)) continue;\n const name = getStringField(row, 'name');\n if (!name) continue;\n db.exec(`DROP TABLE IF EXISTS \"${name}\"`);\n }\n\n for (const table of database.tables) {\n db.exec(table.sql);\n }\n\n for (const [tableName, rows] of Object.entries(database.data)) {\n if (!Array.isArray(rows) || rows.length === 0) continue;\n\n const firstRow = rows[0];\n if (!isRecord(firstRow)) continue;\n const columns = Object.keys(firstRow);\n if (columns.length === 0) continue;\n\n const placeholders = columns.map(() => '?').join(', ');\n const insertStmt = db.prepare(\n `INSERT INTO \"${tableName}\" (${columns.join(', ')}) VALUES (${placeholders})`\n );\n\n for (const row of rows) {\n if (!isRecord(row)) continue;\n const values = columns.map((col) => row[col]);\n insertStmt.run(...values);\n }\n }\n\n for (const index of database.indexes) {\n if (index.sql.trim().length > 0) {\n db.exec(index.sql);\n }\n }\n });\n\n transaction();\n }\n\n /**\n * Execute a raw SQL query.\n */\n exec(sql: string): void {\n if (!this.db) {\n throw new Error('Database not open');\n }\n this.db.exec(sql);\n }\n\n /**\n * Get the database file path.\n */\n getPath(): string {\n return this.dbPath;\n }\n}\n","/**\n * Terminal prompt utilities.\n */\n\nimport { stdin, stdout } from 'node:process';\nimport * as readline from 'node:readline/promises';\n\n/**\n * Prompt for password input (hidden).\n */\nexport async function promptPassword(prompt: string): Promise<string> {\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n stdout.write(prompt);\n return await new Promise((resolve) => {\n let input = '';\n\n if (stdin.isTTY) {\n stdin.setRawMode(true);\n }\n stdin.resume();\n stdin.setEncoding('utf8');\n\n const onData = (char: string): void => {\n if (char === '\\n' || char === '\\r' || char === '\\u0004') {\n stdin.removeListener('data', onData);\n if (stdin.isTTY) {\n stdin.setRawMode(false);\n }\n stdout.write('\\n');\n resolve(input);\n } else if (char === '\\u0003') {\n process.exit(1);\n } else if (char === '\\u007F' || char === '\\b') {\n if (input.length > 0) {\n input = input.slice(0, -1);\n }\n } else {\n input += char;\n }\n };\n\n stdin.on('data', onData);\n });\n } finally {\n rl.close();\n }\n}\n\n/**\n * Prompt for yes/no confirmation.\n */\nexport async function promptConfirm(prompt: string): Promise<boolean> {\n const rl = readline.createInterface({ input: stdin, output: stdout });\n try {\n const answer = await rl.question(prompt);\n return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';\n } finally {\n rl.close();\n }\n}\n","/**\n * Dump command - Export database to unencrypted JSON files.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { decode } from '../backup/index.js';\nimport type { BackupDatabase } from '../backup/types.js';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n exportBackupDatabase,\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession\n} from '../db/index.js';\nimport { promptConfirm, promptPassword } from '../utils/prompt.js';\n\ninterface DumpOptions {\n force?: boolean;\n blobs?: boolean;\n inputFile?: string;\n password?: string;\n}\n\nexport async function runDump(\n folder: string,\n options: DumpOptions\n): Promise<void> {\n let database: BackupDatabase;\n\n if (options.inputFile) {\n // Dump from .rbu backup file\n const filePath = path.resolve(options.inputFile);\n const password = options.password\n ? options.password\n : await promptPassword('Backup password: ');\n\n try {\n const backupData = await fs.readFile(filePath);\n const decoded = await decode({\n data: new Uint8Array(backupData),\n password\n });\n database = decoded.database;\n\n if (decoded.blobs.length > 0) {\n console.warn(\n `Warning: backup contains ${decoded.blobs.length} blobs that will be ignored.`\n );\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n console.error(`File not found: ${filePath}`);\n } else {\n console.error(\n err instanceof Error\n ? err.message\n : 'Failed to read or decode backup file.'\n );\n }\n process.exit(1);\n }\n } else {\n // Dump from live database\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n if (!isDatabaseUnlocked()) {\n const canRestore = await hasPersistedSession();\n if (!canRestore || !(await restoreDatabaseSession())) {\n const message = canRestore\n ? 'Session expired. Run \"tearleads unlock\" first.'\n : 'Database not unlocked. Run \"tearleads unlock\" first.';\n console.error(message);\n process.exit(1);\n }\n }\n\n database = exportBackupDatabase();\n }\n\n const outputPath = path.resolve(folder);\n\n try {\n const stat = await fs.stat(outputPath);\n if (stat.isDirectory()) {\n if (!options.force) {\n const confirmed = await promptConfirm(\n `Folder ${outputPath} exists. Overwrite? (y/n): `\n );\n if (!confirmed) {\n console.log('Dump cancelled.');\n return;\n }\n }\n await fs.rm(outputPath, { recursive: true });\n } else {\n console.error(`${outputPath} exists and is not a directory.`);\n process.exit(1);\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error(\n `Error checking output path \"${outputPath}\": ${(err as Error).message}`\n );\n process.exit(1);\n }\n // Folder doesn't exist, which is fine\n }\n\n await fs.mkdir(outputPath, { recursive: true });\n await fs.mkdir(path.join(outputPath, 'tables'), { recursive: true });\n if (options.blobs !== false) {\n await fs.mkdir(path.join(outputPath, 'files'), { recursive: true });\n }\n\n const manifest = {\n createdAt: new Date().toISOString(),\n platform: 'cli' as const,\n appVersion: 'cli',\n exportedTables: database.tables.map((t) => t.name),\n blobCount: 0,\n blobTotalSize: 0\n };\n await fs.writeFile(\n path.join(outputPath, 'manifest.json'),\n JSON.stringify(manifest, null, 2)\n );\n\n const schema = {\n tables: database.tables,\n indexes: database.indexes\n };\n await fs.writeFile(\n path.join(outputPath, 'schema.json'),\n JSON.stringify(schema, null, 2)\n );\n\n for (const table of database.tables) {\n const tableData = database.data[table.name] ?? [];\n await fs.writeFile(\n path.join(outputPath, 'tables', `${table.name}.json`),\n JSON.stringify(tableData, null, 2)\n );\n }\n\n console.log(`Database dumped to ${outputPath}`);\n console.log(` Tables: ${database.tables.length}`);\n}\n\nexport const dumpCommand = new Command('dump')\n .description('Export database to unencrypted JSON files')\n .argument('<folder>', 'Output folder path')\n .option(\n '-f, --input-file <file>',\n 'Read from .rbu backup file instead of live database'\n )\n .option(\n '-p, --password <password>',\n 'Backup file password (used with --input-file)'\n )\n .option('--force', 'Overwrite existing folder without confirmation')\n .option('--no-blobs', 'Skip files directory')\n .action(runDump);\n","/**\n * Lock command - Lock the database and clear session.\n */\n\nimport { Command } from 'commander';\nimport { lockDatabase } from '../db/index.js';\n\nexport async function runLock(): Promise<void> {\n await lockDatabase();\n console.log('Database locked.');\n}\n\nexport const lockCommand = new Command('lock')\n .description('Lock the database')\n .action(runLock);\n","/**\n * Password command - Change the database password.\n */\n\nimport { Command } from 'commander';\nimport { changePassword, isDatabaseSetUp } from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\nexport async function runPassword(): Promise<void> {\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n const oldPassword = await promptPassword('Current password: ');\n const newPassword = await promptPassword('New password: ');\n\n if (!newPassword) {\n console.error('Password cannot be empty.');\n process.exit(1);\n }\n\n const confirm = await promptPassword('Confirm new password: ');\n\n if (newPassword !== confirm) {\n console.error('Passwords do not match.');\n process.exit(1);\n }\n\n const success = await changePassword(oldPassword, newPassword);\n\n if (!success) {\n console.error('Incorrect current password.');\n process.exit(1);\n }\n\n console.log('Password changed successfully.');\n}\n\nexport const passwordCommand = new Command('password')\n .description('Change database password')\n .action(runPassword);\n","/**\n * Restore command - Import database from a JSON file.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { decode } from '../backup/index.js';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n importBackupDatabase,\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession\n} from '../db/index.js';\nimport { promptConfirm, promptPassword } from '../utils/prompt.js';\n\ninterface RestoreOptions {\n force?: boolean;\n password?: string;\n}\n\nexport async function runRestore(\n file: string,\n options: RestoreOptions\n): Promise<void> {\n const filePath = path.resolve(file);\n\n try {\n await fs.access(filePath);\n } catch {\n console.error(`File not found: ${filePath}`);\n process.exit(1);\n }\n\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n // Try to restore session if not unlocked\n if (!isDatabaseUnlocked()) {\n if (await hasPersistedSession()) {\n const restored = await restoreDatabaseSession();\n if (!restored) {\n console.error('Session expired. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n } else {\n console.error('Database not unlocked. Run \"tearleads unlock\" first.');\n process.exit(1);\n }\n }\n\n if (!options.force) {\n const confirmed = await promptConfirm(\n 'This will overwrite existing data. Continue? (y/n): '\n );\n if (!confirmed) {\n console.log('Restore cancelled.');\n return;\n }\n }\n\n const password = options.password\n ? options.password\n : await promptPassword('Backup password: ');\n\n const backupData = await fs.readFile(filePath);\n let decoded: Awaited<ReturnType<typeof decode>>;\n try {\n decoded = await decode({ data: new Uint8Array(backupData), password });\n } catch (err) {\n console.error(\n err instanceof Error ? err.message : 'Failed to decode backup file.'\n );\n process.exit(1);\n }\n\n if (decoded.blobs.length > 0) {\n console.warn(\n `Warning: backup contains ${decoded.blobs.length} blobs that will be ignored in the CLI restore.`\n );\n }\n\n importBackupDatabase(decoded.database);\n console.log('Database restored successfully.');\n}\n\nexport const restoreCommand = new Command('restore')\n .description('Restore database from a backup file')\n .argument('<file>', 'Backup file path')\n .option('-f, --force', 'Overwrite without confirmation')\n .option('-p, --password <password>', 'Backup password')\n .action(runRestore);\n","/**\n * Setup command - Initialize a new encrypted database.\n */\n\nimport { Command } from 'commander';\nimport { isDatabaseSetUp, setupDatabase } from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\nexport async function runSetup(): Promise<void> {\n if (await isDatabaseSetUp()) {\n console.error(\n 'Database already set up. Use \"tearleads password\" to change password.'\n );\n process.exit(1);\n }\n\n const password = await promptPassword('Enter password: ');\n if (!password) {\n console.error('Password cannot be empty.');\n process.exit(1);\n }\n\n const confirm = await promptPassword('Confirm password: ');\n if (password !== confirm) {\n console.error('Passwords do not match.');\n process.exit(1);\n }\n\n await setupDatabase(password);\n console.log('Database initialized successfully.');\n}\n\nexport const setupCommand = new Command('setup')\n .description('Initialize a new encrypted database')\n .action(runSetup);\n","/**\n * Unlock command - Unlock the database with a password.\n */\n\nimport { Command } from 'commander';\nimport { hasPersistedSession } from '../crypto/key-manager.js';\nimport {\n isDatabaseSetUp,\n isDatabaseUnlocked,\n restoreDatabaseSession,\n unlockDatabase\n} from '../db/index.js';\nimport { promptPassword } from '../utils/prompt.js';\n\nexport async function runUnlock(): Promise<void> {\n if (!(await isDatabaseSetUp())) {\n console.error('Database not set up. Run \"tearleads setup\" first.');\n process.exit(1);\n }\n\n if (isDatabaseUnlocked()) {\n console.log('Database already unlocked.');\n return;\n }\n\n // Try to restore session first\n if (await hasPersistedSession()) {\n const restored = await restoreDatabaseSession();\n if (restored) {\n console.log('Database unlocked (session restored).');\n return;\n }\n }\n\n const password = await promptPassword('Enter password: ');\n const success = await unlockDatabase(password);\n\n if (!success) {\n console.error('Incorrect password.');\n process.exit(1);\n }\n\n console.log('Database unlocked.');\n}\n\nexport const unlockCommand = new Command('unlock')\n .description('Unlock the database')\n .action(runUnlock);\n"],"mappings":"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","names":["Command","fs","path","key","fs","PBKDF2_ITERATIONS","generateSalt","PBKDF2_ITERATIONS","fs","generateSalt","fs","fs","path","isRecord","fs","path","changePassword","path","fs","fs","path","Command","path","fs","Command","Command","Command","Command","changePassword","Command","fs","path","Command","path","fs","Command","Command","Command","Command","Command","require","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tearleads/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.26",
4
4
  "description": "Tearleads CLI for database management",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,6 +29,11 @@
29
29
  ],
30
30
  "author": "",
31
31
  "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/a2f0/rapid.git",
35
+ "directory": "packages/cli"
36
+ },
32
37
  "dependencies": {
33
38
  "better-sqlite3-multiple-ciphers": "12.6.2",
34
39
  "commander": "14.0.3"
package/dist/.tsbuildinfo DELETED
@@ -1 +0,0 @@
1
- {"fileNames":["../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.scripthost.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.array.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.collection.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2024.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.array.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.collection.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.float16.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.error.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.full.d.ts","../../../node_modules/.pnpm/commander@14.0.3/node_modules/commander/typings/index.d.ts","../../../node_modules/.pnpm/commander@14.0.3/node_modules/commander/typings/esm.d.mts","../src/backup/constants.ts","../src/backup/compression.ts","../src/backup/crypto.ts","../src/backup/types.ts","../src/backup/decoder.ts","../src/backup/encoder.ts","../src/backup/index.ts","../../shared/dist/crypto/asymmetric.d.ts","../../shared/dist/crypto/web-crypto.d.ts","../../shared/dist/ai-conversations.d.ts","../../shared/dist/chat.d.ts","../../shared/dist/openrouter.d.ts","../../shared/dist/tree/types.d.ts","../../shared/dist/tree/usetree.d.ts","../../shared/dist/tree/index.d.ts","../../shared/dist/index.d.ts","../src/config/index.ts","../src/crypto/key-manager.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/compatibility/iterators.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/globals.typedarray.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/buffer.buffer.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/globals.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/blob.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/console.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/crypto.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/domexception.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/encoding.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/events.d.ts","../../../node_modules/.pnpm/buffer@5.7.1/node_modules/buffer/index.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/utility.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/header.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/readable.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/fetch.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/formdata.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/connector.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/client-stats.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/client.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/errors.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/dispatcher.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/global-origin.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/pool-stats.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/pool.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/handlers.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/h2c-client.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-call-history.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-client.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-pool.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/snapshot-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-errors.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/retry-handler.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/retry-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/api.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/cache-interceptor.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/interceptors.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/util.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/cookies.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/patch.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/websocket.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/eventsource.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/content-type.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/cache.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/index.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/fetch.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/importmeta.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/messaging.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/navigator.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/performance.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/storage.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/streams.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/timers.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/web-globals/url.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/assert.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/assert/strict.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/async_hooks.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/buffer.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/child_process.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/cluster.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/console.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/constants.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/crypto.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/dgram.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/dns.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/dns/promises.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/domain.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/events.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/fs.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/fs/promises.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/http.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/http2.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/https.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/inspector.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/inspector.generated.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/inspector/promises.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/module.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/net.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/os.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/path.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/path/posix.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/path/win32.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/process.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/punycode.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/querystring.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/quic.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/readline.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/readline/promises.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/repl.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/sea.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/sqlite.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/stream.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/stream/promises.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/stream/web.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/string_decoder.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/test.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/test/reporters.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/timers.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/timers/promises.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/tls.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/trace_events.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/tty.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/url.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/util.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/util/types.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/v8.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/vm.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/wasi.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/worker_threads.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/zlib.d.ts","../../../node_modules/.pnpm/@types+node@25.2.0/node_modules/@types/node/index.d.ts","../../../node_modules/.pnpm/@types+better-sqlite3@7.6.13/node_modules/@types/better-sqlite3/index.d.ts","../../../node_modules/.pnpm/better-sqlite3-multiple-ciphers@12.6.2/node_modules/better-sqlite3-multiple-ciphers/index.d.ts","../src/db/adapter.ts","../src/db/index.ts","../src/utils/prompt.ts","../src/commands/backup.ts","../src/commands/dump.ts","../src/commands/lock.ts","../src/commands/password.ts","../src/commands/restore.ts","../src/commands/setup.ts","../src/commands/unlock.ts","../src/index.ts","../src/test/helpers.ts","../../../node_modules/.pnpm/vitest-fail-on-console@0.10.1_@vitest+utils@4.0.18_vite@7.3.1_@types+node@25.2.0_jiti@2.6.1_l_rezxodxj6hykkxnxqcmqiwelva/node_modules/vitest-fail-on-console/dist/index.d.ts","../src/test/setup.ts","../../../node_modules/@types/deep-eql/index.d.ts","../../../node_modules/assertion-error/index.d.ts","../../../node_modules/@types/chai/index.d.ts","../../../node_modules/@types/ms/index.d.ts","../../../node_modules/@types/debug/index.d.ts","../../../node_modules/@types/estree/index.d.ts","../../../node_modules/@types/katex/index.d.ts","../../../node_modules/@types/unist/index.d.ts"],"fileIdsList":[[109,172,180,184,187,189,190,191,203,228],[109,169,170,172,180,184,187,189,190,191,203],[109,171,172,180,184,187,189,190,191,203],[172,180,184,187,189,190,191,203],[109,172,180,184,187,189,190,191,203,211],[109,172,173,178,180,183,184,187,189,190,191,193,203,208,220],[109,172,173,174,180,183,184,187,189,190,191,203],[109,172,180,184,187,189,190,191,203],[109,172,175,180,184,187,189,190,191,203,221],[109,172,176,177,180,184,187,189,190,191,194,203],[109,172,177,180,184,187,189,190,191,203,208,217],[109,172,178,180,183,184,187,189,190,191,193,203],[109,171,172,179,180,184,187,189,190,191,203],[109,172,180,181,184,187,189,190,191,203],[109,172,180,182,183,184,187,189,190,191,203],[109,171,172,180,183,184,187,189,190,191,203],[109,172,180,183,184,185,187,189,190,191,203,208,220],[109,172,180,183,184,185,187,189,190,191,203,208,211],[109,159,172,180,183,184,186,187,189,190,191,193,203,208,220],[109,172,180,183,184,186,187,189,190,191,193,203,208,217,220],[109,172,180,184,186,187,188,189,190,191,203,208,217,220],[107,108,109,110,111,112,113,114,115,116,117,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227],[109,172,180,183,184,187,189,190,191,203],[109,172,180,184,187,189,191,203],[109,172,180,184,187,189,190,191,192,203,220],[109,172,180,183,184,187,189,190,191,193,203,208],[109,172,180,184,187,189,190,191,194,203],[109,172,180,184,187,189,190,191,195,203],[109,172,180,183,184,187,189,190,191,198,203],[109,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227],[109,172,180,184,187,189,190,191,200,203],[109,172,180,184,187,189,190,191,201,203],[109,172,177,180,184,187,189,190,191,193,203,211],[109,172,180,183,184,187,189,190,191,203,204],[109,172,180,184,187,189,190,191,203,205,221,224],[109,172,180,183,184,187,189,190,191,203,208,210,211],[109,172,180,184,187,189,190,191,203,209,211],[109,172,180,184,187,189,190,191,203,211,221],[109,172,180,184,187,189,190,191,203,212],[109,169,172,180,184,187,189,190,191,203,208,214],[109,172,180,184,187,189,190,191,203,208,213],[109,172,180,183,184,187,189,190,191,203,215,216],[109,172,180,184,187,189,190,191,203,215,216],[109,172,177,180,184,187,189,190,191,193,203,208,217],[109,172,180,184,187,189,190,191,203,218],[109,172,180,184,187,189,190,191,193,203,219],[109,172,180,184,186,187,189,190,191,201,203,220],[109,172,180,184,187,189,190,191,203,221,222],[109,172,177,180,184,187,189,190,191,203,222],[109,172,180,184,187,189,190,191,203,208,223],[109,172,180,184,187,189,190,191,192,203,224],[109,172,180,184,187,189,190,191,203,225],[109,172,175,180,184,187,189,190,191,203],[109,172,177,180,184,187,189,190,191,203],[109,172,180,184,187,189,190,191,203,221],[109,159,172,180,184,187,189,190,191,203],[109,172,180,184,187,189,190,191,203,220],[109,172,180,184,187,189,190,191,203,226],[109,172,180,184,187,189,190,191,198,203],[109,172,180,184,187,189,190,191,203,216],[109,159,172,180,183,184,185,187,189,190,191,198,203,208,211,220,223,224,226],[109,172,180,184,187,189,190,191,203,208,227],[87,109,172,180,184,187,189,190,191,203],[109,125,128,131,132,172,180,184,187,189,190,191,203,220],[109,128,172,180,184,187,189,190,191,203,208,220],[109,128,132,172,180,184,187,189,190,191,203,220],[109,172,180,184,187,189,190,191,203,208],[109,122,172,180,184,187,189,190,191,203],[109,126,172,180,184,187,189,190,191,203],[109,124,125,128,172,180,184,187,189,190,191,203,220],[109,172,180,184,187,189,190,191,193,203,217],[109,122,172,180,184,187,189,190,191,203,228],[109,124,128,172,180,184,187,189,190,191,193,203,220],[109,119,120,121,123,127,172,180,183,184,187,189,190,191,203,208,220],[109,128,136,144,172,180,184,187,189,190,191,203],[109,120,126,172,180,184,187,189,190,191,203],[109,128,153,154,172,180,184,187,189,190,191,203],[109,120,123,128,172,180,184,187,189,190,191,203,211,220,228],[109,128,172,180,184,187,189,190,191,203],[109,124,128,172,180,184,187,189,190,191,203,220],[109,119,172,180,184,187,189,190,191,203],[109,122,123,124,126,127,128,129,130,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,154,155,156,157,158,172,180,184,187,189,190,191,203],[109,128,146,149,172,180,184,187,189,190,191,203],[109,128,136,137,138,172,180,184,187,189,190,191,203],[109,126,128,137,139,172,180,184,187,189,190,191,203],[109,127,172,180,184,187,189,190,191,203],[109,120,122,128,172,180,184,187,189,190,191,203],[109,128,132,137,139,172,180,184,187,189,190,191,203],[109,132,172,180,184,187,189,190,191,203],[109,126,128,131,172,180,184,187,189,190,191,203,220],[109,120,124,128,136,172,180,184,187,189,190,191,203],[109,128,146,172,180,184,187,189,190,191,203],[109,139,172,180,184,187,189,190,191,203],[109,122,128,153,172,180,184,187,189,190,191,203,211,226,228],[109,172,180,184,187,189,190,191,203,245,246],[109,172,180,184,187,189,190,191,203,248],[109,172,180,184,187,189,190,191,203,227],[89,109,172,180,184,187,189,190,191,203],[89,90,91,92,109,172,180,184,187,189,190,191,203],[89,92,93,94,109,172,180,184,187,189,190,191,203],[88,92,95,106,109,172,180,184,185,187,189,190,191,195,203,232,233],[88,109,172,180,184,187,189,190,191,203,232],[88,109,172,180,184,187,189,190,191,203,232,233],[88,95,106,109,172,180,184,185,187,189,190,191,195,203,232,233],[88,106,109,172,180,184,187,189,190,191,203,232,233],[109,172,180,184,185,187,189,190,191,194,195,203],[104,105,109,172,180,184,185,187,189,190,191,203],[92,105,109,172,180,184,185,187,189,190,191,195,203,229,230],[92,105,106,109,172,180,184,185,187,189,190,191,203,231],[88,109,172,180,184,187,189,190,191,203,234,235,236,237,238,239,240],[109,172,180,184,187,189,190,191,203,243],[109,172,180,184,187,189,190,191,199,203,204],[96,97,98,99,100,103,109,172,180,184,187,189,190,191,203],[101,102,109,172,180,184,187,189,190,191,203],[101,109,172,180,184,187,189,190,191,203]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"bde31fd423cd93b0eff97197a3f66df7c93e8c0c335cbeb113b7ff1ac35c23f4","impliedFormat":1},{"version":"0237580177f1a858ab125992af8a6dfc29268fe7d4bac5308b9f462f88b0cd31","impliedFormat":1},{"version":"b124c0624b15412ace7d54644ade38d7a69db7e25488a1a4d2a8df6e11696538","impliedFormat":99},{"version":"c07757d13ee29a8599c21a162ba92b08e943911ded055f718f4e348f730136c4","signature":"0d1c3a6716ee6ef2cfe2f74a80a0124787dfd21d7972d09ebdecf617fa76e923","impliedFormat":99},{"version":"742927ee7d3193b96197a297f4949efe2e543b0f54f2c6187638908d4fd78b0a","signature":"0357a19891793411fa5814d614a1943f55b3c0a624afeb8d23334ac798fffe1f","impliedFormat":99},{"version":"f3a81e18d96429f59d247a06885a0837e8e88a26b7a8080c945774c4b97e29b7","signature":"244959a294c625cd4062407c558435b0d4ada42426d8fc8dffe3f943f809d76f","impliedFormat":99},{"version":"9e87a8b655a22bd234c82baa4ce6706f856e633bae11fbb84c3c4e81c9314394","signature":"aacb6efc86a38fa1838d4435f4b475d7031e4bd156557b58a8a3c3e743ee3f0e","impliedFormat":99},{"version":"26a51d3ed2830a1086b441e016c80e589540d83a7b5bb7fa8108e2b8677a3092","signature":"ecac66d73d7d79e2134971f11f188d25f9ba2bd530949980464e0b403a31e299","impliedFormat":99},{"version":"22a287e952358c13ac2cbe47441aac8dddb8f80e53e247796d42431068fa2407","signature":"b7a023e6a51ea7eec05b83a67af138ed7ac5e0d935334bd5ac96607c0eea8457","impliedFormat":99},{"version":"810af9e10aedccf4829aad80992e5f3e668b2bdc1e4e98ce24e01f13d50bc158","signature":"14b4f60a9256f2c34c913fb7ee24f9eec6b48c2b5cb90a8c0d3c976656aaa19b","impliedFormat":99},{"version":"e8eccdd54fa33d76ded5d49dfbdf2a59a60159db4f4542f89bd4013a2f5d9039","impliedFormat":99},{"version":"3d02890ff09c6ad42b989cbdfec303055dc3e8bc8f87b23e107eefb338815bb7","impliedFormat":99},{"version":"4670c0da0e14be8c432d2604d5820dbef7a3290497f681e2547189fa4767a62c","impliedFormat":99},{"version":"910c9a6462d98e918d12fffedbf19fdb9e6958fa7b1bf301a743eafe57abf171","impliedFormat":99},{"version":"11a3c5171594c1157914592b84c4adf58a831adb89dbb0695a6a71a0a123b2f7","impliedFormat":99},{"version":"7aef80857d6191c5ffa8fd1b5c468eed2e2d50f5ac75ca1d7eedc73605908ed4","impliedFormat":99},{"version":"10acd9677e3f6d60e29e76282f45e631da229b97320cb8dbafd2bf1d76bcb91a","impliedFormat":99},{"version":"81613eaefa3f736be20ccc9b3b1f42a2830bc65f19925cb73b837f5a7f5c87d6","impliedFormat":99},{"version":"b964a0d7150ffae773209a4ced5a84c6ee0bf974b373c28489f974425526905b","impliedFormat":99},{"version":"a8bbec4196ea19811614de675325f4970a369b7dcfeffe0f4698b75f15c066bd","signature":"3d3c531112cdfdf21bd6087fd4944b92fba50539d176be44c8406e44d75aa85e","impliedFormat":99},{"version":"3ee8fcb4fbaa410cad5a6c7ca56fdd3c582b8495f3d62e737a0cfa1176823d95","signature":"ced68b68396f07f1dee6a6c4f7db0bd9c220173d681883f8d2cb06058d1b5d54","impliedFormat":99},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"0ccdaa19852d25ecd84eec365c3bfa16e7859cadecf6e9ca6d0dbbbee439743f","affectsGlobalScope":true,"impliedFormat":1},{"version":"438b41419b1df9f1fbe33b5e1b18f5853432be205991d1b19f5b7f351675541e","affectsGlobalScope":true,"impliedFormat":1},{"version":"096116f8fedc1765d5bd6ef360c257b4a9048e5415054b3bf3c41b07f8951b0b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5e01375c9e124a83b52ee4b3244ed1a4d214a6cfb54ac73e164a823a4a7860a","affectsGlobalScope":true,"impliedFormat":1},{"version":"f90ae2bbce1505e67f2f6502392e318f5714bae82d2d969185c4a6cecc8af2fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b58e207b93a8f1c88bbf2a95ddc686ac83962b13830fe8ad3f404ffc7051fb4","affectsGlobalScope":true,"impliedFormat":1},{"version":"1fefabcb2b06736a66d2904074d56268753654805e829989a46a0161cd8412c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"c18a99f01eb788d849ad032b31cafd49de0b19e083fe775370834c5675d7df8e","affectsGlobalScope":true,"impliedFormat":1},{"version":"5247874c2a23b9a62d178ae84f2db6a1d54e6c9a2e7e057e178cc5eea13757fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","impliedFormat":1},{"version":"487b694c3de27ddf4ad107d4007ad304d29effccf9800c8ae23c2093638d906a","impliedFormat":1},{"version":"3a80bc85f38526ca3b08007ee80712e7bb0601df178b23fbf0bf87036fce40ce","impliedFormat":1},{"version":"ccf4552357ce3c159ef75f0f0114e80401702228f1898bdc9402214c9499e8c0","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"2931540c47ee0ff8a62860e61782eb17b155615db61e36986e54645ec67f67c2","impliedFormat":1},{"version":"ccab02f3920fc75c01174c47fcf67882a11daf16baf9e81701d0a94636e94556","impliedFormat":1},{"version":"f6faf5f74e4c4cc309a6c6a6c4da02dbb840be5d3e92905a23dcd7b2b0bd1986","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"33e981bf6376e939f99bd7f89abec757c64897d33c005036b9a10d9587d80187","impliedFormat":1},{"version":"7fd1b31fd35876b0aa650811c25ec2c97a3c6387e5473eb18004bed86cdd76b6","impliedFormat":1},{"version":"b41767d372275c154c7ea6c9d5449d9a741b8ce080f640155cc88ba1763e35b3","impliedFormat":1},{"version":"3bacf516d686d08682751a3bd2519ea3b8041a164bfb4f1d35728993e70a2426","impliedFormat":1},{"version":"7fb266686238369442bd1719bc0d7edd0199da4fb8540354e1ff7f16669b4323","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"5b03a034c72146b61573aab280f295b015b9168470f2df05f6080a2122f9b4df","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"249b9cab7f5d628b71308c7d9bb0a808b50b091e640ba3ed6e2d0516f4a8d91d","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"54c3e2371e3d016469ad959697fd257e5621e16296fa67082c2575d0bf8eced0","impliedFormat":1},{"version":"beb8233b2c220cfa0feea31fbe9218d89fa02faa81ef744be8dce5acb89bb1fd","impliedFormat":1},{"version":"c183b931b68ad184bc8e8372bf663f3d33304772fb482f29fb91b3c391031f3e","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"48cc3ec153b50985fb95153258a710782b25975b10dd4ac8a4f3920632d10790","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"e1528ca65ac90f6fa0e4a247eb656b4263c470bb22d9033e466463e13395e599","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"866078923a56d026e39243b4392e282c1c63159723996fa89243140e1388a98d","impliedFormat":1},{"version":"dd0109710de4cd93e245121ab86d8c66d20f3ead80074b68e9c3e349c4f53342","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3275d55fac10b799c9546804126239baf020d220136163f763b55a74e50e750","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa68a0a3b7cb32c00e39ee3cd31f8f15b80cac97dce51b6ee7fc14a1e8deb30b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c36e755bced82df7fb6ce8169265d0a7bb046ab4e2cb6d0da0cb72b22033e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"7a93de4ff8a63bafe62ba86b89af1df0ccb5e40bb85b0c67d6bbcfdcf96bf3d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"90e85f9bc549dfe2b5749b45fe734144e96cd5d04b38eae244028794e142a77e","affectsGlobalScope":true,"impliedFormat":1},{"version":"e0a5deeb610b2a50a6350bd23df6490036a1773a8a71d70f2f9549ab009e67ee","affectsGlobalScope":true,"impliedFormat":1},{"version":"435b3711465425770ed2ee2f1cf00ce071835265e0851a7dc4600ab4b007550e","impliedFormat":1},{"version":"7e49f52a159435fc8df4de9dc377ef5860732ca2dc9efec1640531d3cf5da7a3","impliedFormat":1},{"version":"dd4bde4bdc2e5394aed6855e98cf135dfdf5dd6468cad842e03116d31bbcc9bc","impliedFormat":1},{"version":"4d4e879009a84a47c05350b8dca823036ba3a29a3038efed1be76c9f81e45edf","affectsGlobalScope":true,"impliedFormat":1},{"version":"237ba5ac2a95702a114a309e39c53a5bddff5f6333b325db9764df9b34f3502b","impliedFormat":1},{"version":"9ba13b47cb450a438e3076c4a3f6afb9dc85e17eae50f26d4b2d72c0688c9251","impliedFormat":1},{"version":"b64cd4401633ea4ecadfd700ddc8323a13b63b106ac7127c1d2726f32424622c","impliedFormat":1},{"version":"37c6e5fe5715814412b43cc9b50b24c67a63c4e04e753e0d1305970d65417a60","impliedFormat":1},{"version":"1d024184fb57c58c5c91823f9d10b4915a4867b7934e89115fd0d861a9df27c8","impliedFormat":1},{"version":"ee0e4946247f842c6dd483cbb60a5e6b484fee07996e3a7bc7343dfb68a04c5d","impliedFormat":1},{"version":"ef051f42b7e0ef5ca04552f54c4552eac84099d64b6c5ad0ef4033574b6035b8","impliedFormat":1},{"version":"853a43154f1d01b0173d9cbd74063507ece57170bad7a3b68f3fa1229ad0a92f","impliedFormat":1},{"version":"56231e3c39a031bfb0afb797690b20ed4537670c93c0318b72d5180833d98b72","impliedFormat":1},{"version":"5cc7c39031bfd8b00ad58f32143d59eb6ffc24f5d41a20931269011dccd36c5e","impliedFormat":1},{"version":"b0b69c61b0f0ec8ca15db4c8c41f6e77f4cacb784d42bca948f42dea33e8757e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f96a48183254c00d24575401f1a761b4ce4927d927407e7862a83e06ce5d6964","impliedFormat":1},{"version":"cc25940cfb27aa538e60d465f98bb5068d4d7d33131861ace43f04fe6947d68f","impliedFormat":1},{"version":"9dec1d75d47c23b595402f265babeac9c0f645427df7e937d69ddfa05cdddc1f","impliedFormat":1},{"version":"01ff95aa1443e3f7248974e5a771f513cb2ac158c8898f470a1792f817bee497","impliedFormat":1},{"version":"757227c8b345c57d76f7f0e3bbad7a91ffca23f1b2547cbed9e10025816c9cb7","impliedFormat":1},{"version":"42a05d8f239f74587d4926aba8cc54792eed8e8a442c7adc9b38b516642aadfe","impliedFormat":1},{"version":"5d21b58d60383cc6ab9ad3d3e265d7d25af24a2c9b506247e0e50b0a884920be","impliedFormat":1},{"version":"101f482fd48cb4c7c0468dcc6d62c843d842977aea6235644b1edd05e81fbf22","impliedFormat":1},{"version":"ae6757460f37078884b1571a3de3ebaf724d827d7e1d53626c02b3c2a408ac63","affectsGlobalScope":true,"impliedFormat":1},{"version":"9451a46a89ed209e2e08329e6cac59f89356eae79a7230f916d8cc38725407c7","impliedFormat":1},{"version":"3ef397f12387eff17f550bc484ea7c27d21d43816bbe609d495107f44b97e933","impliedFormat":1},{"version":"1023282e2ba810bc07905d3668349fbd37a26411f0c8f94a70ef3c05fe523fcf","impliedFormat":1},{"version":"b214ebcf76c51b115453f69729ee8aa7b7f8eccdae2a922b568a45c2d7ff52f7","impliedFormat":1},{"version":"429c9cdfa7d126255779efd7e6d9057ced2d69c81859bbab32073bad52e9ba76","impliedFormat":1},{"version":"e236b5eba291f51bdf32c231673e6cab81b5410850e61f51a7a524dddadc0f95","impliedFormat":1},{"version":"f7ba0e839daa0702e3ff1a1a871c0d8ea2d586ce684dd8a72c786c36a680b1d9","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f2c62938251b45715fd2a9887060ec4fbc8724727029d1cbce373747252bdd7","impliedFormat":1},{"version":"e3ace08b6bbd84655d41e244677b474fd995923ffef7149ddb68af8848b60b05","impliedFormat":1},{"version":"132580b0e86c48fab152bab850fc57a4b74fe915c8958d2ccb052b809a44b61c","impliedFormat":1},{"version":"af4ab0aa8908fc9a655bb833d3bc28e117c4f0e1038c5a891546158beb25accb","impliedFormat":1},{"version":"69c9a5a9392e8564bd81116e1ed93b13205201fb44cb35a7fde8c9f9e21c4b23","impliedFormat":1},{"version":"5f8fc37f8434691ffac1bfd8fc2634647da2c0e84253ab5d2dd19a7718915b35","impliedFormat":1},{"version":"5981c2340fd8b076cae8efbae818d42c11ffc615994cb060b1cd390795f1be2b","impliedFormat":1},{"version":"f64deb26664af64dc274637343bde8d82f930c77af05a412c7d310b77207a448","impliedFormat":1},{"version":"ed4f674fc8c0c993cc7e145069ac44129e03519b910c62be206a0cc777bdc60b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0250da3eb85c99624f974e77ef355cdf86f43980251bc371475c2b397ba55bcd","impliedFormat":1},{"version":"f1c93e046fb3d9b7f8249629f4b63dc068dd839b824dd0aa39a5e68476dc9420","impliedFormat":1},{"version":"3d3a5f27ffbc06c885dd4d5f9ee20de61faf877fe2c3a7051c4825903d9a7fdc","impliedFormat":1},{"version":"12806f9f085598ef930edaf2467a5fa1789a878fba077cd27e85dc5851e11834","impliedFormat":1},{"version":"17d06eb5709839c7ce719f0c38ada6f308fb433f2cd6d8c87b35856e07400950","impliedFormat":1},{"version":"a43fe41c33d0a192a0ecaf9b92e87bef3709c9972e6d53c42c49251ccb962d69","impliedFormat":1},{"version":"a177959203c017fad3ecc4f3d96c8757a840957a4959a3ae00dab9d35961ca6c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fc727ccf9b36e257ff982ea0badeffbfc2c151802f741bddff00c6af3b784cf","impliedFormat":1},{"version":"2a00d005e3af99cd1cfa75220e60c61b04bfb6be7ca7453bfe2ef6cca37cc03c","impliedFormat":1},{"version":"4844a4c9b4b1e812b257676ed8a80b3f3be0e29bf05e742cc2ea9c3c6865e6c6","impliedFormat":1},{"version":"064878a60367e0407c42fb7ba02a2ea4d83257357dc20088e549bd4d89433e9c","impliedFormat":1},{"version":"14d4bd22d1b05824971b98f7e91b2484c90f1a684805c330476641417c3d9735","impliedFormat":1},{"version":"c3877fef8a43cd434f9728f25a97575b0eb73d92f38b5c87c840daccc3e21d97","impliedFormat":1},{"version":"b484ec11ba00e3a2235562a41898d55372ccabe607986c6fa4f4aba72093749f","impliedFormat":1},{"version":"1dbd83860e7634f9c236647f45dbc5d3c4f9eba8827d87209d6e9826fdf4dbd5","impliedFormat":1},{"version":"41ef7992c555671a8fe54db302788adefa191ded810a50329b79d20a6772d14c","impliedFormat":1},{"version":"041a7781b9127ab568d2cdcce62c58fdea7c7407f40b8c50045d7866a2727130","impliedFormat":1},{"version":"b37f83e7deea729aa9ce5593f78905afb45b7532fdff63041d374f60059e7852","impliedFormat":1},{"version":"e1cb68f3ef3a8dd7b2a9dfb3de482ed6c0f1586ba0db4e7d73c1d2147b6ffc51","impliedFormat":1},{"version":"55cdbeebe76a1fa18bbd7e7bf73350a2173926bd3085bb050cf5a5397025ee4e","impliedFormat":1},{"version":"c2a6a737189ced24ffe0634e9239b087e4c26378d0490f95141b9b9b042b746c","impliedFormat":1},{"version":"d155ee704a409614c8384898a95fdccc4faf3b15cbe522f930ce724a2e192200","impliedFormat":1},{"version":"648960b82bab5f17fdd98e2a1f31b46c2672f9125a880dd0d4a4ac999c940b7e","signature":"088798ca23022b9d93aa0981a88099ba809f632f6624d2b18da09b46078c6528","impliedFormat":99},{"version":"ea8e90adc0143d921e45d8c0563711fe2991cd13afb7b61c5335020309f25603","signature":"e468cec705188baa9fa0818a5506f3b3a06f7c4eab20bcc671da9dea69de3fba","impliedFormat":99},{"version":"89840886bbfdf18e92fa8487a4b481494fe7e6ab1ec4029082da21d3c1e74041","signature":"80090fc261a9521da5dec515a53296cc4b63e07c5b71260c2a7b8b0ba7aa9500","impliedFormat":99},{"version":"b29d483f6ccee233fd8aa1b4a8b52aa0db1ea95c2fd9e0d109ff8326ec4447f3","signature":"50bf37def0e4fd9e003ed7935611a2a973bdd0ff4714167fe3e8812de622b877","impliedFormat":99},{"version":"1be3be7dbd090a960aa5b596ecd6f07797862171651d6476e93056f0211de178","signature":"2d277edeea30a25940cf197dee84e2f4da198e694f95738c72af362027042276","impliedFormat":99},{"version":"38e4ca11054b211fb5264a9b9b0008e8c8dbbfb7f1f15762812dd8e371f4cf7b","signature":"06d9eab692391153ce2345244d0e052adf68f498722186e8320ef2e04e5ef9d5","impliedFormat":99},{"version":"7b42f04fc6a6bfe8535994c6f410c444fbf98298679e18f1d488dadeca80c99f","signature":"5e70f30ed4ce94d2d904f2fc84d5cfac3a49bfa60438b306be851eab0db2c9ed","impliedFormat":99},{"version":"2cd797c74460e772a8efde4b858aad2372594efc40214e69ec02c8ad47fca451","signature":"e333318d286d16f230268cc7c864584d58678afb66238cd112ad9fe3dc8f5064","impliedFormat":99},{"version":"cf84db2ccdd3f9a0970f777251e66358c433c3bc5f69cc01c83433ec31829ad5","signature":"a0f05084519aa2facd8a4d98966f4975cb578bff2a5a93a8a712e6968102c681","impliedFormat":99},{"version":"7cd0206697194ef47125df4ac05987a2aa91b3120d38423e1770304f54a87540","signature":"38547339f4607c853fa828a5ed5b844f2a60b5dfcaf32704d475a2d8969c34c6","impliedFormat":99},{"version":"ee1f663683519f42df299f9d2f3e9b78b0b95442590a3ae783752ffd2aae2c5b","signature":"814cc5239cf34fdd9c1e27ca02fadbc393cc80509affb6a6b46464c95bb66804","impliedFormat":99},{"version":"5c186b37b01e0e9ab1d467a8d1ff0da8159c2a802dcf536da9ee5572eec0c9e5","signature":"b93cdcbbc6f7d3f4154a8166a3982fdd89ae8083c77a38ce5700d24285ed620c","impliedFormat":99},{"version":"16e169425634fd24ac0b9686aab6f112dbc44cac0605a2dbb5c9e44557fe3e84","impliedFormat":99},{"version":"9ea8e4c5a4a14897e666fabddbfe4c40d4228895960baf58eff74378b9676ea9","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"fb893a0dfc3c9fb0f9ca93d0648694dd95f33cbad2c0f2c629f842981dfd4e2e","impliedFormat":1},{"version":"3eb11dbf3489064a47a2e1cf9d261b1f100ef0b3b50ffca6c44dd99d6dd81ac1","impliedFormat":1},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"8cbbb12bfb321de8bd58ba74329f683d82e4e0abb56d998c7f1eef2e764a74c8","impliedFormat":1},{"version":"6d09838b65c3c780513878793fc394ae29b8595d9e4729246d14ce69abc71140","impliedFormat":1}],"root":[[89,95],105,106,[231,242],244],"options":{"allowJs":false,"allowUnreachableCode":false,"allowUnusedLabels":false,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noPropertyAccessFromIndexSignature":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./","rootDir":"../src","skipLibCheck":true,"strict":true,"target":99,"tsBuildInfoFile":"./.tsbuildinfo"},"referencedMap":[[229,1],[169,2],[170,2],[171,3],[109,4],[172,5],[173,6],[174,7],[107,8],[175,9],[176,10],[177,11],[178,12],[179,13],[180,14],[181,14],[182,15],[183,16],[184,17],[185,18],[110,8],[108,8],[186,19],[187,20],[188,21],[228,22],[189,23],[190,24],[191,23],[192,25],[193,26],[194,27],[195,28],[196,28],[197,28],[198,29],[199,30],[200,31],[201,32],[202,33],[203,34],[204,34],[205,35],[206,8],[207,8],[208,36],[209,37],[210,36],[211,38],[212,39],[213,40],[214,41],[215,42],[216,43],[217,44],[218,45],[219,46],[220,47],[221,48],[222,49],[223,50],[224,51],[225,52],[111,23],[112,8],[113,53],[114,54],[115,8],[116,55],[117,8],[160,56],[161,57],[162,58],[163,58],[164,59],[165,8],[166,5],[167,60],[168,57],[226,61],[227,62],[230,1],[118,8],[88,63],[87,8],[84,8],[85,8],[15,8],[13,8],[14,8],[19,8],[18,8],[2,8],[20,8],[21,8],[22,8],[23,8],[24,8],[25,8],[26,8],[27,8],[3,8],[28,8],[29,8],[4,8],[30,8],[34,8],[31,8],[32,8],[33,8],[35,8],[36,8],[37,8],[5,8],[38,8],[39,8],[40,8],[41,8],[6,8],[45,8],[42,8],[43,8],[44,8],[46,8],[7,8],[47,8],[52,8],[53,8],[48,8],[49,8],[50,8],[51,8],[8,8],[57,8],[54,8],[55,8],[56,8],[58,8],[9,8],[59,8],[60,8],[61,8],[63,8],[62,8],[64,8],[65,8],[10,8],[66,8],[67,8],[68,8],[11,8],[69,8],[70,8],[71,8],[72,8],[73,8],[1,8],[74,8],[75,8],[12,8],[79,8],[77,8],[82,8],[81,8],[86,8],[76,8],[80,8],[78,8],[83,8],[17,8],[16,8],[136,64],[148,65],[134,66],[149,67],[158,68],[125,69],[126,70],[124,71],[157,1],[152,72],[156,73],[128,74],[145,75],[127,76],[155,77],[122,78],[123,72],[129,79],[130,8],[135,80],[133,79],[120,81],[159,82],[150,83],[139,84],[138,79],[140,85],[143,86],[137,87],[141,88],[153,1],[131,89],[132,90],[144,91],[121,67],[147,92],[146,79],[142,93],[151,8],[119,8],[154,94],[243,8],[247,95],[249,96],[245,8],[250,8],[251,8],[248,8],[252,8],[246,8],[90,97],[89,8],[91,98],[93,99],[94,99],[95,100],[92,8],[234,101],[235,101],[236,102],[237,103],[238,104],[239,103],[240,105],[105,106],[106,107],[231,108],[232,109],[241,110],[242,106],[244,111],[233,112],[98,8],[99,8],[96,8],[97,8],[104,113],[100,8],[103,114],[101,8],[102,115]],"latestChangedDtsFile":"./commands/dump.d.ts","version":"5.9.3"}