@tobilu/qmd 0.9.0 → 1.0.5

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 CHANGED
@@ -1,34 +1,302 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to QMD will be documented in this file.
3
+ ## [Unreleased]
4
+
5
+ ## [1.0.5] - 2026-02-16
6
+
7
+ The npm package now ships compiled JavaScript instead of raw TypeScript,
8
+ removing the `tsx` runtime dependency. A new `/release` skill automates the
9
+ full release workflow with changelog validation and git hook enforcement.
10
+
11
+ ### Changes
12
+
13
+ - Build: compile TypeScript to `dist/` via `tsc` so the npm package no longer
14
+ requires `tsx` at runtime. The `qmd` shell wrapper now runs `dist/qmd.js`
15
+ directly.
16
+ - Release tooling: new `/release` skill that manages the full release
17
+ lifecycle — validates changelog, installs git hooks, previews release notes,
18
+ and cuts the release. Auto-populates `[Unreleased]` from git history when
19
+ empty.
20
+ - Release tooling: `scripts/extract-changelog.sh` extracts cumulative notes
21
+ for the full minor series (e.g. 1.0.0 through 1.0.5) for GitHub releases.
22
+ Includes `[Unreleased]` content in previews.
23
+ - Release tooling: `scripts/release.sh` renames `[Unreleased]` to a versioned
24
+ heading and inserts a fresh empty `[Unreleased]` section automatically.
25
+ - Release tooling: pre-push git hook blocks `v*` tag pushes unless
26
+ `package.json` version matches the tag, a changelog entry exists, and CI
27
+ passed on GitHub.
28
+ - Publish workflow: GitHub Actions now builds TypeScript, creates a GitHub
29
+ release with cumulative notes extracted from the changelog, and publishes
30
+ to npm with provenance.
31
+
32
+ ## [1.0.0] - 2026-02-15
33
+
34
+ QMD now runs on both Node.js and Bun, with up to 2.7x faster reranking
35
+ through parallel GPU contexts. GPU auto-detection replaces the unreliable
36
+ `gpu: "auto"` with explicit CUDA/Metal/Vulkan probing.
37
+
38
+ ### Changes
39
+
40
+ - Runtime: support Node.js (>=22) alongside Bun via a cross-runtime SQLite
41
+ abstraction layer (`src/db.ts`). `bun:sqlite` on Bun, `better-sqlite3` on
42
+ Node. The `qmd` wrapper auto-detects a suitable Node.js install via PATH,
43
+ then falls back to mise, asdf, nvm, and Homebrew locations.
44
+ - Performance: parallel embedding & reranking via multiple LlamaContext
45
+ instances — up to 2.7x faster on multi-core machines.
46
+ - Performance: flash attention for ~20% less VRAM per reranking context,
47
+ enabling more parallel contexts on GPU.
48
+ - Performance: right-sized reranker context (40960 → 2048 tokens, 17x less
49
+ memory) since chunks are capped at ~900 tokens.
50
+ - Performance: adaptive parallelism — context count computed from available
51
+ VRAM (GPU) or CPU math cores rather than hardcoded.
52
+ - GPU: probe for CUDA, Metal, Vulkan explicitly at startup instead of
53
+ relying on node-llama-cpp's `gpu: "auto"`. `qmd status` shows device info.
54
+ - Tests: reorganized into flat `test/` directory with vitest for Node.js and
55
+ bun test for Bun. New `eval-bm25` and `store.helpers.unit` suites.
56
+
57
+ ### Fixes
58
+
59
+ - Prevent VRAM waste from duplicate context creation during concurrent
60
+ `embedBatch` calls — initialization lock now covers the full path.
61
+ - Collection-aware FTS filtering so scoped keyword search actually restricts
62
+ results to the requested collection.
4
63
 
5
64
  ## [0.9.0] - 2026-02-15
6
65
 
