@qnote/q-ai-note 1.0.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 +50 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +55 -0
- package/dist/cli.js.map +1 -0
- package/dist/server/aiClient.d.ts +11 -0
- package/dist/server/aiClient.d.ts.map +1 -0
- package/dist/server/aiClient.js +83 -0
- package/dist/server/aiClient.js.map +1 -0
- package/dist/server/api/batchRecovery.d.ts +11 -0
- package/dist/server/api/batchRecovery.d.ts.map +1 -0
- package/dist/server/api/batchRecovery.js +68 -0
- package/dist/server/api/batchRecovery.js.map +1 -0
- package/dist/server/api/chat.d.ts +3 -0
- package/dist/server/api/chat.d.ts.map +1 -0
- package/dist/server/api/chat.js +485 -0
- package/dist/server/api/chat.js.map +1 -0
- package/dist/server/api/diary.d.ts +3 -0
- package/dist/server/api/diary.d.ts.map +1 -0
- package/dist/server/api/diary.js +102 -0
- package/dist/server/api/diary.js.map +1 -0
- package/dist/server/api/sandbox.d.ts +3 -0
- package/dist/server/api/sandbox.d.ts.map +1 -0
- package/dist/server/api/sandbox.js +87 -0
- package/dist/server/api/sandbox.js.map +1 -0
- package/dist/server/api/settings.d.ts +3 -0
- package/dist/server/api/settings.d.ts.map +1 -0
- package/dist/server/api/settings.js +45 -0
- package/dist/server/api/settings.js.map +1 -0
- package/dist/server/api/workItem.d.ts +3 -0
- package/dist/server/api/workItem.d.ts.map +1 -0
- package/dist/server/api/workItem.js +290 -0
- package/dist/server/api/workItem.js.map +1 -0
- package/dist/server/chatUtils.d.ts +15 -0
- package/dist/server/chatUtils.d.ts.map +1 -0
- package/dist/server/chatUtils.js +52 -0
- package/dist/server/chatUtils.js.map +1 -0
- package/dist/server/config.d.ts +14 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +56 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/db.d.ts +6 -0
- package/dist/server/db.d.ts.map +1 -0
- package/dist/server/db.js +106 -0
- package/dist/server/db.js.map +1 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +72 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/react/agent.d.ts +56 -0
- package/dist/server/react/agent.d.ts.map +1 -0
- package/dist/server/react/agent.js +219 -0
- package/dist/server/react/agent.js.map +1 -0
- package/dist/server/react/prompts.d.ts +13 -0
- package/dist/server/react/prompts.d.ts.map +1 -0
- package/dist/server/react/prompts.js +84 -0
- package/dist/server/react/prompts.js.map +1 -0
- package/dist/server/react/tools.d.ts +67 -0
- package/dist/server/react/tools.d.ts.map +1 -0
- package/dist/server/react/tools.js +208 -0
- package/dist/server/react/tools.js.map +1 -0
- package/dist/server/types.d.ts +59 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/web/app.js +1081 -0
- package/dist/web/chatView.js +31 -0
- package/dist/web/index.html +218 -0
- package/dist/web/shared.js +49 -0
- package/dist/web/styles.css +1320 -0
- package/dist/web/vueRenderers.js +191 -0
- package/package.json +46 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { db } from '../db';
|
|
4
|
+
const router = Router();
|
|
5
|
+
function now() {
|
|
6
|
+
return new Date().toISOString();
|
|
7
|
+
}
|
|
8
|
+
router.get('/', (_req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const sandboxes = db.prepare('SELECT * FROM sandboxes ORDER BY updated_at DESC').all();
|
|
11
|
+
const response = { success: true, data: sandboxes };
|
|
12
|
+
res.json(response);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
const response = { success: false, error: String(error) };
|
|
16
|
+
res.status(500).json(response);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
router.get('/:id', (req, res) => {
|
|
20
|
+
try {
|
|
21
|
+
const sandbox = db.prepare('SELECT * FROM sandboxes WHERE id = ?').get(req.params.id);
|
|
22
|
+
if (!sandbox) {
|
|
23
|
+
const response = { success: false, error: 'Sandbox not found' };
|
|
24
|
+
return res.status(404).json(response);
|
|
25
|
+
}
|
|
26
|
+
const response = { success: true, data: sandbox };
|
|
27
|
+
res.json(response);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
const response = { success: false, error: String(error) };
|
|
31
|
+
res.status(500).json(response);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
router.post('/', (req, res) => {
|
|
35
|
+
try {
|
|
36
|
+
const { name, description = '' } = req.body;
|
|
37
|
+
if (!name) {
|
|
38
|
+
const response = { success: false, error: 'Name is required' };
|
|
39
|
+
return res.status(400).json(response);
|
|
40
|
+
}
|
|
41
|
+
const id = uuidv4();
|
|
42
|
+
const timestamp = now();
|
|
43
|
+
db.prepare('INSERT INTO sandboxes (id, name, description, created_at, updated_at) VALUES (?, ?, ?, ?, ?)').run(id, name, description, timestamp, timestamp);
|
|
44
|
+
const sandbox = { id, name, description, created_at: timestamp, updated_at: timestamp };
|
|
45
|
+
const response = { success: true, data: sandbox };
|
|
46
|
+
res.status(201).json(response);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const response = { success: false, error: String(error) };
|
|
50
|
+
res.status(500).json(response);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
router.put('/:id', (req, res) => {
|
|
54
|
+
try {
|
|
55
|
+
const { name, description } = req.body;
|
|
56
|
+
const timestamp = now();
|
|
57
|
+
const result = db.prepare('UPDATE sandboxes SET name = COALESCE(?, name), description = COALESCE(?, description), updated_at = ? WHERE id = ?').run(name ?? null, description ?? null, timestamp, req.params.id);
|
|
58
|
+
if (result.changes === 0) {
|
|
59
|
+
const response = { success: false, error: 'Sandbox not found' };
|
|
60
|
+
return res.status(404).json(response);
|
|
61
|
+
}
|
|
62
|
+
const sandbox = db.prepare('SELECT * FROM sandboxes WHERE id = ?').get(req.params.id);
|
|
63
|
+
const response = { success: true, data: sandbox };
|
|
64
|
+
res.json(response);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const response = { success: false, error: String(error) };
|
|
68
|
+
res.status(500).json(response);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
router.delete('/:id', (req, res) => {
|
|
72
|
+
try {
|
|
73
|
+
const result = db.prepare('DELETE FROM sandboxes WHERE id = ?').run(req.params.id);
|
|
74
|
+
if (result.changes === 0) {
|
|
75
|
+
const response = { success: false, error: 'Sandbox not found' };
|
|
76
|
+
return res.status(404).json(response);
|
|
77
|
+
}
|
|
78
|
+
const response = { success: true, data: null };
|
|
79
|
+
res.json(response);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const response = { success: false, error: String(error) };
|
|
83
|
+
res.status(500).json(response);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
export default router;
|
|
87
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../src/server/api/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/server/api/settings.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA0CxB,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { setSetting, getAllSettings } from '../config.js';
|
|
3
|
+
const router = Router();
|
|
4
|
+
const ALLOWED_SETTING_KEYS = new Set(['api_url', 'api_key', 'model', 'group_id', 'proxy']);
|
|
5
|
+
router.get('/', (_req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const settings = getAllSettings();
|
|
8
|
+
const sanitizedSettings = {
|
|
9
|
+
...settings,
|
|
10
|
+
has_api_key: Boolean(settings.api_key),
|
|
11
|
+
};
|
|
12
|
+
delete sanitizedSettings.api_key;
|
|
13
|
+
const response = { success: true, data: sanitizedSettings };
|
|
14
|
+
res.json(response);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
const response = { success: false, error: String(error) };
|
|
18
|
+
res.status(500).json(response);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
router.put('/:key', (req, res) => {
|
|
22
|
+
try {
|
|
23
|
+
const { key } = req.params;
|
|
24
|
+
const { value } = req.body;
|
|
25
|
+
if (!ALLOWED_SETTING_KEYS.has(key)) {
|
|
26
|
+
const response = { success: false, error: `Unsupported setting key: ${key}` };
|
|
27
|
+
return res.status(400).json(response);
|
|
28
|
+
}
|
|
29
|
+
if (value === undefined) {
|
|
30
|
+
const response = { success: false, error: 'Value is required' };
|
|
31
|
+
return res.status(400).json(response);
|
|
32
|
+
}
|
|
33
|
+
const normalizedValue = String(value);
|
|
34
|
+
setSetting(key, normalizedValue);
|
|
35
|
+
const safeValue = key === 'api_key' ? '***' : normalizedValue;
|
|
36
|
+
const response = { success: true, data: { key, value: safeValue } };
|
|
37
|
+
res.json(response);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const response = { success: false, error: String(error) };
|
|
41
|
+
res.status(500).json(response);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
export default router;
|
|
45
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/server/api/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG1D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AACxB,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3F,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAC5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,cAAc,EAAwC,CAAC;QACxE,MAAM,iBAAiB,GAAqC;YAC1D,GAAG,QAAQ;YACX,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;SACvC,CAAC;QACF,OAAO,iBAAiB,CAAC,OAAO,CAAC;QACjC,MAAM,QAAQ,GAAkD,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;QAC3G,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IAC/B,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;QAC3B,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,GAAG,EAAE,EAAE,CAAC;YAC3F,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;YAC7E,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9D,MAAM,QAAQ,GAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workItem.d.ts","sourceRoot":"","sources":["../../../src/server/api/workItem.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,MAAM,4CAAgC,CAAC;AA2U7C,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { db } from '../db';
|
|
4
|
+
const router = Router({ mergeParams: true });
|
|
5
|
+
function now() {
|
|
6
|
+
return new Date().toISOString();
|
|
7
|
+
}
|
|
8
|
+
function parseWorkItem(row) {
|
|
9
|
+
return {
|
|
10
|
+
id: row.id,
|
|
11
|
+
sandbox_id: row.sandbox_id,
|
|
12
|
+
parent_id: row.parent_id,
|
|
13
|
+
name: row.name,
|
|
14
|
+
description: row.description,
|
|
15
|
+
assignee: row.assignee,
|
|
16
|
+
status: row.status,
|
|
17
|
+
priority: row.priority,
|
|
18
|
+
tags: JSON.parse(row.tags || '[]'),
|
|
19
|
+
extra_data: JSON.parse(row.extra_data || '{}'),
|
|
20
|
+
created_at: row.created_at,
|
|
21
|
+
updated_at: row.updated_at,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function safeParseJson(value) {
|
|
25
|
+
if (typeof value !== 'string' || !value) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(value);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
router.get('/', (req, res) => {
|
|
36
|
+
try {
|
|
37
|
+
const sandboxId = req.params.sandboxId;
|
|
38
|
+
const items = db.prepare('SELECT * FROM work_items WHERE sandbox_id = ? ORDER BY created_at ASC').all(sandboxId);
|
|
39
|
+
const workItems = items.map(parseWorkItem);
|
|
40
|
+
const response = { success: true, data: workItems };
|
|
41
|
+
res.json(response);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const response = { success: false, error: String(error) };
|
|
45
|
+
res.status(500).json(response);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
router.get('/:id', (req, res) => {
|
|
49
|
+
try {
|
|
50
|
+
const item = db.prepare('SELECT * FROM work_items WHERE id = ?').get(req.params.id);
|
|
51
|
+
if (!item) {
|
|
52
|
+
const response = { success: false, error: 'Work item not found' };
|
|
53
|
+
return res.status(404).json(response);
|
|
54
|
+
}
|
|
55
|
+
const workItem = parseWorkItem(item);
|
|
56
|
+
const response = { success: true, data: workItem };
|
|
57
|
+
res.json(response);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const response = { success: false, error: String(error) };
|
|
61
|
+
res.status(500).json(response);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
router.post('/', (req, res) => {
|
|
65
|
+
try {
|
|
66
|
+
const sandboxId = req.params.sandboxId;
|
|
67
|
+
const body = req.body;
|
|
68
|
+
const name = body.name || '';
|
|
69
|
+
const description = body.description || '';
|
|
70
|
+
const assignee = body.assignee || '';
|
|
71
|
+
const status = body.status || 'pending';
|
|
72
|
+
const priority = body.priority || 'medium';
|
|
73
|
+
const parent_id = body.parent_id || null;
|
|
74
|
+
const tags = body.tags || [];
|
|
75
|
+
const extra_data = body.extra_data || {};
|
|
76
|
+
if (!name) {
|
|
77
|
+
const response = { success: false, error: 'Name is required' };
|
|
78
|
+
return res.status(400).json(response);
|
|
79
|
+
}
|
|
80
|
+
const id = uuidv4();
|
|
81
|
+
const timestamp = now();
|
|
82
|
+
db.prepare(`
|
|
83
|
+
INSERT INTO work_items (id, sandbox_id, parent_id, name, description, assignee, status, priority, tags, extra_data, created_at, updated_at)
|
|
84
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
85
|
+
`).run(id, sandboxId, parent_id, name, description, assignee, status, priority, JSON.stringify(tags), JSON.stringify(extra_data), timestamp, timestamp);
|
|
86
|
+
db.prepare('UPDATE sandboxes SET updated_at = ? WHERE id = ?').run(timestamp, sandboxId);
|
|
87
|
+
const operationId = uuidv4();
|
|
88
|
+
const dataAfter = { id, sandbox_id: sandboxId, parent_id, name, description, assignee, status, priority, tags, extra_data };
|
|
89
|
+
db.prepare('INSERT INTO operations (id, sandbox_id, operation_type, data_after, created_at) VALUES (?, ?, ?, ?, ?)').run(operationId, sandboxId, 'create', JSON.stringify(dataAfter), timestamp);
|
|
90
|
+
const workItem = {
|
|
91
|
+
id, sandbox_id: sandboxId, parent_id, name, description, assignee, status, priority, tags, extra_data, created_at: timestamp, updated_at: timestamp
|
|
92
|
+
};
|
|
93
|
+
const response = { success: true, data: workItem };
|
|
94
|
+
res.status(201).json(response);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const response = { success: false, error: String(error) };
|
|
98
|
+
res.status(500).json(response);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
router.put('/:id', (req, res) => {
|
|
102
|
+
try {
|
|
103
|
+
const body = req.body;
|
|
104
|
+
const name = body.name;
|
|
105
|
+
const description = body.description;
|
|
106
|
+
const assignee = body.assignee;
|
|
107
|
+
const status = body.status;
|
|
108
|
+
const priority = body.priority;
|
|
109
|
+
const tags = body.tags;
|
|
110
|
+
const extra_data = body.extra_data;
|
|
111
|
+
const parent_id = body.parent_id;
|
|
112
|
+
const existing = db.prepare('SELECT * FROM work_items WHERE id = ?').get(req.params.id);
|
|
113
|
+
if (!existing) {
|
|
114
|
+
const response = { success: false, error: 'Work item not found' };
|
|
115
|
+
return res.status(404).json(response);
|
|
116
|
+
}
|
|
117
|
+
const timestamp = now();
|
|
118
|
+
const dataBefore = parseWorkItem(existing);
|
|
119
|
+
db.prepare(`
|
|
120
|
+
UPDATE work_items SET
|
|
121
|
+
name = COALESCE(?, name),
|
|
122
|
+
description = COALESCE(?, description),
|
|
123
|
+
assignee = COALESCE(?, assignee),
|
|
124
|
+
status = COALESCE(?, status),
|
|
125
|
+
priority = COALESCE(?, priority),
|
|
126
|
+
tags = COALESCE(?, tags),
|
|
127
|
+
extra_data = COALESCE(?, extra_data),
|
|
128
|
+
parent_id = COALESCE(?, parent_id),
|
|
129
|
+
updated_at = ?
|
|
130
|
+
WHERE id = ?
|
|
131
|
+
`).run(name ?? null, description ?? null, assignee ?? null, status ?? null, priority ?? null, tags ? JSON.stringify(tags) : null, extra_data ? JSON.stringify(extra_data) : null, parent_id !== undefined ? parent_id : null, timestamp, req.params.id);
|
|
132
|
+
db.prepare('UPDATE sandboxes SET updated_at = ? WHERE id = ?').run(timestamp, dataBefore.sandbox_id);
|
|
133
|
+
const operationId = uuidv4();
|
|
134
|
+
const updated = db.prepare('SELECT * FROM work_items WHERE id = ?').get(req.params.id);
|
|
135
|
+
const dataAfter = parseWorkItem(updated);
|
|
136
|
+
db.prepare('INSERT INTO operations (id, sandbox_id, operation_type, data_before, data_after, created_at) VALUES (?, ?, ?, ?, ?, ?)').run(operationId, dataBefore.sandbox_id, 'update', JSON.stringify(dataBefore), JSON.stringify(dataAfter), timestamp);
|
|
137
|
+
const workItem = parseWorkItem(updated);
|
|
138
|
+
const response = { success: true, data: workItem };
|
|
139
|
+
res.json(response);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
const response = { success: false, error: String(error) };
|
|
143
|
+
res.status(500).json(response);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
router.delete('/:id', (req, res) => {
|
|
147
|
+
try {
|
|
148
|
+
const existing = db.prepare('SELECT * FROM work_items WHERE id = ?').get(req.params.id);
|
|
149
|
+
if (!existing) {
|
|
150
|
+
const response = { success: false, error: 'Work item not found' };
|
|
151
|
+
return res.status(404).json(response);
|
|
152
|
+
}
|
|
153
|
+
const dataBefore = parseWorkItem(existing);
|
|
154
|
+
const timestamp = now();
|
|
155
|
+
db.prepare('DELETE FROM work_items WHERE id = ?').run(req.params.id);
|
|
156
|
+
db.prepare('UPDATE sandboxes SET updated_at = ? WHERE id = ?').run(timestamp, dataBefore.sandbox_id);
|
|
157
|
+
const operationId = uuidv4();
|
|
158
|
+
db.prepare('INSERT INTO operations (id, sandbox_id, operation_type, data_before, created_at) VALUES (?, ?, ?, ?, ?)').run(operationId, dataBefore.sandbox_id, 'delete', JSON.stringify(dataBefore), timestamp);
|
|
159
|
+
const response = { success: true, data: null };
|
|
160
|
+
res.json(response);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
const response = { success: false, error: String(error) };
|
|
164
|
+
res.status(500).json(response);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
router.post('/:id/rollback', (req, res) => {
|
|
168
|
+
try {
|
|
169
|
+
const item = db.prepare('SELECT * FROM work_items WHERE id = ?').get(req.params.id);
|
|
170
|
+
if (!item) {
|
|
171
|
+
const response = { success: false, error: 'Work item not found' };
|
|
172
|
+
return res.status(404).json(response);
|
|
173
|
+
}
|
|
174
|
+
const sandboxId = item.sandbox_id;
|
|
175
|
+
const operations = db.prepare('SELECT * FROM operations WHERE sandbox_id = ? ORDER BY created_at DESC').all(sandboxId);
|
|
176
|
+
if (operations.length === 0) {
|
|
177
|
+
const response = { success: false, error: 'No operation to rollback' };
|
|
178
|
+
return res.status(400).json(response);
|
|
179
|
+
}
|
|
180
|
+
const targetOperation = operations.find((operation) => {
|
|
181
|
+
const before = safeParseJson(operation.data_before);
|
|
182
|
+
const after = safeParseJson(operation.data_after);
|
|
183
|
+
return before?.id === req.params.id || after?.id === req.params.id;
|
|
184
|
+
});
|
|
185
|
+
if (!targetOperation) {
|
|
186
|
+
const response = { success: false, error: 'No operation found for this item' };
|
|
187
|
+
return res.status(400).json(response);
|
|
188
|
+
}
|
|
189
|
+
const opType = targetOperation.operation_type;
|
|
190
|
+
const timestamp = now();
|
|
191
|
+
if (opType === 'create') {
|
|
192
|
+
const dataAfter = safeParseJson(targetOperation.data_after);
|
|
193
|
+
const itemId = dataAfter?.id || req.params.id;
|
|
194
|
+
db.prepare('DELETE FROM work_items WHERE id = ?').run(itemId);
|
|
195
|
+
}
|
|
196
|
+
else if (opType === 'update') {
|
|
197
|
+
const dataBefore = safeParseJson(targetOperation.data_before);
|
|
198
|
+
if (!dataBefore) {
|
|
199
|
+
const response = { success: false, error: 'Invalid operation history' };
|
|
200
|
+
return res.status(500).json(response);
|
|
201
|
+
}
|
|
202
|
+
db.prepare(`
|
|
203
|
+
UPDATE work_items SET name = ?, description = ?, assignee = ?, status = ?, priority = ?, tags = ?, extra_data = ?, parent_id = ?, updated_at = ?
|
|
204
|
+
WHERE id = ?
|
|
205
|
+
`).run(dataBefore.name, dataBefore.description, dataBefore.assignee, dataBefore.status, dataBefore.priority, dataBefore.tags, dataBefore.extra_data, dataBefore.parent_id, timestamp, dataBefore.id);
|
|
206
|
+
}
|
|
207
|
+
else if (opType === 'delete') {
|
|
208
|
+
const dataBefore = safeParseJson(targetOperation.data_before);
|
|
209
|
+
if (!dataBefore) {
|
|
210
|
+
const response = { success: false, error: 'Invalid operation history' };
|
|
211
|
+
return res.status(500).json(response);
|
|
212
|
+
}
|
|
213
|
+
db.prepare(`
|
|
214
|
+
INSERT INTO work_items (id, sandbox_id, parent_id, name, description, assignee, status, priority, tags, extra_data, created_at, updated_at)
|
|
215
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
216
|
+
`).run(dataBefore.id, dataBefore.sandbox_id, dataBefore.parent_id, dataBefore.name, dataBefore.description, dataBefore.assignee, dataBefore.status, dataBefore.priority, dataBefore.tags, dataBefore.extra_data, dataBefore.created_at, timestamp);
|
|
217
|
+
}
|
|
218
|
+
db.prepare('DELETE FROM operations WHERE id = ?').run(targetOperation.id);
|
|
219
|
+
db.prepare('UPDATE sandboxes SET updated_at = ? WHERE id = ?').run(timestamp, sandboxId);
|
|
220
|
+
const updated = db.prepare('SELECT * FROM work_items WHERE id = ?').get(req.params.id);
|
|
221
|
+
const workItem = updated ? parseWorkItem(updated) : null;
|
|
222
|
+
const response = { success: true, data: workItem };
|
|
223
|
+
res.json(response);
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
const response = { success: false, error: String(error) };
|
|
227
|
+
res.status(500).json(response);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
router.get('/operations/recent', (req, res) => {
|
|
231
|
+
try {
|
|
232
|
+
const sandboxId = req.query.sandbox_id;
|
|
233
|
+
const limitRaw = req.query.limit;
|
|
234
|
+
const limit = Math.max(1, Math.min(200, Number(limitRaw || '30')));
|
|
235
|
+
let operations;
|
|
236
|
+
if (sandboxId) {
|
|
237
|
+
operations = db.prepare('SELECT * FROM operations WHERE sandbox_id = ? ORDER BY created_at DESC LIMIT ?').all(sandboxId, limit);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
operations = db.prepare('SELECT * FROM operations ORDER BY created_at DESC LIMIT ?').all(limit);
|
|
241
|
+
}
|
|
242
|
+
const response = { success: true, data: operations };
|
|
243
|
+
res.json(response);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
const response = { success: false, error: String(error) };
|
|
247
|
+
res.status(500).json(response);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
router.post('/operations/:operationId/undo', (req, res) => {
|
|
251
|
+
try {
|
|
252
|
+
const { operationId } = req.params;
|
|
253
|
+
const operation = db.prepare('SELECT * FROM operations WHERE id = ?').get(operationId);
|
|
254
|
+
if (!operation) {
|
|
255
|
+
const response = { success: false, error: 'Operation not found' };
|
|
256
|
+
return res.status(404).json(response);
|
|
257
|
+
}
|
|
258
|
+
const opType = operation.operation_type;
|
|
259
|
+
const sandboxId = operation.sandbox_id;
|
|
260
|
+
const timestamp = now();
|
|
261
|
+
if (opType === 'create') {
|
|
262
|
+
const dataAfter = JSON.parse(operation.data_after);
|
|
263
|
+
db.prepare('DELETE FROM work_items WHERE id = ?').run(dataAfter.id);
|
|
264
|
+
}
|
|
265
|
+
else if (opType === 'update') {
|
|
266
|
+
const dataBefore = JSON.parse(operation.data_before);
|
|
267
|
+
db.prepare(`
|
|
268
|
+
UPDATE work_items SET name = ?, description = ?, assignee = ?, status = ?, priority = ?, tags = ?, extra_data = ?, parent_id = ?, updated_at = ?
|
|
269
|
+
WHERE id = ?
|
|
270
|
+
`).run(dataBefore.name, dataBefore.description, dataBefore.assignee, dataBefore.status, dataBefore.priority, dataBefore.tags, dataBefore.extra_data, dataBefore.parent_id, timestamp, dataBefore.id);
|
|
271
|
+
}
|
|
272
|
+
else if (opType === 'delete') {
|
|
273
|
+
const dataBefore = JSON.parse(operation.data_before);
|
|
274
|
+
db.prepare(`
|
|
275
|
+
INSERT INTO work_items (id, sandbox_id, parent_id, name, description, assignee, status, priority, tags, extra_data, created_at, updated_at)
|
|
276
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
277
|
+
`).run(dataBefore.id, dataBefore.sandbox_id, dataBefore.parent_id, dataBefore.name, dataBefore.description, dataBefore.assignee, dataBefore.status, dataBefore.priority, dataBefore.tags, dataBefore.extra_data, dataBefore.created_at, timestamp);
|
|
278
|
+
}
|
|
279
|
+
db.prepare('DELETE FROM operations WHERE id = ?').run(operationId);
|
|
280
|
+
db.prepare('UPDATE sandboxes SET updated_at = ? WHERE id = ?').run(timestamp, sandboxId);
|
|
281
|
+
const response = { success: true, data: null };
|
|
282
|
+
res.json(response);
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
const response = { success: false, error: String(error) };
|
|
286
|
+
res.status(500).json(response);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
export default router;
|
|
290
|
+
//# sourceMappingURL=workItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workItem.js","sourceRoot":"","sources":["../../../src/server/api/workItem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface ParsedOperation {
|
|
2
|
+
action: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
task_id?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ParsedOperationResult {
|
|
8
|
+
reply: string;
|
|
9
|
+
operations: ParsedOperation[];
|
|
10
|
+
}
|
|
11
|
+
export declare function stripCodeFence(text: string): string;
|
|
12
|
+
export declare function parseOperationResult(aiText: string): ParsedOperationResult | null;
|
|
13
|
+
export declare function parseRelationIds(aiText: string): string[];
|
|
14
|
+
export declare function buildOperationsPrompt(content: string, sandboxContext?: string): string;
|
|
15
|
+
//# sourceMappingURL=chatUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatUtils.d.ts","sourceRoot":"","sources":["../../src/server/chatUtils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAajF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CASzD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BtF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function stripCodeFence(text) {
|
|
2
|
+
return text.replace(/```json|```/g, '').trim();
|
|
3
|
+
}
|
|
4
|
+
export function parseOperationResult(aiText) {
|
|
5
|
+
try {
|
|
6
|
+
const parsed = JSON.parse(stripCodeFence(aiText));
|
|
7
|
+
return {
|
|
8
|
+
reply: parsed.reply || aiText,
|
|
9
|
+
operations: Array.isArray(parsed.operations) ? parsed.operations : [],
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function parseRelationIds(aiText) {
|
|
17
|
+
const normalized = aiText.trim().toLowerCase();
|
|
18
|
+
if (!normalized || normalized === 'none') {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return aiText
|
|
22
|
+
.split(',')
|
|
23
|
+
.map((segment) => segment.trim().replace(/["']/g, ''))
|
|
24
|
+
.filter(Boolean);
|
|
25
|
+
}
|
|
26
|
+
export function buildOperationsPrompt(content, sandboxContext) {
|
|
27
|
+
const sandboxLine = sandboxContext
|
|
28
|
+
? `当前沙盘: ${sandboxContext}\n`
|
|
29
|
+
: '';
|
|
30
|
+
return `用户消息: "${content}"
|
|
31
|
+
|
|
32
|
+
分析用户想要进行的操作,返回JSON格式的编辑建议。
|
|
33
|
+
|
|
34
|
+
操作类型说明:
|
|
35
|
+
- "create": 创建新任务
|
|
36
|
+
- "update": 更新现有任务(需要task_id)
|
|
37
|
+
- "delete": 删除任务(需要task_id)
|
|
38
|
+
|
|
39
|
+
${sandboxLine}返回JSON格式:
|
|
40
|
+
{
|
|
41
|
+
"reply": "给用户的回复",
|
|
42
|
+
"operations": [
|
|
43
|
+
{"action": "create", "name": "任务名称", "description": "描述"},
|
|
44
|
+
{"action": "update", "task_id": "现有任务ID", "name": "新名称"},
|
|
45
|
+
{"action": "delete", "task_id": "现有任务ID"}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
如果不需要任何操作,operations为空数组。
|
|
50
|
+
只返回JSON,不要其他内容。`;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=chatUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatUtils.js","sourceRoot":"","sources":["../../src/server/chatUtils.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAG/C,CAAC;QACF,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM;YAC7B,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;SACtE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QACzC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM;SACV,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;SACrD,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,cAAuB;IAC5E,MAAM,WAAW,GAAG,cAAc;QAChC,CAAC,CAAC,SAAS,cAAc,IAAI;QAC7B,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,UAAU,OAAO;;;;;;;;;EASxB,WAAW;;;;;;;;;;;gBAWG,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Config {
|
|
2
|
+
api_url?: string;
|
|
3
|
+
api_key?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
group_id?: string;
|
|
6
|
+
proxy?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function getResolvedConfigDir(): string;
|
|
9
|
+
export declare function getResolvedConfigPath(): string;
|
|
10
|
+
export declare function getSetting(key: string): string | undefined;
|
|
11
|
+
export declare function setSetting(key: string, value: string): void;
|
|
12
|
+
export declare function getAllSettings(): Config;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAIA,UAAU,MAAM;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAoBD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAsBD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG1D;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAIpD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
function ensureConfigDir() {
|
|
5
|
+
const configDir = getConfigDir();
|
|
6
|
+
if (!fs.existsSync(configDir)) {
|
|
7
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function getConfigDir() {
|
|
11
|
+
const customConfigDir = process.env.Q_AI_NOTE_CONFIG_DIR || process.env.PERSONAL_AI_NOTEBOOK_CONFIG_DIR;
|
|
12
|
+
return customConfigDir && customConfigDir.trim()
|
|
13
|
+
? customConfigDir
|
|
14
|
+
: path.join(os.homedir(), '.q-ai-note');
|
|
15
|
+
}
|
|
16
|
+
function getConfigPath() {
|
|
17
|
+
return path.join(getConfigDir(), 'config.json');
|
|
18
|
+
}
|
|
19
|
+
export function getResolvedConfigDir() {
|
|
20
|
+
return getConfigDir();
|
|
21
|
+
}
|
|
22
|
+
export function getResolvedConfigPath() {
|
|
23
|
+
return getConfigPath();
|
|
24
|
+
}
|
|
25
|
+
function readConfig() {
|
|
26
|
+
ensureConfigDir();
|
|
27
|
+
const configPath = getConfigPath();
|
|
28
|
+
if (!fs.existsSync(configPath)) {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const data = fs.readFileSync(configPath, 'utf-8');
|
|
33
|
+
return JSON.parse(data);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function writeConfig(config) {
|
|
40
|
+
ensureConfigDir();
|
|
41
|
+
const configPath = getConfigPath();
|
|
42
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
43
|
+
}
|
|
44
|
+
export function getSetting(key) {
|
|
45
|
+
const config = readConfig();
|
|
46
|
+
return config[key];
|
|
47
|
+
}
|
|
48
|
+
export function setSetting(key, value) {
|
|
49
|
+
const config = readConfig();
|
|
50
|
+
config[key] = value;
|
|
51
|
+
writeConfig(config);
|
|
52
|
+
}
|
|
53
|
+
export function getAllSettings() {
|
|
54
|
+
return readConfig();
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAUpB,SAAS,eAAe;IACtB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;IACxG,OAAO,eAAe,IAAI,eAAe,CAAC,IAAI,EAAE;QAC9C,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,YAAY,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,aAAa,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,UAAU;IACjB,eAAe,EAAE,CAAC;IAClB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,eAAe,EAAE,CAAC;IAClB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,GAAmB,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,KAAa;IACnD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC3B,MAAc,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC7B,WAAW,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Database as DatabaseType } from 'better-sqlite3';
|
|
2
|
+
export declare function getResolvedDbPath(): string;
|
|
3
|
+
export declare const db: DatabaseType;
|
|
4
|
+
export declare function initDb(): void;
|
|
5
|
+
export declare function closeDb(): void;
|
|
6
|
+
//# sourceMappingURL=db.d.ts.map
|