@gmickel/gno 0.10.4 → 0.12.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 (41) hide show
  1. package/README.md +11 -0
  2. package/assets/skill/SKILL.md +12 -0
  3. package/assets/skill/mcp-reference.md +29 -188
  4. package/package.json +1 -1
  5. package/src/cli/commands/embed.ts +21 -2
  6. package/src/cli/commands/links.ts +896 -0
  7. package/src/cli/commands/ref-parser.ts +1 -1
  8. package/src/cli/commands/vec.ts +287 -0
  9. package/src/cli/options.ts +6 -0
  10. package/src/cli/program.ts +192 -0
  11. package/src/core/job-manager.ts +94 -1
  12. package/src/core/links.ts +400 -0
  13. package/src/embed/backlog.ts +144 -0
  14. package/src/embed/index.ts +11 -0
  15. package/src/ingestion/position.ts +119 -0
  16. package/src/ingestion/strip.ts +162 -0
  17. package/src/ingestion/sync.ts +58 -1
  18. package/src/mcp/tools/embed.ts +151 -0
  19. package/src/mcp/tools/index-cmd.ts +219 -0
  20. package/src/mcp/tools/index.ts +100 -0
  21. package/src/mcp/tools/job-status.ts +34 -4
  22. package/src/mcp/tools/links.ts +617 -0
  23. package/src/mcp/tools/list-jobs.ts +3 -2
  24. package/src/serve/embed-scheduler.ts +263 -0
  25. package/src/serve/public/app.tsx +2 -0
  26. package/src/serve/public/components/BacklinksPanel.tsx +321 -0
  27. package/src/serve/public/components/OutgoingLinksPanel.tsx +323 -0
  28. package/src/serve/public/components/RelatedNotesSidebar.tsx +482 -0
  29. package/src/serve/public/components/WikiLinkAutocomplete.tsx +554 -0
  30. package/src/serve/public/globals.built.css +1 -1
  31. package/src/serve/public/pages/DocView.tsx +344 -259
  32. package/src/serve/public/pages/DocumentEditor.tsx +101 -17
  33. package/src/serve/routes/api.ts +84 -1
  34. package/src/serve/routes/links.ts +471 -0
  35. package/src/serve/server.ts +74 -1
  36. package/src/store/migrations/004-doc-links.ts +64 -0
  37. package/src/store/migrations/index.ts +2 -1
  38. package/src/store/sqlite/adapter.ts +305 -0
  39. package/src/store/types.ts +109 -0
  40. package/src/store/vector/sqlite-vec.ts +62 -45
  41. package/src/store/vector/types.ts +3 -1
package/README.md CHANGED
@@ -27,6 +27,16 @@ GNO is a local knowledge engine for privacy-conscious developers and AI agents.
27
27
 
28
28
  ---
29
29
 
30
+ ## What's New in v0.12
31
+
32
+ - **Note Linking**: Wiki-style `[[links]]`, backlinks, and AI-powered related notes
33
+ - **Tag System**: Filter searches by frontmatter tags with `--tags-any`/`--tags-all`
34
+ - **Web UI**: Outgoing links panel, backlinks panel, related notes sidebar
35
+ - **CLI**: `gno links`, `gno backlinks`, `gno similar` commands
36
+ - **MCP**: New tools for AI agents to navigate your knowledge graph
37
+
38
+ ---
39
+
30
40
  ## Quick Start
31
41
 
32
42
  ```bash
@@ -315,6 +325,7 @@ graph TD
315
325
  | **MCP Server** | Works with Claude Desktop, Cursor, Zed, + 8 more |
316
326
  | **Collections** | Organize sources with patterns, excludes, contexts |
317
327
  | **Tag Filtering** | Frontmatter tags with hierarchical paths, filter via `--tags-any`/`--tags-all` |
328
+ | **Note Linking** | Wiki links, backlinks, related notes, cross-collection navigation |
318
329
  | **Multilingual** | 30+ languages, auto-detection, cross-lingual search |
319
330
  | **Incremental** | SHA-256 tracking, only changed files re-indexed |
320
331
  | **Keyboard First** | ⌘N capture, ⌘K search, ⌘/ shortcuts, ⌘S save |
@@ -83,6 +83,18 @@ gno search "your query" # BM25 keyword search
83
83
  --no-pager Disable paging
84
84
  ```
85
85
 
