@ixxrllg/localmind 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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +290 -0
  3. package/dist/ask/answer.d.ts +9 -0
  4. package/dist/ask/answer.d.ts.map +1 -0
  5. package/dist/ask/answer.js +183 -0
  6. package/dist/ask/answer.js.map +1 -0
  7. package/dist/bin/localmind.d.ts +3 -0
  8. package/dist/bin/localmind.d.ts.map +1 -0
  9. package/dist/bin/localmind.js +11 -0
  10. package/dist/bin/localmind.js.map +1 -0
  11. package/dist/cli/format.d.ts +7 -0
  12. package/dist/cli/format.d.ts.map +1 -0
  13. package/dist/cli/format.js +67 -0
  14. package/dist/cli/format.js.map +1 -0
  15. package/dist/cli/program.d.ts +4 -0
  16. package/dist/cli/program.d.ts.map +1 -0
  17. package/dist/cli/program.js +228 -0
  18. package/dist/cli/program.js.map +1 -0
  19. package/dist/core/config.d.ts +17 -0
  20. package/dist/core/config.d.ts.map +1 -0
  21. package/dist/core/config.js +55 -0
  22. package/dist/core/config.js.map +1 -0
  23. package/dist/core/db.d.ts +50 -0
  24. package/dist/core/db.d.ts.map +1 -0
  25. package/dist/core/db.js +180 -0
  26. package/dist/core/db.js.map +1 -0
  27. package/dist/core/hash.d.ts +3 -0
  28. package/dist/core/hash.d.ts.map +1 -0
  29. package/dist/core/hash.js +8 -0
  30. package/dist/core/hash.js.map +1 -0
  31. package/dist/core/logger.d.ts +12 -0
  32. package/dist/core/logger.d.ts.map +1 -0
  33. package/dist/core/logger.js +45 -0
  34. package/dist/core/logger.js.map +1 -0
  35. package/dist/core/paths.d.ts +16 -0
  36. package/dist/core/paths.d.ts.map +1 -0
  37. package/dist/core/paths.js +43 -0
  38. package/dist/core/paths.js.map +1 -0
  39. package/dist/graph/related.d.ts +11 -0
  40. package/dist/graph/related.d.ts.map +1 -0
  41. package/dist/graph/related.js +144 -0
  42. package/dist/graph/related.js.map +1 -0
  43. package/dist/index.d.ts +17 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +16 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/indexer/chunker.d.ts +16 -0
  48. package/dist/indexer/chunker.d.ts.map +1 -0
  49. package/dist/indexer/chunker.js +76 -0
  50. package/dist/indexer/chunker.js.map +1 -0
  51. package/dist/indexer/ignore.d.ts +6 -0
  52. package/dist/indexer/ignore.d.ts.map +1 -0
  53. package/dist/indexer/ignore.js +71 -0
  54. package/dist/indexer/ignore.js.map +1 -0
  55. package/dist/indexer/indexer.d.ts +11 -0
  56. package/dist/indexer/indexer.d.ts.map +1 -0
  57. package/dist/indexer/indexer.js +182 -0
  58. package/dist/indexer/indexer.js.map +1 -0
  59. package/dist/indexer/languages.d.ts +5 -0
  60. package/dist/indexer/languages.d.ts.map +1 -0
  61. package/dist/indexer/languages.js +144 -0
  62. package/dist/indexer/languages.js.map +1 -0
  63. package/dist/indexer/relations.d.ts +9 -0
  64. package/dist/indexer/relations.d.ts.map +1 -0
  65. package/dist/indexer/relations.js +81 -0
  66. package/dist/indexer/relations.js.map +1 -0
  67. package/dist/indexer/walker.d.ts +21 -0
  68. package/dist/indexer/walker.d.ts.map +1 -0
  69. package/dist/indexer/walker.js +86 -0
  70. package/dist/indexer/walker.js.map +1 -0
  71. package/dist/mcp/server.d.ts +5 -0
  72. package/dist/mcp/server.d.ts.map +1 -0
  73. package/dist/mcp/server.js +291 -0
  74. package/dist/mcp/server.js.map +1 -0
  75. package/dist/search/bm25.d.ts +9 -0
  76. package/dist/search/bm25.d.ts.map +1 -0
  77. package/dist/search/bm25.js +109 -0
  78. package/dist/search/bm25.js.map +1 -0
  79. package/dist/search/embeddings.d.ts +15 -0
  80. package/dist/search/embeddings.d.ts.map +1 -0
  81. package/dist/search/embeddings.js +193 -0
  82. package/dist/search/embeddings.js.map +1 -0
  83. package/dist/search/search.d.ts +9 -0
  84. package/dist/search/search.d.ts.map +1 -0
  85. package/dist/search/search.js +47 -0
  86. package/dist/search/search.js.map +1 -0
  87. package/dist/search/tokenize.d.ts +6 -0
  88. package/dist/search/tokenize.d.ts.map +1 -0
  89. package/dist/search/tokenize.js +163 -0
  90. package/dist/search/tokenize.js.map +1 -0
  91. package/dist/status.d.ts +4 -0
  92. package/dist/status.d.ts.map +1 -0
  93. package/dist/status.js +33 -0
  94. package/dist/status.js.map +1 -0
  95. package/dist/types.d.ts +105 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +11 -0
  98. package/dist/types.js.map +1 -0
  99. package/package.json +72 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ixxrllg and LocalMind contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,290 @@
