@loghead/core 0.1.32 ā 0.1.34
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/api/server.js +129 -49
- package/dist/cli_main.js +46 -41
- package/dist/db/client.js +37 -53
- package/dist/db/migrate.js +0 -13
- package/dist/public/assets/index-Bhs7GffT.js +203 -0
- package/dist/public/assets/index-DNKOkq6D.css +1 -0
- package/dist/public/index.html +2 -2
- package/dist/public/logo.png +0 -0
- package/dist/services/db.js +1 -2
- package/dist/types.js +1 -2
- package/dist/ui/main.js +43 -50
- package/dist/utils/startup.js +22 -20
- package/package.json +7 -5
- package/build/npm/README.md +0 -194
- package/build/npm/bin/loghead +0 -0
- package/build/npm/package.json +0 -32
- package/dist/public/assets/index-BGOKjK0s.css +0 -1
- package/dist/public/assets/index-BtWnFjRZ.js +0 -111
package/dist/api/server.js
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
-
const auth = new auth_1.AuthService();
|
|
13
|
-
async function startApiServer(db) {
|
|
14
|
-
const app = (0, express_1.default)();
|
|
1
|
+
import express from "express";
|
|
2
|
+
import cors from "cors";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
export async function startApiServer(db, auth) {
|
|
10
|
+
const app = express();
|
|
15
11
|
const port = process.env.PORT || 4567;
|
|
16
|
-
app.use((
|
|
17
|
-
app.use(
|
|
12
|
+
app.use(cors());
|
|
13
|
+
app.use(express.json());
|
|
18
14
|
// Serve static frontend files
|
|
19
15
|
// Determine path based on whether we are running in src (dev) or dist (prod)
|
|
20
|
-
let publicPath =
|
|
21
|
-
if (!
|
|
16
|
+
let publicPath = path.join(__dirname, "../public");
|
|
17
|
+
if (!fs.existsSync(publicPath)) {
|
|
22
18
|
// Try looking in dist/public if we are in src
|
|
23
|
-
publicPath =
|
|
19
|
+
publicPath = path.join(__dirname, "../../dist/public");
|
|
24
20
|
}
|
|
25
|
-
if (
|
|
26
|
-
console.log(
|
|
27
|
-
app.use(
|
|
21
|
+
if (fs.existsSync(publicPath)) {
|
|
22
|
+
console.log(chalk.blue(`Serving frontend from: ${publicPath}`));
|
|
23
|
+
app.use(express.static(publicPath));
|
|
28
24
|
}
|
|
29
25
|
else {
|
|
30
|
-
console.warn(
|
|
26
|
+
console.warn(chalk.yellow("Frontend build not found. Run 'npm run build' in packages/core/frontend to build the UI."));
|
|
31
27
|
}
|
|
32
28
|
await auth.initialize();
|
|
33
29
|
// console.log(chalk.bold.green(`\nš» API server running on:`));
|
|
@@ -195,37 +191,55 @@ async function startApiServer(db) {
|
|
|
195
191
|
res.status(500).json({ error: String(e) });
|
|
196
192
|
}
|
|
197
193
|
});
|
|
198
|
-
app.get("/api/projects", (req, res) => {
|
|
199
|
-
const projects = db.listProjects();
|
|
194
|
+
app.get("/api/projects", async (req, res) => {
|
|
195
|
+
const projects = await db.listProjects();
|
|
200
196
|
res.json(projects);
|
|
201
197
|
});
|
|
202
|
-
app.post("/api/projects", (req, res) => {
|
|
198
|
+
app.post("/api/projects", async (req, res) => {
|
|
203
199
|
const { name } = req.body;
|
|
204
200
|
if (!name)
|
|
205
201
|
return res.status(400).json({ error: "Name required" });
|
|
206
|
-
const project = db.createProject(name);
|
|
202
|
+
const project = await db.createProject(name);
|
|
207
203
|
res.json(project);
|
|
208
204
|
});
|
|
209
|
-
app.delete("/api/projects/:id", (req, res) => {
|
|
205
|
+
app.delete("/api/projects/:id", async (req, res) => {
|
|
210
206
|
const { id } = req.params;
|
|
211
|
-
db.deleteProject(id);
|
|
207
|
+
await db.deleteProject(id);
|
|
212
208
|
res.json({ success: true });
|
|
213
209
|
});
|
|
214
|
-
app.
|
|
210
|
+
app.patch("/api/projects/:id", async (req, res) => {
|
|
211
|
+
const { id } = req.params;
|
|
212
|
+
const { name } = req.body;
|
|
213
|
+
if (!name || !name.trim()) {
|
|
214
|
+
return res.status(400).send("Name required");
|
|
215
|
+
}
|
|
216
|
+
const project = await db.renameProject(id, name.trim());
|
|
217
|
+
res.json(project);
|
|
218
|
+
});
|
|
219
|
+
app.get("/api/streams", async (req, res) => {
|
|
215
220
|
const projectId = req.query.projectId;
|
|
216
221
|
if (projectId) {
|
|
217
|
-
const streams = db.listStreams(projectId);
|
|
222
|
+
const streams = await db.listStreams(projectId);
|
|
218
223
|
res.json(streams);
|
|
219
224
|
}
|
|
220
225
|
else {
|
|
221
226
|
res.status(400).send("Missing projectId");
|
|
222
227
|
}
|
|
223
228
|
});
|
|
224
|
-
app.delete("/api/streams/:id", (req, res) => {
|
|
229
|
+
app.delete("/api/streams/:id", async (req, res) => {
|
|
225
230
|
const { id } = req.params;
|
|
226
|
-
db.deleteStream(id);
|
|
231
|
+
await db.deleteStream(id);
|
|
227
232
|
res.json({ success: true });
|
|
228
233
|
});
|
|
234
|
+
app.patch("/api/streams/:id", async (req, res) => {
|
|
235
|
+
const { id } = req.params;
|
|
236
|
+
const { name } = req.body;
|
|
237
|
+
if (!name || !name.trim()) {
|
|
238
|
+
return res.status(400).send("Name required");
|
|
239
|
+
}
|
|
240
|
+
const stream = await db.renameStream(id, name.trim());
|
|
241
|
+
res.json(stream);
|
|
242
|
+
});
|
|
229
243
|
app.get("/api/streams/:id/token", async (req, res) => {
|
|
230
244
|
const { id } = req.params;
|
|
231
245
|
try {
|
|
@@ -236,19 +250,24 @@ async function startApiServer(db) {
|
|
|
236
250
|
res.status(500).json({ error: String(e) });
|
|
237
251
|
}
|
|
238
252
|
});
|
|
239
|
-
app.post("/api/streams", (req, res) => {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
253
|
+
app.post("/api/streams", async (req, res) => {
|
|
254
|
+
try {
|
|
255
|
+
const { projectId, name, type, config } = req.body || {};
|
|
256
|
+
if (!projectId) {
|
|
257
|
+
return res.status(400).send("Missing projectId");
|
|
258
|
+
}
|
|
259
|
+
if (!name || typeof name !== "string" || !name.trim()) {
|
|
260
|
+
return res.status(400).send("Missing name");
|
|
261
|
+
}
|
|
262
|
+
if (!type || typeof type !== "string") {
|
|
263
|
+
return res.status(400).send("Missing type");
|
|
264
|
+
}
|
|
265
|
+
const stream = await db.createStream(projectId, type, name.trim(), config || {});
|
|
266
|
+
res.json(stream);
|
|
249
267
|
}
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
catch (e) {
|
|
269
|
+
console.error("Create stream error:", e);
|
|
270
|
+
res.status(500).json({ error: String(e) });
|
|
252
271
|
}
|
|
253
272
|
});
|
|
254
273
|
app.post("/api/streams/create", async (req, res) => {
|
|
@@ -256,6 +275,23 @@ async function startApiServer(db) {
|
|
|
256
275
|
const stream = await db.createStream(body.projectId, body.type, body.name, body.config || {});
|
|
257
276
|
res.json(stream);
|
|
258
277
|
});
|
|
278
|
+
app.get("/api/search", async (req, res) => {
|
|
279
|
+
const query = req.query.query || req.query.q;
|
|
280
|
+
const streamId = req.query.streamId;
|
|
281
|
+
const limitStr = req.query.limit;
|
|
282
|
+
const limit = limitStr ? parseInt(limitStr) : 50;
|
|
283
|
+
if (!query) {
|
|
284
|
+
return res.json([]);
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const results = await db.searchLogs(query, streamId, limit);
|
|
288
|
+
res.json(results);
|
|
289
|
+
}
|
|
290
|
+
catch (e) {
|
|
291
|
+
console.error("Error searching logs:", e);
|
|
292
|
+
res.status(500).send(String(e));
|
|
293
|
+
}
|
|
294
|
+
});
|
|
259
295
|
app.get("/api/logs", async (req, res) => {
|
|
260
296
|
const streamId = req.query.streamId;
|
|
261
297
|
if (!streamId) {
|
|
@@ -275,20 +311,64 @@ async function startApiServer(db) {
|
|
|
275
311
|
const query = req.query.q;
|
|
276
312
|
let logs;
|
|
277
313
|
if (query) {
|
|
278
|
-
logs = await db.searchLogs(
|
|
314
|
+
logs = await db.searchLogs(query, streamId, limit);
|
|
279
315
|
}
|
|
280
316
|
else {
|
|
281
|
-
logs = db.getRecentLogs(streamId, limit, offset);
|
|
317
|
+
logs = await db.getRecentLogs(streamId, limit, offset);
|
|
282
318
|
}
|
|
283
319
|
res.json(logs);
|
|
284
320
|
});
|
|
321
|
+
app.get("/api/issues", async (req, res) => {
|
|
322
|
+
const projectId = req.query.projectId;
|
|
323
|
+
const status = req.query.status;
|
|
324
|
+
const limit = parseInt(req.query.limit || "50");
|
|
325
|
+
if (!projectId) {
|
|
326
|
+
return res.status(400).send("Missing projectId");
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
const issues = await db.getIssues(projectId, status, limit);
|
|
330
|
+
res.json(issues);
|
|
331
|
+
}
|
|
332
|
+
catch (e) {
|
|
333
|
+
console.error("Error fetching issues:", e);
|
|
334
|
+
res.status(500).send(String(e));
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
app.get("/api/issues/:id", async (req, res) => {
|
|
338
|
+
const { id } = req.params;
|
|
339
|
+
try {
|
|
340
|
+
const data = await db.getIssue(id);
|
|
341
|
+
if (!data)
|
|
342
|
+
return res.status(404).send("Issue not found");
|
|
343
|
+
res.json(data);
|
|
344
|
+
}
|
|
345
|
+
catch (e) {
|
|
346
|
+
console.error("Error fetching issue details:", e);
|
|
347
|
+
res.status(500).send(String(e));
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
app.patch("/api/issues/:id", async (req, res) => {
|
|
351
|
+
const { id } = req.params;
|
|
352
|
+
const { status } = req.body;
|
|
353
|
+
if (status !== "open" && status !== "resolved") {
|
|
354
|
+
return res.status(400).send("Invalid status");
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
await db.updateIssueStatus(id, status);
|
|
358
|
+
res.json({ success: true });
|
|
359
|
+
}
|
|
360
|
+
catch (e) {
|
|
361
|
+
console.error("Error updating issue:", e);
|
|
362
|
+
res.status(500).send(String(e));
|
|
363
|
+
}
|
|
364
|
+
});
|
|
285
365
|
// SPA fallback
|
|
286
366
|
app.get("*", (req, res) => {
|
|
287
367
|
if (req.path.startsWith("/api")) {
|
|
288
368
|
return res.status(404).json({ error: "Not Found" });
|
|
289
369
|
}
|
|
290
|
-
if (
|
|
291
|
-
res.sendFile(
|
|
370
|
+
if (fs.existsSync(path.join(publicPath, "index.html"))) {
|
|
371
|
+
res.sendFile(path.join(publicPath, "index.html"));
|
|
292
372
|
}
|
|
293
373
|
else {
|
|
294
374
|
res.status(404).send("Dashboard not found. Please build the frontend.");
|
package/dist/cli_main.js
CHANGED
|
@@ -1,59 +1,64 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// import { ensureInfrastructure } from "./utils/startup"; // Might need adjustment
|
|
13
|
-
const auth_1 = require("./services/auth");
|
|
14
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
-
const db = new db_1.DbService();
|
|
16
|
-
const auth = new auth_1.AuthService();
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { hideBin } from "yargs/helpers";
|
|
4
|
+
import { dbService, authService, dbAdapter } from "./db/client.js";
|
|
5
|
+
import { startApiServer } from "./api/server.js";
|
|
6
|
+
import { migrate } from "@loghead/db";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
function isUnsupportedVectorIndexError(error) {
|
|
9
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
10
|
+
return msg.includes("invalid expression in CREATE INDEX") && msg.includes("libsql_vector_idx");
|
|
11
|
+
}
|
|
17
12
|
async function main() {
|
|
18
|
-
const argv = await (
|
|
13
|
+
const argv = await yargs(hideBin(process.argv))
|
|
19
14
|
.command(["start", "$0"], "Start API Server", {}, async (argv) => {
|
|
20
15
|
// console.log("Ensuring database is initialized...");
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
try {
|
|
17
|
+
await migrate(dbAdapter, false); // Run migrations silently
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
if (isUnsupportedVectorIndexError(e)) {
|
|
21
|
+
console.warn("[Vector] Embedded DB does not support vector index expressions yet; continuing without vec_logs_idx.");
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
throw e;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const token = await authService.getOrCreateMcpToken();
|
|
23
28
|
// Start API Server (this sets up express listen)
|
|
24
|
-
await (
|
|
29
|
+
await startApiServer(dbService, authService);
|
|
25
30
|
// console.clear();
|
|
26
|
-
console.log(
|
|
31
|
+
console.log(chalk.bold.green(`
|
|
27
32
|
ā ā ā
|
|
28
33
|
ā āāāāāāāāāāāāāāāāāā
|
|
29
34
|
ā ā āāāāā āāā āāāā ā
|
|
30
35
|
āāāāā āāāā āāāāāāāāāā
|
|
31
36
|
`));
|
|
32
|
-
console.log(
|
|
33
|
-
console.log(
|
|
34
|
-
console.log(
|
|
37
|
+
console.log(chalk.gray("--------------------------------------------------"));
|
|
38
|
+
console.log(chalk.bold(" š¢ Loghead is running"));
|
|
39
|
+
console.log(chalk.gray("--------------------------------------------------"));
|
|
35
40
|
console.log("");
|
|
36
|
-
console.log(
|
|
37
|
-
console.log(
|
|
41
|
+
console.log(chalk.bold(" š„ļø Dashboard : ") + chalk.cyan("http://localhost:4567"));
|
|
42
|
+
console.log(chalk.bold(" š MCP Server: ") + chalk.cyan("http://localhost:4567/sse"));
|
|
38
43
|
console.log("");
|
|
39
|
-
console.log(
|
|
40
|
-
console.log(
|
|
44
|
+
console.log(chalk.bold(" š MCP Token : "));
|
|
45
|
+
console.log(chalk.yellow(token));
|
|
41
46
|
console.log("");
|
|
42
|
-
console.log(
|
|
43
|
-
console.log(
|
|
47
|
+
console.log(chalk.gray("--------------------------------------------------"));
|
|
48
|
+
console.log(chalk.gray(" Press Ctrl+C to stop"));
|
|
44
49
|
})
|
|
45
50
|
.command("projects <cmd> [name]", "Manage projects", (yargs) => {
|
|
46
51
|
yargs
|
|
47
|
-
.command("list", "List projects", {}, () => {
|
|
48
|
-
const projects =
|
|
52
|
+
.command("list", "List projects", {}, async () => {
|
|
53
|
+
const projects = await dbService.listProjects();
|
|
49
54
|
console.table(projects);
|
|
50
55
|
})
|
|
51
|
-
.command("add <name>", "Add project", {}, (argv) => {
|
|
52
|
-
const p =
|
|
56
|
+
.command("add <name>", "Add project", {}, async (argv) => {
|
|
57
|
+
const p = await dbService.createProject(argv.name);
|
|
53
58
|
console.log(`Project created: ${p.id}`);
|
|
54
59
|
})
|
|
55
|
-
.command("delete <id>", "Delete project", {}, (argv) => {
|
|
56
|
-
|
|
60
|
+
.command("delete <id>", "Delete project", {}, async (argv) => {
|
|
61
|
+
await dbService.deleteProject(argv.id);
|
|
57
62
|
console.log(`Project deleted: ${argv.id}`);
|
|
58
63
|
});
|
|
59
64
|
})
|
|
@@ -61,8 +66,8 @@ async function main() {
|
|
|
61
66
|
yargs
|
|
62
67
|
.command("list", "List streams", {
|
|
63
68
|
project: { type: "string", demandOption: true },
|
|
64
|
-
}, (argv) => {
|
|
65
|
-
const streams =
|
|
69
|
+
}, async (argv) => {
|
|
70
|
+
const streams = await dbService.listStreams(argv.project);
|
|
66
71
|
console.table(streams);
|
|
67
72
|
})
|
|
68
73
|
.command("add <type> <name>", "Add stream", {
|
|
@@ -73,16 +78,16 @@ async function main() {
|
|
|
73
78
|
if (argv.type === "docker" && argv.container) {
|
|
74
79
|
config.container = argv.container;
|
|
75
80
|
}
|
|
76
|
-
const s = await
|
|
81
|
+
const s = await dbService.createStream(argv.project, argv.type, argv.name, config);
|
|
77
82
|
console.log(`Stream created: ${s.id}`);
|
|
78
83
|
console.log(`Token: ${s.token}`);
|
|
79
84
|
})
|
|
80
85
|
.command("token <streamId>", "Get token for stream", {}, async (argv) => {
|
|
81
|
-
const token = await
|
|
86
|
+
const token = await authService.createStreamToken(argv.streamId);
|
|
82
87
|
console.log(`Token: ${token}`);
|
|
83
88
|
})
|
|
84
|
-
.command("delete <id>", "Delete stream", {}, (argv) => {
|
|
85
|
-
|
|
89
|
+
.command("delete <id>", "Delete stream", {}, async (argv) => {
|
|
90
|
+
await dbService.deleteStream(argv.id);
|
|
86
91
|
console.log(`Stream deleted: ${argv.id}`);
|
|
87
92
|
});
|
|
88
93
|
})
|
package/dist/db/client.js
CHANGED
|
@@ -1,55 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.db = void 0;
|
|
40
|
-
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
41
|
-
const sqliteVec = __importStar(require("sqlite-vec"));
|
|
42
|
-
const path_1 = __importDefault(require("path"));
|
|
43
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
44
|
-
dotenv_1.default.config();
|
|
1
|
+
import { connect } from "@tursodatabase/database";
|
|
2
|
+
import { rm } from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import dotenv from "dotenv";
|
|
5
|
+
import { LocalLibSqlAdapter, DbService, AuthService, OllamaService } from "@loghead/db";
|
|
6
|
+
dotenv.config();
|
|
45
7
|
const dbPath = process.env.LOGHEAD_DB_PATH || "loghead.db";
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
8
|
+
const resolvedDbPath = path.resolve(dbPath);
|
|
9
|
+
console.log(`[DB] Using database at: ${resolvedDbPath}`);
|
|
10
|
+
async function openLocalDb() {
|
|
11
|
+
let db = await connect(resolvedDbPath);
|
|
12
|
+
try {
|
|
13
|
+
const legacyRows = (await db
|
|
14
|
+
.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='vec_logs'")
|
|
15
|
+
.all());
|
|
16
|
+
const hasLegacyVec0 = legacyRows.some((r) => (r.sql || "").toLowerCase().includes("vec0"));
|
|
17
|
+
if (hasLegacyVec0) {
|
|
18
|
+
console.warn("[DB] Legacy sqlite-vec schema detected. Resetting local DB file.");
|
|
19
|
+
db.close();
|
|
20
|
+
await Promise.allSettled([
|
|
21
|
+
rm(resolvedDbPath, { force: true }),
|
|
22
|
+
rm(`${resolvedDbPath}-wal`, { force: true }),
|
|
23
|
+
rm(`${resolvedDbPath}-shm`, { force: true }),
|
|
24
|
+
rm(`${resolvedDbPath}-journal`, { force: true }),
|
|
25
|
+
]);
|
|
26
|
+
db = await connect(resolvedDbPath);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// If sqlite_master inspection fails, continue and let migrations handle setup.
|
|
31
|
+
}
|
|
32
|
+
return db;
|
|
55
33
|
}
|
|
34
|
+
const db = await openLocalDb();
|
|
35
|
+
const dbAdapter = new LocalLibSqlAdapter(db);
|
|
36
|
+
const authService = new AuthService(dbAdapter);
|
|
37
|
+
const ollamaService = new OllamaService();
|
|
38
|
+
const dbService = new DbService(dbAdapter, authService, ollamaService);
|
|
39
|
+
export { dbAdapter, authService, ollamaService, dbService };
|
package/dist/db/migrate.js
CHANGED
|
@@ -60,19 +60,6 @@ function migrate(verbose = true) {
|
|
|
60
60
|
catch (e) {
|
|
61
61
|
console.warn("Failed to create virtual vector table. Is sqlite-vec loaded?", e);
|
|
62
62
|
}
|
|
63
|
-
// Trigger to clean up vec_logs when logs are deleted
|
|
64
|
-
try {
|
|
65
|
-
client_1.db.exec(`
|
|
66
|
-
CREATE TRIGGER IF NOT EXISTS delete_vec_log
|
|
67
|
-
AFTER DELETE ON logs
|
|
68
|
-
BEGIN
|
|
69
|
-
DELETE FROM vec_logs WHERE rowid = old.rowid;
|
|
70
|
-
END;
|
|
71
|
-
`);
|
|
72
|
-
}
|
|
73
|
-
catch (e) {
|
|
74
|
-
console.warn("Failed to create trigger delete_vec_log", e);
|
|
75
|
-
}
|
|
76
63
|
if (verbose)
|
|
77
64
|
console.log("Migrations complete.");
|
|
78
65
|
}
|