@robthepcguy/rag-vault 1.5.0 → 1.5.2

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.
Files changed (84) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +13 -4
  3. package/dist/bin/install-skills.d.ts +0 -0
  4. package/dist/bin/install-skills.js +0 -0
  5. package/dist/chunker/index.d.ts +0 -0
  6. package/dist/chunker/index.js +0 -0
  7. package/dist/chunker/semantic-chunker.d.ts +0 -0
  8. package/dist/chunker/semantic-chunker.js +0 -0
  9. package/dist/chunker/sentence-splitter.d.ts +0 -0
  10. package/dist/chunker/sentence-splitter.js +0 -0
  11. package/dist/embedder/index.d.ts +0 -0
  12. package/dist/embedder/index.js +0 -0
  13. package/dist/errors/index.d.ts +0 -0
  14. package/dist/errors/index.js +0 -0
  15. package/dist/explainability/index.d.ts +0 -0
  16. package/dist/explainability/index.js +0 -0
  17. package/dist/explainability/keywords.d.ts +0 -0
  18. package/dist/explainability/keywords.js +0 -0
  19. package/dist/flywheel/feedback.d.ts +0 -0
  20. package/dist/flywheel/feedback.js +0 -0
  21. package/dist/flywheel/index.d.ts +0 -0
  22. package/dist/flywheel/index.js +0 -0
  23. package/dist/index.d.ts +0 -0
  24. package/dist/parser/html-parser.d.ts +0 -0
  25. package/dist/parser/html-parser.js +0 -0
  26. package/dist/parser/index.d.ts +0 -0
  27. package/dist/parser/index.js +0 -0
  28. package/dist/parser/pdf-filter.d.ts +0 -0
  29. package/dist/parser/pdf-filter.js +0 -0
  30. package/dist/query/index.d.ts +0 -0
  31. package/dist/query/index.js +0 -0
  32. package/dist/query/parser.d.ts +0 -0
  33. package/dist/query/parser.js +0 -0
  34. package/dist/server/index.d.ts +0 -0
  35. package/dist/server/index.js +0 -0
  36. package/dist/server/raw-data-utils.d.ts +0 -0
  37. package/dist/server/raw-data-utils.js +0 -0
  38. package/dist/server/schemas.d.ts +0 -0
  39. package/dist/server/schemas.js +0 -0
  40. package/dist/utils/config-parsers.d.ts +0 -0
  41. package/dist/utils/config-parsers.js +0 -0
  42. package/dist/utils/config.d.ts +0 -0
  43. package/dist/utils/config.js +0 -0
  44. package/dist/utils/file-utils.d.ts +0 -0
  45. package/dist/utils/file-utils.js +0 -0
  46. package/dist/utils/math.d.ts +0 -0
  47. package/dist/utils/math.js +0 -0
  48. package/dist/utils/process-handlers.d.ts +0 -0
  49. package/dist/utils/process-handlers.js +0 -0
  50. package/dist/vectordb/index.d.ts +24 -0
  51. package/dist/vectordb/index.js +122 -14
  52. package/dist/web/api-routes.d.ts +0 -0
  53. package/dist/web/api-routes.js +0 -0
  54. package/dist/web/config-routes.d.ts +0 -0
  55. package/dist/web/config-routes.js +0 -0
  56. package/dist/web/database-manager.d.ts +0 -0
  57. package/dist/web/database-manager.js +0 -0
  58. package/dist/web/http-server.d.ts +0 -0
  59. package/dist/web/http-server.js +0 -0
  60. package/dist/web/index.d.ts +0 -0
  61. package/dist/web/index.js +0 -0
  62. package/dist/web/middleware/async-handler.d.ts +0 -0
  63. package/dist/web/middleware/async-handler.js +0 -0
  64. package/dist/web/middleware/auth.d.ts +0 -0
  65. package/dist/web/middleware/auth.js +0 -0
  66. package/dist/web/middleware/error-handler.d.ts +0 -0
  67. package/dist/web/middleware/error-handler.js +0 -0
  68. package/dist/web/middleware/index.d.ts +0 -0
  69. package/dist/web/middleware/index.js +0 -0
  70. package/dist/web/middleware/rate-limit.d.ts +0 -0
  71. package/dist/web/middleware/rate-limit.js +0 -0
  72. package/dist/web/middleware/request-logger.d.ts +0 -0
  73. package/dist/web/middleware/request-logger.js +0 -0
  74. package/dist/web/types.d.ts +0 -0
  75. package/dist/web/types.js +0 -0
  76. package/package.json +42 -50
  77. package/skills/rag-vault/SKILL.md +111 -111
  78. package/skills/rag-vault/references/html-ingestion.md +73 -73
  79. package/skills/rag-vault/references/query-optimization.md +57 -57
  80. package/skills/rag-vault/references/result-refinement.md +54 -54
  81. package/web-ui/dist/assets/index-SBHxoAwi.js +0 -0
  82. package/web-ui/dist/assets/index-ej8i4PGl.css +0 -0
  83. package/web-ui/dist/index.html +0 -0
  84. package/web-ui/dist/vite.svg +0 -0
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -397,6 +397,7 @@ Copy the `DB_PATH` directory (default: `./lancedb/`).
397
397
  | File too large | Default limit is 100MB. Set `MAX_FILE_SIZE` higher or split the file. |