86
+ ## Important: Embedding After Changes
87
+
88
+ If you edit/create files that should be searchable via vector search:
89
+
90
+ ```bash
91
+ gno index # Full re-index (sync + embed)
92
+ # or
93
+ gno embed # Embed only (if already synced)
94
+ ```
95
+
96
+ MCP `gno.sync` and `gno.capture` do NOT auto-embed. Use CLI for embedding.
97
+
86
98
  ## Reference Documentation
87
99
 
88
100
  | Topic | File |
@@ -1,8 +1,23 @@
1
- # GNO MCP Reference
1
+ # GNO MCP Installation
2
2
 
3
- GNO provides an MCP (Model Context Protocol) server for AI integration.
3
+ GNO provides an MCP (Model Context Protocol) server for AI client integration.
4
4
 
5
- ## Setup
5
+ > **Full reference**: See [gno.sh/docs/MCP](https://www.gno.sh/docs/MCP) for complete tool documentation.
6
+
7
+ ## Quick Install
8
+
9
+ ```bash
10
+ # Claude Desktop (default)
11
+ gno mcp install
12
+
13
+ # Claude Code
14
+ gno mcp install -t claude-code
15
+
16
+ # With write tools enabled
17
+ gno mcp install --enable-write
18
+ ```
19
+
20
+ ## Manual Setup
6
21
 
7
22
  ### Claude Desktop
8
23
 
@@ -19,202 +34,28 @@ Add to `claude_desktop_config.json`:
19
34
  }
20
35
  ```
21
36
 
22
- Config location:
37
+ Config locations:
23
38
 
24
39
  - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
25
40
  - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
26
41
  - Linux: `~/.config/Claude/claude_desktop_config.json`
27
42
 
28
- ### Start Server
43
+ ### Claude Code
29
44
 
30
45
  ```bash
31
- gno mcp
32
- ```
33
-
34
- Runs JSON-RPC 2.0 over stdio.
35
-
36
- ## Tools
37
-
38
- ### gno.search
39
-
40
- BM25 keyword search.
41
-
42
- ```json
43
- {
44
- "query": "search terms",
45
- "collection": "optional-collection",
46
- "limit": 5,
47
- "minScore": 0.5,
48
- "lang": "en",
49
- "tagsAny": ["project", "work"],
50
- "tagsAll": ["reviewed"]
51
- }
52
- ```
53
-
54
- | Parameter | Description |
55
- | ------------ | ----------------------------------- |
56
- | `query` | Search query (required) |
57
- | `collection` | Filter by collection |
58
- | `limit` | Max results (default: 5) |
59
- | `minScore` | Minimum score 0-1 |
60
- | `tagsAny` | Filter: has ANY of these tags (OR) |
61
- | `tagsAll` | Filter: has ALL of these tags (AND) |
62
-
63
- ### gno.vsearch
64
-
65
- Vector semantic search. Same parameters as `gno.search`.
66
-
67
- ### gno.query
68
-
69
- Hybrid search (best quality).
70
-
71
- ```json
72
- {
73
- "query": "search terms",
74
- "collection": "optional-collection",
75
- "limit": 5
76
- }
77
- ```
78
-
79
- **Search modes** (via parameters):
80
-
81
- | Mode | Parameters | Time |
82
- | -------- | ---------------- | ----- |
83
- | Fast | `fast: true` | ~0.7s |
84
- | Default | (none) | ~2-3s |
85
- | Thorough | `thorough: true` | ~5-8s |
86
-
87
- Default skips expansion, with reranking. Use `thorough: true` for best recall.
88
-
89
- **Agent retry strategy**: Use default mode first. If no relevant results:
90
-
91
- 1. Rephrase the query (free, often effective)
92
- 2. Then try `thorough: true` for better recall
93
-
94
- ### gno.get
95
-
96
- Retrieve document by reference.
97
-
98
- ```json
99
- {
100
- "ref": "gno://collection/path or #docid",
101
- "fromLine": 1,
102
- "lineCount": 100,
103
- "lineNumbers": true
104
- }
105
- ```
106
-
107
- ### gno.multi_get
108
-
109
- Retrieve multiple documents.
110
-
111
- ```json
112
- {
113
- "refs": ["gno://work/doc1.md", "#a1b2c3d4"],
114
- "maxBytes": 10240,
115
- "lineNumbers": true
116
- }
117
- ```
118
-
119
- Or by pattern:
120
-
121
- ```json
122
- {
123
- "pattern": "work/**/*.md",
124
- "maxBytes": 10240
125
- }
126
- ```
127
-
128
- ### gno.status
129
-
130
- Get index status.
131
-
132
- ```json
133
- {}
134
- ```
135
-
136
- ### gno.list_tags
137
-
138
- List tags with document counts.
139
-
140
- ```json
141
- {
142
- "collection": "optional-collection",
143
- "prefix": "project/"
144
- }
145
- ```
146
-
147
- | Parameter | Description |
148
- | ------------ | --------------------------------------- |
149
- | `collection` | Filter by collection |
150
- | `prefix` | Filter by tag prefix (e.g., `project/`) |
151
-
152
- ### gno.tag
153
-
154
- Add or remove tag from document.
155
-
156
- ```json
157
- {
158
- "ref": "gno://work/readme.md",
159
- "tag": "project/api",
160
- "action": "add"
161
- }
46
+ gno mcp install -t claude-code -s user # User scope
47
+ gno mcp install -t claude-code -s project # Project scope
162
48
  ```
163
49
 
164
- | Parameter | Description |
165
- | --------- | ---------------------------------- |
166
- | `ref` | Document URI or docid (required) |
167
- | `tag` | Tag string (required) |
168
- | `action` | `add` or `remove` (default: `add`) |
50
+ ## Check Status
169
51
 
170
- ## Resources
171
-
172
- Documents accessible as MCP resources:
173
-
174
- ```
175
- gno://{collection}/{path}
176
- ```
177
-
178
- Examples:
179
-
180
- - `gno://work/contracts/nda.docx`
181
- - `gno://notes/2025/01/meeting.md`
182
-
183
- Returns Markdown content with line numbers.
184
-
185
- ## Response Format
186
-
187
- All tools return:
188
-
189
- ```json
190
- {
191
- "content": [
192
- { "type": "text", "text": "Human-readable summary" }
193
- ],
194
- "structuredContent": {
195
- "results": [...],
196
- "meta": { "query": "...", "mode": "hybrid" }
197
- }
198
- }
52
+ ```bash
53
+ gno mcp status
199
54
  ```
200
55
 
201
- ## Error Handling
56
+ ## Uninstall
202
57
 
203
- Errors return:
204
-
205
- ```json
206
- {
207
- "isError": true,
208
- "content": [
209
- { "type": "text", "text": "Error: Document not found" }
210
- ]
211
- }
58
+ ```bash
59
+ gno mcp uninstall
60
+ gno mcp uninstall -t claude-code
212
61
  ```
