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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export interface NoteEmbedding {
|
|
2
|
+
path: string;
|
|
3
|
+
vault_path: string;
|
|
4
|
+
embedding: number[];
|
|
5
|
+
metadata: {
|
|
6
|
+
type?: string;
|
|
7
|
+
repo?: string;
|
|
8
|
+
context?: string;
|
|
9
|
+
modified?: string;
|
|
10
|
+
tags?: string[];
|
|
11
|
+
title?: string;
|
|
12
|
+
};
|
|
13
|
+
excerpt: string;
|
|
14
|
+
indexed_at: string;
|
|
15
|
+
hash: string;
|
|
16
|
+
}
|
|
17
|
+
export interface EmbeddingStore {
|
|
18
|
+
version: string;
|
|
19
|
+
model: string;
|
|
20
|
+
dimensions: number;
|
|
21
|
+
indexed_at: string;
|
|
22
|
+
notes: NoteEmbedding[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Storage manager for embeddings
|
|
26
|
+
*/
|
|
27
|
+
export declare class StorageManager {
|
|
28
|
+
private storagePath;
|
|
29
|
+
private data;
|
|
30
|
+
constructor(storagePath: string);
|
|
31
|
+
/**
|
|
32
|
+
* Initialize storage (create directory and load existing data)
|
|
33
|
+
*/
|
|
34
|
+
initialize(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Load existing embeddings from disk
|
|
37
|
+
*/
|
|
38
|
+
load(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Save embeddings to disk
|
|
41
|
+
*/
|
|
42
|
+
save(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Get all stored notes
|
|
45
|
+
*/
|
|
46
|
+
getNotes(): NoteEmbedding[];
|
|
47
|
+
/**
|
|
48
|
+
* Add or update a note embedding
|
|
49
|
+
*/
|
|
50
|
+
upsertNote(note: NoteEmbedding): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Remove a note by path
|
|
53
|
+
*/
|
|
54
|
+
removeNote(notePath: string): Promise<boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* Check if a note needs updating based on content hash
|
|
57
|
+
*/
|
|
58
|
+
needsUpdate(notePath: string, contentHash: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Get storage statistics
|
|
61
|
+
*/
|
|
62
|
+
getStats(): {
|
|
63
|
+
noteCount: number;
|
|
64
|
+
totalSize: number;
|
|
65
|
+
model: string;
|
|
66
|
+
dimensions: number;
|
|
67
|
+
lastIndexed: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Clear all stored notes
|
|
71
|
+
*/
|
|
72
|
+
clear(): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Create empty store structure
|
|
75
|
+
*/
|
|
76
|
+
private createEmptyStore;
|
|
77
|
+
/**
|
|
78
|
+
* Validate loaded data
|
|
79
|
+
*/
|
|
80
|
+
private validate;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAMD;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,IAAI,CAA+B;gBAE/B,WAAW,EAAE,MAAM;IAI/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B;;OAEG;IACH,QAAQ,IAAI,aAAa,EAAE;IAO3B;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBpD;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpD;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAc3D;;OAEG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB;IAwBD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,QAAQ;CAoBjB"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as fsSync from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
const STORAGE_VERSION = '1.0';
|
|
5
|
+
const DEFAULT_MODEL = 'mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ';
|
|
6
|
+
const DEFAULT_DIMENSIONS = 2048;
|
|
7
|
+
/**
|
|
8
|
+
* Storage manager for embeddings
|
|
9
|
+
*/
|
|
10
|
+
export class StorageManager {
|
|
11
|
+
storagePath;
|
|
12
|
+
data = null;
|
|
13
|
+
constructor(storagePath) {
|
|
14
|
+
this.storagePath = path.resolve(storagePath);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initialize storage (create directory and load existing data)
|
|
18
|
+
*/
|
|
19
|
+
async initialize() {
|
|
20
|
+
const dir = path.dirname(this.storagePath);
|
|
21
|
+
try {
|
|
22
|
+
await fs.mkdir(dir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error(`Failed to create storage directory: ${error.message}`);
|
|
26
|
+
}
|
|
27
|
+
await this.load();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Load existing embeddings from disk
|
|
31
|
+
*/
|
|
32
|
+
async load() {
|
|
33
|
+
try {
|
|
34
|
+
const content = await fs.readFile(this.storagePath, 'utf-8');
|
|
35
|
+
this.data = JSON.parse(content);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error.code === 'ENOENT') {
|
|
39
|
+
// File doesn't exist, create new store
|
|
40
|
+
this.data = this.createEmptyStore();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new Error(`Failed to load storage: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Validate data structure
|
|
47
|
+
this.validate();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Save embeddings to disk
|
|
51
|
+
*/
|
|
52
|
+
async save() {
|
|
53
|
+
if (!this.data) {
|
|
54
|
+
throw new Error('No data to save');
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const json = JSON.stringify(this.data);
|
|
58
|
+
fsSync.writeFileSync(this.storagePath, json, 'utf-8');
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(`Failed to save storage: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get all stored notes
|
|
66
|
+
*/
|
|
67
|
+
getNotes() {
|
|
68
|
+
if (!this.data) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
return this.data.notes;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Add or update a note embedding
|
|
75
|
+
*/
|
|
76
|
+
async upsertNote(note) {
|
|
77
|
+
if (!this.data) {
|
|
78
|
+
await this.initialize();
|
|
79
|
+
}
|
|
80
|
+
const existingIndex = this.data.notes.findIndex(n => n.path === note.path);
|
|
81
|
+
if (existingIndex >= 0) {
|
|
82
|
+
// Update existing note
|
|
83
|
+
this.data.notes[existingIndex] = note;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Add new note
|
|
87
|
+
this.data.notes.push(note);
|
|
88
|
+
}
|
|
89
|
+
this.data.indexed_at = new Date().toISOString();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Remove a note by path
|
|
93
|
+
*/
|
|
94
|
+
async removeNote(notePath) {
|
|
95
|
+
if (!this.data) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const initialLength = this.data.notes.length;
|
|
99
|
+
this.data.notes = this.data.notes.filter(n => n.path !== notePath);
|
|
100
|
+
if (this.data.notes.length < initialLength) {
|
|
101
|
+
this.data.indexed_at = new Date().toISOString();
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Check if a note needs updating based on content hash
|
|
108
|
+
*/
|
|
109
|
+
needsUpdate(notePath, contentHash) {
|
|
110
|
+
if (!this.data) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
const existing = this.data.notes.find(n => n.path === notePath);
|
|
114
|
+
if (!existing) {
|
|
115
|
+
return true; // Note doesn't exist
|
|
116
|
+
}
|
|
117
|
+
return existing.hash !== contentHash; // Content changed
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get storage statistics
|
|
121
|
+
*/
|
|
122
|
+
getStats() {
|
|
123
|
+
if (!this.data) {
|
|
124
|
+
return {
|
|
125
|
+
noteCount: 0,
|
|
126
|
+
totalSize: 0,
|
|
127
|
+
model: DEFAULT_MODEL,
|
|
128
|
+
dimensions: DEFAULT_DIMENSIONS,
|
|
129
|
+
lastIndexed: 'never'
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const totalSize = this.data.notes.reduce((sum, note) => {
|
|
133
|
+
return sum + note.embedding.length * 4; // 4 bytes per float32
|
|
134
|
+
}, 0);
|
|
135
|
+
return {
|
|
136
|
+
noteCount: this.data.notes.length,
|
|
137
|
+
totalSize,
|
|
138
|
+
model: this.data.model,
|
|
139
|
+
dimensions: this.data.dimensions,
|
|
140
|
+
lastIndexed: this.data.indexed_at
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Clear all stored notes
|
|
145
|
+
*/
|
|
146
|
+
async clear() {
|
|
147
|
+
this.data = this.createEmptyStore();
|
|
148
|
+
await this.save();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create empty store structure
|
|
152
|
+
*/
|
|
153
|
+
createEmptyStore() {
|
|
154
|
+
return {
|
|
155
|
+
version: STORAGE_VERSION,
|
|
156
|
+
model: DEFAULT_MODEL,
|
|
157
|
+
dimensions: DEFAULT_DIMENSIONS,
|
|
158
|
+
indexed_at: new Date().toISOString(),
|
|
159
|
+
notes: []
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Validate loaded data
|
|
164
|
+
*/
|
|
165
|
+
validate() {
|
|
166
|
+
if (!this.data) {
|
|
167
|
+
throw new Error('No data loaded');
|
|
168
|
+
}
|
|
169
|
+
if (this.data.version !== STORAGE_VERSION) {
|
|
170
|
+
console.warn(`Warning: Storage version mismatch. Expected ${STORAGE_VERSION}, got ${this.data.version}`);
|
|
171
|
+
}
|
|
172
|
+
if (!this.data.notes || !Array.isArray(this.data.notes)) {
|
|
173
|
+
throw new Error('Invalid storage structure: missing notes array');
|
|
174
|
+
}
|
|
175
|
+
// Validate each note
|
|
176
|
+
for (const note of this.data.notes) {
|
|
177
|
+
if (!note.path || !note.embedding || !Array.isArray(note.embedding)) {
|
|
178
|
+
throw new Error('Invalid note structure in storage');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate cosine similarity between two vectors
|
|
3
|
+
*/
|
|
4
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
5
|
+
/**
|
|
6
|
+
* Generate SHA256 hash of content
|
|
7
|
+
*/
|
|
8
|
+
export declare function hashContent(content: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Truncate text to approximately maxTokens (rough estimate)
|
|
11
|
+
*/
|
|
12
|
+
export declare function truncateToTokens(text: string, maxTokens?: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Generate excerpt from content
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateExcerpt(content: string, maxLength?: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format file size for display
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatFileSize(bytes: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Format duration in seconds
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatDuration(seconds: number): string;
|
|
25
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAcjE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAa,GAAG,MAAM,CAO/E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAYhF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKtD"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Calculate cosine similarity between two vectors
|
|
4
|
+
*/
|
|
5
|
+
export function cosineSimilarity(a, b) {
|
|
6
|
+
if (a.length !== b.length) {
|
|
7
|
+
throw new Error('Vectors must have the same length');
|
|
8
|
+
}
|
|
9
|
+
const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
|
|
10
|
+
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
|
|
11
|
+
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
|
|
12
|
+
if (magnitudeA === 0 || magnitudeB === 0) {
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
return dotProduct / (magnitudeA * magnitudeB);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generate SHA256 hash of content
|
|
19
|
+
*/
|
|
20
|
+
export function hashContent(content) {
|
|
21
|
+
return createHash('sha256').update(content).digest('hex');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Truncate text to approximately maxTokens (rough estimate)
|
|
25
|
+
*/
|
|
26
|
+
export function truncateToTokens(text, maxTokens = 8000) {
|
|
27
|
+
// Rough estimate: 1 token ≈ 4 characters
|
|
28
|
+
const maxChars = maxTokens * 4;
|
|
29
|
+
if (text.length <= maxChars) {
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
return text.substring(0, maxChars);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate excerpt from content
|
|
36
|
+
*/
|
|
37
|
+
export function generateExcerpt(content, maxLength = 200) {
|
|
38
|
+
// Remove YAML frontmatter
|
|
39
|
+
const withoutFrontmatter = content.replace(/^---\n.*?\n---\n/s, '');
|
|
40
|
+
// Get first paragraph or section
|
|
41
|
+
const firstParagraph = withoutFrontmatter.split('\n\n')[0].replace(/\n/g, ' ').trim();
|
|
42
|
+
if (firstParagraph.length <= maxLength) {
|
|
43
|
+
return firstParagraph;
|
|
44
|
+
}
|
|
45
|
+
return firstParagraph.substring(0, maxLength) + '...';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Format file size for display
|
|
49
|
+
*/
|
|
50
|
+
export function formatFileSize(bytes) {
|
|
51
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
52
|
+
let size = bytes;
|
|
53
|
+
let unitIndex = 0;
|
|
54
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
55
|
+
size /= 1024;
|
|
56
|
+
unitIndex++;
|
|
57
|
+
}
|
|
58
|
+
return `${size.toFixed(2)} ${units[unitIndex]}`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Format duration in seconds
|
|
62
|
+
*/
|
|
63
|
+
export function formatDuration(seconds) {
|
|
64
|
+
if (seconds < 1) {
|
|
65
|
+
return `${(seconds * 1000).toFixed(0)}ms`;
|
|
66
|
+
}
|
|
67
|
+
return `${seconds.toFixed(2)}s`;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "obedding",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Semantic search for Obsidian notes using local MLX embeddings",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"obedding": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"prepublishOnly": "npm run build",
|
|
14
|
+
"start": "node dist/cli.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"obsidian",
|
|
18
|
+
"semantic-search",
|
|
19
|
+
"embeddings",
|
|
20
|
+
"mlx",
|
|
21
|
+
"local",
|
|
22
|
+
"privacy",
|
|
23
|
+
"note-taking",
|
|
24
|
+
"knowledge-base",
|
|
25
|
+
"vector-search"
|
|
26
|
+
],
|
|
27
|
+
"author": "tuannvm <tuannvm@users.noreply.github.com>",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/tuannvm/obedding.git"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/tuannvm/obedding#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/tuannvm/obedding/issues"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"commander": "^12.0.0",
|
|
47
|
+
"chalk": "^5.3.0",
|
|
48
|
+
"gray-matter": "^4.0.3",
|
|
49
|
+
"glob": "^10.3.10",
|
|
50
|
+
"node-fetch": "^3.3.2"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/glob": "^8.1.0",
|
|
54
|
+
"@types/node": "^20.11.0",
|
|
55
|
+
"typescript": "^5.3.3"
|
|
56
|
+
}
|
|
57
|
+
}
|