@gmickel/gno 0.9.1 → 0.9.3

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/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # GNO
2
2
 
3
- **Your Local Second Brain** Index, search, and synthesize your entire digital life.
3
+ **Your Local Second Brain**: Index, search, and synthesize your entire digital life.
4
4
 
5
5
  [![npm](./assets/badges/npm.svg)](https://www.npmjs.com/package/@gmickel/gno)
6
6
  [![MIT License](./assets/badges/license.svg)](./LICENSE)
7
7
  [![Website](./assets/badges/website.svg)](https://gno.sh)
8
8
  [![Twitter](./assets/badges/twitter.svg)](https://twitter.com/gmickel)
9
9
 
10
- GNO is a local knowledge engine for privacy-conscious developers and AI agents. Index your notes, code, PDFs, and Office docs. Get hybrid search (BM25 + vector + reranking) and AI-powered answersall running 100% on your machine.
10
+ GNO is a local knowledge engine for privacy-conscious developers and AI agents. Index your notes, code, PDFs, and Office docs. Get hybrid search (BM25 + vector + reranking) and AI-powered answers, all running 100% on your machine.
11
11
 
12
12
  ---
13
13
 
@@ -16,9 +16,9 @@ GNO is a local knowledge engine for privacy-conscious developers and AI agents.
16
16
  - [Quick Start](#quick-start)
17
17
  - [Installation](#installation)
18
18
  - [Search Modes](#search-modes)
19
+ - [Agent Integration](#agent-integration)
19
20
  - [Web UI](#web-ui)
20
21
  - [REST API](#rest-api)
21
- - [Agent Integration](#agent-integration)
22
22
  - [How It Works](#how-it-works)
23
23
  - [Features](#features)
24
24
  - [Local Models](#local-models)
@@ -85,7 +85,7 @@ Check status: `gno mcp status`
85
85
 
86
86
  #### Skills (Claude Code, Codex, OpenCode)
87
87
 
88
- Skills integrate via CLIno MCP overhead:
88
+ Skills integrate via CLI with no MCP overhead:
89
89
 
90
90
  ```bash
91
91
  gno skill install --scope user # User-wide
@@ -106,7 +106,7 @@ gno skill install --target all # Both Claude + Codex
106
106
  | `gno query` | Hybrid | Best accuracy (BM25 + vector + reranking) |
107
107
  | `gno ask --answer` | RAG | Direct answers with citations |
108
108
 
109
- **BM25** indexes full documents (not chunks) with Snowball stemming"running" matches "run".
109
+ **BM25** indexes full documents (not chunks) with Snowball stemming, so "running" matches "run".
110
110
  **Vector** embeds chunks with document titles for context awareness.
111
111
 
112
112
  ```bash
@@ -120,29 +120,76 @@ Output formats: `--json`, `--files`, `--csv`, `--md`, `--xml`
120
120
 
121
121
  ---
122
122
 
123
+ ## Agent Integration
124
+
125
+ Give your local LLM agents a long-term memory. GNO integrates as a Claude Code skill or MCP server, allowing agents to search, read, and cite your local files.
126
+
127
+ ### Skills
128
+
129
+ Skills add GNO search to Claude Code/Codex without MCP protocol overhead:
130
+
131
+ ```bash
132
+ gno skill install --scope user
133
+ ```
134
+
135
+ ![GNO Skill in Claude Code](./assets/screenshots/claudecodeskill.jpg)
136
+
137
+ Then ask your agent: _"Search my notes for the auth discussion"_
138
+
139
+ [Skill setup guide →](https://gno.sh/docs/integrations/skills/)
140
+
141
+ ### MCP Server
142
+
143
+ Connect GNO to Claude Desktop, Cursor, Raycast, and more:
144
+
145
+ ![GNO MCP](./assets/screenshots/mcp.jpg)
146
+
147
+ GNO exposes 6 tools via [Model Context Protocol](https://modelcontextprotocol.io):
148
+
149
+ | Tool | Description |
150
+ | :-------------- | :-------------------------- |
151
+ | `gno_search` | BM25 keyword search |
152
+ | `gno_vsearch` | Vector semantic search |
153
+ | `gno_query` | Hybrid search (recommended) |
154
+ | `gno_get` | Retrieve document by ID |
155
+ | `gno_multi_get` | Batch document retrieval |
156
+ | `gno_status` | Index health check |
157
+
158
+ **Design**: MCP tools are retrieval-only. Your AI assistant (Claude, GPT-4) synthesizes answers from retrieved context. Best retrieval (GNO) + best reasoning (your LLM).
159
+
160
+ [MCP setup guide →](https://gno.sh/docs/MCP/)
161
+
162
+ ---
163
+
123
164
  ## Web UI
124
165
 
125
- Visual dashboard for search, browsing, editing, and AI answers—right in your browser.
166
+ Visual dashboard for search, browsing, editing, and AI answers. Right in your browser.
126
167
 
127
168
  ```bash
128
169
  gno serve # Start on port 3000
129
170
  gno serve --port 8080 # Custom port
130
171
  ```
131
172
 
132
- ![GNO Web UI](./assets/screenshots/webui-home.png)
173
+ ![GNO Web UI](./assets/screenshots/webui-home.jpg)
133
174
 
134
175
  Open `http://localhost:3000` to:
135
176
 
136
- - **Search** BM25, vector, or hybrid modes with visual results
137
- - **Browse** Paginated document list, filter by collection
138
- - **Edit** Create, edit, and delete documents with live preview
139
- - **Ask** AI-powered Q&A with citations
140
- - **Manage Collections** Add, remove, and re-index collections
141
- - **Switch presets** Change models live without restart
177
+ - **Search**: BM25, vector, or hybrid modes with visual results
178
+ - **Browse**: Paginated document list, filter by collection
179
+ - **Edit**: Create, edit, and delete documents with live preview
180
+ - **Ask**: AI-powered Q&A with citations
181
+ - **Manage Collections**: Add, remove, and re-index collections
182
+ - **Switch presets**: Change models live without restart
183
+
184
+ ### Search
185
+
186
+ ![GNO Search](./assets/screenshots/webui-search.jpg)
187
+
188
+ Three retrieval modes: BM25 (keyword), Vector (semantic), or Hybrid (best of both). Adjust search depth for speed vs thoroughness.
142
189
 
143
190
  ### Document Editing
144
191
 
145
- ![GNO Document Editor](./assets/screenshots/webui-editor.png)
192
+ ![GNO Document Editor](./assets/screenshots/webui-editor.jpg)
146
193
 
147
194
  Full-featured markdown editor with:
148
195
 
@@ -156,7 +203,7 @@ Full-featured markdown editor with:
156
203
 
157
204
  ### Collections Management
158
205
 
159
- ![GNO Collections](./assets/screenshots/webui-collections.png)
206
+ ![GNO Collections](./assets/screenshots/webui-collections.jpg)
160
207
 
161
208
  - Add collections with folder path input
162
209
  - View document count, chunk count, embedding status
@@ -165,9 +212,9 @@ Full-featured markdown editor with:
165
212
 
166
213
  ### AI Answers
167
214
 
168
- ![GNO AI Answers](./assets/screenshots/webui-ask-answer.png)
215
+ ![GNO AI Answers](./assets/screenshots/webui-ask-answer.jpg)
169
216
 
170
- Ask questions in natural languageGNO searches your documents and synthesizes answers with inline citations linking to sources.
217
+ Ask questions in natural language. GNO searches your documents and synthesizes answers with inline citations linking to sources.
171
218
 
172
219
  Everything runs locally. No cloud, no accounts, no data leaving your machine.
173
220
 
@@ -219,41 +266,6 @@ No authentication. No rate limits. Build custom tools, automate workflows, integ
219
266
 
220
267
  ---
221
268
 
222
- ## Agent Integration
223
-
224
- ### MCP Server
225
-
226
- ![GNO MCP](./assets/screenshots/mcp.jpg)
227
-
228
- GNO exposes 6 tools via [Model Context Protocol](https://modelcontextprotocol.io):
229
-
230
- | Tool | Description |
231
- | :-------------- | :-------------------------- |
232
- | `gno_search` | BM25 keyword search |
233
- | `gno_vsearch` | Vector semantic search |
234
- | `gno_query` | Hybrid search (recommended) |
235
- | `gno_get` | Retrieve document by ID |
236
- | `gno_multi_get` | Batch document retrieval |
237
- | `gno_status` | Index health check |
238
-
239
- **Design**: MCP tools are retrieval-only. Your AI assistant (Claude, GPT-4) synthesizes answers from retrieved context—best retrieval (GNO) + best reasoning (your LLM).
240
-
241
- ### Skills
242
-
243
- Skills add GNO search to Claude Code/Codex without MCP protocol overhead:
244
-
245
- ```bash
246
- gno skill install --scope user
247
- ```
248
-
249
- ![GNO Skill in Claude Code](./assets/screenshots/claudecodeskill.jpg)
250
-
251
- Then ask your agent: _"Search my notes for the auth discussion"_
252
-
253
- > **Detailed docs**: [MCP Integration](https://gno.sh/docs/MCP/) · [Use Cases](https://gno.sh/docs/USE-CASES/)
254
-
255
- ---
256
-
257
269
  ## How It Works
258
270
 
259
271
  ```mermaid
@@ -279,11 +291,11 @@ graph TD
279
291
  M --> N[Final Results]
280
292
  ```
281
293
 
282
- 0. **Strong Signal Check** Skip expansion if BM25 has confident match (saves 1-3s)
283
- 1. **Query Expansion** LLM generates lexical variants, semantic rephrases, and a [HyDE](https://arxiv.org/abs/2212.10496) passage
284
- 2. **Parallel Retrieval** Document-level BM25 + chunk-level vector search on all variants
285
- 3. **Fusion** RRF with 2× weight for original query, tiered bonus for top ranks
286
- 4. **Reranking** Qwen3-Reranker scores full documents (32K context), blended with fusion
294
+ 0. **Strong Signal Check**: Skip expansion if BM25 has confident match (saves 1-3s)
295
+ 1. **Query Expansion**: LLM generates lexical variants, semantic rephrases, and a [HyDE](https://arxiv.org/abs/2212.10496) passage
296
+ 2. **Parallel Retrieval**: Document-level BM25 + chunk-level vector search on all variants
297
+ 3. **Fusion**: RRF with 2× weight for original query, tiered bonus for top ranks
298
+ 4. **Reranking**: Qwen3-Reranker scores best chunk per document (4K), blended with fusion
287
299
 
288
300
  > **Deep dive**: [How Search Works](https://gno.sh/docs/HOW-SEARCH-WORKS/)
289
301
 
@@ -298,12 +310,12 @@ graph TD
298
310
  | **Web UI** | Visual dashboard for search, browse, edit, and AI Q&A |
299
311
  | **REST API** | HTTP API for custom tools and integrations |
300
312
  | **Multi-Format** | Markdown, PDF, DOCX, XLSX, PPTX, plain text |
301
- | **Local LLM** | AI answers via llama.cppno API keys |
313
+ | **Local LLM** | AI answers via llama.cpp, no API keys |
302
314
  | **Privacy First** | 100% offline, zero telemetry, your data stays yours |
303
315
  | **MCP Server** | Works with Claude Desktop, Cursor, Zed, + 8 more |
304
316
  | **Collections** | Organize sources with patterns, excludes, contexts |
305
317
  | **Multilingual** | 30+ languages, auto-detection, cross-lingual search |
306
- | **Incremental** | SHA-256 trackingonly changed files re-indexed |
318
+ | **Incremental** | SHA-256 tracking, only changed files re-indexed |
307
319
  | **Keyboard First** | ⌘N capture, ⌘K search, ⌘/ shortcuts, ⌘S save |
308
320
 
309
321
  ---
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
5
5
  "keywords": [
6
6
  "embeddings",
@@ -100,6 +100,7 @@
100
100
  "react-dom": "^19.2.3",
101
101
  "react-markdown": "^10.1.0",
102
102
  "rehype-sanitize": "^6.0.0",
103
+ "remark-gfm": "^4.0.1",
103
104
  "shiki": "^3.20.0",
104
105
  "sqlite-vec": "^0.1.7-alpha.2",
105
106
  "streamdown": "^1.6.10",
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Shell completion commands - output scripts or auto-install.
3
+ *
4
+ * @module src/cli/commands/completion/completion
5
+ */
6
+
7
+ // node:fs/promises - no Bun equivalent for mkdir/appendFile/writeFile
8
+ import { appendFile, mkdir, writeFile } from "node:fs/promises";
9
+ import { homedir } from "node:os";
10
+ import { join } from "node:path";
11
+
12
+ import { CLI_NAME } from "../../../app/constants.js";
13
+ import { CliError } from "../../errors.js";
14
+ import {
15
+ getCompletionScript,
16
+ SUPPORTED_SHELLS,
17
+ type Shell,
18
+ } from "./scripts.js";
19
+
20
+ // ─────────────────────────────────────────────────────────────────────────────
21
+ // Types
22
+ // ─────────────────────────────────────────────────────────────────────────────
23
+
24
+ export interface OutputOptions {
25
+ shell: Shell;
26
+ }
27
+
28
+ export interface InstallOptions {
29
+ /** Override shell detection */
30
+ shell?: Shell;
31
+ /** JSON output */
32
+ json?: boolean;
33
+ }
34
+
35
+ interface InstallResult {
36
+ shell: Shell;
37
+ path: string;
38
+ action: "installed" | "already_installed";
39
+ }
40
+
41
+ // ─────────────────────────────────────────────────────────────────────────────
42
+ // Shell Detection
43
+ // ─────────────────────────────────────────────────────────────────────────────
44
+
45
+ /**
46
+ * Detect user's current shell.
47
+ */
48
+ function detectShell(): Shell | undefined {
49
+ // Check $SHELL env
50
+ const shellEnv = process.env.SHELL || "";
51
+ if (shellEnv.includes("zsh")) return "zsh";
52
+ if (shellEnv.includes("bash")) return "bash";
53
+ if (shellEnv.includes("fish")) return "fish";
54
+
55
+ // Check parent process name on Unix
56
+ // This is less reliable but can help
57
+ const parentName = process.env._ || "";
58
+ if (parentName.includes("zsh")) return "zsh";
59
+ if (parentName.includes("bash")) return "bash";
60
+ if (parentName.includes("fish")) return "fish";
61
+
62
+ return undefined;
63
+ }
64
+
65
+ /**
66
+ * Get the appropriate rc file for a shell.
67
+ */
68
+ function getShellRcPath(shell: Shell): string {
69
+ const home = homedir();
70
+ switch (shell) {
71
+ case "bash":
72
+ // Prefer .bashrc, but .bash_profile on macOS
73
+ return process.platform === "darwin"
74
+ ? join(home, ".bash_profile")
75
+ : join(home, ".bashrc");
76
+ case "zsh":
77
+ return join(home, ".zshrc");
78
+ case "fish":
79
+ return join(home, ".config", "fish", "completions", `${CLI_NAME}.fish`);
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Check if completion is already installed.
85
+ */
86
+ async function isCompletionInstalled(shell: Shell): Promise<boolean> {
87
+ const path = getShellRcPath(shell);
88
+
89
+ // For fish, check if file exists
90
+ if (shell === "fish") {
91
+ return await Bun.file(path).exists();
92
+ }
93
+
94
+ // For bash/zsh, check for shell-specific patterns
95
+ try {
96
+ const content = await Bun.file(path).text();
97
+ // Generic header comment
98
+ const header = `# ${CLI_NAME}`;
99
+ // Bash function name
100
+ const bashFn = `_${CLI_NAME}_completions`;
101
+ // Zsh-specific patterns (function definition or completion header)
102
+ const zshFn = `_${CLI_NAME}()`;
103
+
104
+ if (shell === "bash") {
105
+ return content.includes(header) || content.includes(bashFn);
106
+ }
107
+ if (shell === "zsh") {
108
+ return content.includes(header) || content.includes(zshFn);
109
+ }
110
+ return false;
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+
116
+ // ─────────────────────────────────────────────────────────────────────────────
117
+ // Commands
118
+ // ─────────────────────────────────────────────────────────────────────────────
119
+
120
+ /**
121
+ * Output completion script to stdout.
122
+ */
123
+ export function completionOutput(options: OutputOptions): string {
124
+ const { shell } = options;
125
+
126
+ if (!SUPPORTED_SHELLS.includes(shell)) {
127
+ throw new CliError(
128
+ "VALIDATION",
129
+ `Unsupported shell: ${shell}. Supported: ${SUPPORTED_SHELLS.join(", ")}`
130
+ );
131
+ }
132
+
133
+ return getCompletionScript(shell);
134
+ }
135
+
136
+ /**
137
+ * Auto-install completion to user's shell config.
138
+ */
139
+ export async function completionInstall(
140
+ options: InstallOptions
141
+ ): Promise<void> {
142
+ const { json = false } = options;
143
+ let { shell } = options;
144
+
145
+ // Auto-detect shell if not specified
146
+ if (!shell) {
147
+ shell = detectShell();
148
+ if (!shell) {
149
+ throw new CliError(
150
+ "VALIDATION",
151
+ "Could not detect shell. Please specify: gno completion install --shell <bash|zsh|fish>"
152
+ );
153
+ }
154
+ }
155
+
156
+ if (!SUPPORTED_SHELLS.includes(shell)) {
157
+ throw new CliError(
158
+ "VALIDATION",
159
+ `Unsupported shell: ${shell}. Supported: ${SUPPORTED_SHELLS.join(", ")}`
160
+ );
161
+ }
162
+
163
+ // Check if already installed
164
+ const alreadyInstalled = await isCompletionInstalled(shell);
165
+ const rcPath = getShellRcPath(shell);
166
+ const script = getCompletionScript(shell);
167
+
168
+ let result: InstallResult;
169
+
170
+ if (alreadyInstalled) {
171
+ result = { shell, path: rcPath, action: "already_installed" };
172
+ } else {
173
+ // Install completion
174
+ if (shell === "fish") {
175
+ // Fish uses a separate file in completions dir
176
+ const dir = join(homedir(), ".config", "fish", "completions");
177
+ await mkdir(dir, { recursive: true });
178
+ await writeFile(rcPath, script, "utf-8");
179
+ } else {
180
+ // Bash/zsh append to rc file
181
+ const separator = "\n\n";
182
+ await appendFile(rcPath, separator + script, "utf-8");
183
+ }
184
+ result = { shell, path: rcPath, action: "installed" };
185
+ }
186
+
187
+ // Output result
188
+ if (json) {
189
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
190
+ } else {
191
+ if (result.action === "already_installed") {
192
+ process.stdout.write(`Completion already installed for ${shell}.\n`);
193
+ process.stdout.write(`Config: ${result.path}\n`);
194
+ } else {
195
+ process.stdout.write(`Completion installed for ${shell}.\n`);
196
+ process.stdout.write(`Config: ${result.path}\n`);
197
+ process.stdout.write(`\nRestart your shell or run:\n`);
198
+ process.stdout.write(` source ${result.path}\n`);
199
+ }
200
+ }
201
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shell completion command - output or install completion scripts.
3
+ *
4
+ * @module src/cli/commands/completion
5
+ */
6
+
7
+ export { completionOutput, completionInstall } from "./completion.js";
8
+ export { SUPPORTED_SHELLS, type Shell } from "./scripts.js";