@gmickel/gno 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +256 -0
  2. package/assets/skill/SKILL.md +112 -0
  3. package/assets/skill/cli-reference.md +327 -0
  4. package/assets/skill/examples.md +234 -0
  5. package/assets/skill/mcp-reference.md +159 -0
  6. package/package.json +90 -0
  7. package/src/app/constants.ts +313 -0
  8. package/src/cli/colors.ts +65 -0
  9. package/src/cli/commands/ask.ts +545 -0
  10. package/src/cli/commands/cleanup.ts +105 -0
  11. package/src/cli/commands/collection/add.ts +120 -0
  12. package/src/cli/commands/collection/index.ts +10 -0
  13. package/src/cli/commands/collection/list.ts +108 -0
  14. package/src/cli/commands/collection/remove.ts +64 -0
  15. package/src/cli/commands/collection/rename.ts +95 -0
  16. package/src/cli/commands/context/add.ts +67 -0
  17. package/src/cli/commands/context/check.ts +153 -0
  18. package/src/cli/commands/context/index.ts +10 -0
  19. package/src/cli/commands/context/list.ts +109 -0
  20. package/src/cli/commands/context/rm.ts +52 -0
  21. package/src/cli/commands/doctor.ts +393 -0
  22. package/src/cli/commands/embed.ts +462 -0
  23. package/src/cli/commands/get.ts +356 -0
  24. package/src/cli/commands/index-cmd.ts +119 -0
  25. package/src/cli/commands/index.ts +102 -0
  26. package/src/cli/commands/init.ts +328 -0
  27. package/src/cli/commands/ls.ts +217 -0
  28. package/src/cli/commands/mcp/config.ts +300 -0
  29. package/src/cli/commands/mcp/index.ts +24 -0
  30. package/src/cli/commands/mcp/install.ts +203 -0
  31. package/src/cli/commands/mcp/paths.ts +470 -0
  32. package/src/cli/commands/mcp/status.ts +222 -0
  33. package/src/cli/commands/mcp/uninstall.ts +158 -0
  34. package/src/cli/commands/mcp.ts +20 -0
  35. package/src/cli/commands/models/clear.ts +103 -0
  36. package/src/cli/commands/models/index.ts +32 -0
  37. package/src/cli/commands/models/list.ts +214 -0
  38. package/src/cli/commands/models/path.ts +51 -0
  39. package/src/cli/commands/models/pull.ts +199 -0
  40. package/src/cli/commands/models/use.ts +85 -0
  41. package/src/cli/commands/multi-get.ts +400 -0
  42. package/src/cli/commands/query.ts +220 -0
  43. package/src/cli/commands/ref-parser.ts +108 -0
  44. package/src/cli/commands/reset.ts +191 -0
  45. package/src/cli/commands/search.ts +136 -0
  46. package/src/cli/commands/shared.ts +156 -0
  47. package/src/cli/commands/skill/index.ts +19 -0
  48. package/src/cli/commands/skill/install.ts +197 -0
  49. package/src/cli/commands/skill/paths-cmd.ts +81 -0
  50. package/src/cli/commands/skill/paths.ts +191 -0
  51. package/src/cli/commands/skill/show.ts +73 -0
  52. package/src/cli/commands/skill/uninstall.ts +141 -0
  53. package/src/cli/commands/status.ts +205 -0
  54. package/src/cli/commands/update.ts +68 -0
  55. package/src/cli/commands/vsearch.ts +188 -0
  56. package/src/cli/context.ts +64 -0
  57. package/src/cli/errors.ts +64 -0
  58. package/src/cli/format/search-results.ts +211 -0
  59. package/src/cli/options.ts +183 -0
  60. package/src/cli/program.ts +1330 -0
  61. package/src/cli/run.ts +213 -0
  62. package/src/cli/ui.ts +92 -0
  63. package/src/config/defaults.ts +20 -0
  64. package/src/config/index.ts +55 -0
  65. package/src/config/loader.ts +161 -0
  66. package/src/config/paths.ts +87 -0
  67. package/src/config/saver.ts +153 -0
  68. package/src/config/types.ts +280 -0
  69. package/src/converters/adapters/markitdownTs/adapter.ts +140 -0
  70. package/src/converters/adapters/officeparser/adapter.ts +126 -0
  71. package/src/converters/canonicalize.ts +89 -0
  72. package/src/converters/errors.ts +218 -0
  73. package/src/converters/index.ts +51 -0
  74. package/src/converters/mime.ts +163 -0
  75. package/src/converters/native/markdown.ts +115 -0
  76. package/src/converters/native/plaintext.ts +56 -0
  77. package/src/converters/path.ts +48 -0
  78. package/src/converters/pipeline.ts +159 -0
  79. package/src/converters/registry.ts +74 -0
  80. package/src/converters/types.ts +123 -0
  81. package/src/converters/versions.ts +24 -0
  82. package/src/index.ts +27 -0
  83. package/src/ingestion/chunker.ts +238 -0
  84. package/src/ingestion/index.ts +32 -0
  85. package/src/ingestion/language.ts +276 -0
  86. package/src/ingestion/sync.ts +671 -0
  87. package/src/ingestion/types.ts +219 -0
  88. package/src/ingestion/walker.ts +235 -0
  89. package/src/llm/cache.ts +467 -0
  90. package/src/llm/errors.ts +191 -0
  91. package/src/llm/index.ts +58 -0
  92. package/src/llm/nodeLlamaCpp/adapter.ts +133 -0
  93. package/src/llm/nodeLlamaCpp/embedding.ts +165 -0
  94. package/src/llm/nodeLlamaCpp/generation.ts +88 -0
  95. package/src/llm/nodeLlamaCpp/lifecycle.ts +317 -0
  96. package/src/llm/nodeLlamaCpp/rerank.ts +94 -0
  97. package/src/llm/registry.ts +86 -0
  98. package/src/llm/types.ts +129 -0
  99. package/src/mcp/resources/index.ts +151 -0
  100. package/src/mcp/server.ts +229 -0
  101. package/src/mcp/tools/get.ts +220 -0
  102. package/src/mcp/tools/index.ts +160 -0
  103. package/src/mcp/tools/multi-get.ts +263 -0
  104. package/src/mcp/tools/query.ts +226 -0
  105. package/src/mcp/tools/search.ts +119 -0
  106. package/src/mcp/tools/status.ts +81 -0
  107. package/src/mcp/tools/vsearch.ts +198 -0
  108. package/src/pipeline/chunk-lookup.ts +44 -0
  109. package/src/pipeline/expansion.ts +256 -0
  110. package/src/pipeline/explain.ts +115 -0
  111. package/src/pipeline/fusion.ts +185 -0
  112. package/src/pipeline/hybrid.ts +535 -0
  113. package/src/pipeline/index.ts +64 -0
  114. package/src/pipeline/query-language.ts +118 -0
  115. package/src/pipeline/rerank.ts +223 -0
  116. package/src/pipeline/search.ts +261 -0
  117. package/src/pipeline/types.ts +328 -0
  118. package/src/pipeline/vsearch.ts +348 -0
  119. package/src/store/index.ts +41 -0
  120. package/src/store/migrations/001-initial.ts +196 -0
  121. package/src/store/migrations/index.ts +20 -0
  122. package/src/store/migrations/runner.ts +187 -0
  123. package/src/store/sqlite/adapter.ts +1242 -0
  124. package/src/store/sqlite/index.ts +7 -0
  125. package/src/store/sqlite/setup.ts +129 -0
  126. package/src/store/sqlite/types.ts +28 -0
  127. package/src/store/types.ts +506 -0
  128. package/src/store/vector/index.ts +13 -0
  129. package/src/store/vector/sqlite-vec.ts +373 -0
  130. package/src/store/vector/stats.ts +152 -0
  131. package/src/store/vector/types.ts +115 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * SQLite store adapter exports.
