localrag 0.1.0

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 (86) hide show
  1. package/README.md +178 -0
  2. package/dist/chunking/chunking-service.d.ts +18 -0
  3. package/dist/chunking/chunking-service.d.ts.map +1 -0
  4. package/dist/chunking/chunking-service.js +71 -0
  5. package/dist/chunking/chunking-service.js.map +1 -0
  6. package/dist/cli/commands/init.d.ts +8 -0
  7. package/dist/cli/commands/init.d.ts.map +1 -0
  8. package/dist/cli/commands/init.js +107 -0
  9. package/dist/cli/commands/init.js.map +1 -0
  10. package/dist/cli/commands/open.d.ts +8 -0
  11. package/dist/cli/commands/open.d.ts.map +1 -0
  12. package/dist/cli/commands/open.js +105 -0
  13. package/dist/cli/commands/open.js.map +1 -0
  14. package/dist/cli/commands/search.d.ts +10 -0
  15. package/dist/cli/commands/search.d.ts.map +1 -0
  16. package/dist/cli/commands/search.js +73 -0
  17. package/dist/cli/commands/search.js.map +1 -0
  18. package/dist/cli/commands/start.d.ts +8 -0
  19. package/dist/cli/commands/start.d.ts.map +1 -0
  20. package/dist/cli/commands/start.js +122 -0
  21. package/dist/cli/commands/start.js.map +1 -0
  22. package/dist/cli/commands/status.d.ts +12 -0
  23. package/dist/cli/commands/status.d.ts.map +1 -0
  24. package/dist/cli/commands/status.js +89 -0
  25. package/dist/cli/commands/status.js.map +1 -0
  26. package/dist/cli/index.d.ts +3 -0
  27. package/dist/cli/index.d.ts.map +1 -0
  28. package/dist/cli/index.js +62 -0
  29. package/dist/cli/index.js.map +1 -0
  30. package/dist/config/config-service.d.ts +22 -0
  31. package/dist/config/config-service.d.ts.map +1 -0
  32. package/dist/config/config-service.js +108 -0
  33. package/dist/config/config-service.js.map +1 -0
  34. package/dist/db/lancedb-repository.d.ts +28 -0
  35. package/dist/db/lancedb-repository.d.ts.map +1 -0
  36. package/dist/db/lancedb-repository.js +132 -0
  37. package/dist/db/lancedb-repository.js.map +1 -0
  38. package/dist/embedding/embedding-service.d.ts +22 -0
  39. package/dist/embedding/embedding-service.d.ts.map +1 -0
  40. package/dist/embedding/embedding-service.js +99 -0
  41. package/dist/embedding/embedding-service.js.map +1 -0
  42. package/dist/extractors/docx-extractor.d.ts +12 -0
  43. package/dist/extractors/docx-extractor.d.ts.map +1 -0
  44. package/dist/extractors/docx-extractor.js +29 -0
  45. package/dist/extractors/docx-extractor.js.map +1 -0
  46. package/dist/extractors/extractor.interface.d.ts +14 -0
  47. package/dist/extractors/extractor.interface.d.ts.map +1 -0
  48. package/dist/extractors/extractor.interface.js +63 -0
  49. package/dist/extractors/extractor.interface.js.map +1 -0
  50. package/dist/extractors/pdf-extractor.d.ts +11 -0
  51. package/dist/extractors/pdf-extractor.d.ts.map +1 -0
  52. package/dist/extractors/pdf-extractor.js +89 -0
  53. package/dist/extractors/pdf-extractor.js.map +1 -0
  54. package/dist/extractors/pptx-extractor.d.ts +12 -0
  55. package/dist/extractors/pptx-extractor.d.ts.map +1 -0
  56. package/dist/extractors/pptx-extractor.js +98 -0
  57. package/dist/extractors/pptx-extractor.js.map +1 -0
  58. package/dist/extractors/text-extractor.d.ts +10 -0
  59. package/dist/extractors/text-extractor.d.ts.map +1 -0
  60. package/dist/extractors/text-extractor.js +52 -0
  61. package/dist/extractors/text-extractor.js.map +1 -0
  62. package/dist/extractors/xlsx-extractor.d.ts +11 -0
  63. package/dist/extractors/xlsx-extractor.d.ts.map +1 -0
  64. package/dist/extractors/xlsx-extractor.js +28 -0
  65. package/dist/extractors/xlsx-extractor.js.map +1 -0
  66. package/dist/indexer/indexer.d.ts +34 -0
  67. package/dist/indexer/indexer.d.ts.map +1 -0
  68. package/dist/indexer/indexer.js +100 -0
  69. package/dist/indexer/indexer.js.map +1 -0
  70. package/dist/metadata/metadata-service.d.ts +34 -0
  71. package/dist/metadata/metadata-service.d.ts.map +1 -0
  72. package/dist/metadata/metadata-service.js +147 -0
  73. package/dist/metadata/metadata-service.js.map +1 -0
  74. package/dist/scanner/file-scanner.d.ts +20 -0
  75. package/dist/scanner/file-scanner.d.ts.map +1 -0
  76. package/dist/scanner/file-scanner.js +110 -0
  77. package/dist/scanner/file-scanner.js.map +1 -0
  78. package/dist/search/search-service.d.ts +18 -0
  79. package/dist/search/search-service.d.ts.map +1 -0
  80. package/dist/search/search-service.js +98 -0
  81. package/dist/search/search-service.js.map +1 -0
  82. package/dist/watcher/file-watcher.d.ts +27 -0
  83. package/dist/watcher/file-watcher.d.ts.map +1 -0
  84. package/dist/watcher/file-watcher.js +110 -0
  85. package/dist/watcher/file-watcher.js.map +1 -0
  86. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # localrag