398
398
  | Path outside BASE_DIR | All file paths must be under `BASE_DIR`. Use absolute paths. |
399
399
  | MCP tools not showing | Verify config syntax, restart your AI tool completely (Cmd+Q on Mac). |
400
+ | `mcp-publisher login github` fails with `slow_down` | Use token login instead: `mcp-publisher login github --token "$(gh auth token)"` (or pass a PAT). |
400
401
  | 401 Unauthorized | API key required. Set `RAG_API_KEY` or use correct header format. |
401
402
  | 429 Too Many Requests | Rate limited. Wait for reset or increase `RATE_LIMIT_MAX_REQUESTS`. |
402
403
  | CORS errors | Add your origin to `CORS_ORIGINS` environment variable. |
@@ -429,6 +430,12 @@ pnpm dev
429
430
 
430
431
  # Run web server locally
431
432
  pnpm web:dev
433
+
434
+ # Release to npm (local, guarded)
435
+ pnpm release:patch
436
+ pnpm release:minor
437
+ pnpm release:major
438
+ pnpm release:dry
432
439
  ```
433
440
 
434
441
 
@@ -439,11 +446,13 @@ pnpm web:dev
439
446
 
440
447
  Use `RUN_EMBEDDING_INTEGRATION=1` to explicitly opt into network/model-dependent suites.
441
448
 
442
- ### CI Strategy
449
+ ### Release Strategy
443
450
 
444
- - `quality.yml` runs on PRs and pushes and enforces the root quality gate (`pnpm check:all`), which includes backend checks and web-ui type/lint/format checks plus unit tests.
445
- - A nightly scheduled job runs the integration/E2E suite so model-dependent workflows stay healthy without blocking every PR.
446
- - `publish-npm.yml` publishes to npm on GitHub Releases, validates tag/version alignment, blocks duplicate npm versions, and supports a manual dry-run, while a real publish requires `NPM_TOKEN`.
451
+ - Releases are local and scripted via `scripts/release-npm.sh`.
452
+ - Supported bumps: `patch`, `minor`, `major`.
453
+ - The script runs dependency installs, `pnpm check:all`, and `pnpm ui:build` before touching version files.
454
+ - `package.json` and `server.json` versions are updated only after checks pass, and auto-restored if any later step fails.
455
+ - `pnpm release:dry` performs the full gate plus npm dry-run publish and always restores version files.
447
456
 
448
457
  ### Project Structure
449
458
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/index.d.ts CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -149,6 +149,30 @@ export declare class VectorStore {
149
149
  * Record FTS success (resets circuit breaker)
150
150
  */
151
151
  private recordFtsSuccess;
152
+ /**
153
+ * Extract unsupported custom metadata field from LanceDB schema mismatch errors.
154
+ *
155
+ * Returns:
156
+ * - specific key (e.g., "character") for metadata.custom.character mismatch
157
+ * - CUSTOM_METADATA_ALL_FIELDS when metadata.custom itself is unsupported
158
+ * - null when error is unrelated
159
+ */
160
+ private extractUnsupportedCustomMetadataField;
161
+ /**
162
+ * Remove unsupported custom metadata field from chunks for schema compatibility.
163
+ *
164
+ * @param chunks - Source chunks
165
+ * @param field - Unsupported field name, or CUSTOM_METADATA_ALL_FIELDS to drop all custom metadata
166
+ * @returns Sanitized chunks and whether any changes were applied
167
+ */
168
+ private stripUnsupportedCustomMetadata;
169
+ /**
170
+ * Add chunks to existing table with automatic fallback for custom metadata schema mismatches.
171
+ *
172
+ * LanceDB infers struct fields from early inserts, so later custom metadata keys may fail.
173
+ * This method retries by stripping only unsupported custom fields when needed.
174
+ */
175
+ private addChunksWithSchemaFallback;
152
176
  /**
153
177
  * Initialize LanceDB and create table
154
178
  */
@@ -74,6 +74,13 @@ const DELETE_IGNORABLE_PATTERNS = [
74
74
  'no rows',
75
75
  'empty result',
76
76
  ];
77
+ /**
78
+ * LanceDB schema mismatch pattern for custom metadata fields.
79
+ * Example: "Found field not in schema: metadata.custom.character at row 0"
80
+ */
81
+ const CUSTOM_METADATA_SCHEMA_MISMATCH_REGEX = /Found field not in schema:\s*metadata\.custom(?:\.([A-Za-z0-9_-]+))?/i;
82
+ /** Sentinel for "metadata.custom itself is not in schema" */
83
+ const CUSTOM_METADATA_ALL_FIELDS = '__all__';
77
84
  /**
78
85
  * Regex for validating file paths before use in queries.
79
86
  * Allows alphanumeric characters, slashes, dots, underscores, hyphens, colons (Windows), and spaces.
@@ -311,6 +318,108 @@ class VectorStore {
311
318
  this.ftsLastFailure = null;
312
319
  }
313
320
  }
321
+ /**
322
+ * Extract unsupported custom metadata field from LanceDB schema mismatch errors.
323
+ *
324
+ * Returns:
325
+ * - specific key (e.g., "character") for metadata.custom.character mismatch
326
+ * - CUSTOM_METADATA_ALL_FIELDS when metadata.custom itself is unsupported
327
+ * - null when error is unrelated
328
+ */
329
+ extractUnsupportedCustomMetadataField(error) {
330
+ const message = error instanceof Error ? error.message : typeof error === 'string' ? error : String(error);
331
+ const match = CUSTOM_METADATA_SCHEMA_MISMATCH_REGEX.exec(message);
332
+ if (!match)
333
+ return null;
334
+ return match[1] || CUSTOM_METADATA_ALL_FIELDS;
335
+ }
336
+ /**
337
+ * Remove unsupported custom metadata field from chunks for schema compatibility.
338
+ *
339
+ * @param chunks - Source chunks
340
+ * @param field - Unsupported field name, or CUSTOM_METADATA_ALL_FIELDS to drop all custom metadata
341
+ * @returns Sanitized chunks and whether any changes were applied
342
+ */
343
+ stripUnsupportedCustomMetadata(chunks, field) {
344
+ let changed = false;
345
+ const sanitizedChunks = chunks.map((chunk) => {
346
+ const custom = chunk.metadata.custom;
347
+ if (!custom)
348
+ return chunk;
349
+ // Entire custom object is unsupported by table schema
350
+ if (field === CUSTOM_METADATA_ALL_FIELDS) {
351
+ changed = true;
352
+ const metadataWithoutCustom = { ...chunk.metadata };
353
+ delete metadataWithoutCustom.custom;
354
+ return {
355
+ ...chunk,
356
+ metadata: metadataWithoutCustom,
357
+ };
358
+ }
359
+ // Specific custom key is unsupported by table schema
360
+ if (!(field in custom)) {
361
+ return chunk;
362
+ }
363
+ changed = true;
364
+ const filteredCustom = Object.fromEntries(Object.entries(custom).filter(([key]) => key !== field));
365
+ if (Object.keys(filteredCustom).length === 0) {
366
+ const metadataWithoutCustom = { ...chunk.metadata };
367
+ delete metadataWithoutCustom.custom;
368
+ return {
369
+ ...chunk,
370
+ metadata: metadataWithoutCustom,
371
+ };
372
+ }
373
+ return {
374
+ ...chunk,
375
+ metadata: {
376
+ ...chunk.metadata,
377
+ custom: filteredCustom,
378
+ },
379
+ };
380
+ });
381
+ return { chunks: sanitizedChunks, changed };
382
+ }
383
+ /**
384
+ * Add chunks to existing table with automatic fallback for custom metadata schema mismatches.
385
+ *
386
+ * LanceDB infers struct fields from early inserts, so later custom metadata keys may fail.
387
+ * This method retries by stripping only unsupported custom fields when needed.
388
+ */
389
+ async addChunksWithSchemaFallback(chunks) {
390
+ if (!this.table) {
391
+ throw new index_js_1.DatabaseError('VectorStore is not initialized. Call initialize() first.');
392
+ }
393
+ let chunksToInsert = chunks;
394
+ const removedFields = new Set();
395
+ // Multiple unknown keys can surface one-by-one; allow bounded retries.
396
+ for (let attempt = 0; attempt < 10; attempt++) {
397
+ try {
398
+ const records = chunksToInsert.map(toDbRecord);
399
+ await this.table.add(records);
400
+ if (removedFields.size > 0) {
401
+ const removed = Array.from(removedFields)
402
+ .map((field) => (field === CUSTOM_METADATA_ALL_FIELDS ? 'metadata.custom' : field))
403
+ .join(', ');
404
+ console.warn(`VectorStore: Removed unsupported custom metadata field(s) for schema compatibility: ${removed}`);
405
+ }
406
+ return;
407
+ }
408
+ catch (error) {
409
+ const unsupportedField = this.extractUnsupportedCustomMetadataField(error);
410
+ if (!unsupportedField) {
411
+ throw error;
412
+ }
413
+ const { chunks: strippedChunks, changed } = this.stripUnsupportedCustomMetadata(chunksToInsert, unsupportedField);
414
+ if (!changed) {
415
+ throw error;
416
+ }
417
+ removedFields.add(unsupportedField);
418
+ chunksToInsert = strippedChunks;
419
+ }
420
+ }
421
+ throw new index_js_1.DatabaseError('Failed to insert chunks after schema fallback retries');
422
+ }
314
423
  /**
315
424
  * Initialize LanceDB and create table
316
425
  */
@@ -323,15 +432,15 @@ class VectorStore {
323
432
  if (tableNames.includes(this.config.tableName)) {
324
433
  // Open existing table
325
434
  this.table = await this.db.openTable(this.config.tableName);
326
- console.log(`VectorStore: Opened existing table "${this.config.tableName}"`);
435
+ console.error(`VectorStore: Opened existing table "${this.config.tableName}"`);
327
436
  // Ensure FTS index exists (migration for existing databases)
328
437
  await this.ensureFtsIndex();
329
438
  }
330
439
  else {
331
440
  // Create new table (schema auto-defined on first data insertion)
332
- console.log(`VectorStore: Table "${this.config.tableName}" will be created on first data insertion`);
441
+ console.error(`VectorStore: Table "${this.config.tableName}" will be created on first data insertion`);
333
442
  }
334
- console.log(`VectorStore initialized: ${this.config.dbPath}`);
443
+ console.error(`VectorStore initialized: ${this.config.dbPath}`);
335
444
  }
336
445
  catch (error) {
337
446
  // Clean up partially initialized resources on failure
@@ -365,7 +474,7 @@ class VectorStore {
365
474
  async deleteChunks(filePath) {
366
475
  if (!this.table) {
367
476
  // If table doesn't exist, no deletion targets, return normally
368
- console.log('VectorStore: Skipping deletion as table does not exist');
477
+ console.error('VectorStore: Skipping deletion as table does not exist');
369
478
  return;
370
479
  }
371
480
  // Validate file path before use in query to prevent SQL injection
@@ -381,7 +490,7 @@ class VectorStore {
381
490
  // so call delete directly
382
491
  // Note: Field names are case-sensitive, use backticks for camelCase fields
383
492
  await this.table.delete(`\`filePath\` = '${escapedFilePath}'`);