213
-
214
- ## Graceful Degradation
215
-
216
- `gno.query` degrades gracefully:
217
-
218
- - No vectors → BM25 only
219
- - No expansion model → skips expansion
220
- - No rerank model → skips reranking
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "0.10.4",
3
+ "version": "0.12.0",
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",
@@ -161,13 +161,12 @@ async function processBatches(ctx: BatchContext): Promise<BatchResult> {
161
161
  continue;
162
162
  }
163
163
 
164
- // Store vectors
164
+ // Store vectors (embeddedAt set by DB)
165
165
  const vectors: VectorRow[] = batch.map((b, idx) => ({
166
166
  mirrorHash: b.mirrorHash,
167
167
  seq: b.seq,
168
168
  model: ctx.modelUri,
169
169
  embedding: new Float32Array(embeddings[idx] as number[]),
170
- embeddedAt: new Date().toISOString(),
171
170
  }));
172
171
 
173
172
  const storeResult = await ctx.vectorIndex.upsertVectors(vectors);
@@ -373,6 +372,26 @@ export async function embed(options: EmbedOptions = {}): Promise<EmbedResult> {
373
372
  return { success: false, error: result.error };
374
373
  }
375
374
 
375
+ // Sync vec index if any vec0 writes failed (matches embedBacklog behavior)
376
+ if (vectorIndex.vecDirty) {
377
+ const syncResult = await vectorIndex.syncVecIndex();
378
+ if (syncResult.ok) {
379
+ const { added, removed } = syncResult.value;
380
+ if (added > 0 || removed > 0) {
381
+ if (!options.json) {
382
+ process.stdout.write(
383
+ `\n[vec] Synced index: +${added} -${removed}\n`
384
+ );
385
+ }
386
+ }
387
+ vectorIndex.vecDirty = false;
388
+ } else if (!options.json) {
389
+ process.stdout.write(
390
+ `\n[vec] Sync failed: ${syncResult.error.message}\n`
391
+ );
392
+ }
393
+ }
394
+
376
395
  return {
377
396
  success: true,
378
397
  embedded: result.embedded,