@tobilu/qmd 1.1.5 → 1.1.6
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/CHANGELOG.md +15 -0
- package/README.md +75 -0
- package/dist/collections.d.ts +16 -2
- package/dist/collections.js +57 -8
- package/dist/index.d.ts +129 -0
- package/dist/index.js +95 -0
- package/package.json +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.1.6] - 2026-03-09
|
|
6
|
+
|
|
7
|
+
QMD can now be used as a library. `import { createStore } from '@tobilu/qmd'`
|
|
8
|
+
gives you the full search and indexing API — hybrid query, BM25, structured
|
|
9
|
+
search, collection/context management — without shelling out to the CLI.
|
|
10
|
+
|
|
11
|
+
### Changes
|
|
12
|
+
|
|
13
|
+
- **SDK / library mode**: `createStore({ dbPath, config })` returns a
|
|
14
|
+
`QMDStore` with `query()`, `search()`, `structuredSearch()`, `get()`,
|
|
15
|
+
`multiGet()`, and collection/context management methods. Supports inline
|
|
16
|
+
config (no files needed) or a YAML config path.
|
|
17
|
+
- **Package exports**: `package.json` now declares `main`, `types`, and
|
|
18
|
+
`exports` so bundlers and TypeScript resolve `@tobilu/qmd` correctly.
|
|
19
|
+
|
|
5
20
|
## [1.1.5] - 2026-03-07
|
|
6
21
|
|
|
7
22
|
Ambiguous queries like "performance" now produce dramatically better results
|
package/README.md
CHANGED
|
@@ -137,6 +137,81 @@ LLM models stay loaded in VRAM across requests. Embedding/reranking contexts are
|
|
|
137
137
|
|
|
138
138
|
Point any MCP client at `http://localhost:8181/mcp` to connect.
|
|
139
139
|
|
|
140
|
+
### SDK / Library Usage
|
|
141
|
+
|
|
142
|
+
Use QMD as a library in your own Node.js or Bun applications:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
npm install @tobilu/qmd
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { createStore } from '@tobilu/qmd'
|
|
150
|
+
|
|
151
|
+
// Create a store with inline config (no config file needed)
|
|
152
|
+
const store = createStore({
|
|
153
|
+
dbPath: './my-index.sqlite',
|
|
154
|
+
config: {
|
|
155
|
+
collections: {
|
|
156
|
+
docs: { path: '/path/to/docs', pattern: '**/*.md' },
|
|
157
|
+
notes: { path: '/path/to/notes', pattern: '**/*.md' },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
// Or reference a YAML config file
|
|
163
|
+
const store2 = createStore({
|
|
164
|
+
dbPath: './my-index.sqlite',
|
|
165
|
+
configPath: './qmd.yml',
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Search & retrieval:**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// Hybrid search: BM25 + vector + query expansion + LLM reranking (best quality)
|
|
173
|
+
const results = await store.query("authentication flow", { limit: 5 })
|
|
174
|
+
|
|
175
|
+
// Fast BM25 keyword search (no LLM, synchronous)
|
|
176
|
+
const keywords = store.search("auth middleware", { limit: 10 })
|
|
177
|
+
|
|
178
|
+
// Structured search with pre-expanded queries (for LLM callers)
|
|
179
|
+
const structured = await store.structuredSearch([
|
|
180
|
+
{ type: 'lex', query: 'authentication' },
|
|
181
|
+
{ type: 'vec', query: 'how users log in' },
|
|
182
|
+
], { limit: 5 })
|
|
183
|
+
|
|
184
|
+
// Get a document by path or docid
|
|
185
|
+
const doc = store.get("docs/readme.md")
|
|
186
|
+
const byId = store.get("#abc123")
|
|
187
|
+
|
|
188
|
+
// Get multiple documents by glob
|
|
189
|
+
const { docs, errors } = store.multiGet("docs/**/*.md")
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Collection & context management:**
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// Add a collection
|
|
196
|
+
store.addCollection("myapp", { path: "/src/myapp", pattern: "**/*.ts" })
|
|
197
|
+
|
|
198
|
+
// Add context (improves search relevance)
|
|
199
|
+
store.addContext("myapp", "/auth", "Authentication and session management")
|
|
200
|
+
store.setGlobalContext("Internal engineering documentation")
|
|
201
|
+
|
|
202
|
+
// List everything
|
|
203
|
+
store.listCollections()
|
|
204
|
+
store.listContexts()
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Lifecycle:**
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
store.close()
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The SDK requires explicit `dbPath` and config — no defaults are assumed. This makes it safe to embed in any application without side effects.
|
|
214
|
+
|
|
140
215
|
## Architecture
|
|
141
216
|
|
|
142
217
|
```
|
package/dist/collections.d.ts
CHANGED
|
@@ -34,18 +34,32 @@ export interface CollectionConfig {
|
|
|
34
34
|
export interface NamedCollection extends Collection {
|
|
35
35
|
name: string;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Set the config source for SDK mode.
|
|
39
|
+
* - File path: load/save from a specific YAML file
|
|
40
|
+
* - Inline config: use an in-memory CollectionConfig (saveConfig updates in place, no file I/O)
|
|
41
|
+
* - undefined: reset to default file-based config
|
|
42
|
+
*/
|
|
43
|
+
export declare function setConfigSource(source?: {
|
|
44
|
+
configPath?: string;
|
|
45
|
+
config?: CollectionConfig;
|
|
46
|
+
}): void;
|
|
37
47
|
/**
|
|
38
48
|
* Set the current index name for config file lookup
|
|
39
49
|
* Config file will be ~/.config/qmd/{indexName}.yml
|
|
40
50
|
*/
|
|
41
51
|
export declare function setConfigIndexName(name: string): void;
|
|
42
52
|
/**
|
|
43
|
-
* Load configuration from
|
|
53
|
+
* Load configuration from the configured source.
|
|
54
|
+
* - Inline config: returns the in-memory object directly
|
|
55
|
+
* - File-based: reads from YAML file (default ~/.config/qmd/index.yml)
|
|
44
56
|
* Returns empty config if file doesn't exist
|
|
45
57
|
*/
|
|
46
58
|
export declare function loadConfig(): CollectionConfig;
|
|
47
59
|
/**
|
|
48
|
-
* Save configuration to
|
|
60
|
+
* Save configuration to the configured source.
|
|
61
|
+
* - Inline config: updates the in-memory object (no file I/O)
|
|
62
|
+
* - File-based: writes to YAML file (default ~/.config/qmd/index.yml)
|
|
49
63
|
*/
|
|
50
64
|
export declare function saveConfig(config: CollectionConfig): void;
|
|
51
65
|
/**
|
package/dist/collections.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Collections define which directories to index and their associated contexts.
|
|
6
6
|
*/
|
|
7
7
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
8
|
-
import { join } from "path";
|
|
8
|
+
import { join, dirname } from "path";
|
|
9
9
|
import { homedir } from "os";
|
|
10
10
|
import YAML from "yaml";
|
|
11
11
|
// ============================================================================
|
|
@@ -13,6 +13,33 @@ import YAML from "yaml";
|
|
|
13
13
|
// ============================================================================
|
|
14
14
|
// Current index name (default: "index")
|
|
15
15
|
let currentIndexName = "index";
|
|
16
|
+
// SDK mode: optional in-memory config or custom config path
|
|
17
|
+
let configSource = { type: 'file' };
|
|
18
|
+
/**
|
|
19
|
+
* Set the config source for SDK mode.
|
|
20
|
+
* - File path: load/save from a specific YAML file
|
|
21
|
+
* - Inline config: use an in-memory CollectionConfig (saveConfig updates in place, no file I/O)
|
|
22
|
+
* - undefined: reset to default file-based config
|
|
23
|
+
*/
|
|
24
|
+
export function setConfigSource(source) {
|
|
25
|
+
if (!source) {
|
|
26
|
+
configSource = { type: 'file' };
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (source.config) {
|
|
30
|
+
// Ensure collections object exists
|
|
31
|
+
if (!source.config.collections) {
|
|
32
|
+
source.config.collections = {};
|
|
33
|
+
}
|
|
34
|
+
configSource = { type: 'inline', config: source.config };
|
|
35
|
+
}
|
|
36
|
+
else if (source.configPath) {
|
|
37
|
+
configSource = { type: 'file', path: source.configPath };
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
configSource = { type: 'file' };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
16
43
|
/**
|
|
17
44
|
* Set the current index name for config file lookup
|
|
18
45
|
* Config file will be ~/.config/qmd/{indexName}.yml
|
|
@@ -57,11 +84,18 @@ function ensureConfigDir() {
|
|
|
57
84
|
// Core functions
|
|
58
85
|
// ============================================================================
|
|
59
86
|
/**
|
|
60
|
-
* Load configuration from
|
|
87
|
+
* Load configuration from the configured source.
|
|
88
|
+
* - Inline config: returns the in-memory object directly
|
|
89
|
+
* - File-based: reads from YAML file (default ~/.config/qmd/index.yml)
|
|
61
90
|
* Returns empty config if file doesn't exist
|
|
62
91
|
*/
|
|
63
92
|
export function loadConfig() {
|
|
64
|
-
|
|
93
|
+
// SDK inline config mode
|
|
94
|
+
if (configSource.type === 'inline') {
|
|
95
|
+
return configSource.config;
|
|
96
|
+
}
|
|
97
|
+
// File-based config (SDK custom path or default)
|
|
98
|
+
const configPath = configSource.path || getConfigFilePath();
|
|
65
99
|
if (!existsSync(configPath)) {
|
|
66
100
|
return { collections: {} };
|
|
67
101
|
}
|
|
@@ -79,11 +113,21 @@ export function loadConfig() {
|
|
|
79
113
|
}
|
|
80
114
|
}
|
|
81
115
|
/**
|
|
82
|
-
* Save configuration to
|
|
116
|
+
* Save configuration to the configured source.
|
|
117
|
+
* - Inline config: updates the in-memory object (no file I/O)
|
|
118
|
+
* - File-based: writes to YAML file (default ~/.config/qmd/index.yml)
|
|
83
119
|
*/
|
|
84
120
|
export function saveConfig(config) {
|
|
85
|
-
|
|
86
|
-
|
|
121
|
+
// SDK inline config mode: update in place, no file I/O
|
|
122
|
+
if (configSource.type === 'inline') {
|
|
123
|
+
configSource.config = config;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const configPath = configSource.path || getConfigFilePath();
|
|
127
|
+
const configDir = dirname(configPath);
|
|
128
|
+
if (!existsSync(configDir)) {
|
|
129
|
+
mkdirSync(configDir, { recursive: true });
|
|
130
|
+
}
|
|
87
131
|
try {
|
|
88
132
|
const yaml = YAML.stringify(config, {
|
|
89
133
|
indent: 2,
|
|
@@ -318,13 +362,18 @@ export function findContextForPath(collectionName, filePath) {
|
|
|
318
362
|
* Get the config file path (useful for error messages)
|
|
319
363
|
*/
|
|
320
364
|
export function getConfigPath() {
|
|
321
|
-
|
|
365
|
+
if (configSource.type === 'inline')
|
|
366
|
+
return '<inline>';
|
|
367
|
+
return configSource.path || getConfigFilePath();
|
|
322
368
|
}
|
|
323
369
|
/**
|
|
324
370
|
* Check if config file exists
|
|
325
371
|
*/
|
|
326
372
|
export function configExists() {
|
|
327
|
-
|
|
373
|
+
if (configSource.type === 'inline')
|
|
374
|
+
return true;
|
|
375
|
+
const path = configSource.path || getConfigFilePath();
|
|
376
|
+
return existsSync(path);
|
|
328
377
|
}
|
|
329
378
|
/**
|
|
330
379
|
* Validate a collection name
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QMD SDK - Library mode for programmatic access to QMD search and indexing.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { createStore } from '@tobilu/qmd'
|
|
6
|
+
*
|
|
7
|
+
* const store = createStore({
|
|
8
|
+
* dbPath: './my-index.sqlite',
|
|
9
|
+
* config: {
|
|
10
|
+
* collections: {
|
|
11
|
+
* docs: { path: '/path/to/docs', pattern: '**\/*.md' }
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* })
|
|
15
|
+
*
|
|
16
|
+
* const results = await store.query("how does auth work?")
|
|
17
|
+
* store.close()
|
|
18
|
+
*/
|
|
19
|
+
import { type Store as InternalStore, type DocumentResult, type DocumentNotFound, type SearchResult, type HybridQueryResult, type HybridQueryOptions, type HybridQueryExplain, type StructuredSubSearch, type StructuredSearchOptions, type MultiGetResult, type IndexStatus, type IndexHealthInfo, type ExpandedQuery, type SearchHooks } from "./store.js";
|
|
20
|
+
import { type Collection, type CollectionConfig, type NamedCollection, type ContextMap } from "./collections.js";
|
|
21
|
+
export type { DocumentResult, DocumentNotFound, SearchResult, HybridQueryResult, HybridQueryOptions, HybridQueryExplain, StructuredSubSearch, StructuredSearchOptions, MultiGetResult, IndexStatus, IndexHealthInfo, ExpandedQuery, SearchHooks, Collection, CollectionConfig, NamedCollection, ContextMap, };
|
|
22
|
+
/**
|
|
23
|
+
* Options for creating a QMD store.
|
|
24
|
+
* You must provide `dbPath` and either `configPath` (YAML file) or `config` (inline).
|
|
25
|
+
*/
|
|
26
|
+
export interface StoreOptions {
|
|
27
|
+
/** Path to the SQLite database file */
|
|
28
|
+
dbPath: string;
|
|
29
|
+
/** Path to a YAML config file (mutually exclusive with `config`) */
|
|
30
|
+
configPath?: string;
|
|
31
|
+
/** Inline collection config (mutually exclusive with `configPath`) */
|
|
32
|
+
config?: CollectionConfig;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The QMD SDK store — provides search, retrieval, collection management,
|
|
36
|
+
* context management, and indexing operations.
|
|
37
|
+
*/
|
|
38
|
+
export interface QMDStore {
|
|
39
|
+
/** The underlying internal store (for advanced use) */
|
|
40
|
+
readonly internal: InternalStore;
|
|
41
|
+
/** Path to the SQLite database */
|
|
42
|
+
readonly dbPath: string;
|
|
43
|
+
/** Hybrid search: BM25 + vector + query expansion + LLM reranking */
|
|
44
|
+
query(query: string, options?: HybridQueryOptions): Promise<HybridQueryResult[]>;
|
|
45
|
+
/** BM25 full-text keyword search (fast, no LLM) */
|
|
46
|
+
search(query: string, options?: {
|
|
47
|
+
limit?: number;
|
|
48
|
+
collection?: string;
|
|
49
|
+
}): SearchResult[];
|
|
50
|
+
/** Structured search with pre-expanded queries (for LLM callers) */
|
|
51
|
+
structuredSearch(searches: StructuredSubSearch[], options?: StructuredSearchOptions): Promise<HybridQueryResult[]>;
|
|
52
|
+
/** Get a single document by path or docid */
|
|
53
|
+
get(pathOrDocid: string, options?: {
|
|
54
|
+
includeBody?: boolean;
|
|
55
|
+
}): DocumentResult | DocumentNotFound;
|
|
56
|
+
/** Get multiple documents by glob pattern or comma-separated list */
|
|
57
|
+
multiGet(pattern: string, options?: {
|
|
58
|
+
includeBody?: boolean;
|
|
59
|
+
maxBytes?: number;
|
|
60
|
+
}): {
|
|
61
|
+
docs: MultiGetResult[];
|
|
62
|
+
errors: string[];
|
|
63
|
+
};
|
|
64
|
+
/** Add or update a collection */
|
|
65
|
+
addCollection(name: string, opts: {
|
|
66
|
+
path: string;
|
|
67
|
+
pattern?: string;
|
|
68
|
+
ignore?: string[];
|
|
69
|
+
}): void;
|
|
70
|
+
/** Remove a collection */
|
|
71
|
+
removeCollection(name: string): boolean;
|
|
72
|
+
/** Rename a collection */
|
|
73
|
+
renameCollection(oldName: string, newName: string): boolean;
|
|
74
|
+
/** List all collections with document stats */
|
|
75
|
+
listCollections(): {
|
|
76
|
+
name: string;
|
|
77
|
+
pwd: string;
|
|
78
|
+
glob_pattern: string;
|
|
79
|
+
doc_count: number;
|
|
80
|
+
active_count: number;
|
|
81
|
+
last_modified: string | null;
|
|
82
|
+
}[];
|
|
83
|
+
/** Add context for a path within a collection */
|
|
84
|
+
addContext(collectionName: string, pathPrefix: string, contextText: string): boolean;
|
|
85
|
+
/** Remove context from a collection path */
|
|
86
|
+
removeContext(collectionName: string, pathPrefix: string): boolean;
|
|
87
|
+
/** Set global context (applies to all collections) */
|
|
88
|
+
setGlobalContext(context: string | undefined): void;
|
|
89
|
+
/** Get global context */
|
|
90
|
+
getGlobalContext(): string | undefined;
|
|
91
|
+
/** List all contexts across all collections */
|
|
92
|
+
listContexts(): Array<{
|
|
93
|
+
collection: string;
|
|
94
|
+
path: string;
|
|
95
|
+
context: string;
|
|
96
|
+
}>;
|
|
97
|
+
/** Get index status (document counts, collections, embedding state) */
|
|
98
|
+
getStatus(): IndexStatus;
|
|
99
|
+
/** Get index health info (stale embeddings, etc.) */
|
|
100
|
+
getIndexHealth(): IndexHealthInfo;
|
|
101
|
+
/** Close the database connection */
|
|
102
|
+
close(): void;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create a QMD store for programmatic access to search and indexing.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* // With a YAML config file
|
|
110
|
+
* const store = createStore({
|
|
111
|
+
* dbPath: './index.sqlite',
|
|
112
|
+
* configPath: './qmd.yml',
|
|
113
|
+
* })
|
|
114
|
+
*
|
|
115
|
+
* // With inline config (no files needed besides the DB)
|
|
116
|
+
* const store = createStore({
|
|
117
|
+
* dbPath: './index.sqlite',
|
|
118
|
+
* config: {
|
|
119
|
+
* collections: {
|
|
120
|
+
* docs: { path: '/path/to/docs', pattern: '**\/*.md' }
|
|
121
|
+
* }
|
|
122
|
+
* }
|
|
123
|
+
* })
|
|
124
|
+
*
|
|
125
|
+
* const results = await store.query("authentication flow")
|
|
126
|
+
* store.close()
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export declare function createStore(options: StoreOptions): QMDStore;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QMD SDK - Library mode for programmatic access to QMD search and indexing.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { createStore } from '@tobilu/qmd'
|
|
6
|
+
*
|
|
7
|
+
* const store = createStore({
|
|
8
|
+
* dbPath: './my-index.sqlite',
|
|
9
|
+
* config: {
|
|
10
|
+
* collections: {
|
|
11
|
+
* docs: { path: '/path/to/docs', pattern: '**\/*.md' }
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* })
|
|
15
|
+
*
|
|
16
|
+
* const results = await store.query("how does auth work?")
|
|
17
|
+
* store.close()
|
|
18
|
+
*/
|
|
19
|
+
import { createStore as createStoreInternal, hybridQuery, structuredSearch, listCollections as storeListCollections, } from "./store.js";
|
|
20
|
+
import { setConfigSource, loadConfig, addCollection as collectionsAddCollection, removeCollection as collectionsRemoveCollection, renameCollection as collectionsRenameCollection, listCollections as collectionsListCollections, addContext as collectionsAddContext, removeContext as collectionsRemoveContext, setGlobalContext as collectionsSetGlobalContext, getGlobalContext as collectionsGetGlobalContext, listAllContexts as collectionsListAllContexts, } from "./collections.js";
|
|
21
|
+
/**
|
|
22
|
+
* Create a QMD store for programmatic access to search and indexing.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // With a YAML config file
|
|
27
|
+
* const store = createStore({
|
|
28
|
+
* dbPath: './index.sqlite',
|
|
29
|
+
* configPath: './qmd.yml',
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* // With inline config (no files needed besides the DB)
|
|
33
|
+
* const store = createStore({
|
|
34
|
+
* dbPath: './index.sqlite',
|
|
35
|
+
* config: {
|
|
36
|
+
* collections: {
|
|
37
|
+
* docs: { path: '/path/to/docs', pattern: '**\/*.md' }
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* })
|
|
41
|
+
*
|
|
42
|
+
* const results = await store.query("authentication flow")
|
|
43
|
+
* store.close()
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function createStore(options) {
|
|
47
|
+
if (!options.dbPath) {
|
|
48
|
+
throw new Error("dbPath is required");
|
|
49
|
+
}
|
|
50
|
+
if (!options.configPath && !options.config) {
|
|
51
|
+
throw new Error("Either configPath or config is required");
|
|
52
|
+
}
|
|
53
|
+
if (options.configPath && options.config) {
|
|
54
|
+
throw new Error("Provide either configPath or config, not both");
|
|
55
|
+
}
|
|
56
|
+
// Inject config source into collections module
|
|
57
|
+
setConfigSource({
|
|
58
|
+
configPath: options.configPath,
|
|
59
|
+
config: options.config,
|
|
60
|
+
});
|
|
61
|
+
// Create the internal store
|
|
62
|
+
const internal = createStoreInternal(options.dbPath);
|
|
63
|
+
const store = {
|
|
64
|
+
internal,
|
|
65
|
+
dbPath: internal.dbPath,
|
|
66
|
+
// Search & Retrieval
|
|
67
|
+
query: (q, opts) => hybridQuery(internal, q, opts),
|
|
68
|
+
search: (q, opts) => internal.searchFTS(q, opts?.limit, opts?.collection),
|
|
69
|
+
structuredSearch: (searches, opts) => structuredSearch(internal, searches, opts),
|
|
70
|
+
get: (pathOrDocid, opts) => internal.findDocument(pathOrDocid, opts),
|
|
71
|
+
multiGet: (pattern, opts) => internal.findDocuments(pattern, opts),
|
|
72
|
+
// Collection Management
|
|
73
|
+
addCollection: (name, opts) => {
|
|
74
|
+
collectionsAddCollection(name, opts.path, opts.pattern);
|
|
75
|
+
},
|
|
76
|
+
removeCollection: (name) => collectionsRemoveCollection(name),
|
|
77
|
+
renameCollection: (oldName, newName) => collectionsRenameCollection(oldName, newName),
|
|
78
|
+
listCollections: () => storeListCollections(internal.db),
|
|
79
|
+
// Context Management
|
|
80
|
+
addContext: (collectionName, pathPrefix, contextText) => collectionsAddContext(collectionName, pathPrefix, contextText),
|
|
81
|
+
removeContext: (collectionName, pathPrefix) => collectionsRemoveContext(collectionName, pathPrefix),
|
|
82
|
+
setGlobalContext: (context) => collectionsSetGlobalContext(context),
|
|
83
|
+
getGlobalContext: () => collectionsGetGlobalContext(),
|
|
84
|
+
listContexts: () => collectionsListAllContexts(),
|
|
85
|
+
// Index Health
|
|
86
|
+
getStatus: () => internal.getStatus(),
|
|
87
|
+
getIndexHealth: () => internal.getIndexHealth(),
|
|
88
|
+
// Lifecycle
|
|
89
|
+
close: () => {
|
|
90
|
+
internal.close();
|
|
91
|
+
setConfigSource(undefined); // Reset config source
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
return store;
|
|
95
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tobilu/qmd",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Query Markup Documents - On-device hybrid search for markdown files with BM25, vector search, and LLM reranking",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
6
14
|
"bin": {
|
|
7
15
|
"qmd": "dist/qmd.js"
|
|
8
16
|
},
|