384
- console.log(`VectorStore: Deleted chunks for file "${filePath}"`);
493
+ console.error(`VectorStore: Deleted chunks for file "${filePath}"`);
385
494
  // Rebuild FTS index after deleting data
386
495
  await this.rebuildFtsIndex();
387
496
  }
@@ -435,7 +544,7 @@ class VectorStore {
435
544
  // Convert to LanceDB record format using explicit field mapping
436
545
  const records = chunksWithFingerprints.map(toDbRecord);
437
546
  this.table = await this.db.createTable(this.config.tableName, records);
438
- console.log(`VectorStore: Created table "${this.config.tableName}"`);
547
+ console.error(`VectorStore: Created table "${this.config.tableName}"`);
439
548
  // Create FTS index for hybrid search
440
549
  await this.ensureFtsIndex();
441
550
  })();
@@ -445,16 +554,15 @@ class VectorStore {
445
554
  finally {
446
555
  this.tableCreationPromise = null;
447
556
  }
448
- console.log(`VectorStore: Inserted ${chunks.length} chunks`);
557
+ console.error(`VectorStore: Inserted ${chunks.length} chunks`);
449
558
  return;
450
559
  }
451
560
  }
452
561
  // Add data to existing table
453
- const records = chunksWithFingerprints.map(toDbRecord);
454
- await this.table.add(records);
562
+ await this.addChunksWithSchemaFallback(chunksWithFingerprints);
455
563
  // Rebuild FTS index after adding new data