7
- Initial public release.
66
+ First published release on npm as `@tobilu/qmd`. MCP HTTP transport with
67
+ daemon mode cuts warm query latency from ~16s to ~10s by keeping models
68
+ loaded between requests.
69
+
70
+ ### Changes
71
+
72
+ - MCP: HTTP transport with daemon lifecycle — `qmd mcp --http --daemon`
73
+ starts a background server, `qmd mcp stop` shuts it down. Models stay warm
74
+ in VRAM between queries. #149 (thanks @igrigorik)
75
+ - Search: type-routed query expansion preserves lex/vec/hyde type info and
76
+ routes to the appropriate backend. Eliminates ~4 wasted backend calls per
77
+ query (10.0 → 6.0 calls, 1278ms → 549ms). #149 (thanks @igrigorik)
78
+ - Search: unified pipeline — extracted `hybridQuery()` and
79
+ `vectorSearchQuery()` to `store.ts` so CLI and MCP share identical logic.
80
+ Fixes a class of bugs where results differed between the two. #149 (thanks
81
+ @igrigorik)
82
+ - MCP: dynamic instructions generated at startup from actual index state —
83
+ LLMs see collection names, doc counts, and content descriptions. #149
84
+ (thanks @igrigorik)
85
+ - MCP: tool renames (vsearch → vector_search, query → deep_search) with
86
+ rewritten descriptions for better tool selection. #149 (thanks @igrigorik)
87
+ - Integration: Claude Code plugin with inline status checks and MCP
88
+ integration. #99 (thanks @galligan)
89
+
90
+ ### Fixes
91
+
92
+ - BM25 score normalization — formula was inverted (`1/(1+|x|)` instead of
93
+ `|x|/(1+|x|)`), so strong matches scored *lowest*. Broke `--min-score`
94
+ filtering and made the "strong signal" short-circuit dead code. #76 (thanks
95
+ @dgilperez)
96
+ - Normalize Unicode paths to NFC for macOS compatibility. #82 (thanks
97
+ @c-stoeckl)
98
+ - Handle dense content (code) that tokenizes beyond expected chunk size.
99
+ - Proper cleanup of Metal GPU resources on process exit.
100
+ - SQLite-vec readiness verification after extension load.
101
+ - Reactivate deactivated documents on re-index instead of creating duplicates.
102
+ - Bun UTF-8 path corruption workaround for non-ASCII filenames.
103
+ - Disable following symlinks in glob.scan to avoid infinite loops.
104
+
105
+ ## [0.8.0] - 2026-01-28
106
+
107
+ Fine-tuned query expansion model trained with GRPO replaces the stock Qwen3
108
+ 0.6B. The training pipeline scores expansions on named entity preservation,
109
+ format compliance, and diversity — producing noticeably better lexical
110
+ variations and HyDE documents.
111
+
112
+ ### Changes
113
+
114
+ - LLM: deploy GRPO-trained (Group Relative Policy Optimization) query
115
+ expansion model, hosted on HuggingFace and auto-downloaded on first use.
116
+ Better preservation of proper nouns and technical terms in expansions.
117
+ - LLM: `/only:lex` mode for single-type expansions — useful when you know
118
+ which search backend will help.
119
+ - LLM: HyDE output moved to first position so vector search can start
120
+ embedding while other expansions generate.
121
+ - LLM: session lifecycle management via `withLLMSession()` pattern — ensures
122
+ cleanup even on failure, similar to database transactions.
123
+ - Integration: org-mode title extraction support. #50 (thanks @sh54)
124
+ - Integration: SQLite extension loading in Nix devshell. #48 (thanks @sh54)
125
+ - Integration: AI agent discovery via skills.sh. #64 (thanks @Algiras)
126
+
127
+ ### Fixes
128
+
129
+ - Use sequential embedding on CPU-only systems — parallel contexts caused a
130
+ race condition where contexts competed for CPU cores, making things slower.
131
+ #54 (thanks @freeman-jiang)
132
+ - Fix `collectionName` column in vector search SQL (was still using old
133
+ `collectionId` from before YAML migration). #61 (thanks @jdvmi00)
134
+ - Fix Qwen3 sampling params to prevent repetition loops — stock
135
+ temperature/top-p caused occasional infinite repeat patterns.
136
+ - Add `--index` option to CLI argument parser (was documented but not wired
137
+ up). #84 (thanks @Tritlo)
138
+ - Fix DisposedError during slow batch embedding. #41 (thanks @wuhup)
139
+
140
+ ## [0.7.0] - 2026-01-09
8
141
 
9
- ### Features
142
+ First community contributions. The project gained external contributors,
143
+ surfacing bugs that only appear in diverse environments — Homebrew sqlite-vec
144
+ paths, case-sensitive model filenames, and sqlite-vec JOIN incompatibilities.
10
145
 