2
+
3
+ **Local-first semantic document search CLI.**
4
+ Find your files by *meaning*, not keywords — entirely on your machine. No cloud. No API keys.
5
+
6
+ ---
7
+
8
+ ## Features
9
+
10
+ - 🔍 **Semantic search** across PDF, DOCX, XLSX, PPTX, TXT, and Markdown
11
+ - ⚡ **Sub-second search** — queries hit pre-built vectors, not raw files
12
+ - 👁 **Watch-based indexing** — the index updates automatically as files change
13
+ - 🔒 **100% local** — embeddings and vectors never leave your machine
14
+ - 📦 **Zero config** — works out of the box with one command
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install -g localrag
22
+ ```
23
+
24
+ Requires **Node.js ≥ 18**.
25
+
26
+ > **First run note:** On first use the embedding model (`all-MiniLM-L6-v2`, ~25 MB) is downloaded from Hugging Face and cached permanently in `~/.cache/huggingface`. An internet connection is only needed this once.
27
+
28
+ ---
29
+
30
+ ## Quick Start
31
+
32
+ ```bash
33
+ # 1. Add a folder and run an initial index
34
+ localrag init ~/Documents
35
+
36
+ # 2. Search
37
+ localrag search "vacation policy"
38
+
39
+ # 3. Open the first result
40
+ localrag open 1
41
+
42
+ # 4. Start continuous watching (keeps index up-to-date)
43
+ localrag start
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Commands
49
+
50
+ ### `localrag init <folder>`
51
+
52
+ Add a folder to the watch list and immediately index all supported files inside it.
53
+
54
+ ```bash
55
+ localrag init ~/Documents
56
+ localrag init ~/Desktop/Work
57
+ ```
58
+
59
+ ### `localrag search "<query>"`
60
+
61
+ Semantically search indexed documents. Returns file path, page number, similarity score, and a content snippet.
62
+
63
+ ```bash
64
+ localrag search "annual leave policy"
65
+ localrag search "Q3 revenue projections"
66
+ localrag search "meeting notes product roadmap"
67
+ ```
68
+
69
+ Options:
70
+
71
+ | Flag | Description | Default |
72
+ |---|---|---|
73
+ | `-t, --top <n>` | Number of results | `10` |
74
+
75
+ ### `localrag open <N>`
76
+
77
+ Open the Nth result from the last search using your OS default app.
78
+
79
+ ```bash
80
+ localrag open 1
81
+ localrag open 3
82
+ ```
83
+
84
+ ### `localrag start`
85
+
86
+ Start continuous background indexing. Runs in the foreground — press `Ctrl+C` to stop.
87
+
88
+ ```bash
89
+ localrag start
90
+ ```
91
+
92
+ ### `localrag status`
93
+
94
+ Display a summary of the current index.
95
+
96
+ ```bash
97
+ localrag status
98
+ ```
99
+
100
+ Output includes:
101
+ - Watched folders
102
+ - Indexed file count
103
+ - Total chunk count
104
+ - Database size on disk
105
+ - Last indexing activity
106
+
107
+ ---
108
+
109
+ ## Supported File Types
110
+
111
+ | Extension | Parser |
112
+ |---|---|
113
+ | `.pdf` | pdf-parse (per-page text) |
114
+ | `.docx` | mammoth |
115
+ | `.xlsx` | SheetJS |
116
+ | `.pptx` | adm-zip + XML parsing |
117
+ | `.txt` | fs.readFile |
118
+ | `.md` | fs.readFile |
119
+
120
+ ---
121
+
122
+ ## Architecture
123
+
124
+ ```
125
+ localrag init / start
126
+
127
+
128
+ FileScanner / FileWatcher (chokidar)
129
+
130
+
131
+ Indexer (orchestrator)
132
+ ├── Extractor (PDF / DOCX / XLSX / PPTX / TXT / MD)
133
+ ├── ChunkingService (500-char overlapping windows)
134
+ ├── EmbeddingService (Transformers.js, all-MiniLM-L6-v2)
135
+ └── LanceDbRepository (vector storage)
136
+
137
+ └── ~/.localrag/db/ (LanceDB)
138
+
139
+ localrag search
140
+
141
+
142
+ SearchService
143
+ ├── EmbeddingService (embed query)
144
+ └── LanceDbRepository (vector search)
145
+ ```
146
+
147
+ **Data stored in `~/.localrag/`:**
148
+
149
+ | File | Purpose |
150
+ |---|---|
151
+ | `config.json` | Watched folders, DB path |
152
+ | `documents.json` | Per-file metadata + chunk counts |
153
+ | `last-results.json` | Result cache for `open` command |
154
+ | `db/` | LanceDB vector store |
155
+
156
+ ---
157
+
158
+ ## Local-First Design
159
+
160
+ - No cloud services
161
+ - No API keys required
162
+ - All embeddings generated locally via ONNX runtime
163
+ - All vectors stored locally in LanceDB
164
+
165
+ ---
166
+
167
+ ## Extending
168
+
169
+ The extractor layer is designed for easy extension. To add a new file type:
170
+
171
+ 1. Create `src/extractors/<type>-extractor.ts` implementing `Extractor`
172
+ 2. Register it in `src/extractors/extractor.interface.ts`
173
+
174
+ ---
175
+
176
+ ## License
177
+
178
+ MIT
@@ -0,0 +1,18 @@
1
+ import { ExtractedChunk } from '../extractors/extractor.interface';
2
+ export interface TextChunk {
3
+ id: string;
4
+ filePath: string;
5
+ page: number;
6
+ text: string;
7
+ }
8
+ export declare class ChunkingService {
9
+ /**
10
+ * Split an array of ExtractedChunks (from any extractor) into smaller,
11
+ * fixed-size overlapping TextChunks suitable for embedding.
12
+ *
13
+ * Each TextChunk retains the source page number from the ExtractedChunk it
14
+ * came from, enabling result display to show the right page.
15
+ */
16
+ chunk(filePath: string, extracted: ExtractedChunk[]): TextChunk[];
17
+ }
18
+ //# sourceMappingURL=chunking-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunking-service.d.ts","sourceRoot":"","sources":["../../src/chunking/chunking-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAInE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAeD,qBAAa,eAAe;IAC1B;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE;CAqBlE"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChunkingService = void 0;
4
+ // ── Config ────────────────────────────────────────────────────────────────
5
+ /** Target character count per chunk. */
6
+ const CHUNK_SIZE = 500;
7
+ /** Overlap between consecutive chunks (preserves context at boundaries). */
8
+ const CHUNK_OVERLAP = 100;
9
+ /** Minimum length to bother embedding. */
10
+ const MIN_CHUNK_LENGTH = 20;
11
+ // ── Service ───────────────────────────────────────────────────────────────
12
+ class ChunkingService {
13
+ /**
14
+ * Split an array of ExtractedChunks (from any extractor) into smaller,
15
+ * fixed-size overlapping TextChunks suitable for embedding.
16
+ *
17
+ * Each TextChunk retains the source page number from the ExtractedChunk it
18
+ * came from, enabling result display to show the right page.
19
+ */
20
+ chunk(filePath, extracted) {
21
+ const results = [];
22
+ let globalIndex = 0;
23
+ for (const { text, page = 0 } of extracted) {
24
+ if (!text.trim())
25
+ continue;
26
+ const subTexts = splitText(text);
27
+ for (const sub of subTexts) {
28
+ if (sub.trim().length < MIN_CHUNK_LENGTH)
29
+ continue;
30
+ results.push({
31
+ id: `${filePath}::${globalIndex++}`,
32
+ filePath,
33
+ page,
34
+ text: sub.trim(),
35
+ });
36
+ }
37
+ }
38
+ return results;
39
+ }
40
+ }
41
+ exports.ChunkingService = ChunkingService;
42
+ // ── Helpers ───────────────────────────────────────────────────────────────
43
+ /**
44
+ * Split a long string into overlapping windows.
45
+ * Tries to break at whitespace boundaries to avoid cutting words.
46
+ */
47
+ function splitText(text) {
48
+ if (text.length <= CHUNK_SIZE)
49
+ return [text];
50
+ const chunks = [];
51
+ let start = 0;
52
+ while (start < text.length) {
53
+ let end = start + CHUNK_SIZE;
54
+ if (end < text.length) {
55
+ // Extend to the next whitespace so we don't cut mid-word
56
+ const nextSpace = text.indexOf(' ', end);
57
+ if (nextSpace !== -1 && nextSpace - end < 50) {
58
+ end = nextSpace;
59
+ }
60
+ }
61
+ else {
62
+ end = text.length;
63
+ }
64
+ chunks.push(text.slice(start, end));
65
+ // Advance by (CHUNK_SIZE - CHUNK_OVERLAP), but always make progress
66
+ const advance = Math.max(1, CHUNK_SIZE - CHUNK_OVERLAP);
67
+ start += advance;
68
+ }
69
+ return chunks;
70
+ }
71
+ //# sourceMappingURL=chunking-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunking-service.js","sourceRoot":"","sources":["../../src/chunking/chunking-service.ts"],"names":[],"mappings":";;;AAWA,6EAA6E;AAE7E,wCAAwC;AACxC,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB,4EAA4E;AAC5E,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,0CAA0C;AAC1C,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,6EAA6E;AAE7E,MAAa,eAAe;IAC1B;;;;;;OAMG;IACH,KAAK,CAAC,QAAgB,EAAE,SAA2B;QACjD,MAAM,OAAO,GAAgB,EAAE,CAAC;QAChC,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAE3B,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,gBAAgB;oBAAE,SAAS;gBACnD,OAAO,CAAC,IAAI,CAAC;oBACX,EAAE,EAAE,GAAG,QAAQ,KAAK,WAAW,EAAE,EAAE;oBACnC,QAAQ;oBACR,IAAI;oBACJ,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE;iBACjB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA7BD,0CA6BC;AAED,6EAA6E;AAE7E;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,IAAI,GAAG,GAAG,KAAK,GAAG,UAAU,CAAC;QAE7B,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,yDAAyD;YACzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,SAAS,KAAK,CAAC,CAAC,IAAI,SAAS,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;gBAC7C,GAAG,GAAG,SAAS,CAAC;YAClB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACpB,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QAEpC,oEAAoE;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC,CAAC;QACxD,KAAK,IAAI,OAAO,CAAC;IACnB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `localrag init <folder>`
3
+ *
4
+ * Adds the given folder to the watched list and immediately performs
5
+ * a full initial scan so results are available right away.
6
+ */
7
+ export declare function initCommand(folder: string): Promise<void>;
8
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2D/D"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.initCommand = initCommand;
40
+ const path = __importStar(require("path"));
41
+ const fs = __importStar(require("fs"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const ora_1 = __importDefault(require("ora"));
44
+ const config_service_1 = require("../../config/config-service");
45
+ const metadata_service_1 = require("../../metadata/metadata-service");
46
+ const lancedb_repository_1 = require("../../db/lancedb-repository");
47
+ const embedding_service_1 = require("../../embedding/embedding-service");
48
+ const indexer_1 = require("../../indexer/indexer");
49
+ const file_scanner_1 = require("../../scanner/file-scanner");
50
+ /**
51
+ * `localrag init <folder>`
52
+ *
53
+ * Adds the given folder to the watched list and immediately performs
54
+ * a full initial scan so results are available right away.
55
+ */
56
+ async function initCommand(folder) {
57
+ const absFolder = path.resolve(folder);
58
+ // Validate folder
59
+ if (!fs.existsSync(absFolder)) {
60
+ console.error(chalk_1.default.red(`✗ Folder not found: ${absFolder}`));
61
+ process.exit(1);
62
+ }
63
+ if (!fs.statSync(absFolder).isDirectory()) {
64
+ console.error(chalk_1.default.red(`✗ Not a directory: ${absFolder}`));
65
+ process.exit(1);
66
+ }
67
+ const config = new config_service_1.ConfigService();
68
+ const added = config.addWatchedFolder(absFolder);
69
+ if (!added) {
70
+ console.log(chalk_1.default.yellow(`⚠ Folder already watched: ${absFolder}`));
71
+ }
72
+ else {
73
+ console.log(chalk_1.default.green(`✓ Added watched folder: ${absFolder}`));
74
+ }
75
+ // Initialise services
76
+ const repo = new lancedb_repository_1.LanceDbRepository();
77
+ await repo.initialize(config.getDbPath());
78
+ const metadata = new metadata_service_1.MetadataService(config);
79
+ const embedder = new embedding_service_1.EmbeddingService();
80
+ const indexer = new indexer_1.Indexer(config, repo, metadata, embedder);
81
+ const scanner = new file_scanner_1.FileScanner(metadata, indexer);
82
+ console.log(chalk_1.default.cyan('\n🔍 Starting initial scan…\n'));
83
+ const spinner = (0, ora_1.default)({ text: 'Scanning…', spinner: 'dots' }).start();
84
+ let indexed = 0;
85
+ let errors = 0;
86
+ const processed = await scanner.scan([absFolder], {
87
+ onProgress: (msg) => {
88
+ spinner.text = msg;
89
+ },
90
+ onError: (filePath, err) => {
91
+ spinner.warn(chalk_1.default.red(`Error: ${path.basename(filePath)} — ${err.message}`));
92
+ spinner.start();
93
+ errors++;
94
+ },
95
+ });
96
+ indexed = processed;
97
+ spinner.succeed(chalk_1.default.green(`Initial scan complete.`));
98
+ console.log('');
99
+ console.log(` ${chalk_1.default.bold('Indexed:')} ${chalk_1.default.cyan(indexed)} file(s)`);
100
+ if (errors > 0) {
101
+ console.log(` ${chalk_1.default.bold('Errors:')} ${chalk_1.default.red(errors)} file(s) skipped`);
102
+ }
103
+ console.log('');
104
+ console.log(chalk_1.default.dim(`Run ${chalk_1.default.white('localrag start')} to watch for changes.`));
105
+ console.log(chalk_1.default.dim(`Run ${chalk_1.default.white('localrag search "<query>"')} to search.`));
106
+ }
107
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `localrag open <N>`
3
+ *
4
+ * Opens the Nth result from the last `localrag search` run using the
5
+ * OS-default application (open / xdg-open / start).
6
+ */
7
+ export declare function openCommand(resultNumber: string): Promise<void>;
8
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/open.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCrE"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.openCommand = openCommand;
40
+ const path = __importStar(require("path"));
41
+ const childProcess = __importStar(require("child_process"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const config_service_1 = require("../../config/config-service");
44
+ const search_service_1 = require("../../search/search-service");
45
+ const lancedb_repository_1 = require("../../db/lancedb-repository");
46
+ const embedding_service_1 = require("../../embedding/embedding-service");
47
+ /**
48
+ * `localrag open <N>`
49
+ *
50
+ * Opens the Nth result from the last `localrag search` run using the
51
+ * OS-default application (open / xdg-open / start).
52
+ */
53
+ async function openCommand(resultNumber) {
54
+ const n = parseInt(resultNumber, 10);
55
+ if (isNaN(n) || n < 1) {
56
+ console.error(chalk_1.default.red('✗ Please provide a valid result number (e.g. localrag open 1).'));
57
+ process.exit(1);
58
+ }
59
+ const config = new config_service_1.ConfigService();
60
+ // SearchService exposes getLastResults() which reads last-results.json
61
+ const repo = new lancedb_repository_1.LanceDbRepository();
62
+ // We don't need a full DB connection just to read cached results,
63
+ // but SearchService requires a repo instance. We'll instantiate without
64
+ // calling initialize() to avoid the DB overhead.
65
+ const embedder = new embedding_service_1.EmbeddingService();
66
+ const searchService = new search_service_1.SearchService(config, repo, embedder);
67
+ const results = searchService.getLastResults();
68
+ if (results.length === 0) {
69
+ console.error(chalk_1.default.red('✗ No previous search results found.'));
70
+ console.log(chalk_1.default.dim(`Run ${chalk_1.default.white('localrag search "<query>"')} first.`));
71
+ process.exit(1);
72
+ }
73
+ if (n > results.length) {
74
+ console.error(chalk_1.default.red(`✗ Result ${n} doesn't exist. Last search returned ${results.length} result(s).`));
75
+ process.exit(1);
76
+ }
77
+ const result = results[n - 1];
78
+ const filePath = result.filePath;
79
+ console.log(chalk_1.default.cyan(`Opening: ${path.basename(filePath)}`));
80
+ console.log(chalk_1.default.dim(filePath));
81
+ openFile(filePath);
82
+ }
83
+ // ── Helpers ───────────────────────────────────────────────────────────────
84
+ function openFile(filePath) {
85
+ const platform = process.platform;
86
+ let cmd;
87
+ if (platform === 'darwin') {
88
+ cmd = `open "${escapePath(filePath)}"`;
89
+ }
90
+ else if (platform === 'win32') {
91
+ cmd = `start "" "${escapePath(filePath)}"`;
92
+ }
93
+ else {
94
+ cmd = `xdg-open "${escapePath(filePath)}"`;
95
+ }
96
+ childProcess.exec(cmd, (err) => {
97
+ if (err) {
98
+ console.error(chalk_1.default.red(`✗ Failed to open file: ${err.message}`));
99
+ }
100
+ });
101
+ }
102
+ function escapePath(p) {
103
+ return p.replace(/"/g, '\\"');
104
+ }
105
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../../src/cli/commands/open.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `localrag search "<query>"`
3
+ *
4
+ * Embeds the query, runs vector search, and displays ranked results.
5
+ * Results are also saved so `localrag open <N>` can open them by index.
6
+ */
7
+ export declare function searchCommand(query: string, options: {
8
+ top?: string;
9
+ }): Promise<void>;
10
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE3F"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.searchCommand = searchCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const config_service_1 = require("../../config/config-service");
10
+ const lancedb_repository_1 = require("../../db/lancedb-repository");
11
+ const embedding_service_1 = require("../../embedding/embedding-service");
12
+ const search_service_1 = require("../../search/search-service");
13
+ /**
14
+ * `localrag search "<query>"`
15
+ *
16
+ * Embeds the query, runs vector search, and displays ranked results.
17
+ * Results are also saved so `localrag open <N>` can open them by index.
18
+ */
19
+ async function searchCommand(query, options) {
20
+ const topK = options.top ? parseInt(options.top, 10) : 10;
21
+ if (!query.trim()) {
22
+ console.error(chalk_1.default.red('✗ Query cannot be empty.'));
23
+ process.exit(1);
24
+ }
25
+ const config = new config_service_1.ConfigService();
26
+ if (config.getWatchedFolders().length === 0) {
27
+ console.error(chalk_1.default.red('✗ No folders indexed yet.'));
28
+ console.log(chalk_1.default.dim(`Run ${chalk_1.default.white('localrag init <folder>')} first.`));
29
+ process.exit(1);
30
+ }
31
+ const repo = new lancedb_repository_1.LanceDbRepository();
32
+ await repo.initialize(config.getDbPath());
33
+ const embedder = new embedding_service_1.EmbeddingService();
34
+ const searchService = new search_service_1.SearchService(config, repo, embedder);
35
+ const spinner = (0, ora_1.default)({ text: `Searching for "${query}"…`, spinner: 'dots' }).start();
36
+ let results;
37
+ try {
38
+ results = await searchService.search(query, topK);
39
+ }
40
+ catch (err) {
41
+ spinner.fail('Search failed.');
42
+ console.error(chalk_1.default.red((err instanceof Error ? err.message : String(err))));
43
+ process.exit(1);
44
+ }
45
+ spinner.stop();
46
+ if (results.length === 0) {
47
+ console.log(chalk_1.default.yellow('\n No results found.\n'));
48
+ console.log(chalk_1.default.dim(' Try indexing more documents with: localrag init <folder>'));
49
+ return;
50
+ }
51
+ // ── Display results ────────────────────────────────────────────────────
52
+ console.log('');
53
+ console.log(chalk_1.default.bold.cyan(` Search results for: `) + chalk_1.default.bold.white(`"${query}"`) +
54
+ chalk_1.default.dim(` (top ${results.length})`));
55
+ console.log('');
56
+ results.forEach((result, idx) => {
57
+ const num = chalk_1.default.bold.cyan(` [${idx + 1}]`);
58
+ const fileName = chalk_1.default.bold.white(result.fileName);
59
+ const filePath = chalk_1.default.dim(result.filePath);
60
+ const page = result.page > 0
61
+ ? chalk_1.default.dim(` Page ${result.page}`)
62
+ : '';
63
+ const score = chalk_1.default.green(` Score: ${(result.score * 100).toFixed(1)}%`);
64
+ const snippet = chalk_1.default.white(` ${result.text}`);
65
+ console.log(`${num} ${fileName}${page}${score}`);
66
+ console.log(` ${filePath}`);
67
+ console.log(` ${snippet}`);
68
+ console.log('');
69
+ });
70
+ console.log(chalk_1.default.dim(` Run ${chalk_1.default.white('localrag open <N>')} to open a result.`));
71
+ console.log('');
72
+ }
73
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `localrag start`
3
+ *
4
+ * Performs a startup scan to catch missed changes, then starts a persistent
5
+ * file watcher to keep the index up-to-date in real time.
6
+ */
7
+ export declare function startCommand(): Promise<void>;
8
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CA8ElD"}