3
+ *
4
+ * @module src/store/sqlite
5
+ */
6
+
7
+ export { SqliteAdapter } from './adapter';
@@ -0,0 +1,129 @@
1
+ /**
2
+ * SQLite setup for extension support.
3
+ *
4
+ * Platform behavior:
5
+ * - Linux/Windows: Bun's bundled SQLite supports extensions natively
6
+ * - macOS: Apple's SQLite disables extension loading, requires custom SQLite
7
+ *
8
+ * MUST be imported before any Database is created.
9
+ *
10
+ * @module src/store/sqlite/setup
11
+ */
12
+
13
+ import { Database } from 'bun:sqlite';
14
+ // node:fs: existsSync for checking file existence (no async needed at module load)
15
+ import { existsSync } from 'node:fs';
16
+ // node:os: platform detection (no Bun equivalent)
17
+ import { platform } from 'node:os';
18
+
19
+ // ─────────────────────────────────────────────────────────────────────────────
20
+ // Types
21
+ // ─────────────────────────────────────────────────────────────────────────────
22
+
23
+ /**
24
+ * How SQLite extensions are loaded on this platform:
25
+ * - 'native': Bundled SQLite supports extensions (Linux/Windows)
26
+ * - 'custom': Custom SQLite library loaded successfully (macOS with Homebrew)
27
+ * - 'unavailable': Extension loading not possible
28
+ */
29
+ export type ExtensionLoadingMode = 'native' | 'custom' | 'unavailable';
30
+
31
+ /**
32
+ * Record of a SQLite load attempt for diagnostics.
33
+ */
34
+ export interface LoadAttempt {
35
+ path: string;
36
+ error: string;
37
+ }
38
+
39
+ // ─────────────────────────────────────────────────────────────────────────────
40
+ // State
41
+ // ─────────────────────────────────────────────────────────────────────────────
42
+
43
+ // Possible paths to Homebrew SQLite with extension support
44
+ const SQLITE_PATHS = [
45
+ '/opt/homebrew/opt/sqlite3/lib/libsqlite3.dylib', // macOS Apple Silicon
46
+ '/usr/local/opt/sqlite3/lib/libsqlite3.dylib', // macOS Intel
47
+ ];
48
+
49
+ let setupCompleted = false;
50
+ let customSqlitePath: string | null = null;
51
+ const loadAttempts: LoadAttempt[] = [];
52
+
53
+ // ─────────────────────────────────────────────────────────────────────────────
54
+ // Setup
55
+ // ─────────────────────────────────────────────────────────────────────────────
56
+
57
+ /**
58
+ * Configure Bun to use system SQLite with extension support.
59
+ * Safe to call multiple times - only runs once.
60
+ */
61
+ function setupCustomSqlite(): void {
62
+ if (setupCompleted) {
63
+ return;
64
+ }
65
+
66
+ // Linux/Windows: bundled SQLite supports extensions natively
67
+ if (platform() !== 'darwin') {
68
+ setupCompleted = true;
69
+ return;
70
+ }
71
+
72
+ // macOS: try Homebrew paths
73
+ for (const path of SQLITE_PATHS) {
74
+ if (!existsSync(path)) {
75
+ loadAttempts.push({ path, error: 'file not found' });
76
+ continue;
77
+ }
78
+ try {
79
+ Database.setCustomSQLite(path);
80
+ customSqlitePath = path;
81
+ setupCompleted = true;
82
+ return;
83
+ } catch (e) {
84
+ const message = e instanceof Error ? e.message : String(e);
85
+ loadAttempts.push({ path, error: message });
86
+ }
87
+ }
88
+
89
+ setupCompleted = true;
90
+ }
91
+
92
+ // Run setup immediately on import
93
+ setupCustomSqlite();
94
+
95
+ // ─────────────────────────────────────────────────────────────────────────────
96
+ // Public API
97
+ // ─────────────────────────────────────────────────────────────────────────────
98
+
99
+ /**
100
+ * Get the extension loading mode for this platform.
101
+ */
102
+ export function getExtensionLoadingMode(): ExtensionLoadingMode {
103
+ if (platform() !== 'darwin') {
104
+ return 'native'; // Linux/Windows: bundled SQLite supports extensions
105
+ }
106
+ return customSqlitePath ? 'custom' : 'unavailable';
107
+ }
108
+
109
+ /**
110
+ * Get the path to the custom SQLite library, or null if using bundled/native.
111
+ */
112
+ export function getCustomSqlitePath(): string | null {
113
+ return customSqlitePath;
114
+ }
115
+
116
+ /**
117
+ * Get all SQLite load attempts for diagnostics.
118
+ * Useful for debugging why extension loading failed.
119
+ */
120
+ export function getLoadAttempts(): LoadAttempt[] {
121
+ return loadAttempts.map((a) => ({ ...a }));
122
+ }
123
+
124
+ /**
125
+ * @deprecated Use getExtensionLoadingMode() !== 'unavailable' instead
126
+ */
127
+ export function hasExtensionSupport(): boolean {
128
+ return getExtensionLoadingMode() !== 'unavailable';
129
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * SQLite-specific types for raw DB access.
3
+ * These are NOT part of StorePort contract - only used for vector layer.
4
+ *
5
+ * @module src/store/sqlite/types
6
+ */
7
+
8
+ import type { Database } from 'bun:sqlite';
9
+
10
+ /**
11
+ * Type guard interface for accessing raw SQLite DB.
12
+ * Only implemented by SqliteAdapter, not part of StorePort contract.
13
+ */
14
+ export interface SqliteDbProvider {
15
+ getRawDb(): Database;
16
+ }
17
+
18
+ /**
19
+ * Check if a store implements SqliteDbProvider.
20
+ */
21
+ export function isSqliteDbProvider(store: unknown): store is SqliteDbProvider {
22
+ return (
23
+ store !== null &&
24
+ typeof store === 'object' &&
25
+ 'getRawDb' in store &&
26
+ typeof (store as SqliteDbProvider).getRawDb === 'function'
27
+ );
28
+ }
@@ -0,0 +1,506 @@
1
+ /**
2
+ * Store layer types and interfaces.
3
+ * Defines StorePort (port interface) and all data types for persistence.
4
+ *
5
+ * @module src/store/types
6
+ */
7
+
8
+ import type { Collection, Context, FtsTokenizer } from '../config/types';
9
+
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+ // Error Types
12
+ // ─────────────────────────────────────────────────────────────────────────────
13
+
14
+ /** Store error codes */
15
+ export type StoreErrorCode =
16
+ | 'NOT_FOUND'
17
+ | 'ALREADY_EXISTS'
18
+ | 'CONSTRAINT_VIOLATION'
19
+ | 'MIGRATION_FAILED'
20
+ | 'CONNECTION_FAILED'
21
+ | 'QUERY_FAILED'
22
+ | 'TRANSACTION_FAILED'
23
+ | 'INVALID_INPUT'
24
+ | 'IO_ERROR'
25
+ | 'INTERNAL'
26
+ // Vector-specific error codes (EPIC 7)
27
+ | 'VECTOR_WRITE_FAILED'
28
+ | 'VECTOR_DELETE_FAILED'
29
+ | 'VEC_SEARCH_UNAVAILABLE'
30
+ | 'VEC_SEARCH_FAILED'
31
+ | 'VEC_REBUILD_FAILED'
32
+ | 'VEC_SYNC_FAILED';
33
+
34
+ /** Store error with structured details */
35
+ export interface StoreError {
36
+ code: StoreErrorCode;
37
+ message: string;
38
+ cause?: unknown;
39
+ details?: Record<string, unknown>;
40
+ }
41
+
42
+ /** Result type for store operations */
43
+ export type StoreResult<T> =
44
+ | { ok: true; value: T }
45
+ | { ok: false; error: StoreError };
46
+
47
+ /** Create a success result */
48
+ export function ok<T>(value: T): StoreResult<T> {
49
+ return { ok: true, value };
50
+ }
51
+
52
+ /** Create an error result */
53
+ export function err<T>(
54
+ code: StoreErrorCode,
55
+ message: string,
56
+ cause?: unknown
57
+ ): StoreResult<T> {
58
+ return { ok: false, error: { code, message, cause } };
59
+ }
60
+
61
+ // ─────────────────────────────────────────────────────────────────────────────
62
+ // Row Types (DB representations)
63
+ // ─────────────────────────────────────────────────────────────────────────────
64
+
65
+ /** Collection row from DB (mirrors config) */
66
+ export interface CollectionRow {
67
+ name: string;
68
+ path: string;
69
+ pattern: string;
70
+ include: string[] | null;
71
+ exclude: string[] | null;
72
+ updateCmd: string | null;
73
+ languageHint: string | null;
74
+ syncedAt: string;
75
+ }
76
+
77
+ /** Context row from DB (mirrors config) */
78
+ export interface ContextRow {
79
+ scopeType: 'global' | 'collection' | 'prefix';
80
+ scopeKey: string;
81
+ text: string;
82
+ syncedAt: string;
83
+ }
84
+
85
+ /** Document row from DB */
86
+ export interface DocumentRow {
87
+ id: number;
88
+ collection: string;
89
+ relPath: string;
90
+
91
+ // Source metadata
92
+ sourceHash: string;
93
+ sourceMime: string;
94
+ sourceExt: string;
95
+ sourceSize: number;
96
+ sourceMtime: string;
97
+
98
+ // Derived identifiers
99
+ docid: string;
100
+ uri: string;
101
+
102
+ // Conversion output
103
+ title: string | null;
104
+ mirrorHash: string | null;
105
+ converterId: string | null;
106
+ converterVersion: string | null;
107
+ languageHint: string | null;
108
+
109
+ // Status
110
+ active: boolean;
111
+
112
+ // Error tracking
113
+ lastErrorCode: string | null;
114
+ lastErrorMessage: string | null;
115
+ lastErrorAt: string | null;
116
+
117
+ // Timestamps
118
+ createdAt: string;
119
+ updatedAt: string;
120
+ }
121
+
122
+ /** Chunk row from DB */
123
+ export interface ChunkRow {
124
+ mirrorHash: string;
125
+ seq: number;
126
+ pos: number;
127
+ text: string;
128
+ startLine: number;
129
+ endLine: number;
130
+ language: string | null;
131
+ tokenCount: number | null;
132
+ createdAt: string;
133
+ }
134
+
135
+ /** Ingest error row from DB */
136
+ export interface IngestErrorRow {
137
+ id: number;
138
+ collection: string;
139
+ relPath: string;
140
+ occurredAt: string;
141
+ code: string;
142
+ message: string;
143
+ detailsJson: string | null;
144
+ }
145
+
146
+ // ─────────────────────────────────────────────────────────────────────────────
147
+ // Input Types (for upsert operations)
148
+ // ─────────────────────────────────────────────────────────────────────────────
149
+
150
+ /** Input for upserting a document */
151
+ export interface DocumentInput {
152
+ collection: string;
153
+ relPath: string;
154
+ sourceHash: string;
155
+ sourceMime: string;
156
+ sourceExt: string;
157
+ sourceSize: number;
158
+ sourceMtime: string;
159
+ title?: string;
160
+ mirrorHash?: string;
161
+ converterId?: string;
162
+ converterVersion?: string;
163
+ languageHint?: string;
164
+ lastErrorCode?: string;
165
+ lastErrorMessage?: string;
166
+ }
167
+
168
+ /** Input for a single chunk */
169
+ export interface ChunkInput {
170
+ seq: number;
171
+ pos: number;
172
+ text: string;
173
+ startLine: number;
174
+ endLine: number;
175
+ language?: string;
176
+ tokenCount?: number;
177
+ }
178
+
179
+ /** Input for recording an ingest error */
180
+ export interface IngestErrorInput {
181
+ collection: string;
182
+ relPath: string;
183
+ code: string;
184
+ message: string;
185
+ details?: Record<string, unknown>;
186
+ }
187
+
188
+ // ─────────────────────────────────────────────────────────────────────────────
189
+ // Search Types
190
+ // ─────────────────────────────────────────────────────────────────────────────
191
+
192
+ /** Options for FTS search */
193
+ export interface FtsSearchOptions {
194
+ /** Max results to return */
195
+ limit?: number;
196
+ /** Filter by collection */
197
+ collection?: string;
198
+ /** Filter by language */
199
+ language?: string;
200
+ /** Include snippet with highlights */
201
+ snippet?: boolean;
202
+ }
203
+
204
+ /** Single FTS search result */
205
+ export interface FtsResult {
206
+ mirrorHash: string;
207
+ seq: number;
208
+ score: number;
209
+ snippet?: string;
210
+ // Joined from documents table
211
+ docid?: string;
212
+ uri?: string;
213
+ title?: string;
214
+ collection?: string;
215
+ relPath?: string;
216
+ // Source metadata (optional for backward compat)
217
+ sourceMime?: string;
218
+ sourceExt?: string;
219
+ sourceMtime?: string;
220
+ sourceSize?: number;
221
+ sourceHash?: string;
222
+ }
223
+
224
+ // ─────────────────────────────────────────────────────────────────────────────
225
+ // Status Types
226
+ // ─────────────────────────────────────────────────────────────────────────────
227
+
228
+ /** Per-collection status */
229
+ export interface CollectionStatus {
230
+ name: string;
231
+ path: string;
232
+ totalDocuments: number;
233
+ activeDocuments: number;
234
+ errorDocuments: number;
235
+ chunkedDocuments: number;
236
+ /** Total chunks for this collection */
237
+ totalChunks: number;
238
+ /** Chunks with embeddings (EPIC 7) */
239
+ embeddedChunks: number;
240
+ }
241
+
242
+ /** Index-level status */
243
+ export interface IndexStatus {
244
+ /** Config version string */
245
+ version: string;
246
+ /** Index name (from dbPath) */
247
+ indexName: string;
248
+ /** Full path to config file */
249
+ configPath: string;
250
+ /** Full path to database file */
251
+ dbPath: string;
252
+ /** FTS tokenizer in use */
253
+ ftsTokenizer: FtsTokenizer;
254
+ /** Per-collection status */
255
+ collections: CollectionStatus[];
256
+ /** Total documents across all collections */
257
+ totalDocuments: number;
258
+ /** Active (non-deleted) documents */
259
+ activeDocuments: number;
260
+ /** Total chunks across all collections */
261
+ totalChunks: number;
262
+ /** Chunks without embeddings */
263
+ embeddingBacklog: number;
264
+ /** Recent ingest errors (last 24h) */
265
+ recentErrors: number;
266
+ /** Last successful update timestamp (ISO 8601) */
267
+ lastUpdatedAt: string | null;
268
+ /** Overall health status */
269
+ healthy: boolean;
270
+ }
271
+
272
+ /** Cleanup operation stats */
273
+ export interface CleanupStats {
274
+ orphanedContent: number;
275
+ orphanedChunks: number;
276
+ orphanedVectors: number;
277
+ expiredCache: number;
278
+ }
279
+
280
+ // ─────────────────────────────────────────────────────────────────────────────
281
+ // Migration Types
282
+ // ─────────────────────────────────────────────────────────────────────────────
283
+
284
+ /** Migration result */
285
+ export interface MigrationResult {
286
+ applied: number[];
287
+ currentVersion: number;
288
+ ftsTokenizer: FtsTokenizer;
289
+ }
290
+
291
+ // ─────────────────────────────────────────────────────────────────────────────
292
+ // Transaction Types
293
+ // ─────────────────────────────────────────────────────────────────────────────
294
+
295
+ /**
296
+ * Optional transaction wrapper capability.
297
+ * Store implementations that support batching multiple writes into a single
298
+ * durable commit should implement this.
299
+ */
300
+ export type WithTransaction = <T>(
301
+ fn: () => Promise<T>
302
+ ) => Promise<StoreResult<T>>;
303
+
304
+ // ─────────────────────────────────────────────────────────────────────────────
305
+ // StorePort Interface
306
+ // ─────────────────────────────────────────────────────────────────────────────
307
+
308
+ /**
309
+ * StorePort - Port interface for data persistence.
310
+ * Implementations: SQLite adapter (src/store/sqlite/adapter.ts)
311
+ */
312
+ export interface StorePort {
313
+ // ─────────────────────────────────────────────────────────────────────────
314
+ // Lifecycle
315
+ // ─────────────────────────────────────────────────────────────────────────
316
+
317
+ /**
318
+ * Open database connection and run migrations.
319
+ * Creates DB file if it doesn't exist.
320
+ */
321
+ open(
322
+ dbPath: string,
323
+ ftsTokenizer: FtsTokenizer
324
+ ): Promise<StoreResult<MigrationResult>>;
325
+
326
+ /**
327
+ * Close database connection and cleanup resources.
328
+ */
329
+ close(): Promise<void>;
330
+
331
+ /**
332
+ * Check if database is open.
333
+ */
334
+ isOpen(): boolean;
335
+
336
+ /**
337
+ * Run an async function within a single transaction.
338
+ * Optional - implementations without transactional support can omit this.
339
+ * Used by SyncService to batch document writes for better Windows performance.
340
+ */
341
+ withTransaction?: WithTransaction;
342
+
343
+ // ─────────────────────────────────────────────────────────────────────────
344
+ // Config Sync (YAML -> DB)
345
+ // ─────────────────────────────────────────────────────────────────────────
346
+
347
+ /**
348
+ * Sync collections from config to DB.
349
+ * Adds new, updates existing, removes deleted.
350
+ */
351
+ syncCollections(collections: Collection[]): Promise<StoreResult<void>>;
352
+
353
+ /**
354
+ * Sync contexts from config to DB.
355
+ * Adds new, updates existing, removes deleted.
356
+ */
357
+ syncContexts(contexts: Context[]): Promise<StoreResult<void>>;
358
+
359
+ /**
360
+ * Get all collections from DB.
361
+ */
362
+ getCollections(): Promise<StoreResult<CollectionRow[]>>;
363
+
364
+ /**
365
+ * Get all contexts from DB.
366
+ */
367
+ getContexts(): Promise<StoreResult<ContextRow[]>>;
368
+
369
+ // ─────────────────────────────────────────────────────────────────────────
370
+ // Documents
371
+ // ─────────────────────────────────────────────────────────────────────────
372
+
373
+ /**
374
+ * Upsert a document. Returns docid.
375
+ * Creates new or updates existing by (collection, relPath).
376
+ */
377
+ upsertDocument(doc: DocumentInput): Promise<StoreResult<string>>;
378
+
379
+ /**
380
+ * Get document by collection and relative path.
381
+ */
382
+ getDocument(
383
+ collection: string,
384
+ relPath: string
385
+ ): Promise<StoreResult<DocumentRow | null>>;
386
+
387
+ /**
388
+ * Get document by docid (#hex).
389
+ */
390
+ getDocumentByDocid(docid: string): Promise<StoreResult<DocumentRow | null>>;
391
+
392
+ /**
393
+ * Get document by URI (gno://collection/path).
394
+ */
395
+ getDocumentByUri(uri: string): Promise<StoreResult<DocumentRow | null>>;
396
+
397
+ /**
398
+ * List all documents, optionally filtered by collection.
399
+ */
400
+ listDocuments(collection?: string): Promise<StoreResult<DocumentRow[]>>;
401
+
402
+ /**
403
+ * Mark documents as inactive (soft delete).
404
+ * Returns count of affected documents.
405
+ */
406
+ markInactive(
407
+ collection: string,
408
+ relPaths: string[]
409
+ ): Promise<StoreResult<number>>;
410
+
411
+ // ─────────────────────────────────────────────────────────────────────────
412
+ // Content (content-addressed)
413
+ // ─────────────────────────────────────────────────────────────────────────
414
+
415
+ /**
416
+ * Store markdown content by mirror hash.
417
+ * Idempotent - no-op if hash exists.
418
+ */
419
+ upsertContent(
420
+ mirrorHash: string,
421
+ markdown: string
422
+ ): Promise<StoreResult<void>>;
423
+
424
+ /**
425
+ * Get markdown content by mirror hash.
426
+ */
427
+ getContent(mirrorHash: string): Promise<StoreResult<string | null>>;
428
+
429
+ // ─────────────────────────────────────────────────────────────────────────
430
+ // Chunks
431
+ // ─────────────────────────────────────────────────────────────────────────
432
+
433
+ /**
434
+ * Store chunks for a mirror hash.
435
+ * Replaces existing chunks for this hash.
436
+ */
437
+ upsertChunks(
438
+ mirrorHash: string,
439
+ chunks: ChunkInput[]
440
+ ): Promise<StoreResult<void>>;
441
+
442
+ /**
443
+ * Get all chunks for a mirror hash.
444
+ */
445
+ getChunks(mirrorHash: string): Promise<StoreResult<ChunkRow[]>>;
446
+
447
+ /**
448
+ * Batch fetch chunks for multiple mirror hashes.
449
+ * Returns Map where each ChunkRow[] is sorted by seq ascending.
450
+ * Missing hashes are not present in the returned Map.
451
+ * Note: Map is not JSON-serializable; internal pipeline optimization only.
452
+ */
453
+ getChunksBatch(
454
+ mirrorHashes: string[]
455
+ ): Promise<StoreResult<Map<string, ChunkRow[]>>>;
456
+
457
+ // ─────────────────────────────────────────────────────────────────────────
458
+ // FTS Search
459
+ // ─────────────────────────────────────────────────────────────────────────
460
+
461
+ /**
462
+ * Search chunks using FTS5.
463
+ */
464
+ searchFts(
465
+ query: string,
466
+ options?: FtsSearchOptions
467
+ ): Promise<StoreResult<FtsResult[]>>;
468
+
469
+ /**
470
+ * Rebuild FTS index for a mirror hash.
471
+ * Called after upserting chunks.
472
+ */
473
+ rebuildFtsForHash(mirrorHash: string): Promise<StoreResult<void>>;
474
+
475
+ // ─────────────────────────────────────────────────────────────────────────
476
+ // Status
477
+ // ─────────────────────────────────────────────────────────────────────────
478
+
479
+ /**
480
+ * Get index status with counts and health info.
481
+ */
482
+ getStatus(): Promise<StoreResult<IndexStatus>>;
483
+
484
+ // ─────────────────────────────────────────────────────────────────────────
485
+ // Errors
486
+ // ─────────────────────────────────────────────────────────────────────────
487
+
488
+ /**
489
+ * Record an ingest error.
490
+ */
491
+ recordError(error: IngestErrorInput): Promise<StoreResult<void>>;
492
+
493
+ /**
494
+ * Get recent ingest errors.
495
+ */
496
+ getRecentErrors(limit?: number): Promise<StoreResult<IngestErrorRow[]>>;
497
+
498
+ // ─────────────────────────────────────────────────────────────────────────
499
+ // Cleanup
500
+ // ─────────────────────────────────────────────────────────────────────────
501
+
502
+ /**
503
+ * Remove orphaned content, chunks, vectors, and expired cache.
504
+ */
505
+ cleanupOrphans(): Promise<StoreResult<CleanupStats>>;
506
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Vector storage and search module.
3
+ *
4
+ * @module src/store/vector
5
+ */
6
+
7
+ export {
8
+ createVectorIndexPort,
9
+ decodeEmbedding,
10
+ encodeEmbedding,
11
+ } from './sqlite-vec';
12
+ export { createVectorStatsPort } from './stats';
13
+ export * from './types';