obedding 1.0.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.
- package/LICENSE +21 -0
- package/README.md +223 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +147 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +136 -0
- package/dist/index.js.map +1 -0
- package/dist/mlx.d.ts +39 -0
- package/dist/mlx.d.ts.map +1 -0
- package/dist/mlx.js +151 -0
- package/dist/mlx.js.map +1 -0
- package/dist/ollama.d.ts +30 -0
- package/dist/ollama.d.ts.map +1 -0
- package/dist/ollama.js +101 -0
- package/dist/ollama.js.map +1 -0
- package/dist/scanner.d.ts +32 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +104 -0
- package/dist/scanner.js.map +1 -0
- package/dist/search.d.ts +36 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +115 -0
- package/dist/search.js.map +1 -0
- package/dist/storage.d.ts +82 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +183 -0
- package/dist/storage.js.map +1 -0
- package/dist/utils.d.ts +25 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +69 -0
- package/dist/utils.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tuannvm
|
|
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,223 @@
|
|
|
1
|
+
# Obsidian Memory - Semantic Search with MLX Embeddings
|
|
2
|
+
|
|
3
|
+
Semantic search for your Obsidian vault using local MLX embeddings.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Obsidian Memory indexes your Obsidian notes and generates embeddings using the local MLX embedding server. This enables semantic search that understands the meaning of your queries, not just keyword matching.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Semantic Search**: Find notes by meaning, not just keywords
|
|
12
|
+
- **Fast & Local**: All processing happens on your machine using MLX
|
|
13
|
+
- **Incremental Indexing**: Only re-index changed files
|
|
14
|
+
- **YAML Frontmatter Support**: Extracts metadata from note properties
|
|
15
|
+
- **Privacy First**: No external API calls, everything runs locally
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### npm Package (Recommended)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g obedging
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### From Source
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/tuannvm/obedding.git
|
|
29
|
+
cd obedging
|
|
30
|
+
npm install
|
|
31
|
+
npm run build
|
|
32
|
+
npm link
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
1. **MLX Embedding Server** running at `http://localhost:28100` with model `mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ`
|
|
38
|
+
|
|
39
|
+
2. **Node.js** 18+ installed
|
|
40
|
+
|
|
41
|
+
3. **Obsidian vault** at:
|
|
42
|
+
```
|
|
43
|
+
~/.obsidian/Projects
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### Using the CLI
|
|
49
|
+
|
|
50
|
+
Index all notes in your Obsidian vault:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
obedding index --vault ~/.obsidian/Projects
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Incremental indexing (only new/modified files):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
obedding index --vault ~/.obsidian/Projects --incremental
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Semantic search:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
obedding search "caching strategies"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Get top 5 results:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
obedding search "database optimization" --top-k 5
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Output as JSON:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
obedding search "API design" --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Other Commands
|
|
81
|
+
|
|
82
|
+
Show statistics:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
obedding stats
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Clear all embeddings:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
obedding clear --force
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Options
|
|
95
|
+
|
|
96
|
+
### Index Command
|
|
97
|
+
|
|
98
|
+
| Option | Description | Default |
|
|
99
|
+
|--------|-------------|---------|
|
|
100
|
+
| `-v, --vault <path>` | Path to Obsidian vault | `~/.obsidian` |
|
|
101
|
+
| `-s, --storage <path>` | Path to storage file | `~/.claude/data/obsidian-embeddings.json` |
|
|
102
|
+
| `-i, --incremental` | Only index new/modified files | false |
|
|
103
|
+
| `-m, --model <name>` | MLX model to use | `mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ` |
|
|
104
|
+
|
|
105
|
+
### Search Command
|
|
106
|
+
|
|
107
|
+
| Option | Description | Default |
|
|
108
|
+
|--------|-------------|---------|
|
|
109
|
+
| `-k, --top-k <number>` | Number of results | 10 |
|
|
110
|
+
| `-s, --storage <path>` | Path to storage file | `~/.claude/data/obsidian-embeddings.json` |
|
|
111
|
+
| `-m, --model <name>` | MLX model to use | `mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ` |
|
|
112
|
+
| `--min-score <number>` | Minimum similarity (0-1) | 0 |
|
|
113
|
+
| `--json` | Output as JSON | false |
|
|
114
|
+
|
|
115
|
+
## Data Structure
|
|
116
|
+
|
|
117
|
+
Embeddings are stored in `~/.claude/data/obsidian-embeddings.json`:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"version": "1.0",
|
|
122
|
+
"model": "mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ",
|
|
123
|
+
"dimensions": 2048,
|
|
124
|
+
"indexed_at": "2026-03-08T10:00:00Z",
|
|
125
|
+
"notes": [
|
|
126
|
+
{
|
|
127
|
+
"path": "Projects/cli/my-repo/feature-x/note.md",
|
|
128
|
+
"vault_path": "/full/path/to/note.md",
|
|
129
|
+
"embedding": [0.0123, -0.0456, ...],
|
|
130
|
+
"metadata": {
|
|
131
|
+
"type": "cli",
|
|
132
|
+
"repo": "my-repo",
|
|
133
|
+
"context": "feature-x",
|
|
134
|
+
"tags": ["decision", "architecture"],
|
|
135
|
+
"title": "Note Title"
|
|
136
|
+
},
|
|
137
|
+
"excerpt": "First 200 chars...",
|
|
138
|
+
"indexed_at": "2026-03-08T10:00:00Z",
|
|
139
|
+
"hash": "sha256..."
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Performance
|
|
146
|
+
|
|
147
|
+
- **Embedding dimensions**: 2048 (truncated from variable MLX output)
|
|
148
|
+
- **Storage per note**: ~8KB
|
|
149
|
+
- **Index speed**: ~1-2 notes/sec (depends on hardware)
|
|
150
|
+
- **Search latency**: ~50-100ms for 100 notes
|
|
151
|
+
|
|
152
|
+
## Claude Code Integration
|
|
153
|
+
|
|
154
|
+
The `/obsidian-search` skill automatically triggers when you ask to search your notes:
|
|
155
|
+
|
|
156
|
+
- "Search obsidian for..."
|
|
157
|
+
- "Find notes about..."
|
|
158
|
+
- "What did we decide about..."
|
|
159
|
+
- "Show me notes related to..."
|
|
160
|
+
|
|
161
|
+
## YAML Frontmatter
|
|
162
|
+
|
|
163
|
+
Obsidian Memory extracts metadata from YAML frontmatter:
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
---
|
|
167
|
+
type: cli
|
|
168
|
+
repo: my-repo
|
|
169
|
+
context: feature-x
|
|
170
|
+
date: 2024-01-15
|
|
171
|
+
tags: [decision, architecture, cache]
|
|
172
|
+
title: Cache Strategy Decision
|
|
173
|
+
---
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Troubleshooting
|
|
177
|
+
|
|
178
|
+
### MLX server not running
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Check if MLX server is running
|
|
182
|
+
curl http://localhost:28100/
|
|
183
|
+
|
|
184
|
+
# Test embedding endpoint
|
|
185
|
+
curl -X POST http://localhost:28100/v1/embeddings \
|
|
186
|
+
-H "Content-Type: application/json" \
|
|
187
|
+
-d '{"input": ["test"], "model": "mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ"}'
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Vault path not found
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Specify custom vault path
|
|
194
|
+
node dist/cli.js index --vault /path/to/vault
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Search returns no results
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# Check if embeddings exist
|
|
201
|
+
node dist/cli.js stats
|
|
202
|
+
|
|
203
|
+
# Re-index if needed
|
|
204
|
+
node dist/cli.js index --vault ~/.obsidian/Projects
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Known Issues
|
|
208
|
+
|
|
209
|
+
- **Variable-length embeddings**: MLX server returns variable-length embeddings based on input content. The client truncates to 2048 dimensions as a workaround.
|
|
210
|
+
|
|
211
|
+
## Development
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Watch mode for development
|
|
215
|
+
npm run dev
|
|
216
|
+
|
|
217
|
+
# Build
|
|
218
|
+
npm run build
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { indexNotes } from './index.js';
|
|
5
|
+
import { searchNotes, formatSearchResults } from './search.js';
|
|
6
|
+
const DEFAULT_VAULT_PATH = path.resolve(process.env.HOME || '', 'Library/Mobile Documents/iCloud~md~obsidian/Documents/obsidian');
|
|
7
|
+
const DEFAULT_STORAGE_PATH = path.resolve(process.env.HOME || '', '.claude/data/obsidian-embeddings.json');
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name('obsidian-memory')
|
|
11
|
+
.description('Semantic search for Obsidian notes using MLX embeddings')
|
|
12
|
+
.version('1.0.0');
|
|
13
|
+
program
|
|
14
|
+
.command('index')
|
|
15
|
+
.description('Index Obsidian notes and generate embeddings')
|
|
16
|
+
.option('-v, --vault <path>', `Path to Obsidian vault`, DEFAULT_VAULT_PATH)
|
|
17
|
+
.option('-s, --storage <path>', `Path to storage file`, DEFAULT_STORAGE_PATH)
|
|
18
|
+
.option('-i, --incremental', 'Only index new or modified files')
|
|
19
|
+
.option('-m, --model <name>', 'MLX model to use', 'mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ')
|
|
20
|
+
.action(async (options) => {
|
|
21
|
+
try {
|
|
22
|
+
const vaultPath = path.resolve(options.vault);
|
|
23
|
+
const storagePath = path.resolve(options.storage);
|
|
24
|
+
console.log('🔍 Obsidian Memory - Index Notes\n');
|
|
25
|
+
const result = await indexNotes({
|
|
26
|
+
vaultPath,
|
|
27
|
+
storagePath,
|
|
28
|
+
incremental: options.incremental,
|
|
29
|
+
model: options.model
|
|
30
|
+
});
|
|
31
|
+
console.log('\n✓ Indexing complete!');
|
|
32
|
+
console.log(` Storage: ${storagePath}`);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error(`\n✗ Error: ${error.message}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
program
|
|
40
|
+
.command('search')
|
|
41
|
+
.description('Search notes using semantic similarity')
|
|
42
|
+
.argument('<query>', 'Search query')
|
|
43
|
+
.option('-v, --vault <path>', `Path to Obsidian vault (for reference)`, DEFAULT_VAULT_PATH)
|
|
44
|
+
.option('-s, --storage <path>', `Path to storage file`, DEFAULT_STORAGE_PATH)
|
|
45
|
+
.option('-k, --top-k <number>', 'Number of results to return', '10')
|
|
46
|
+
.option('-m, --model <name>', 'MLX model to use', 'mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ')
|
|
47
|
+
.option('--min-score <number>', 'Minimum similarity score (0-1)', '0')
|
|
48
|
+
.option('--json', 'Output results as JSON')
|
|
49
|
+
.action(async (query, options) => {
|
|
50
|
+
try {
|
|
51
|
+
const storagePath = path.resolve(options.storage);
|
|
52
|
+
const topK = parseInt(options.topK, 10);
|
|
53
|
+
const minScore = parseFloat(options.minScore);
|
|
54
|
+
// Validate numeric options
|
|
55
|
+
if (isNaN(topK) || topK < 1) {
|
|
56
|
+
console.error('✗ Error: --top-k must be a positive integer');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (isNaN(minScore) || minScore < 0 || minScore > 1) {
|
|
60
|
+
console.error('✗ Error: --min-score must be a number between 0 and 1');
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
console.log('🔍 Obsidian Memory - Search\n');
|
|
64
|
+
const response = await searchNotes({
|
|
65
|
+
query,
|
|
66
|
+
storagePath,
|
|
67
|
+
topK,
|
|
68
|
+
model: options.model,
|
|
69
|
+
minScore
|
|
70
|
+
});
|
|
71
|
+
if (options.json) {
|
|
72
|
+
console.log(JSON.stringify(response, null, 2));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(formatSearchResults(response));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`\n✗ Error: ${error.message}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
program
|
|
84
|
+
.command('stats')
|
|
85
|
+
.description('Show storage statistics')
|
|
86
|
+
.option('-s, --storage <path>', `Path to storage file`, DEFAULT_STORAGE_PATH)
|
|
87
|
+
.action(async (options) => {
|
|
88
|
+
try {
|
|
89
|
+
const { StorageManager } = await import('./storage.js');
|
|
90
|
+
const { formatFileSize } = await import('./utils.js');
|
|
91
|
+
const storagePath = path.resolve(options.storage);
|
|
92
|
+
const storage = new StorageManager(storagePath);
|
|
93
|
+
await storage.initialize();
|
|
94
|
+
const stats = storage.getStats();
|
|
95
|
+
console.log('🔍 Obsidian Memory - Statistics\n');
|
|
96
|
+
console.log(` Storage: ${storagePath}`);
|
|
97
|
+
console.log(` Notes: ${stats.noteCount}`);
|
|
98
|
+
console.log(` Model: ${stats.model}`);
|
|
99
|
+
console.log(` Dimensions: ${stats.dimensions}`);
|
|
100
|
+
console.log(` Storage size: ${formatFileSize(stats.totalSize)}`);
|
|
101
|
+
console.log(` Last indexed: ${stats.lastIndexed}`);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error(`\n✗ Error: ${error.message}`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
program
|
|
109
|
+
.command('clear')
|
|
110
|
+
.description('Clear all stored embeddings')
|
|
111
|
+
.option('-s, --storage <path>', `Path to storage file`, DEFAULT_STORAGE_PATH)
|
|
112
|
+
.option('-f, --force', 'Skip confirmation')
|
|
113
|
+
.action(async (options) => {
|
|
114
|
+
try {
|
|
115
|
+
const { StorageManager } = await import('./storage.js');
|
|
116
|
+
const storagePath = path.resolve(options.storage);
|
|
117
|
+
if (!options.force) {
|
|
118
|
+
const readline = await import('readline');
|
|
119
|
+
const rl = readline.createInterface({
|
|
120
|
+
input: process.stdin,
|
|
121
|
+
output: process.stdout
|
|
122
|
+
});
|
|
123
|
+
const answer = await new Promise((resolve) => {
|
|
124
|
+
rl.question(`Are you sure you want to clear all embeddings at ${storagePath}? (yes/no): `, resolve);
|
|
125
|
+
});
|
|
126
|
+
rl.close();
|
|
127
|
+
if (answer.toLowerCase() !== 'yes') {
|
|
128
|
+
console.log('Cancelled.');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const storage = new StorageManager(storagePath);
|
|
133
|
+
await storage.initialize();
|
|
134
|
+
await storage.clear();
|
|
135
|
+
console.log('✓ Cleared all embeddings');
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.error(`\n✗ Error: ${error.message}`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// Parse arguments
|
|
143
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
144
|
+
console.error(`Error: ${error.message}`);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface IndexOptions {
|
|
2
|
+
vaultPath: string;
|
|
3
|
+
storagePath: string;
|
|
4
|
+
incremental?: boolean;
|
|
5
|
+
model?: string;
|
|
6
|
+
onProgress?: (current: number, total: number, file: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface IndexResult {
|
|
9
|
+
totalNotes: number;
|
|
10
|
+
indexedNotes: number;
|
|
11
|
+
skippedNotes: number;
|
|
12
|
+
failedNotes: number;
|
|
13
|
+
duration: number;
|
|
14
|
+
model: string;
|
|
15
|
+
storageSize: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Index Obsidian notes and generate embeddings
|
|
19
|
+
*/
|
|
20
|
+
export declare function indexNotes(options: IndexOptions): Promise<IndexResult>;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrE;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiK5E"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { scanObsidianVault, extractMetadata, getNoteHash } from './scanner.js';
|
|
2
|
+
import { generateEmbeddings, checkMLXConnection, getModelInfo } from './mlx.js';
|
|
3
|
+
import { StorageManager } from './storage.js';
|
|
4
|
+
import { truncateToTokens, generateExcerpt, formatDuration, formatFileSize } from './utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Index Obsidian notes and generate embeddings
|
|
7
|
+
*/
|
|
8
|
+
export async function indexNotes(options) {
|
|
9
|
+
const startTime = Date.now();
|
|
10
|
+
const { vaultPath, storagePath, incremental = false, model = 'mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ' } = options;
|
|
11
|
+
// Check MLX connection
|
|
12
|
+
console.log('Checking MLX embedding server connection...');
|
|
13
|
+
const isConnected = await checkMLXConnection();
|
|
14
|
+
if (!isConnected) {
|
|
15
|
+
throw new Error('Cannot connect to MLX embedding server. Make sure it is running at http://localhost:28100');
|
|
16
|
+
}
|
|
17
|
+
console.log('✓ MLX embedding server is running');
|
|
18
|
+
// Get model info
|
|
19
|
+
const modelInfo = await getModelInfo(model);
|
|
20
|
+
if (modelInfo) {
|
|
21
|
+
console.log(`✓ Using model: ${modelInfo.name} (${modelInfo.dimensions} dimensions)`);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log(`✓ Using model: ${model}`);
|
|
25
|
+
}
|
|
26
|
+
// Initialize storage
|
|
27
|
+
const storage = new StorageManager(storagePath);
|
|
28
|
+
await storage.initialize();
|
|
29
|
+
// Scan vault for notes
|
|
30
|
+
console.log(`\nScanning vault: ${vaultPath}`);
|
|
31
|
+
const notes = await scanObsidianVault(vaultPath);
|
|
32
|
+
console.log(`Found ${notes.length} markdown files`);
|
|
33
|
+
// Filter notes for incremental indexing
|
|
34
|
+
let notesToIndex = notes;
|
|
35
|
+
if (incremental) {
|
|
36
|
+
console.log('\nIncremental mode: checking for modified files...');
|
|
37
|
+
notesToIndex = notes.filter(note => {
|
|
38
|
+
const contentHash = getNoteHash(note);
|
|
39
|
+
const needsUpdate = storage.needsUpdate(note.relativePath, contentHash);
|
|
40
|
+
if (!needsUpdate) {
|
|
41
|
+
options.onProgress?.(0, notes.length, note.relativePath);
|
|
42
|
+
}
|
|
43
|
+
return needsUpdate;
|
|
44
|
+
});
|
|
45
|
+
console.log(`Will index ${notesToIndex.length} modified/new files`);
|
|
46
|
+
}
|
|
47
|
+
// Prepare texts for embedding
|
|
48
|
+
const textsToEmbed = [];
|
|
49
|
+
const noteMapping = [];
|
|
50
|
+
for (const note of notesToIndex) {
|
|
51
|
+
// Use content without frontmatter for embedding
|
|
52
|
+
const contentForEmbedding = note.frontmatter.content;
|
|
53
|
+
// Truncate to avoid token limits
|
|
54
|
+
const truncated = truncateToTokens(contentForEmbedding, 8000);
|
|
55
|
+
textsToEmbed.push(truncated);
|
|
56
|
+
const hash = getNoteHash(note);
|
|
57
|
+
noteMapping.push({ note, hash });
|
|
58
|
+
}
|
|
59
|
+
if (textsToEmbed.length === 0) {
|
|
60
|
+
console.log('\nNo notes to index (all up to date)');
|
|
61
|
+
const stats = storage.getStats();
|
|
62
|
+
return {
|
|
63
|
+
totalNotes: notes.length,
|
|
64
|
+
indexedNotes: 0,
|
|
65
|
+
skippedNotes: notes.length,
|
|
66
|
+
failedNotes: 0,
|
|
67
|
+
duration: (Date.now() - startTime) / 1000,
|
|
68
|
+
model,
|
|
69
|
+
storageSize: stats.totalSize
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Generate embeddings
|
|
73
|
+
console.log(`\nGenerating embeddings for ${textsToEmbed.length} notes...`);
|
|
74
|
+
const embeddings = await generateEmbeddings(textsToEmbed, model, (current, total) => {
|
|
75
|
+
const percent = ((current / total) * 100).toFixed(1);
|
|
76
|
+
const note = noteMapping[current - 1]?.note.relativePath || 'unknown';
|
|
77
|
+
console.log(` [${percent}%] ${note}`);
|
|
78
|
+
options.onProgress?.(current, total, note);
|
|
79
|
+
});
|
|
80
|
+
// Store embeddings
|
|
81
|
+
console.log('\nStoring embeddings...');
|
|
82
|
+
let indexedCount = 0;
|
|
83
|
+
let failedCount = 0;
|
|
84
|
+
for (let i = 0; i < embeddings.length; i++) {
|
|
85
|
+
try {
|
|
86
|
+
const { note, hash } = noteMapping[i];
|
|
87
|
+
const embedding = embeddings[i];
|
|
88
|
+
const metadata = extractMetadata(note, vaultPath);
|
|
89
|
+
const excerpt = generateExcerpt(note.content);
|
|
90
|
+
// Validate embedding
|
|
91
|
+
if (!embedding || embedding.length === 0) {
|
|
92
|
+
console.warn(` Warning: Empty embedding for ${note.relativePath}, skipping`);
|
|
93
|
+
failedCount++;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
await storage.upsertNote({
|
|
97
|
+
path: note.relativePath,
|
|
98
|
+
vault_path: note.fullPath,
|
|
99
|
+
embedding,
|
|
100
|
+
metadata,
|
|
101
|
+
excerpt,
|
|
102
|
+
indexed_at: new Date().toISOString(),
|
|
103
|
+
hash
|
|
104
|
+
});
|
|
105
|
+
indexedCount++;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error(` Failed to store note ${i + 1}: ${error.message}`);
|
|
109
|
+
failedCount++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Save to disk
|
|
113
|
+
await storage.save();
|
|
114
|
+
// Save to disk
|
|
115
|
+
await storage.save();
|
|
116
|
+
// Save to disk
|
|
117
|
+
await storage.save();
|
|
118
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
119
|
+
const stats = storage.getStats();
|
|
120
|
+
console.log(`\n✓ Indexed ${indexedCount} notes in ${formatDuration(duration)}`);
|
|
121
|
+
console.log(` Skipped: ${notes.length - indexedCount} notes`);
|
|
122
|
+
if (failedCount > 0) {
|
|
123
|
+
console.log(` Failed: ${failedCount} notes`);
|
|
124
|
+
}
|
|
125
|
+
console.log(` Storage size: ${formatFileSize(stats.totalSize)}`);
|
|
126
|
+
return {
|
|
127
|
+
totalNotes: notes.length,
|
|
128
|
+
indexedNotes: indexedCount,
|
|
129
|
+
skippedNotes: notes.length - indexedCount,
|
|
130
|
+
failedNotes: failedCount,
|
|
131
|
+
duration,
|
|
132
|
+
model,
|
|
133
|
+
storageSize: stats.totalSize
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAY,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqB/F;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAqB;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,GAAG,KAAK,EAAE,KAAK,GAAG,6CAA6C,EAAE,GAAG,OAAO,CAAC;IAEvH,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAE/C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;IAC/G,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAEjD,iBAAiB;IACjB,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,cAAc,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,qBAAqB;IACrB,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAE3B,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,qBAAqB,SAAS,EAAE,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAEpD,wCAAwC;IACxC,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QAElE,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACjC,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YAExE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3D,CAAC;YAED,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,cAAc,YAAY,CAAC,MAAM,qBAAqB,CAAC,CAAC;IACtE,CAAC;IAED,8BAA8B;IAC9B,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,WAAW,GAA4C,EAAE,CAAC;IAEhE,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,gDAAgD;QAChD,MAAM,mBAAmB,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;QAErD,iCAAiC;QACjC,MAAM,SAAS,GAAG,gBAAgB,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;QAC9D,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE7B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QAEpD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QACjC,OAAO;YACL,UAAU,EAAE,KAAK,CAAC,MAAM;YACxB,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,KAAK,CAAC,MAAM;YAC1B,WAAW,EAAE,CAAC;YACd,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI;YACzC,KAAK;YACL,WAAW,EAAE,KAAK,CAAC,SAAS;SAC7B,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,OAAO,CAAC,GAAG,CAAC,+BAA+B,YAAY,CAAC,MAAM,WAAW,CAAC,CAAC;IAE3E,MAAM,UAAU,GAAG,MAAM,kBAAkB,CACzC,YAAY,EACZ,KAAK,EACL,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACjB,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE9C,qBAAqB;YACrB,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzC,OAAO,CAAC,IAAI,CAAC,kCAAkC,IAAI,CAAC,YAAY,YAAY,CAAC,CAAC;gBAC9E,WAAW,EAAE,CAAC;gBACd,SAAS;YACX,CAAC;YAED,MAAM,OAAO,CAAC,UAAU,CAAC;gBACvB,IAAI,EAAE,IAAI,CAAC,YAAY;gBACvB,UAAU,EAAE,IAAI,CAAC,QAAQ;gBACzB,SAAS;gBACT,QAAQ;gBACR,OAAO;gBACP,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,IAAI;aACL,CAAC,CAAC;YAEH,YAAY,EAAE,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,GAAG,CAAC,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9E,WAAW,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,eAAe;IACf,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAErB,eAAe;IACf,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAErB,eAAe;IACf,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAErB,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAEjC,OAAO,CAAC,GAAG,CAAC,eAAe,YAAY,aAAa,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,MAAM,GAAG,YAAY,QAAQ,CAAC,CAAC;IAC/D,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,aAAa,WAAW,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAElE,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,YAAY,EAAE,YAAY;QAC1B,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,YAAY;QACzC,WAAW,EAAE,WAAW;QACxB,QAAQ;QACR,KAAK;QACL,WAAW,EAAE,KAAK,CAAC,SAAS;KAC7B,CAAC;AACJ,CAAC"}
|
package/dist/mlx.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MLX Embedding API client for generating embeddings
|
|
3
|
+
* Compatible with OpenAI-style /v1/embeddings endpoint
|
|
4
|
+
*/
|
|
5
|
+
export interface EmbeddingResponse {
|
|
6
|
+
data: Array<{
|
|
7
|
+
embedding: number[];
|
|
8
|
+
index: number;
|
|
9
|
+
}>;
|
|
10
|
+
model: string;
|
|
11
|
+
usage?: {
|
|
12
|
+
prompt_tokens: number;
|
|
13
|
+
total_tokens: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface MLXError {
|
|
17
|
+
error: string;
|
|
18
|
+
message?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if MLX embedding server is running
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkMLXConnection(): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Generate embedding for text using MLX server
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateEmbedding(text: string, model?: string): Promise<number[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Batch generate embeddings for multiple texts
|
|
30
|
+
*/
|
|
31
|
+
export declare function generateEmbeddings(texts: string[], model?: string, onProgress?: (current: number, total: number) => void): Promise<number[][]>;
|
|
32
|
+
/**
|
|
33
|
+
* Get model information (basic, MLX doesn't expose model info like Ollama)
|
|
34
|
+
*/
|
|
35
|
+
export declare function getModelInfo(model?: string): Promise<{
|
|
36
|
+
name: string;
|
|
37
|
+
dimensions: number;
|
|
38
|
+
} | null>;
|
|
39
|
+
//# sourceMappingURL=mlx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mlx.d.ts","sourceRoot":"","sources":["../src/mlx.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,CAAC;QACV,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAgB3D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,MAAsB,GAC5B,OAAO,CAAC,MAAM,EAAE,CAAC,CAsDnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,GAAE,MAAsB,EAC7B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACpD,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAsDrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,KAAK,GAAE,MAAsB,GAAG,OAAO,CAAC;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAAC,CAWR"}
|