456
564
  await this.rebuildFtsIndex();
457
- console.log(`VectorStore: Inserted ${chunks.length} chunks`);
565
+ console.error(`VectorStore: Inserted ${chunks.length} chunks`);
458
566
  }
459
567
  catch (error) {
460
568
  throw new index_js_1.DatabaseError('Failed to insert chunks', error);
@@ -492,12 +600,12 @@ class VectorStore {
492
600
  name: FTS_INDEX_NAME,
493
601
  });
494
602
  this.ftsEnabled = true;
495
- console.log(`VectorStore: FTS index "${FTS_INDEX_NAME}" created successfully`);
603
+ console.error(`VectorStore: FTS index "${FTS_INDEX_NAME}" created successfully`);
496
604
  // Drop old FTS indices
497
605
  for (const idx of existingFtsIndices) {
498
606
  if (idx.name !== FTS_INDEX_NAME) {
499
607
  await this.table.dropIndex(idx.name);
500
- console.log(`VectorStore: Dropped old FTS index "${idx.name}"`);
608
+ console.error(`VectorStore: Dropped old FTS index "${idx.name}"`);
501
609
  }
502
610
  }
503
611
  }
@@ -579,7 +687,7 @@ class VectorStore {
579
687
  */
580
688
  async search(queryVector, queryText, limit = 10) {
581
689
  if (!this.table) {
582
- console.log('VectorStore: Returning empty results as table does not exist');
690
+ console.error('VectorStore: Returning empty results as table does not exist');
583
691
  return [];
584
692
  }
585
693
  if (limit < 1 || limit > 20) {
@@ -779,7 +887,7 @@ class VectorStore {
779
887
  this.ftsEnabled = false;
780
888
  this.ftsFailureCount = 0;
781
889
  this.ftsLastFailure = null;
782
- console.log('VectorStore: Connection closed');
890
+ console.error('VectorStore: Connection closed');
783
891
  // Propagate errors to caller after cleanup is complete
784
892
  if (errors.length > 0) {
785
893
  throw new index_js_1.DatabaseError(`Errors during close: ${errors.map((e) => e.message).join('; ')}`, errors[0]);
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/web/index.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/web/types.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robthepcguy/rag-vault",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Local RAG MCP Server - Easy-to-setup document search with minimal configuration",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -41,42 +41,6 @@
41
41
  "type": "git",
42
42
  "url": "git+https://github.com/RobThePCGuy/rag-vault.git"
43
43
  },
44
- "scripts": {
45
- "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
46
- "check": "pnpm type-check && pnpm lint && pnpm format:check",
47
- "check:all": "pnpm check && pnpm check:web-ui && pnpm check:unused && pnpm check:deps && pnpm build && pnpm test:unit",
48
- "check:deps": "madge --circular --extensions ts src",
49
- "check:deps:graph": "madge --extensions ts --image graph.svg src",
50
- "check:web-ui": "pnpm --prefix web-ui check",
51
- "check:unused": "node scripts/check-unused-exports.js",
52
- "check:unused:all": "knip",
53
- "cleanup:processes": "bash ./scripts/cleanup-test-processes.sh",
54
- "clean:dev": "rm -rf ./node_modules ./tmp ./uploads ./models ./lancedb ./dist ./package-lock.json && cd web-ui && rm -rf ./dist ./node_modules ./package-lock.json",
55
- "dev": "tsx src/index.ts",
56
- "format": "biome format --write src",
57
- "format:check": "biome format src",
58
- "lint": "biome lint src",
59
- "lint:fix": "biome lint --write src",
60
- "start": "node dist/index.js",
61
- "test": "vitest run",
62
- "test:coverage": "vitest run --coverage",
63
- "test:safe": "pnpm test && pnpm cleanup:processes",
64
- "test:watch": "vitest",
65
- "type-check": "tsc --noEmit",
66
- "audit": "pnpm audit --audit-level=moderate",
67
- "audit:fix": "pnpm audit --fix",
68
- "setup:web": "pnpm install && pnpm web:build && pnpm --prefix web-ui install && pnpm ui:build && pnpm web:start",
69
- "ui:build": "pnpm --prefix web-ui build",
70
- "ui:dev": "cd web-ui && pnpm dev",
71
- "web:build": "pnpm build",
72
- "web:dev": "concurrently -n api,ui -c blue,magenta \"pnpm web:watch\" \"pnpm --prefix web-ui dev\"",
73
- "web:start": "node dist/web/index.js",
74
- "web:watch": "tsx watch src/web/index.ts",
75
- "web": "tsx src/web/index.ts",
76
- "test:unit": "vitest run --project backend-unit --project web-ui",
77
- "test:integration": "RUN_EMBEDDING_INTEGRATION=1 vitest run --project backend-integration",
78
- "hooks:install": "git config core.hooksPath .githooks"
79
- },
80
44
  "dependencies": {
81
45
  "@huggingface/transformers": "^3.7.6",
82
46
  "@lancedb/lancedb": "^0.23.0",
@@ -118,17 +82,45 @@
118
82
  "node": ">=20"
119
83
  },
120
84
  "mcpName": "io.github.RobThePCGuy/rag-vault",
121
- "pnpm": {
122
- "overrides": {
123
- "tar": ">=7.5.7",
124
- "diff": ">=4.0.4"
125
- },
126
- "onlyBuiltDependencies": [
127
- "esbuild",
128
- "onnxruntime-node",
129
- "protobufjs",
130
- "@robthepcguy/rag-vault",
131
- "sharp"
132
- ]
85
+ "scripts": {
86
+ "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
87
+ "check": "pnpm type-check && pnpm lint && pnpm format:check",
88
+ "check:all": "pnpm check && pnpm check:web-ui && pnpm check:unused && pnpm check:deps && pnpm build && pnpm test:unit",
89
+ "check:deps": "madge --circular --extensions ts src",
90
+ "check:deps:graph": "madge --extensions ts --image graph.svg src",
91
+ "check:web-ui": "pnpm --prefix web-ui check",
92
+ "check:unused": "node scripts/check-unused-exports.js",
93
+ "check:unused:all": "knip",
94
+ "cleanup:processes": "bash ./scripts/cleanup-test-processes.sh",
95
+ "clean:dev": "rm -rf ./node_modules ./tmp ./uploads ./models ./lancedb ./dist ./package-lock.json && cd web-ui && rm -rf ./dist ./node_modules ./package-lock.json",
96
+ "dev": "tsx src/index.ts",
97
+ "format": "biome format --write src",
98
+ "format:check": "biome format src",
99
+ "lint": "biome lint src",
100
+ "lint:fix": "biome lint --write src",
101
+ "start": "node dist/index.js",
102
+ "test": "vitest run",
103
+ "test:coverage": "vitest run --coverage",
104
+ "test:safe": "pnpm test && pnpm cleanup:processes",
105
+ "test:watch": "vitest",
106
+ "type-check": "tsc --noEmit",
107
+ "audit": "pnpm audit --audit-level=moderate",
108
+ "audit:fix": "pnpm audit --fix",
109
+ "setup:web": "pnpm install && pnpm web:build && pnpm --prefix web-ui install && pnpm ui:build && pnpm web:start",
110
+ "ui:build": "pnpm --prefix web-ui build",
111
+ "ui:dev": "cd web-ui && pnpm dev",
112
+ "web:build": "pnpm build",
113
+ "web:dev": "concurrently -n api,ui -c blue,magenta \"pnpm web:watch\" \"pnpm --prefix web-ui dev\"",
114
+ "web:start": "node dist/web/index.js",
115
+ "web:watch": "tsx watch src/web/index.ts",
116
+ "web": "tsx src/web/index.ts",
117
+ "test:unit": "vitest run --project backend-unit --project web-ui",
118
+ "test:integration": "RUN_EMBEDDING_INTEGRATION=1 vitest run --project backend-integration",
119
+ "hooks:install": "git config core.hooksPath .githooks",
120
+ "release:patch": "bash ./scripts/release-npm.sh --bump patch",
121
+ "release:minor": "bash ./scripts/release-npm.sh --bump minor",
122
+ "release:major": "bash ./scripts/release-npm.sh --bump major",
123
+ "release:dry": "bash ./scripts/release-npm.sh --bump patch --dry-run",
124
+ "release:publish": "bash ./scripts/release-npm.sh --bump patch"
133
125
  }
134
- }
126
+ }