@knowledgine/cli 0.6.1 → 0.6.3
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/dist/CLAUDE.md +7 -0
- package/dist/commands/benchmark.d.ts +6 -0
- package/dist/commands/benchmark.d.ts.map +1 -0
- package/dist/commands/benchmark.js +136 -0
- package/dist/commands/benchmark.js.map +1 -0
- package/dist/commands/deprecation-check.d.ts +1 -0
- package/dist/commands/deprecation-check.d.ts.map +1 -1
- package/dist/commands/deprecation-check.js +23 -5
- package/dist/commands/deprecation-check.js.map +1 -1
- package/dist/commands/doctor.d.ts +23 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +600 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/explain.d.ts.map +1 -1
- package/dist/commands/explain.js +4 -1
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/ingest.d.ts +1 -0
- package/dist/commands/ingest.d.ts.map +1 -1
- package/dist/commands/ingest.js +142 -2
- package/dist/commands/ingest.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/search.d.ts +2 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +54 -14
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/serve.d.ts +1 -0
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +16 -1
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +8 -0
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +5 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/suggest.d.ts.map +1 -1
- package/dist/commands/suggest.js +12 -0
- package/dist/commands/suggest.js.map +1 -1
- package/dist/commands/upgrade.d.ts +1 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +99 -2
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/index.js +45 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/entity-extractor.d.ts +17 -0
- package/dist/lib/entity-extractor.d.ts.map +1 -0
- package/dist/lib/entity-extractor.js +22 -0
- package/dist/lib/entity-extractor.js.map +1 -0
- package/dist/lib/formatter.d.ts.map +1 -1
- package/dist/lib/formatter.js +13 -8
- package/dist/lib/formatter.js.map +1 -1
- package/dist/templates/skills/knowledgine-explain/references.d.ts +2 -0
- package/dist/templates/skills/knowledgine-explain/references.d.ts.map +1 -0
- package/dist/templates/skills/knowledgine-explain/references.js +183 -0
- package/dist/templates/skills/knowledgine-explain/references.js.map +1 -0
- package/dist/templates/skills/knowledgine-explain/skill-md.d.ts +2 -0
- package/dist/templates/skills/knowledgine-explain/skill-md.d.ts.map +1 -0
- package/dist/templates/skills/knowledgine-explain/skill-md.js +89 -0
- package/dist/templates/skills/knowledgine-explain/skill-md.js.map +1 -0
- package/dist/templates/skills/knowledgine-recall/references.d.ts +2 -0
- package/dist/templates/skills/knowledgine-recall/references.d.ts.map +1 -0
- package/dist/templates/skills/knowledgine-recall/references.js +207 -0
- package/dist/templates/skills/knowledgine-recall/references.js.map +1 -0
- package/dist/templates/skills/knowledgine-recall/skill-md.d.ts +2 -0
- package/dist/templates/skills/knowledgine-recall/skill-md.d.ts.map +1 -0
- package/dist/templates/skills/knowledgine-recall/skill-md.js +86 -0
- package/dist/templates/skills/knowledgine-recall/skill-md.js.map +1 -0
- package/dist/templates/skills/knowledgine-suggest/references.d.ts +2 -0
- package/dist/templates/skills/knowledgine-suggest/references.d.ts.map +1 -0
- package/dist/templates/skills/knowledgine-suggest/references.js +121 -0
- package/dist/templates/skills/knowledgine-suggest/references.js.map +1 -0
- package/dist/templates/skills/knowledgine-suggest/skill-md.d.ts +2 -0
- package/dist/templates/skills/knowledgine-suggest/skill-md.d.ts.map +1 -0
- package/dist/templates/skills/knowledgine-suggest/skill-md.js +94 -0
- package/dist/templates/skills/knowledgine-suggest/skill-md.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
2
|
+
import { existsSync, statSync, accessSync, constants } from "fs";
|
|
3
|
+
import { resolveDefaultPath, createDatabase, Migrator, KnowledgeRepository, ALL_MIGRATIONS, ModelManager, DEFAULT_MODEL_NAME, } from "@knowledgine/core";
|
|
4
|
+
import { colors, symbols } from "../lib/ui/index.js";
|
|
5
|
+
// Check 1: .knowledgine directory exists
|
|
6
|
+
export function checkKnowledgineDir(knowledgineDir) {
|
|
7
|
+
if (!existsSync(knowledgineDir)) {
|
|
8
|
+
return {
|
|
9
|
+
name: "knowledgine directory",
|
|
10
|
+
status: "error",
|
|
11
|
+
message: `.knowledgine directory not found at ${knowledgineDir}`,
|
|
12
|
+
fix: `knowledgine init --path ${resolve(knowledgineDir, "..")}`,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
name: "knowledgine directory",
|
|
17
|
+
status: "pass",
|
|
18
|
+
message: ".knowledgine directory exists",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// Check 2: Database exists and is readable
|
|
22
|
+
export function checkDatabaseExists(dbPath) {
|
|
23
|
+
if (!existsSync(dbPath)) {
|
|
24
|
+
return {
|
|
25
|
+
name: "database file",
|
|
26
|
+
status: "error",
|
|
27
|
+
message: `index.sqlite not found at ${dbPath}`,
|
|
28
|
+
fix: `knowledgine init --path ${resolve(dbPath, "../..")}`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
accessSync(dbPath, constants.R_OK);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return {
|
|
36
|
+
name: "database file",
|
|
37
|
+
status: "error",
|
|
38
|
+
message: `index.sqlite is not readable (permission denied)`,
|
|
39
|
+
fix: `chmod 600 ${dbPath}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
name: "database file",
|
|
44
|
+
status: "pass",
|
|
45
|
+
message: "index.sqlite exists and is readable",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Check 3: Database is not empty (0-byte)
|
|
49
|
+
export function checkDatabaseNotEmpty(dbPath) {
|
|
50
|
+
if (!existsSync(dbPath)) {
|
|
51
|
+
return {
|
|
52
|
+
name: "database size",
|
|
53
|
+
status: "error",
|
|
54
|
+
message: "index.sqlite not found — cannot check size",
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const stat = statSync(dbPath);
|
|
58
|
+
if (stat.size === 0) {
|
|
59
|
+
return {
|
|
60
|
+
name: "database size",
|
|
61
|
+
status: "error",
|
|
62
|
+
message: "index.sqlite is 0 bytes (empty/corrupt file)",
|
|
63
|
+
fix: `rm ${dbPath} && knowledgine init --path ${resolve(dbPath, "../..")}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
name: "database size",
|
|
68
|
+
status: "pass",
|
|
69
|
+
message: `database file is ${stat.size} bytes`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Check 4: Database file permissions (should be readable/writable by owner on Unix)
|
|
73
|
+
export function checkDatabasePermissions(dbPath) {
|
|
74
|
+
if (!existsSync(dbPath)) {
|
|
75
|
+
return {
|
|
76
|
+
name: "database permissions",
|
|
77
|
+
status: "error",
|
|
78
|
+
message: "index.sqlite not found — cannot check permissions",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// On Windows, skip permission check
|
|
82
|
+
if (process.platform === "win32") {
|
|
83
|
+
return {
|
|
84
|
+
name: "database permissions",
|
|
85
|
+
status: "pass",
|
|
86
|
+
message: "permission check skipped on Windows",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
accessSync(dbPath, constants.R_OK | constants.W_OK);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return {
|
|
94
|
+
name: "database permissions",
|
|
95
|
+
status: "warning",
|
|
96
|
+
message: "index.sqlite is not writable by current user",
|
|
97
|
+
fix: `chmod 600 ${dbPath}`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
name: "database permissions",
|
|
102
|
+
status: "pass",
|
|
103
|
+
message: "database file permissions are correct",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Check 5: FTS5 integrity
|
|
107
|
+
export function checkFTS5Integrity(dbPath) {
|
|
108
|
+
if (!existsSync(dbPath) || statSync(dbPath).size === 0) {
|
|
109
|
+
return {
|
|
110
|
+
name: "FTS5 integrity",
|
|
111
|
+
status: "error",
|
|
112
|
+
message: "database unavailable — cannot check FTS5 integrity",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const db = createDatabase(dbPath);
|
|
117
|
+
try {
|
|
118
|
+
// Check if FTS5 index exists
|
|
119
|
+
const ftsTable = db
|
|
120
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='knowledge_notes_fts'")
|
|
121
|
+
.get();
|
|
122
|
+
if (!ftsTable) {
|
|
123
|
+
return {
|
|
124
|
+
name: "FTS5 integrity",
|
|
125
|
+
status: "warning",
|
|
126
|
+
message: "FTS5 index table not found — database may need migration",
|
|
127
|
+
fix: `knowledgine init --path ${resolve(dbPath, "../..")}`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Run FTS5 integrity check (special SELECT command, read-only safe)
|
|
131
|
+
db.prepare("SELECT content FROM knowledge_notes_fts WHERE knowledge_notes_fts MATCH 'a*' LIMIT 1").all();
|
|
132
|
+
return {
|
|
133
|
+
name: "FTS5 integrity",
|
|
134
|
+
status: "pass",
|
|
135
|
+
message: "FTS5 index integrity check passed",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
db.close();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
144
|
+
return {
|
|
145
|
+
name: "FTS5 integrity",
|
|
146
|
+
status: "error",
|
|
147
|
+
message: `FTS5 integrity check failed: ${msg}`,
|
|
148
|
+
fix: `knowledgine init --force --path ${resolve(dbPath, "../..")}`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Check 6: Embedding model files exist
|
|
153
|
+
export function checkModelFiles() {
|
|
154
|
+
try {
|
|
155
|
+
const modelManager = new ModelManager();
|
|
156
|
+
const available = modelManager.isModelAvailable();
|
|
157
|
+
if (!available) {
|
|
158
|
+
return {
|
|
159
|
+
name: "embedding model",
|
|
160
|
+
status: "warning",
|
|
161
|
+
message: `${DEFAULT_MODEL_NAME} model files not found — semantic search unavailable`,
|
|
162
|
+
fix: "knowledgine upgrade --semantic",
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
name: "embedding model",
|
|
167
|
+
status: "pass",
|
|
168
|
+
message: `${DEFAULT_MODEL_NAME} model files are present`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
173
|
+
return {
|
|
174
|
+
name: "embedding model",
|
|
175
|
+
status: "warning",
|
|
176
|
+
message: `Could not check model availability: ${msg}`,
|
|
177
|
+
fix: "knowledgine upgrade --semantic",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Check 7: Embedding coverage percentage
|
|
182
|
+
export function checkEmbeddingCoverage(dbPath) {
|
|
183
|
+
if (!existsSync(dbPath) || statSync(dbPath).size === 0) {
|
|
184
|
+
return {
|
|
185
|
+
name: "embedding coverage",
|
|
186
|
+
status: "error",
|
|
187
|
+
message: "database unavailable — cannot check embedding coverage",
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
const db = createDatabase(dbPath);
|
|
192
|
+
try {
|
|
193
|
+
new Migrator(db, ALL_MIGRATIONS).migrate();
|
|
194
|
+
const repository = new KnowledgeRepository(db);
|
|
195
|
+
const stats = repository.getStats();
|
|
196
|
+
if (stats.totalNotes === 0) {
|
|
197
|
+
return {
|
|
198
|
+
name: "embedding coverage",
|
|
199
|
+
status: "pass",
|
|
200
|
+
message: "no notes indexed yet",
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const withoutEmbeddings = repository.getNotesWithoutEmbeddingIds().length;
|
|
204
|
+
const withEmbeddings = stats.totalNotes - withoutEmbeddings;
|
|
205
|
+
const coverage = Math.round((withEmbeddings / stats.totalNotes) * 100);
|
|
206
|
+
// Determine correct fix command: if model exists, suggest ingest; otherwise, suggest upgrade
|
|
207
|
+
const modelManager = new ModelManager();
|
|
208
|
+
const modelExists = modelManager.isModelAvailable();
|
|
209
|
+
const fixCommand = modelExists
|
|
210
|
+
? "knowledgine ingest --all"
|
|
211
|
+
: "knowledgine upgrade --semantic";
|
|
212
|
+
if (coverage === 100) {
|
|
213
|
+
return {
|
|
214
|
+
name: "embedding coverage",
|
|
215
|
+
status: "pass",
|
|
216
|
+
message: `100% coverage (${withEmbeddings}/${stats.totalNotes} notes have embeddings)`,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
else if (coverage >= 80) {
|
|
220
|
+
return {
|
|
221
|
+
name: "embedding coverage",
|
|
222
|
+
status: "pass",
|
|
223
|
+
message: `${coverage}% coverage (${withEmbeddings}/${stats.totalNotes} notes have embeddings)`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
else if (coverage > 0) {
|
|
227
|
+
return {
|
|
228
|
+
name: "embedding coverage",
|
|
229
|
+
status: "warning",
|
|
230
|
+
message: `${coverage}% coverage — ${withoutEmbeddings} notes missing embeddings`,
|
|
231
|
+
fix: fixCommand,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
return {
|
|
236
|
+
name: "embedding coverage",
|
|
237
|
+
status: "warning",
|
|
238
|
+
message: "no embeddings generated yet — semantic search is unavailable",
|
|
239
|
+
fix: fixCommand,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
db.close();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
249
|
+
return {
|
|
250
|
+
name: "embedding coverage",
|
|
251
|
+
status: "error",
|
|
252
|
+
message: `Failed to check embedding coverage: ${msg}`,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Check 8: sqlite-vec extension loadable
|
|
257
|
+
export async function checkSqliteVec(dbPath) {
|
|
258
|
+
if (!existsSync(dbPath) || statSync(dbPath).size === 0) {
|
|
259
|
+
return {
|
|
260
|
+
name: "sqlite-vec extension",
|
|
261
|
+
status: "warning",
|
|
262
|
+
message: "database unavailable — cannot check sqlite-vec",
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
const { loadSqliteVecExtension, createDatabase: createDb } = await import("@knowledgine/core");
|
|
267
|
+
const db = createDb(dbPath);
|
|
268
|
+
try {
|
|
269
|
+
const loaded = await loadSqliteVecExtension(db);
|
|
270
|
+
if (!loaded) {
|
|
271
|
+
return {
|
|
272
|
+
name: "sqlite-vec extension",
|
|
273
|
+
status: "warning",
|
|
274
|
+
message: "sqlite-vec extension not available — vector search disabled",
|
|
275
|
+
fix: "npm install sqlite-vec (or reinstall knowledgine)",
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
name: "sqlite-vec extension",
|
|
280
|
+
status: "pass",
|
|
281
|
+
message: "sqlite-vec extension loaded successfully",
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
finally {
|
|
285
|
+
db.close();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
290
|
+
return {
|
|
291
|
+
name: "sqlite-vec extension",
|
|
292
|
+
status: "warning",
|
|
293
|
+
message: `sqlite-vec check failed: ${msg}`,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Check 9: Stale embeddings (notes modified after embedding was generated)
|
|
298
|
+
export function checkStaleEmbeddings(dbPath) {
|
|
299
|
+
if (!existsSync(dbPath) || statSync(dbPath).size === 0) {
|
|
300
|
+
return {
|
|
301
|
+
name: "stale embeddings",
|
|
302
|
+
status: "error",
|
|
303
|
+
message: "database unavailable — cannot check stale embeddings",
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const db = createDatabase(dbPath);
|
|
308
|
+
try {
|
|
309
|
+
new Migrator(db, ALL_MIGRATIONS).migrate();
|
|
310
|
+
// Check if embedding_updated_at column exists in the schema
|
|
311
|
+
const tableInfo = db.prepare("PRAGMA table_info(knowledge_notes)").all();
|
|
312
|
+
const hasEmbeddingCol = tableInfo.some((col) => col.name === "embedding_updated_at");
|
|
313
|
+
if (!hasEmbeddingCol) {
|
|
314
|
+
return {
|
|
315
|
+
name: "stale embeddings",
|
|
316
|
+
status: "pass",
|
|
317
|
+
message: "stale embedding check not applicable (embedding_updated_at column not present)",
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
// Count notes where updated_at > embedding_updated_at
|
|
321
|
+
const staleCount = db
|
|
322
|
+
.prepare(`SELECT COUNT(*) as count FROM knowledge_notes
|
|
323
|
+
WHERE embedding_updated_at IS NOT NULL
|
|
324
|
+
AND updated_at IS NOT NULL
|
|
325
|
+
AND updated_at > embedding_updated_at`)
|
|
326
|
+
.get().count;
|
|
327
|
+
if (staleCount > 0) {
|
|
328
|
+
return {
|
|
329
|
+
name: "stale embeddings",
|
|
330
|
+
status: "warning",
|
|
331
|
+
message: `${staleCount} notes have stale embeddings (modified after last embedding update)`,
|
|
332
|
+
fix: "knowledgine upgrade --semantic",
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
name: "stale embeddings",
|
|
337
|
+
status: "pass",
|
|
338
|
+
message: "no stale embeddings detected",
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
finally {
|
|
342
|
+
db.close();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
347
|
+
return {
|
|
348
|
+
name: "stale embeddings",
|
|
349
|
+
status: "warning",
|
|
350
|
+
message: `Could not check stale embeddings: ${msg}`,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Check 10: Node.js version >= 20
|
|
355
|
+
export function checkNodeVersion() {
|
|
356
|
+
const version = process.version; // e.g., "v20.11.0"
|
|
357
|
+
const match = version.match(/^v(\d+)\./);
|
|
358
|
+
if (!match) {
|
|
359
|
+
return {
|
|
360
|
+
name: "Node.js version",
|
|
361
|
+
status: "warning",
|
|
362
|
+
message: `Could not parse Node.js version: ${version}`,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
const major = parseInt(match[1], 10);
|
|
366
|
+
if (major < 20) {
|
|
367
|
+
return {
|
|
368
|
+
name: "Node.js version",
|
|
369
|
+
status: "error",
|
|
370
|
+
message: `Node.js ${version} is below required minimum v20`,
|
|
371
|
+
fix: "nvm install 20 && nvm use 20 (or upgrade Node.js to v20+)",
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
name: "Node.js version",
|
|
376
|
+
status: "pass",
|
|
377
|
+
message: `Node.js ${version} meets minimum requirement (v20+)`,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
// Check 11: Search latency micro-benchmark (single query)
|
|
381
|
+
export async function checkSearchLatency(dbPath) {
|
|
382
|
+
if (!existsSync(dbPath) || statSync(dbPath).size === 0) {
|
|
383
|
+
return {
|
|
384
|
+
name: "search latency",
|
|
385
|
+
status: "error",
|
|
386
|
+
message: "database unavailable — cannot benchmark search",
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
const db = createDatabase(dbPath);
|
|
391
|
+
try {
|
|
392
|
+
new Migrator(db, ALL_MIGRATIONS).migrate();
|
|
393
|
+
const ftsTable = db
|
|
394
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='knowledge_notes_fts'")
|
|
395
|
+
.get();
|
|
396
|
+
if (!ftsTable) {
|
|
397
|
+
return {
|
|
398
|
+
name: "search latency",
|
|
399
|
+
status: "warning",
|
|
400
|
+
message: "FTS5 index not found — cannot benchmark search",
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
const start = Date.now();
|
|
404
|
+
db.prepare("SELECT rowid FROM knowledge_notes_fts WHERE knowledge_notes_fts MATCH ? LIMIT 10").all("test");
|
|
405
|
+
const latencyMs = Date.now() - start;
|
|
406
|
+
if (latencyMs > 500) {
|
|
407
|
+
return {
|
|
408
|
+
name: "search latency",
|
|
409
|
+
status: "warning",
|
|
410
|
+
message: `FTS5 search took ${latencyMs}ms — slower than expected (>500ms)`,
|
|
411
|
+
fix: "Consider running VACUUM on the database: sqlite3 index.sqlite VACUUM",
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
name: "search latency",
|
|
416
|
+
status: "pass",
|
|
417
|
+
message: `FTS5 search latency: ${latencyMs}ms`,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
finally {
|
|
421
|
+
db.close();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
426
|
+
return {
|
|
427
|
+
name: "search latency",
|
|
428
|
+
status: "warning",
|
|
429
|
+
message: `Search latency benchmark failed: ${msg}`,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
export async function doctorCommand(options) {
|
|
434
|
+
const rootPath = resolveDefaultPath(options.path);
|
|
435
|
+
const knowledgineDir = resolve(rootPath, ".knowledgine");
|
|
436
|
+
const dbPath = resolve(knowledgineDir, "index.sqlite");
|
|
437
|
+
const results = [];
|
|
438
|
+
console.error("");
|
|
439
|
+
console.error(` ${colors.bold("knowledgine doctor")} — running health checks...`);
|
|
440
|
+
console.error("");
|
|
441
|
+
// Run all checks, capturing each independently so one failure doesn't block others
|
|
442
|
+
try {
|
|
443
|
+
results.push(checkKnowledgineDir(knowledgineDir));
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
results.push({
|
|
447
|
+
name: "knowledgine directory",
|
|
448
|
+
status: "error",
|
|
449
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
try {
|
|
453
|
+
results.push(checkDatabaseExists(dbPath));
|
|
454
|
+
}
|
|
455
|
+
catch (error) {
|
|
456
|
+
results.push({
|
|
457
|
+
name: "database file",
|
|
458
|
+
status: "error",
|
|
459
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
results.push(checkDatabaseNotEmpty(dbPath));
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
results.push({
|
|
467
|
+
name: "database size",
|
|
468
|
+
status: "error",
|
|
469
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
try {
|
|
473
|
+
results.push(checkDatabasePermissions(dbPath));
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
results.push({
|
|
477
|
+
name: "database permissions",
|
|
478
|
+
status: "error",
|
|
479
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
try {
|
|
483
|
+
results.push(checkFTS5Integrity(dbPath));
|
|
484
|
+
}
|
|
485
|
+
catch (error) {
|
|
486
|
+
results.push({
|
|
487
|
+
name: "FTS5 integrity",
|
|
488
|
+
status: "error",
|
|
489
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
results.push(checkModelFiles());
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
results.push({
|
|
497
|
+
name: "embedding model",
|
|
498
|
+
status: "error",
|
|
499
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
try {
|
|
503
|
+
results.push(checkEmbeddingCoverage(dbPath));
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
results.push({
|
|
507
|
+
name: "embedding coverage",
|
|
508
|
+
status: "error",
|
|
509
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
try {
|
|
513
|
+
results.push(await checkSqliteVec(dbPath));
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
results.push({
|
|
517
|
+
name: "sqlite-vec extension",
|
|
518
|
+
status: "error",
|
|
519
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
try {
|
|
523
|
+
results.push(checkStaleEmbeddings(dbPath));
|
|
524
|
+
}
|
|
525
|
+
catch (error) {
|
|
526
|
+
results.push({
|
|
527
|
+
name: "stale embeddings",
|
|
528
|
+
status: "error",
|
|
529
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
results.push(checkNodeVersion());
|
|
534
|
+
}
|
|
535
|
+
catch (error) {
|
|
536
|
+
results.push({
|
|
537
|
+
name: "Node.js version",
|
|
538
|
+
status: "error",
|
|
539
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
try {
|
|
543
|
+
results.push(await checkSearchLatency(dbPath));
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
results.push({
|
|
547
|
+
name: "search latency",
|
|
548
|
+
status: "error",
|
|
549
|
+
message: `Unexpected error: ${error instanceof Error ? error.message : String(error)}`,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
// Auto-fix: attempt to repair issues when --fix is specified
|
|
553
|
+
if (options.fix) {
|
|
554
|
+
for (const result of results) {
|
|
555
|
+
if (result.status !== "pass" && result.fix) {
|
|
556
|
+
// Auto-fix DB permissions
|
|
557
|
+
if (result.name === "database permissions" && existsSync(dbPath)) {
|
|
558
|
+
try {
|
|
559
|
+
const { chmodSync } = await import("fs");
|
|
560
|
+
chmodSync(dbPath, 0o600);
|
|
561
|
+
result.status = "pass";
|
|
562
|
+
result.message = "database file permissions fixed (chmod 600)";
|
|
563
|
+
console.error(` ${symbols.success} ${colors.success(`Fixed: ${result.name}`)}`);
|
|
564
|
+
}
|
|
565
|
+
catch {
|
|
566
|
+
/* non-fatal */
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// Output: failures first, then success summary
|
|
573
|
+
const failures = results.filter((r) => r.status !== "pass");
|
|
574
|
+
const passes = results.filter((r) => r.status === "pass");
|
|
575
|
+
if (failures.length > 0) {
|
|
576
|
+
for (const f of failures) {
|
|
577
|
+
const icon = f.status === "error" ? symbols.error : symbols.warning;
|
|
578
|
+
const color = f.status === "error" ? colors.error : colors.warning;
|
|
579
|
+
console.error(` ${icon} ${color(f.name)}: ${f.message}`);
|
|
580
|
+
if (f.fix) {
|
|
581
|
+
console.error(` Fix: ${colors.hint(f.fix)}`);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
console.error("");
|
|
585
|
+
}
|
|
586
|
+
if (passes.length > 0) {
|
|
587
|
+
const passNames = passes.map((p) => p.name).join(", ");
|
|
588
|
+
console.error(` ${symbols.success} ${passes.length} checks passed (${passNames})`);
|
|
589
|
+
}
|
|
590
|
+
// Health score: 100 - (errors * 15 + warnings * 5)
|
|
591
|
+
const errorCount = results.filter((r) => r.status === "error").length;
|
|
592
|
+
const warningCount = results.filter((r) => r.status === "warning").length;
|
|
593
|
+
const score = Math.max(0, 100 - errorCount * 15 - warningCount * 5);
|
|
594
|
+
const scoreColor = score >= 80 ? colors.success : score >= 50 ? colors.warning : colors.error;
|
|
595
|
+
console.error(`\n Health Score: ${scoreColor(String(score))}/100`);
|
|
596
|
+
console.error("");
|
|
597
|
+
if (errorCount > 0)
|
|
598
|
+
process.exitCode = 1;
|
|
599
|
+
}
|
|
600
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAqTD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAU7D"}
|
package/dist/commands/explain.js
CHANGED
|
@@ -7,7 +7,10 @@ function formatDate(iso) {
|
|
|
7
7
|
function formatPlain(entityName, entityGraph, provenance) {
|
|
8
8
|
const lines = [];
|
|
9
9
|
lines.push(`Entity: ${entityGraph.name}`);
|
|
10
|
-
|
|
10
|
+
const typeDisplay = entityGraph.entityType === "unknown"
|
|
11
|
+
? `unknown (detected in ${entityGraph.linkedNotes.length} note${entityGraph.linkedNotes.length !== 1 ? "s" : ""}, type not yet classified)`
|
|
12
|
+
: entityGraph.entityType;
|
|
13
|
+
lines.push(`Type: ${typeDisplay}`);
|
|
11
14
|
if (entityGraph.description) {
|
|
12
15
|
lines.push(`Description: ${entityGraph.description}`);
|
|
13
16
|
}
|