@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.
- package/README.md +256 -0
- package/assets/skill/SKILL.md +112 -0
- package/assets/skill/cli-reference.md +327 -0
- package/assets/skill/examples.md +234 -0
- package/assets/skill/mcp-reference.md +159 -0
- package/package.json +90 -0
- package/src/app/constants.ts +313 -0
- package/src/cli/colors.ts +65 -0
- package/src/cli/commands/ask.ts +545 -0
- package/src/cli/commands/cleanup.ts +105 -0
- package/src/cli/commands/collection/add.ts +120 -0
- package/src/cli/commands/collection/index.ts +10 -0
- package/src/cli/commands/collection/list.ts +108 -0
- package/src/cli/commands/collection/remove.ts +64 -0
- package/src/cli/commands/collection/rename.ts +95 -0
- package/src/cli/commands/context/add.ts +67 -0
- package/src/cli/commands/context/check.ts +153 -0
- package/src/cli/commands/context/index.ts +10 -0
- package/src/cli/commands/context/list.ts +109 -0
- package/src/cli/commands/context/rm.ts +52 -0
- package/src/cli/commands/doctor.ts +393 -0
- package/src/cli/commands/embed.ts +462 -0
- package/src/cli/commands/get.ts +356 -0
- package/src/cli/commands/index-cmd.ts +119 -0
- package/src/cli/commands/index.ts +102 -0
- package/src/cli/commands/init.ts +328 -0
- package/src/cli/commands/ls.ts +217 -0
- package/src/cli/commands/mcp/config.ts +300 -0
- package/src/cli/commands/mcp/index.ts +24 -0
- package/src/cli/commands/mcp/install.ts +203 -0
- package/src/cli/commands/mcp/paths.ts +470 -0
- package/src/cli/commands/mcp/status.ts +222 -0
- package/src/cli/commands/mcp/uninstall.ts +158 -0
- package/src/cli/commands/mcp.ts +20 -0
- package/src/cli/commands/models/clear.ts +103 -0
- package/src/cli/commands/models/index.ts +32 -0
- package/src/cli/commands/models/list.ts +214 -0
- package/src/cli/commands/models/path.ts +51 -0
- package/src/cli/commands/models/pull.ts +199 -0
- package/src/cli/commands/models/use.ts +85 -0
- package/src/cli/commands/multi-get.ts +400 -0
- package/src/cli/commands/query.ts +220 -0
- package/src/cli/commands/ref-parser.ts +108 -0
- package/src/cli/commands/reset.ts +191 -0
- package/src/cli/commands/search.ts +136 -0
- package/src/cli/commands/shared.ts +156 -0
- package/src/cli/commands/skill/index.ts +19 -0
- package/src/cli/commands/skill/install.ts +197 -0
- package/src/cli/commands/skill/paths-cmd.ts +81 -0
- package/src/cli/commands/skill/paths.ts +191 -0
- package/src/cli/commands/skill/show.ts +73 -0
- package/src/cli/commands/skill/uninstall.ts +141 -0
- package/src/cli/commands/status.ts +205 -0
- package/src/cli/commands/update.ts +68 -0
- package/src/cli/commands/vsearch.ts +188 -0
- package/src/cli/context.ts +64 -0
- package/src/cli/errors.ts +64 -0
- package/src/cli/format/search-results.ts +211 -0
- package/src/cli/options.ts +183 -0
- package/src/cli/program.ts +1330 -0
- package/src/cli/run.ts +213 -0
- package/src/cli/ui.ts +92 -0
- package/src/config/defaults.ts +20 -0
- package/src/config/index.ts +55 -0
- package/src/config/loader.ts +161 -0
- package/src/config/paths.ts +87 -0
- package/src/config/saver.ts +153 -0
- package/src/config/types.ts +280 -0
- package/src/converters/adapters/markitdownTs/adapter.ts +140 -0
- package/src/converters/adapters/officeparser/adapter.ts +126 -0
- package/src/converters/canonicalize.ts +89 -0
- package/src/converters/errors.ts +218 -0
- package/src/converters/index.ts +51 -0
- package/src/converters/mime.ts +163 -0
- package/src/converters/native/markdown.ts +115 -0
- package/src/converters/native/plaintext.ts +56 -0
- package/src/converters/path.ts +48 -0
- package/src/converters/pipeline.ts +159 -0
- package/src/converters/registry.ts +74 -0
- package/src/converters/types.ts +123 -0
- package/src/converters/versions.ts +24 -0
- package/src/index.ts +27 -0
- package/src/ingestion/chunker.ts +238 -0
- package/src/ingestion/index.ts +32 -0
- package/src/ingestion/language.ts +276 -0
- package/src/ingestion/sync.ts +671 -0
- package/src/ingestion/types.ts +219 -0
- package/src/ingestion/walker.ts +235 -0
- package/src/llm/cache.ts +467 -0
- package/src/llm/errors.ts +191 -0
- package/src/llm/index.ts +58 -0
- package/src/llm/nodeLlamaCpp/adapter.ts +133 -0
- package/src/llm/nodeLlamaCpp/embedding.ts +165 -0
- package/src/llm/nodeLlamaCpp/generation.ts +88 -0
- package/src/llm/nodeLlamaCpp/lifecycle.ts +317 -0
- package/src/llm/nodeLlamaCpp/rerank.ts +94 -0
- package/src/llm/registry.ts +86 -0
- package/src/llm/types.ts +129 -0
- package/src/mcp/resources/index.ts +151 -0
- package/src/mcp/server.ts +229 -0
- package/src/mcp/tools/get.ts +220 -0
- package/src/mcp/tools/index.ts +160 -0
- package/src/mcp/tools/multi-get.ts +263 -0
- package/src/mcp/tools/query.ts +226 -0
- package/src/mcp/tools/search.ts +119 -0
- package/src/mcp/tools/status.ts +81 -0
- package/src/mcp/tools/vsearch.ts +198 -0
- package/src/pipeline/chunk-lookup.ts +44 -0
- package/src/pipeline/expansion.ts +256 -0
- package/src/pipeline/explain.ts +115 -0
- package/src/pipeline/fusion.ts +185 -0
- package/src/pipeline/hybrid.ts +535 -0
- package/src/pipeline/index.ts +64 -0
- package/src/pipeline/query-language.ts +118 -0
- package/src/pipeline/rerank.ts +223 -0
- package/src/pipeline/search.ts +261 -0
- package/src/pipeline/types.ts +328 -0
- package/src/pipeline/vsearch.ts +348 -0
- package/src/store/index.ts +41 -0
- package/src/store/migrations/001-initial.ts +196 -0
- package/src/store/migrations/index.ts +20 -0
- package/src/store/migrations/runner.ts +187 -0
- package/src/store/sqlite/adapter.ts +1242 -0
- package/src/store/sqlite/index.ts +7 -0
- package/src/store/sqlite/setup.ts +129 -0
- package/src/store/sqlite/types.ts +28 -0
- package/src/store/types.ts +506 -0
- package/src/store/vector/index.ts +13 -0
- package/src/store/vector/sqlite-vec.ts +373 -0
- package/src/store/vector/stats.ts +152 -0
- package/src/store/vector/types.ts +115 -0
|
@@ -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';
|