11
- - **Hybrid search pipeline** — BM25 full-text + vector similarity + LLM reranking with Reciprocal Rank Fusion
12
- - **Smart chunking** — scored markdown break points keep sections, paragraphs, and code blocks intact (~900 tokens/chunk, 15% overlap)
13
- - **Query expansion** fine-tuned Qwen3 1.7B model generates search variations for better recall
14
- - **Cross-encoder reranking** Qwen3-Reranker scores candidates with position-aware blending
15
- - **Vector embeddings** EmbeddingGemma 300M via node-llama-cpp, all on-device
16
- - **MCP server**stdio and HTTP transports for Claude Desktop, Claude Code, and any MCP client
17
- - **Collection management** index multiple directories with glob patterns
18
- - **Context annotations** — add descriptions to collections and paths for richer search
19
- - **Document IDs** — 6-char content hash for stable references across re-indexes
20
- - **Multi-get** — retrieve multiple documents by glob pattern, comma list, or docids
21
- - **Multiple output formats** — JSON, CSV, Markdown, XML, files list
22
- - **Claude Code plugin** — inline status checks and MCP integration
146
+ ### Changes
147
+
148
+ - Indexing: native `realpathSync()` replaces `readlink -f` subprocess spawn
149
+ per file. On a 5000-file collection this eliminates 5000 shell spawns,
150
+ ~15% faster. #8 (thanks @burke)
151
+ - Indexing: single-pass tokenization chunking algorithm tokenized each
152
+ document twice (count then split); now tokenizes once and reuses. #9
153
+ (thanks @burke)
23
154
 
24
155
  ### Fixes
25
156
 