1
+ # LocalMind
2
+
3
+ **Give every AI agent perfect memory of your codebase — offline.**
4
+
5
+ LocalMind is a local-first knowledge & context engine for developers and AI coding agents. It indexes your repository into a searchable knowledge base (BM25 + optional embeddings), builds a lightweight import graph, answers questions with citations, and exposes everything through a **CLI** and an **MCP server**.
6
+
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D22.5-brightgreen)](https://nodejs.org/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
9
+ [![MCP](https://img.shields.io/badge/MCP-ready-purple)](https://modelcontextprotocol.io/)
10
+ [![GitHub stars](https://img.shields.io/github/stars/ixxrllg/localmind?style=social)](https://github.com/ixxrllg/localmind)
11
+ [![GitHub issues](https://img.shields.io/github/issues/ixxrllg/localmind)](https://github.com/ixxrllg/localmind/issues)
12
+
13
+ ---
14
+
15
+ ## Why LocalMind?
16
+
17
+ | Pain | LocalMind |
18
+ |------|-----------|
19
+ | AI agents forget project context | Persistent local index + MCP tools |
20
+ | Cloud RAG leaks private code | 100% local by default (SQLite) |
21
+ | Grep is not enough for questions | BM25 ranking + extractive / generative answers |
22
+ | “What depends on this file?” | Import / link knowledge graph |
23
+
24
+ Works **without API keys**. Optional OpenAI or Ollama for embeddings and generative answers.
25
+
26
+ ---
27
+
28
+ ## Quick start
29
+
30
+ **Requirements:** Node.js ≥ 22.5
31
+
32
+ ### Install from npm
33
+
34
+ ```bash
35
+ npm install -g @ixxrllg/localmind
36
+
37
+ # in any project
38
+ localmind init
39
+ localmind index
40
+ localmind ask "Where is authentication handled?"
41
+ localmind search "jwt middleware"
42
+ localmind status
43
+ ```
44
+
45
+ Or without global install:
46
+
47
+ ```bash
48
+ npx @ixxrllg/localmind init
49
+ npx @ixxrllg/localmind index
50
+ npx @ixxrllg/localmind ask "Where is authentication handled?"
51
+ ```
52
+
53
+ ### From source
54
+
55
+ ```bash
56
+ git clone https://github.com/ixxrllg/localmind.git
57
+ cd localmind
58
+ npm install
59
+ npm run build
60
+ node dist/bin/localmind.js init --root /path/to/your/project
61
+ ```
62
+
63
+ ---
64
+
65
+ ## CLI
66
+
67
+ | Command | Description |
68
+ |---------|-------------|
69
+ | `localmind init` | Create `.localmind/config.json` + SQLite DB |
70
+ | `localmind index` | Walk repo, chunk files, build inverted index (+ optional embeddings) |
71
+ | `localmind index --full` | Force full re-index |
72
+ | `localmind search <query>` | Ranked code/doc search |
73
+ | `localmind ask <question>` | Q&A with citations |
74
+ | `localmind related <path>` | Files linked via imports / markdown links |
75
+ | `localmind status` | Index statistics |
76
+ | `localmind mcp` | Start MCP server on **stdio** |
77
+ | `localmind config` | Show / update config |
78
+
79
+ Global options:
80
+
81
+ ```
82
+ -r, --root <path> Project root (default: cwd)
83
+ -q, --quiet
84
+ --verbose
85
+ ```
86
+
87
+ ### Examples
88
+
89
+ ```bash
90
+ localmind init --provider ollama
91
+ localmind index
92
+ localmind search "chunkText overlap" --mode bm25
93
+ localmind ask "How are files ignored during indexing?" --extractive
94
+ localmind related src/indexer/indexer.ts
95
+ localmind status --json
96
+ ```
97
+
98
+ ---
99
+
100
+ ## MCP (Cursor / Claude Code / agents)
101
+
102
+ ```bash
103
+ localmind mcp --root /path/to/your/project
104
+ ```
105
+
106
+ Example MCP config (Cursor / Claude Desktop):
107
+
108
+ ```json
109
+ {
110
+ "mcpServers": {
111
+ "localmind": {
112
+ "command": "node",
113
+ "args": [
114
+ "/absolute/path/to/localmind/dist/bin/localmind.js",
115
+ "mcp",
116
+ "--root",
117
+ "/absolute/path/to/your/project"
118
+ ]
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ > Replace paths with your clone of [ixxrllg/localmind](https://github.com/ixxrllg/localmind) and the project you want indexed.
125
+
126
+ ### Tools
127
+
128
+ | Tool | Purpose |
129
+ |------|---------|
130
+ | `search_code` | Semantic/lexical search over the index |
131
+ | `ask_codebase` | Question answering with citations |
132
+ | `find_related_files` | Graph neighborhood for a path |
133
+ | `explain_file` | Dump indexed chunks for a file / line range |
134
+ | `index_status` | Stats |
135
+ | `reindex` | Incremental or full re-index |
136
+
137
+ ---
138
+
139
+ ## How it works
140
+
141
+ ```
142
+ your repo
143
+
144
+
145
+ walker + ignore rules (.gitignore, defaults)
146
+
147
+
148
+ line-aware chunker ──► SQLite
149
+ │ ├─ files / chunks
150
+ │ ├─ BM25 inverted index (terms + postings)
151
+ │ ├─ import/link edges
152
+ │ └─ optional embeddings
153
+
154
+ search (BM25 / vector / hybrid) ──► ask (extractive or LLM)
155
+
156
+
157
+ CLI · MCP · library API
158
+ ```
159
+
160
+ - **Storage:** `.localmind/localmind.db` (Node built-in `node:sqlite`)
161
+ - **Default search:** BM25 (no network, no models)
162
+ - **Optional:** OpenAI / Ollama embeddings + chat
163
+
164
+ ---
165
+
166
+ ## Configuration
167
+
168
+ `.localmind/config.json` (created by `init`):
169
+
170
+ ```json
171
+ {
172
+ "version": 1,
173
+ "provider": "none",
174
+ "include": [],
175
+ "exclude": [],
176
+ "maxFileBytes": 524288,
177
+ "chunkSize": 1200,
178
+ "chunkOverlap": 150,
179
+ "incremental": true
180
+ }
181
+ ```
182
+
183
+ ### Environment (optional)
184
+
185
+ See `.env.example`:
186
+
187
+ | Variable | Role |
188
+ |----------|------|
189
+ | `OPENAI_API_KEY` | Embeddings + generative answers |
190
+ | `OPENAI_BASE_URL` | Compatible gateways |
191
+ | `OPENAI_MODEL` | Chat model (default `gpt-4o-mini`) |
192
+ | `OPENAI_EMBEDDING_MODEL` | Default `text-embedding-3-small` |
193
+ | `OLLAMA_BASE_URL` | Default `http://127.0.0.1:11434` |
194
+ | `OLLAMA_MODEL` / `OLLAMA_EMBEDDING_MODEL` | Local models |
195
+
196
+ ```bash
197
+ localmind config --provider openai
198
+ # or
199
+ localmind config --provider ollama
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Library API
205
+
206
+ ```ts
207
+ import {
208
+ initConfig,
209
+ loadConfig,
210
+ runIndex,
211
+ openDb,
212
+ closeDb,
213
+ search,
214
+ ask,
215
+ } from "@ixxrllg/localmind";
216
+
217
+ const { config } = initConfig({ root: process.cwd() });
218
+ await runIndex(config, { full: true });
219
+
220
+ const db = openDb(config.root);
221
+ const hits = await search(db, "authentication middleware");
222
+ const answer = await ask(db, config, "How does auth work?");
223
+ closeDb(db);
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Development
229
+
230
+ ```bash
231
+ npm install
232
+ npm run build
233
+ npm test
234
+ npm run dev -- init
235
+ npm run dev -- index
236
+ npm run dev -- ask "What is LocalMind?"
237
+ ```
238
+
239
+ Requirements:
240
+
241
+ - **Node.js ≥ 22.5** (uses built-in `node:sqlite`)
242
+
243
+ ---
244
+
245
+ ## Project layout
246
+
247
+ ```
248
+ src/
249
+ bin/localmind.ts CLI entry
250
+ cli/ Commander program + formatting
251
+ core/ config, paths, SQLite
252
+ indexer/ walk, chunk, relations, index pipeline
253
+ search/ tokenize, BM25, embeddings, hybrid
254
+ ask/ extractive + generative Q&A
255
+ graph/ related files
256
+ mcp/ MCP server + tools
257
+ index.ts public exports
258
+ tests/ unit + integration
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Roadmap
264
+
265
+ - [ ] File watcher / live re-index
266
+ - [ ] Tree-sitter aware chunking
267
+ - [ ] sqlite-vec acceleration
268
+ - [ ] Web UI for exploration
269
+ - [ ] Multi-repo workspaces
270
+
271
+ ---
272
+
273
+ ## Contributing
274
+
275
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Issues and PRs welcome.
276
+
277
+ ## License
278
+
279
+ MIT — see [LICENSE](LICENSE).
280
+
281
+ ## Author
282
+
283
+ Maintained by [@ixxrllg](https://github.com/ixxrllg).
284
+
285
+ ---
286
+
287
+ <p align="center">
288
+ <b>Star ⭐ this repo if LocalMind saves you a context switch.</b><br/>
289
+ Built for agents. Useful for humans.
290
+ </p>
@@ -0,0 +1,9 @@
1
+ import type { Db } from "../core/db.js";
2
+ import type { AskResult, LocalMindConfig, ProviderKind } from "../types.js";
3
+ export interface AskOptions {
4
+ limit?: number;
5
+ mode?: "auto" | "extractive" | "generative";
6
+ provider?: ProviderKind;
7
+ }
8
+ export declare function ask(db: Db, config: LocalMindConfig, question: string, options?: AskOptions): Promise<AskResult>;
9
+ //# sourceMappingURL=answer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer.d.ts","sourceRoot":"","sources":["../../src/ask/answer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAa,MAAM,aAAa,CAAC;AAGvF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC;IAC5C,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,wBAAsB,GAAG,CACvB,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CA2DpB"}
@@ -0,0 +1,183 @@
1
+ import { search } from "../search/search.js";
2
+ export async function ask(db, config, question, options = {}) {
3
+ const started = Date.now();
4
+ const q = question.trim();
5
+ if (!q) {
6
+ return {
7
+ question,
8
+ answer: "Please provide a non-empty question.",
9
+ mode: "extractive",
10
+ provider: "none",
11
+ hits: [],
12
+ tookMs: 0,
13
+ };
14
+ }
15
+ const provider = options.provider ?? config.provider;
16
+ const hits = await search(db, q, {
17
+ limit: options.limit ?? 6,
18
+ mode: provider === "none" ? "bm25" : "hybrid",
19
+ provider,
20
+ });
21
+ const wantGenerative = options.mode === "generative" ||
22
+ (options.mode !== "extractive" && provider !== "none");
23
+ if (wantGenerative && hits.length) {
24
+ try {
25
+ const answer = await generateAnswer(q, hits, provider);
26
+ return {
27
+ question: q,
28
+ answer,
29
+ mode: "generative",
30
+ provider,
31
+ hits,
32
+ tookMs: Date.now() - started,
33
+ };
34
+ }
35
+ catch (err) {
36
+ const fallback = buildExtractiveAnswer(q, hits);
37
+ return {
38
+ question: q,
39
+ answer: `${fallback}\n\n_(Generative answer failed: ${err instanceof Error ? err.message : String(err)}; showing extractive result.)_`,
40
+ mode: "extractive",
41
+ provider,
42
+ hits,
43
+ tookMs: Date.now() - started,
44
+ };
45
+ }
46
+ }
47
+ return {
48
+ question: q,
49
+ answer: buildExtractiveAnswer(q, hits),
50
+ mode: "extractive",
51
+ provider: "none",
52
+ hits,
53
+ tookMs: Date.now() - started,
54
+ };
55
+ }
56
+ function buildExtractiveAnswer(question, hits) {
57
+ if (!hits.length) {
58
+ return [
59
+ `No relevant context found for: "${question}"`,
60
+ "",
61
+ "Tips:",
62
+ "- Run `localmind index` after code changes",
63
+ "- Try more specific identifiers (function/class names)",
64
+ "- Check `localmind status` for index size",
65
+ ].join("\n");
66
+ }
67
+ const lines = [
68
+ `## Answer (extractive)`,
69
+ "",
70
+ `Based on ${hits.length} relevant chunk(s) in the local index:`,
71
+ "",
72
+ ];
73
+ for (const hit of hits) {
74
+ const snippet = trimSnippet(hit.content, 500);
75
+ lines.push(`### ${hit.rank}. \`${hit.path}\` (L${hit.startLine}–${hit.endLine})`);
76
+ lines.push(`Score: ${hit.score.toFixed(4)}`);
77
+ lines.push("```" + fenceLang(hit.language));
78
+ lines.push(snippet);
79
+ lines.push("```");
80
+ lines.push("");
81
+ }
82
+ lines.push("---");
83
+ lines.push("Citations only — no LLM was used. Set provider to `openai` or `ollama` (and API env vars) for generative answers.");
84
+ return lines.join("\n");
85
+ }
86
+ function trimSnippet(text, max) {
87
+ const t = text.trim();
88
+ if (t.length <= max)
89
+ return t;
90
+ return t.slice(0, max).trimEnd() + "\n…";
91
+ }
92
+ function fenceLang(language) {
93
+ const map = {
94
+ typescript: "ts",
95
+ javascript: "js",
96
+ python: "python",
97
+ rust: "rust",
98
+ go: "go",
99
+ markdown: "md",
100
+ json: "json",
101
+ yaml: "yaml",
102
+ shell: "bash",
103
+ };
104
+ return map[language] ?? language;
105
+ }
106
+ async function generateAnswer(question, hits, provider) {
107
+ const context = hits
108
+ .map((h, i) => `[${i + 1}] ${h.path}:${h.startLine}-${h.endLine}\n${h.content}`)
109
+ .join("\n\n---\n\n");
110
+ const system = [
111
+ "You are LocalMind, a precise codebase assistant.",
112
+ "Answer using ONLY the provided context chunks.",
113
+ "Cite sources as [n] with file paths.",
114
+ "If the context is insufficient, say what is missing.",
115
+ "Be concise and technical.",
116
+ ].join(" ");
117
+ const user = `Question: ${question}\n\nContext:\n${context}`;
118
+ if (provider === "openai" || (provider === "none" && process.env.OPENAI_API_KEY)) {
119
+ return openaiChat(system, user);
120
+ }
121
+ if (provider === "ollama") {
122
+ return ollamaChat(system, user);
123
+ }
124
+ throw new Error("No generative provider configured");
125
+ }
126
+ async function openaiChat(system, user) {
127
+ const apiKey = process.env.OPENAI_API_KEY;
128
+ if (!apiKey)
129
+ throw new Error("OPENAI_API_KEY is not set");
130
+ const baseUrl = (process.env.OPENAI_BASE_URL?.trim() || "https://api.openai.com/v1").replace(/\/$/, "");
131
+ const model = process.env.OPENAI_MODEL?.trim() || "gpt-4o-mini";
132
+ const res = await fetch(`${baseUrl}/chat/completions`, {
133
+ method: "POST",
134
+ headers: {
135
+ "Content-Type": "application/json",
136
+ Authorization: `Bearer ${apiKey}`,
137
+ },
138
+ body: JSON.stringify({
139
+ model,
140
+ temperature: 0.2,
141
+ messages: [
142
+ { role: "system", content: system },
143
+ { role: "user", content: user },
144
+ ],
145
+ }),
146
+ });
147
+ if (!res.ok) {
148
+ throw new Error(`OpenAI chat failed (${res.status}): ${await res.text()}`);
149
+ }
150
+ const data = (await res.json());
151
+ const content = data.choices?.[0]?.message?.content?.trim();
152
+ if (!content)
153
+ throw new Error("Empty OpenAI response");
154
+ return content;
155
+ }
156
+ async function ollamaChat(system, user) {
157
+ const baseUrl = (process.env.OLLAMA_BASE_URL?.trim() ||
158
+ process.env.OLLAMA_HOST?.trim() ||
159
+ "http://127.0.0.1:11434").replace(/\/$/, "");
160
+ const model = process.env.OLLAMA_MODEL?.trim() || "llama3.2";
161
+ const res = await fetch(`${baseUrl}/api/chat`, {
162
+ method: "POST",
163
+ headers: { "Content-Type": "application/json" },
164
+ body: JSON.stringify({
165
+ model,
166
+ stream: false,
167
+ messages: [
168
+ { role: "system", content: system },
169
+ { role: "user", content: user },
170
+ ],
171
+ options: { temperature: 0.2 },
172
+ }),
173
+ });
174
+ if (!res.ok) {
175
+ throw new Error(`Ollama chat failed (${res.status}): ${await res.text()}`);
176
+ }
177
+ const data = (await res.json());
178
+ const content = data.message?.content?.trim();
179
+ if (!content)
180
+ throw new Error("Empty Ollama response");
181
+ return content;
182
+ }
183
+ //# sourceMappingURL=answer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer.js","sourceRoot":"","sources":["../../src/ask/answer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=localmind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localmind.d.ts","sourceRoot":"","sources":["../../src/bin/localmind.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "../cli/program.js";
3
+ runCli(process.argv).catch((err) => {
4
+ const message = err instanceof Error ? err.message : String(err);
5
+ console.error(`localmind: ${message}`);
6
+ if (err instanceof Error && err.stack && process.env.DEBUG) {
7
+ console.error(err.stack);
8
+ }
9
+ process.exit(1);
10
+ });
11
+ //# sourceMappingURL=localmind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localmind.js","sourceRoot":"","sources":["../../src/bin/localmind.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;IACvC,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AskResult, IndexStats, SearchHit, StatusInfo } from "../types.js";
2
+ export declare function printInitResult(root: string, created: boolean): void;
3
+ export declare function printIndexStats(stats: IndexStats): void;
4
+ export declare function printStatus(status: StatusInfo): void;
5
+ export declare function printSearchHits(hits: SearchHit[]): void;
6
+ export declare function printAskResult(result: AskResult, json?: boolean): void;
7
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGhF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CASpE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAQvD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAYpD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAuBvD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,UAAQ,GAAG,IAAI,CAYpE"}
@@ -0,0 +1,67 @@
1
+ import pc from "picocolors";
2
+ import { formatBytes } from "../status.js";
3
+ export function printInitResult(root, created) {
4
+ if (created) {
5
+ console.log(pc.green("✔") + ` LocalMind initialized in ${pc.bold(root)}`);
6
+ console.log(` Config: ${pc.dim(".localmind/config.json")}`);
7
+ console.log(` Next: ${pc.cyan("localmind index")}`);
8
+ }
9
+ else {
10
+ console.log(pc.yellow("⚠") + ` Already initialized: ${root}`);
11
+ console.log(` Use ${pc.cyan("--force")} to reinitialize.`);
12
+ }
13
+ }
14
+ export function printIndexStats(stats) {
15
+ console.log(pc.green("✔") + " Index complete");
16
+ console.log(` Scanned: ${stats.filesScanned}`);
17
+ console.log(` Indexed: ${stats.filesIndexed}`);
18
+ console.log(` Skipped: ${stats.filesSkipped}`);
19
+ console.log(` Removed: ${stats.filesRemoved}`);
20
+ console.log(` Chunks: ${stats.chunksCreated}`);
21
+ console.log(` Duration: ${(stats.durationMs / 1000).toFixed(2)}s`);
22
+ }
23
+ export function printStatus(status) {
24
+ console.log(pc.bold("LocalMind status"));
25
+ console.log(` Root: ${status.root}`);
26
+ console.log(` Provider: ${status.config.provider}`);
27
+ console.log(` Files: ${status.fileCount}`);
28
+ console.log(` Chunks: ${status.chunkCount}`);
29
+ console.log(` Terms: ${status.termCount}`);
30
+ console.log(` Graph edges:${status.edgeCount}`);
31
+ console.log(` Embeddings: ${status.embeddingCount}`);
32
+ console.log(` DB size: ${formatBytes(status.dbSizeBytes)}`);
33
+ console.log(` Last index: ${status.lastIndexedAt ?? "never"}`);
34
+ console.log(` DB path: ${pc.dim(status.dbPath)}`);
35
+ }
36
+ export function printSearchHits(hits) {
37
+ if (!hits.length) {
38
+ console.log(pc.yellow("No results."));
39
+ return;
40
+ }
41
+ for (const hit of hits) {
42
+ console.log(pc.cyan(`#${hit.rank}`) +
43
+ ` ${pc.bold(hit.path)}` +
44
+ pc.dim(`:${hit.startLine}-${hit.endLine}`) +
45
+ pc.dim(` score=${hit.score.toFixed(4)}`));
46
+ const preview = hit.content
47
+ .split("\n")
48
+ .slice(0, 6)
49
+ .map((l) => " " + l)
50
+ .join("\n");
51
+ console.log(pc.dim(preview));
52
+ if (hit.content.split("\n").length > 6) {
53
+ console.log(pc.dim(" …"));
54
+ }
55
+ console.log();
56
+ }
57
+ }
58
+ export function printAskResult(result, json = false) {
59
+ if (json) {
60
+ console.log(JSON.stringify(result, null, 2));
61
+ return;
62
+ }
63
+ console.log(result.answer);
64
+ console.log();
65
+ console.log(pc.dim(`mode=${result.mode} provider=${result.provider} hits=${result.hits.length} took=${result.tookMs}ms`));
66
+ }
67
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ export declare function buildProgram(): Command;
3
+ export declare function runCli(argv?: string[]): Promise<void>;
4
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,wBAAgB,YAAY,IAAI,OAAO,CA6OtC;AAeD,wBAAsB,MAAM,CAAC,IAAI,WAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/D"}