26
- - Handle dense content (code) that tokenizes beyond expected chunk size
27
- - Proper cleanup of Metal GPU resources
28
- - SQLite-vec readiness verification after extension load
29
- - Reactivate deactivated documents on re-index
30
- - BM25 score normalization with Math.abs
31
- - Bun UTF-8 path corruption workaround
157
+ - Fix `vsearch` and `query` hanging sqlite-vec's virtual table doesn't
158
+ support the JOIN pattern used; rewrote to subquery. #23 (thanks @mbrendan)
159
+ - Fix MCP server exiting immediately after startup — process had no active
160
+ handles keeping the event loop alive. #29 (thanks @mostlydev)
161
+ - Fix collection filter SQL to properly restrict vector search results.
162
+ - Support non-ASCII filenames in collection filter.
163
+ - Skip empty files during indexing instead of crashing on zero-length content.
164
+ - Fix case sensitivity in Qwen3 model filename resolution. #15 (thanks
165
+ @gavrix)
166
+ - Fix sqlite-vec loading on macOS with Homebrew (`BREW_PREFIX` detection).
167
+ #42 (thanks @komsit37)
168
+ - Fix Nix flake to use correct `src/qmd.ts` path. #7 (thanks @burke)
169
+ - Fix docid lookup with quotes support in get command. #36 (thanks
170
+ @JoshuaLelon)
171
+ - Fix query expansion model size in documentation. #38 (thanks @odysseus0)
172
+
173
+ ## [0.6.0] - 2025-12-28
174
+
175
+ Replaced Ollama HTTP API with node-llama-cpp for all LLM operations. Ollama
176
+ adds convenience but also a running server dependency. node-llama-cpp loads
177
+ GGUF models directly in-process — zero external dependencies. Models
178
+ auto-download from HuggingFace on first use.
179
+
180
+ ### Changes
181
+
182
+ - LLM: structured query expansion via JSON schema grammar constraints.
183
+ Model produces typed expansions — **lexical** (BM25 keywords), **vector**
184
+ (semantic rephrasings), **HyDE** (hypothetical document excerpts) — so each
185
+ routes to the right backend instead of sending everything everywhere.
186
+ - LLM: lazy model loading with 2-minute inactivity auto-unload. Keeps memory
187
+ low when idle while avoiding ~3s model load on every query.
188
+ - Search: conditional query expansion — when BM25 returns strong results, the
189
+ expensive LLM expansion is skipped entirely.
190
+ - Search: multi-chunk reranking — documents with multiple relevant chunks
191
+ scored by aggregating across all chunks rather than best single chunk.
192
+ - Search: cosine distance for vector search (was L2).
193
+ - Search: embeddinggemma nomic-style prompt formatting.
194
+ - Testing: evaluation harness with synthetic test documents and Hit@K metrics
195
+ for BM25, vector, and hybrid RRF.
196
+
197
+ ## [0.5.0] - 2025-12-13
198
+
199
+ Collections and contexts moved from SQLite tables to YAML at
200
+ `~/.config/qmd/index.yml`. SQLite was overkill for config — you can't share
201
+ it, and it's opaque. YAML is human-readable and version-controllable. The
202
+ migration was extensive (35+ commits) because every part of the system that
203
+ touched collections or contexts had to be updated.
204
+
205
+ ### Changes
206
+
207
+ - Config: YAML-based collections and contexts replace SQLite tables.
208
+ `collections` and `path_contexts` tables dropped from schema. Collections
209
+ support an optional `update:` command (e.g., `git pull`) before re-index.
210
+ - CLI: `qmd collection add/list/remove/rename` commands with `--name` and
211
+ `--mask` glob pattern support.
212
+ - CLI: `qmd ls` virtual file tree — list collections, files in a collection,
213
+ or files under a path prefix.
214
+ - CLI: `qmd context add/list/check/rm` with hierarchical context inheritance.
215
+ A query to `qmd://notes/2024/jan/` inherits context from `notes/`,
216
+ `notes/2024/`, and `notes/2024/jan/`.
217
+ - CLI: `qmd context add / "text"` for global context across all collections.
218
+ - CLI: `qmd context check` audit command to find paths without context.
219
+ - Paths: `qmd://` virtual URI scheme for portable document references.
220
+ `qmd://notes/ideas.md` works regardless of where the collection lives on
221
+ disk. Works in `get`, `multi-get`, `ls`, and context commands.
222
+ - CLI: document IDs (docid) — first 6 chars of content hash for stable
223
+ references. Shown as `#abc123` in search results, usable with `get` and
224
+ `multi-get`.
225
+ - CLI: `--line-numbers` flag for get command output.
226
+
227
+ ## [0.4.0] - 2025-12-10
228
+
229
+ MCP server for AI agent integration. Without it, agents had to shell out to
230
+ `qmd search` and parse CLI output. The monolithic `qmd.ts` (1840 lines) was
231
+ split into focused modules with the project's first test suite (215 tests).
232
+
233
+ ### Changes
234
+
235
+ - MCP: stdio server with tools for search, vector search, hybrid query,
236
+ document retrieval, and status. Runs over stdio transport for Claude
237
+ Desktop and MCP clients.
238
+ - MCP: spec-compliant with June 2025 MCP specification — removed non-spec
239
+ `mimeType`, added `isError: true` to errors, `structuredContent` for
240
+ machine-readable results, proper URI encoding.
241
+ - MCP: simplified tool naming (`qmd_search` → `search`) since MCP already
242
+ namespaces by server.
243
+ - Architecture: extract `store.ts` (1221 LOC), `llm.ts` (539 LOC),
244
+ `formatter.ts` (359 LOC), `mcp.ts` (503 LOC) from monolithic `qmd.ts`.
245
+ - Testing: 215 tests (store: 96, llm: 60, mcp: 59) with mocked Ollama for
246
+ fast, deterministic runs. Before this: zero tests.
247
+
248
+ ## [0.3.0] - 2025-12-08
249
+
250
+ Document chunking for vector search. A 5000-word document about many topics
251
+ gets a single embedding that averages everything together, matching poorly for
252
+ specific queries. Chunking produces one embedding per ~900-token section with
253
+ focused semantic signal.
254
+
255
+ ### Changes
256
+
257
+ - Search: markdown-aware chunking — prefers heading boundaries, then paragraph
258
+ breaks, then sentence boundaries. 15% overlap between chunks ensures
259
+ cross-boundary queries still match.
260
+ - Search: multi-chunk scoring bonus (+0.02 per additional chunk, capped at
261
+ +0.1 for 5+ chunks). Documents relevant in multiple sections rank higher.
262
+ - CLI: display paths show collection-relative paths and extracted titles
263
+ (from H1 headings or YAML frontmatter) instead of raw filesystem paths.
264
+ - CLI: `--all` flag returns all matches (use with `--min-score` to filter).
265
+ - CLI: byte-based progress bar with ETA for `embed` command.
266
+ - CLI: human-readable time formatting ("15m 4s" instead of "904.2s").
267
+ - CLI: documents >64KB truncated with warning during embedding.
268
+
269
+ ## [0.2.0] - 2025-12-08
270
+
271
+ ### Changes
272
+
273
+ - CLI: `--json`, `--csv`, `--files`, `--md`, `--xml` output format flags.
274
+ `--json` for programmatic access, `--files` for piping, `--md`/`--xml` for
275
+ LLM consumption, `--csv` for spreadsheets.
276
+ - CLI: `qmd status` shows index health — document count, size, embedding
277
+ coverage, time since last update.
278
+ - Search: weighted RRF — original query gets 2x weight relative to expanded
279
+ queries since the user's actual words are a more reliable signal.
280
+
281
+ ## [0.1.0] - 2025-12-07
282
+
283
+ Initial implementation. Built in a single day for searching personal markdown
284
+ notes, journals, and meeting transcripts.
285
+
286
+ ### Changes
287
+
288
+ - Search: SQLite FTS5 with BM25 ranking. Chose SQLite over Elasticsearch
289
+ because QMD is a personal tool — single binary, no server dependencies.
290
+ - Search: sqlite-vec for vector similarity. Same rationale: in-process, no
291
+ external vector database.
292
+ - Search: Reciprocal Rank Fusion to combine BM25 and vector results. RRF is
293
+ parameter-free and handles missing signals gracefully.
294
+ - LLM: Ollama for embeddings, reranking, and query expansion. Later replaced
295
+ with node-llama-cpp in 0.6.0.
296
+ - CLI: `qmd add`, `qmd embed`, `qmd search`, `qmd vsearch`, `qmd query`,
297
+ `qmd get`. ~1800 lines of TypeScript in a single `qmd.ts` file.
32
298
 
33
- [0.9.0]: https://github.com/tobi/qmd/releases/tag/v0.9.0
299
+ [Unreleased]: https://github.com/tobi/qmd/compare/v1.0.0...HEAD
300
+ [1.0.0]: https://github.com/tobi/qmd/releases/tag/v1.0.0
301
+ [0.9.0]: https://github.com/tobi/qmd/compare/v0.8.0...v0.9.0
34
302
 
package/README.md CHANGED
@@ -6,18 +6,26 @@ QMD combines BM25 full-text search, vector semantic search, and LLM re-ranking
6
6
 
7
7
  ![QMD Architecture](assets/qmd-architecture.png)
8
8
 
9
+ You can read more about QMD's progress in the [CHANGELOG](CHANGELOG.md).
10
+
9
11
  ## Quick Start
10
12
 
11
13
  ```sh
12
- # Install globally
14
+ # Install globally (Node or Bun)
15
+ npm install -g @tobilu/qmd
16
+ # or
13
17
  bun install -g @tobilu/qmd
14
18
 
19
+ # Or run directly
20
+ npx @tobilu/qmd ...
21
+ bunx @tobilu/qmd ...
22
+
15
23
  # Create collections for your notes, docs, and meeting transcripts
16
24
  qmd collection add ~/notes --name notes
17
25
  qmd collection add ~/Documents/meetings --name meetings
18
26
  qmd collection add ~/work/docs --name docs
19
27
 
20
- # Add context to help with search results
28
+ # Add context to help with search results, each piece of context will be returned when matching sub documents are returned. This works as a tree. This is the key feature of QMD as it allows LLMs to make much better contextual choices when selecting documents. Don't sleep on it!
21
29
  qmd context add qmd://notes "Personal notes and ideas"
22
30
  qmd context add qmd://meetings "Meeting transcripts and notes"
23
31
  qmd context add qmd://docs "Work documentation"
@@ -231,6 +239,7 @@ The `query` command uses **Reciprocal Rank Fusion (RRF)** with position-aware bl
231
239
 
232
240
  ### System Requirements
233
241
 
242
+ - **Node.js** >= 22
234
243
  - **Bun** >= 1.0.0
235
244
  - **macOS**: Homebrew SQLite (for extension support)
236
245
  ```sh
@@ -252,18 +261,18 @@ Models are downloaded from HuggingFace and cached in `~/.cache/qmd/models/`.
252
261
  ## Installation
253
262
 
254
263
  ```sh
264
+ npm install -g @tobilu/qmd
265
+ # or
255
266
  bun install -g @tobilu/qmd
256
267
  ```
257
268
 
258
- Make sure `~/.bun/bin` is in your PATH.
259
-
260
269
  ### Development
261
270
 
262
271
  ```sh
263
272
  git clone https://github.com/tobi/qmd
264
273
  cd qmd
265
- bun install
266
- bun link
274
+ npm install
275
+ npm link
267
276
  ```
268
277
 
269
278
  ## Usage
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Collections configuration management
3
+ *
4
+ * This module manages the YAML-based collection configuration at ~/.config/qmd/index.yml.
5
+ * Collections define which directories to index and their associated contexts.
6
+ */
7
+ /**
8
+ * Context definitions for a collection
9
+ * Key is path prefix (e.g., "/", "/2024", "/Board of Directors")
10
+ * Value is the context description
11
+ */
12
+ export type ContextMap = Record<string, string>;
13
+ /**
14
+ * A single collection configuration
15
+ */
16
+ export interface Collection {
17
+ path: string;
18
+ pattern: string;
19
+ context?: ContextMap;
20
+ update?: string;
21
+ }
22
+ /**
23
+ * The complete configuration file structure
24
+ */
25
+ export interface CollectionConfig {
26
+ global_context?: string;
27
+ collections: Record<string, Collection>;
28
+ }
29
+ /**
30
+ * Collection with its name (for return values)
31
+ */
32
+ export interface NamedCollection extends Collection {
33
+ name: string;
34
+ }
35
+ /**
36
+ * Set the current index name for config file lookup
37
+ * Config file will be ~/.config/qmd/{indexName}.yml
38
+ */
39
+ export declare function setConfigIndexName(name: string): void;
40
+ /**
41
+ * Load configuration from ~/.config/qmd/index.yml
42
+ * Returns empty config if file doesn't exist
43
+ */
44
+ export declare function loadConfig(): CollectionConfig;
45
+ /**
46
+ * Save configuration to ~/.config/qmd/index.yml
47
+ */
48
+ export declare function saveConfig(config: CollectionConfig): void;
49
+ /**
50
+ * Get a specific collection by name
51
+ * Returns null if not found
52
+ */
53
+ export declare function getCollection(name: string): NamedCollection | null;
54
+ /**
55
+ * List all collections
56
+ */
57
+ export declare function listCollections(): NamedCollection[];
58
+ /**
59
+ * Add or update a collection
60
+ */
61
+ export declare function addCollection(name: string, path: string, pattern?: string): void;
62
+ /**
63
+ * Remove a collection
64
+ */
65
+ export declare function removeCollection(name: string): boolean;
66
+ /**
67
+ * Rename a collection
68
+ */
69
+ export declare function renameCollection(oldName: string, newName: string): boolean;
70
+ /**
71
+ * Get global context
72
+ */
73
+ export declare function getGlobalContext(): string | undefined;
74
+ /**
75
+ * Set global context
76
+ */
77
+ export declare function setGlobalContext(context: string | undefined): void;
78
+ /**
79
+ * Get all contexts for a collection
80
+ */
81
+ export declare function getContexts(collectionName: string): ContextMap | undefined;
82
+ /**
83
+ * Add or update a context for a specific path in a collection
84
+ */
85
+ export declare function addContext(collectionName: string, pathPrefix: string, contextText: string): boolean;
86
+ /**
87
+ * Remove a context from a collection
88
+ */
89
+ export declare function removeContext(collectionName: string, pathPrefix: string): boolean;
90
+ /**
91
+ * List all contexts across all collections
92
+ */
93
+ export declare function listAllContexts(): Array<{
94
+ collection: string;
95
+ path: string;
96
+ context: string;
97
+ }>;
98
+ /**
99
+ * Find best matching context for a given collection and path
100
+ * Returns the most specific matching context (longest path prefix match)
101
+ */
102
+ export declare function findContextForPath(collectionName: string, filePath: string): string | undefined;
103
+ /**
104
+ * Get the config file path (useful for error messages)
105
+ */
106
+ export declare function getConfigPath(): string;
107
+ /**
108
+ * Check if config file exists
109
+ */
110
+ export declare function configExists(): boolean;
111
+ /**
112
+ * Validate a collection name
113
+ * Collection names must be valid and not contain special characters
114
+ */
115
+ export declare function isValidCollectionName(name: string): boolean;