@spool-lab/core 0.4.12 → 0.5.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 +2 -2
- package/dist/db/db.d.ts +10 -2
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +119 -10
- package/dist/db/db.js.map +1 -1
- package/dist/db/queries.d.ts +5 -5
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +32 -14
- package/dist/db/queries.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/observability/exporter-file.d.ts +30 -0
- package/dist/observability/exporter-file.d.ts.map +1 -0
- package/dist/observability/exporter-file.js +125 -0
- package/dist/observability/exporter-file.js.map +1 -0
- package/dist/observability/exporter-pretty.d.ts +27 -0
- package/dist/observability/exporter-pretty.d.ts.map +1 -0
- package/dist/observability/exporter-pretty.js +84 -0
- package/dist/observability/exporter-pretty.js.map +1 -0
- package/dist/observability/index.d.ts +2 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +2 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/layer.d.ts +29 -0
- package/dist/observability/layer.d.ts.map +1 -0
- package/dist/observability/layer.js +45 -0
- package/dist/observability/layer.js.map +1 -0
- package/dist/parsers/opencode.d.ts +23 -0
- package/dist/parsers/opencode.d.ts.map +1 -0
- package/dist/parsers/opencode.js +358 -0
- package/dist/parsers/opencode.js.map +1 -0
- package/dist/projects/sessions.d.ts +29 -1
- package/dist/projects/sessions.d.ts.map +1 -1
- package/dist/projects/sessions.js +115 -11
- package/dist/projects/sessions.js.map +1 -1
- package/dist/security/index.d.ts +14 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +7 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/maintenance.d.ts +15 -0
- package/dist/security/maintenance.d.ts.map +1 -0
- package/dist/security/maintenance.js +68 -0
- package/dist/security/maintenance.js.map +1 -0
- package/dist/security/profile.d.ts +47 -0
- package/dist/security/profile.d.ts.map +1 -0
- package/dist/security/profile.js +131 -0
- package/dist/security/profile.js.map +1 -0
- package/dist/security/purge.d.ts +68 -0
- package/dist/security/purge.d.ts.map +1 -0
- package/dist/security/purge.js +193 -0
- package/dist/security/purge.js.map +1 -0
- package/dist/security/repo.d.ts +190 -0
- package/dist/security/repo.d.ts.map +1 -0
- package/dist/security/repo.js +594 -0
- package/dist/security/repo.js.map +1 -0
- package/dist/security/scan.d.ts +50 -0
- package/dist/security/scan.d.ts.map +1 -0
- package/dist/security/scan.js +122 -0
- package/dist/security/scan.js.map +1 -0
- package/dist/security/types.d.ts +146 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +10 -0
- package/dist/security/types.js.map +1 -0
- package/dist/security/worker.d.ts +69 -0
- package/dist/security/worker.d.ts.map +1 -0
- package/dist/security/worker.js +228 -0
- package/dist/security/worker.js.map +1 -0
- package/dist/sync/source-paths.d.ts +1 -0
- package/dist/sync/source-paths.d.ts.map +1 -1
- package/dist/sync/source-paths.js +48 -6
- package/dist/sync/source-paths.js.map +1 -1
- package/dist/sync/syncer.d.ts +9 -1
- package/dist/sync/syncer.d.ts.map +1 -1
- package/dist/sync/syncer.js +128 -16
- package/dist/sync/syncer.js.map +1 -1
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +8 -2
- package/dist/sync/watcher.js.map +1 -1
- package/dist/types.d.ts +15 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/util/resolve-bin.d.ts +34 -0
- package/dist/util/resolve-bin.d.ts.map +1 -1
- package/dist/util/resolve-bin.js +175 -20
- package/dist/util/resolve-bin.js.map +1 -1
- package/package.json +11 -2
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { stripSpoolSystemPrelude } from './spool-prelude.js';
|
|
4
|
+
export const OPENCODE_INDEX_VERSION = 'opencode-v3-session-model-json';
|
|
5
|
+
export const OPENCODE_DB_NAME = 'opencode.db';
|
|
6
|
+
const OPENCODE_SESSION_SEPARATOR = '#session=';
|
|
7
|
+
const OPENCODE_SUBAGENT_PARENT_PREFIX = 'opencode-subagent:';
|
|
8
|
+
const OPENCODE_SUBAGENT_HEADER_PREFIX = 'OpenCode subagent:';
|
|
9
|
+
// WAL/SHM/journal sidecars share the DB's basename + a suffix; watcher events on
|
|
10
|
+
// them must map back to the main file so commits append to -wal (whose writes the
|
|
11
|
+
// main file's mtime does not reflect until checkpoint) still trigger a re-index.
|
|
12
|
+
const OPENCODE_DB_SIDECAR_SUFFIXES = ['-wal', '-shm', '-journal'];
|
|
13
|
+
// Guards the recursive session-tree walks against pathological/corrupt parent
|
|
14
|
+
// chains. Real OpenCode trees are shallow (root → subagent → subagent); a cycle
|
|
15
|
+
// is unreachable from a NULL-parent root, but this bounds the walk regardless.
|
|
16
|
+
const OPENCODE_MAX_SESSION_DEPTH = 64;
|
|
17
|
+
const sessionMtimeCache = new Map();
|
|
18
|
+
export function makeOpenCodeSessionFilePath(dbPath, sessionId) {
|
|
19
|
+
return `${dbPath}${OPENCODE_SESSION_SEPARATOR}${encodeURIComponent(sessionId)}`;
|
|
20
|
+
}
|
|
21
|
+
export function parseOpenCodeSessionFilePath(filePath) {
|
|
22
|
+
const idx = filePath.lastIndexOf(OPENCODE_SESSION_SEPARATOR);
|
|
23
|
+
if (idx === -1)
|
|
24
|
+
return null;
|
|
25
|
+
const dbPath = filePath.slice(0, idx);
|
|
26
|
+
const encodedSessionId = filePath.slice(idx + OPENCODE_SESSION_SEPARATOR.length);
|
|
27
|
+
if (!dbPath || !encodedSessionId)
|
|
28
|
+
return null;
|
|
29
|
+
return { dbPath, sessionId: decodeURIComponent(encodedSessionId) };
|
|
30
|
+
}
|
|
31
|
+
export function isOpenCodeDatabaseFile(filePath) {
|
|
32
|
+
return basename(filePath) === OPENCODE_DB_NAME;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Map an OpenCode DB sidecar path (`opencode.db-wal` / `-shm` / `-journal`) back
|
|
36
|
+
* to the main `opencode.db`. Non-sidecar paths are returned unchanged. The watcher
|
|
37
|
+
* uses this so WAL-mode writes — which land in `-wal` and leave the main file's
|
|
38
|
+
* mtime stale until checkpoint — still schedule a re-index of the database.
|
|
39
|
+
*/
|
|
40
|
+
export function normalizeOpenCodeWatchPath(filePath) {
|
|
41
|
+
const base = basename(filePath);
|
|
42
|
+
for (const suffix of OPENCODE_DB_SIDECAR_SUFFIXES) {
|
|
43
|
+
if (base === OPENCODE_DB_NAME + suffix) {
|
|
44
|
+
return join(dirname(filePath), OPENCODE_DB_NAME);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return filePath;
|
|
48
|
+
}
|
|
49
|
+
export function listOpenCodeSessionFilePaths(dbPath) {
|
|
50
|
+
const db = openOpenCodeDb(dbPath);
|
|
51
|
+
try {
|
|
52
|
+
const rows = db.prepare(`
|
|
53
|
+
WITH RECURSIVE active_sessions(id, root_id, time_updated, depth) AS (
|
|
54
|
+
SELECT id, id AS root_id, time_updated, 0 AS depth
|
|
55
|
+
FROM session
|
|
56
|
+
WHERE parent_id IS NULL AND time_archived IS NULL
|
|
57
|
+
|
|
58
|
+
UNION ALL
|
|
59
|
+
|
|
60
|
+
SELECT child.id, active_sessions.root_id, child.time_updated, active_sessions.depth + 1
|
|
61
|
+
FROM session child
|
|
62
|
+
JOIN active_sessions ON child.parent_id = active_sessions.id
|
|
63
|
+
WHERE child.time_archived IS NULL AND active_sessions.depth < ${OPENCODE_MAX_SESSION_DEPTH}
|
|
64
|
+
)
|
|
65
|
+
SELECT root_id AS id, MAX(time_updated) AS time_updated
|
|
66
|
+
FROM active_sessions
|
|
67
|
+
GROUP BY root_id
|
|
68
|
+
ORDER BY time_updated DESC, root_id DESC
|
|
69
|
+
`).all();
|
|
70
|
+
sessionMtimeCache.set(dbPath, new Map(rows.map(row => [row.id, row.time_updated])));
|
|
71
|
+
return rows.map(row => makeOpenCodeSessionFilePath(dbPath, row.id));
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
db.close();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function getOpenCodeSessionIndexedMtime(filePath) {
|
|
78
|
+
const parsed = parseOpenCodeSessionFilePath(filePath);
|
|
79
|
+
if (!parsed) {
|
|
80
|
+
throw new Error(`OpenCode session path is missing ${OPENCODE_SESSION_SEPARATOR}: ${filePath}`);
|
|
81
|
+
}
|
|
82
|
+
const cached = sessionMtimeCache.get(parsed.dbPath)?.get(parsed.sessionId);
|
|
83
|
+
if (cached !== undefined)
|
|
84
|
+
return `${cached}::${OPENCODE_INDEX_VERSION}`;
|
|
85
|
+
const db = openOpenCodeDb(parsed.dbPath);
|
|
86
|
+
try {
|
|
87
|
+
const row = db.prepare(`
|
|
88
|
+
WITH RECURSIVE descendants(id, time_updated, depth) AS (
|
|
89
|
+
SELECT id, time_updated, 0 AS depth
|
|
90
|
+
FROM session
|
|
91
|
+
WHERE id = ? AND parent_id IS NULL AND time_archived IS NULL
|
|
92
|
+
|
|
93
|
+
UNION ALL
|
|
94
|
+
|
|
95
|
+
SELECT child.id, child.time_updated, descendants.depth + 1
|
|
96
|
+
FROM session child
|
|
97
|
+
JOIN descendants ON child.parent_id = descendants.id
|
|
98
|
+
WHERE child.time_archived IS NULL AND descendants.depth < ${OPENCODE_MAX_SESSION_DEPTH}
|
|
99
|
+
)
|
|
100
|
+
SELECT MAX(time_updated) AS time_updated
|
|
101
|
+
FROM descendants
|
|
102
|
+
`).get(parsed.sessionId);
|
|
103
|
+
if (!row?.time_updated)
|
|
104
|
+
throw new Error(`OpenCode parent session not found: ${parsed.sessionId}`);
|
|
105
|
+
return `${row.time_updated}::${OPENCODE_INDEX_VERSION}`;
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
db.close();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function loadOpenCodeSession(filePath) {
|
|
112
|
+
const parsedPath = parseOpenCodeSessionFilePath(filePath);
|
|
113
|
+
if (!parsedPath)
|
|
114
|
+
return { kind: 'skipped' };
|
|
115
|
+
const db = openOpenCodeDb(parsedPath.dbPath);
|
|
116
|
+
try {
|
|
117
|
+
const session = db.prepare(`
|
|
118
|
+
SELECT id, parent_id, directory, title, time_created, time_updated, model, agent
|
|
119
|
+
FROM session
|
|
120
|
+
WHERE id = ? AND time_archived IS NULL
|
|
121
|
+
`).get(parsedPath.sessionId);
|
|
122
|
+
if (!session)
|
|
123
|
+
return { kind: 'filtered' };
|
|
124
|
+
// Subagent rows (parent_id set) are folded into their parent, never indexed
|
|
125
|
+
// standalone — surfacing them here would duplicate work already shown under
|
|
126
|
+
// the parent. listOpenCodeSessionFilePaths only ever yields root ids, so this
|
|
127
|
+
// guards the direct-load path (e.g. a stale indexed child path).
|
|
128
|
+
if (session.parent_id)
|
|
129
|
+
return { kind: 'filtered' };
|
|
130
|
+
let cwd = session.directory || '';
|
|
131
|
+
let model = normalizeModel(session.model);
|
|
132
|
+
const messages = loadMessagesForOpenCodeSession(db, session, {
|
|
133
|
+
sidechain: false,
|
|
134
|
+
onCwd: value => { if (!cwd)
|
|
135
|
+
cwd = value; },
|
|
136
|
+
onModel: value => { if (!model)
|
|
137
|
+
model = value; },
|
|
138
|
+
});
|
|
139
|
+
const childSessions = listOpenCodeChildSessions(db, session.id);
|
|
140
|
+
let endedAtMs = Math.max(session.time_updated, ...childSessions.map(child => child.time_updated));
|
|
141
|
+
for (const child of childSessions) {
|
|
142
|
+
const groupKey = `${OPENCODE_SUBAGENT_PARENT_PREFIX}${child.id}`;
|
|
143
|
+
const childMessages = loadMessagesForOpenCodeSession(db, child, {
|
|
144
|
+
sidechain: true,
|
|
145
|
+
uuidPrefix: `${child.id}:`,
|
|
146
|
+
parentUuid: groupKey,
|
|
147
|
+
});
|
|
148
|
+
if (childMessages.length === 0)
|
|
149
|
+
continue;
|
|
150
|
+
endedAtMs = Math.max(endedAtMs, child.time_updated);
|
|
151
|
+
messages.push(makeSubagentHeaderMessage(child, groupKey));
|
|
152
|
+
messages.push(...childMessages);
|
|
153
|
+
}
|
|
154
|
+
if (messages.length === 0)
|
|
155
|
+
return { kind: 'skipped' };
|
|
156
|
+
messages.sort(compareParsedMessages);
|
|
157
|
+
messages.forEach((message, index) => { message.seq = index; });
|
|
158
|
+
const firstUserMessage = messages.find(message => !message.isSidechain && message.role === 'user' && message.contentText.trim().length > 0);
|
|
159
|
+
const title = session.title?.trim()
|
|
160
|
+
|| firstUserMessage?.contentText.replace(/<[^>]+>/g, '').trim().slice(0, 120)
|
|
161
|
+
|| '(no title)';
|
|
162
|
+
return {
|
|
163
|
+
kind: 'parsed',
|
|
164
|
+
session: {
|
|
165
|
+
source: 'opencode',
|
|
166
|
+
sessionUuid: session.id,
|
|
167
|
+
filePath,
|
|
168
|
+
title,
|
|
169
|
+
cwd,
|
|
170
|
+
model,
|
|
171
|
+
startedAt: toIso(session.time_created),
|
|
172
|
+
endedAt: toIso(endedAtMs),
|
|
173
|
+
messages,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
db.close();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export function parseOpenCodeSession(filePath) {
|
|
182
|
+
try {
|
|
183
|
+
const result = loadOpenCodeSession(filePath);
|
|
184
|
+
return result.kind === 'parsed' ? result.session : null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function openOpenCodeDb(dbPath) {
|
|
191
|
+
const db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
192
|
+
// OpenCode may hold a write lock while checkpointing the WAL; wait briefly
|
|
193
|
+
// instead of throwing SQLITE_BUSY and churning the sync error log.
|
|
194
|
+
db.pragma('busy_timeout = 5000');
|
|
195
|
+
return db;
|
|
196
|
+
}
|
|
197
|
+
function groupPartsByMessage(partRows) {
|
|
198
|
+
const byMessage = new Map();
|
|
199
|
+
for (const row of partRows) {
|
|
200
|
+
const list = byMessage.get(row.message_id) ?? [];
|
|
201
|
+
list.push(row);
|
|
202
|
+
byMessage.set(row.message_id, list);
|
|
203
|
+
}
|
|
204
|
+
return byMessage;
|
|
205
|
+
}
|
|
206
|
+
function listOpenCodeChildSessions(db, sessionId) {
|
|
207
|
+
return db.prepare(`
|
|
208
|
+
WITH RECURSIVE child_sessions(
|
|
209
|
+
id, parent_id, directory, title, time_created, time_updated, model, agent, depth
|
|
210
|
+
) AS (
|
|
211
|
+
SELECT id, parent_id, directory, title, time_created, time_updated, model, agent, 1 AS depth
|
|
212
|
+
FROM session
|
|
213
|
+
WHERE parent_id = ? AND time_archived IS NULL
|
|
214
|
+
|
|
215
|
+
UNION ALL
|
|
216
|
+
|
|
217
|
+
SELECT child.id, child.parent_id, child.directory, child.title, child.time_created,
|
|
218
|
+
child.time_updated, child.model, child.agent, child_sessions.depth + 1
|
|
219
|
+
FROM session child
|
|
220
|
+
JOIN child_sessions ON child.parent_id = child_sessions.id
|
|
221
|
+
WHERE child.time_archived IS NULL AND child_sessions.depth < ${OPENCODE_MAX_SESSION_DEPTH}
|
|
222
|
+
)
|
|
223
|
+
SELECT id, parent_id, directory, title, time_created, time_updated, model, agent
|
|
224
|
+
FROM child_sessions
|
|
225
|
+
ORDER BY time_created ASC, depth ASC, id ASC
|
|
226
|
+
`).all(sessionId);
|
|
227
|
+
}
|
|
228
|
+
function loadMessagesForOpenCodeSession(db, session, opts) {
|
|
229
|
+
const messageRows = db.prepare(`
|
|
230
|
+
SELECT id, time_created, data
|
|
231
|
+
FROM message
|
|
232
|
+
WHERE session_id = ?
|
|
233
|
+
ORDER BY time_created ASC, id ASC
|
|
234
|
+
`).all(session.id);
|
|
235
|
+
if (messageRows.length === 0)
|
|
236
|
+
return [];
|
|
237
|
+
const partRows = db.prepare(`
|
|
238
|
+
SELECT id, message_id, time_created, data
|
|
239
|
+
FROM part
|
|
240
|
+
WHERE session_id = ?
|
|
241
|
+
ORDER BY message_id ASC, time_created ASC, id ASC
|
|
242
|
+
`).all(session.id);
|
|
243
|
+
const partsByMessage = groupPartsByMessage(partRows);
|
|
244
|
+
const messages = [];
|
|
245
|
+
for (const messageRow of messageRows) {
|
|
246
|
+
const messageData = parseJson(messageRow.data);
|
|
247
|
+
if (!messageData)
|
|
248
|
+
continue;
|
|
249
|
+
const role = messageData.role;
|
|
250
|
+
if (role !== 'user' && role !== 'assistant')
|
|
251
|
+
continue;
|
|
252
|
+
const cwd = messageData.path?.cwd ?? messageData.path?.root;
|
|
253
|
+
if (cwd)
|
|
254
|
+
opts.onCwd?.(cwd);
|
|
255
|
+
const model = modelFromMessage(messageData);
|
|
256
|
+
if (model)
|
|
257
|
+
opts.onModel?.(model);
|
|
258
|
+
const parts = (partsByMessage.get(messageRow.id) ?? [])
|
|
259
|
+
.map(part => parseJson(part.data))
|
|
260
|
+
.filter((part) => Boolean(part));
|
|
261
|
+
const contentText = extractText(parts);
|
|
262
|
+
const toolNames = extractToolNames(parts);
|
|
263
|
+
if (!contentText && toolNames.length === 0)
|
|
264
|
+
continue;
|
|
265
|
+
messages.push({
|
|
266
|
+
uuid: `${opts.uuidPrefix ?? ''}${messageRow.id}`,
|
|
267
|
+
parentUuid: opts.parentUuid ?? messageData.parentID ?? null,
|
|
268
|
+
role,
|
|
269
|
+
contentText,
|
|
270
|
+
timestamp: toIso(messageRow.time_created),
|
|
271
|
+
isSidechain: opts.sidechain,
|
|
272
|
+
toolNames,
|
|
273
|
+
seq: messages.length,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return messages;
|
|
277
|
+
}
|
|
278
|
+
function makeSubagentHeaderMessage(session, groupKey) {
|
|
279
|
+
const title = session.title?.trim() || session.id;
|
|
280
|
+
const agent = session.agent?.trim();
|
|
281
|
+
const label = agent ? `@${agent} · ${title}` : title;
|
|
282
|
+
return {
|
|
283
|
+
uuid: `${session.id}:header`,
|
|
284
|
+
parentUuid: groupKey,
|
|
285
|
+
role: 'system',
|
|
286
|
+
contentText: `${OPENCODE_SUBAGENT_HEADER_PREFIX} ${label}`,
|
|
287
|
+
timestamp: toIso(session.time_created),
|
|
288
|
+
isSidechain: true,
|
|
289
|
+
toolNames: agent ? [agent] : [],
|
|
290
|
+
seq: 0,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function compareParsedMessages(a, b) {
|
|
294
|
+
const byTimestamp = a.timestamp.localeCompare(b.timestamp);
|
|
295
|
+
if (byTimestamp !== 0)
|
|
296
|
+
return byTimestamp;
|
|
297
|
+
if (a.isSidechain !== b.isSidechain)
|
|
298
|
+
return a.isSidechain ? 1 : -1;
|
|
299
|
+
return a.uuid.localeCompare(b.uuid);
|
|
300
|
+
}
|
|
301
|
+
function extractText(parts) {
|
|
302
|
+
return stripSpoolSystemPrelude(parts
|
|
303
|
+
.filter(part => part.type === 'text' && typeof part.text === 'string')
|
|
304
|
+
.map(part => part.text ?? '')
|
|
305
|
+
.join('\n'))
|
|
306
|
+
.trim();
|
|
307
|
+
}
|
|
308
|
+
function extractToolNames(parts) {
|
|
309
|
+
return Array.from(new Set(parts
|
|
310
|
+
.filter(part => part.type === 'tool' && typeof part.tool === 'string' && part.tool.trim().length > 0)
|
|
311
|
+
.map(part => part.tool)));
|
|
312
|
+
}
|
|
313
|
+
function modelFromMessage(message) {
|
|
314
|
+
const providerId = message.model?.providerID ?? message.providerID;
|
|
315
|
+
const modelId = message.model?.modelID ?? message.modelID;
|
|
316
|
+
if (providerId && modelId)
|
|
317
|
+
return `${providerId}/${modelId}`;
|
|
318
|
+
return modelId ?? '';
|
|
319
|
+
}
|
|
320
|
+
// OpenCode stores `session.model` as a serialized JSON object
|
|
321
|
+
// (`{"id","providerID","variant"?}`), not a plain string — so trim alone would
|
|
322
|
+
// leak raw JSON into the model field. Parse it into the same `provider/model`
|
|
323
|
+
// shape modelFromMessage produces; fall back to the trimmed string for any
|
|
324
|
+
// non-JSON or unparseable value.
|
|
325
|
+
function normalizeModel(model) {
|
|
326
|
+
if (!model)
|
|
327
|
+
return '';
|
|
328
|
+
const trimmed = model.trim();
|
|
329
|
+
if (!trimmed.startsWith('{'))
|
|
330
|
+
return trimmed;
|
|
331
|
+
const parsed = parseJson(trimmed);
|
|
332
|
+
if (!parsed)
|
|
333
|
+
return trimmed;
|
|
334
|
+
const providerId = parsed.providerID;
|
|
335
|
+
const modelId = parsed.modelID ?? parsed.id;
|
|
336
|
+
if (providerId && modelId)
|
|
337
|
+
return `${providerId}/${modelId}`;
|
|
338
|
+
return modelId ?? '';
|
|
339
|
+
}
|
|
340
|
+
function parseJson(raw) {
|
|
341
|
+
try {
|
|
342
|
+
return JSON.parse(raw);
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function toIso(ms) {
|
|
349
|
+
const date = new Date(ms);
|
|
350
|
+
return Number.isNaN(date.getTime()) ? new Date().toISOString() : date.toISOString();
|
|
351
|
+
}
|
|
352
|
+
export function openCodeDbPathFromSessionPath(filePath) {
|
|
353
|
+
return parseOpenCodeSessionFilePath(filePath)?.dbPath ?? filePath;
|
|
354
|
+
}
|
|
355
|
+
export function openCodeDbDisplayPath(filePath) {
|
|
356
|
+
return dirname(openCodeDbPathFromSessionPath(filePath));
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/parsers/opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
import type Database from 'better-sqlite3';
|
|
2
2
|
import type { Session, SessionSource } from '../types.js';
|
|
3
3
|
export type ProjectSessionSortOrder = 'recent' | 'oldest' | 'most_messages' | 'title';
|
|
4
|
+
export type SessionsCursor = {
|
|
5
|
+
startedAt: string;
|
|
6
|
+
sessionUuid: string;
|
|
7
|
+
messageCount: number;
|
|
8
|
+
title: string;
|
|
9
|
+
};
|
|
10
|
+
export type SessionsPage = {
|
|
11
|
+
sessions: Session[];
|
|
12
|
+
nextCursor: SessionsCursor | null;
|
|
13
|
+
};
|
|
4
14
|
export interface ListSessionsByIdentityOptions {
|
|
5
15
|
sources?: SessionSource[];
|
|
6
16
|
sortOrder?: ProjectSessionSortOrder;
|
|
7
17
|
limit?: number;
|
|
8
18
|
excludePinned?: boolean;
|
|
19
|
+
cursor?: SessionsCursor;
|
|
9
20
|
}
|
|
10
|
-
export declare function listSessionsByIdentity(db: Database.Database, identityKey: string, options?: ListSessionsByIdentityOptions):
|
|
21
|
+
export declare function listSessionsByIdentity(db: Database.Database, identityKey: string, options?: ListSessionsByIdentityOptions): SessionsPage;
|
|
22
|
+
export declare function listRecentSessionsPage(db: Database.Database, options?: {
|
|
23
|
+
limit?: number;
|
|
24
|
+
cursor?: SessionsCursor;
|
|
25
|
+
}): SessionsPage;
|
|
26
|
+
export type DirectoryCount = {
|
|
27
|
+
cwd: string;
|
|
28
|
+
sessionCount: number;
|
|
29
|
+
lastSessionAt: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Per-cwd counts across the full project. Drives the chip strip's badges
|
|
33
|
+
* so they show the true distribution rather than just the loaded page.
|
|
34
|
+
* Honors the same `sources` filter as `listSessionsByIdentity`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function listProjectDirectoryCounts(db: Database.Database, identityKey: string, options?: {
|
|
37
|
+
sources?: SessionSource[];
|
|
38
|
+
}): DirectoryCount[];
|
|
11
39
|
export declare function listPinnedSessionsByIdentity(db: Database.Database, identityKey: string): Session[];
|
|
12
40
|
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/projects/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGzD,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,OAAO,CAAA;AAErF,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,SAAS,CAAC,EAAE,uBAAuB,CAAA;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/projects/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGzD,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,OAAO,CAAA;AAErF,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,EAAE,cAAc,GAAG,IAAI,CAAA;CAClC,CAAA;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,SAAS,CAAC,EAAE,uBAAuB,CAAA;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAID,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,6BAAkC,GAC1C,YAAY,CA6Bd;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,cAAc,CAAA;CAAO,GACxD,YAAY,CAUd;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;CAAO,GAC1C,cAAc,EAAE,CAuBlB;AAED,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,EAAE,CAQX"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SESSION_SELECT, rowToSession } from '../db/queries.js';
|
|
2
|
+
const DEFAULT_PAGE_SIZE = 50;
|
|
2
3
|
export function listSessionsByIdentity(db, identityKey, options = {}) {
|
|
3
|
-
const { sources, sortOrder = 'recent', limit =
|
|
4
|
+
const { sources, sortOrder = 'recent', limit = DEFAULT_PAGE_SIZE, excludePinned = false, cursor, } = options;
|
|
4
5
|
const conditions = ['p.identity_key = ?', 's.message_count > 0'];
|
|
5
6
|
const params = [identityKey];
|
|
6
7
|
if (sources && sources.length > 0) {
|
|
@@ -11,16 +12,52 @@ export function listSessionsByIdentity(db, identityKey, options = {}) {
|
|
|
11
12
|
if (excludePinned) {
|
|
12
13
|
conditions.push('NOT EXISTS (SELECT 1 FROM pins WHERE pins.session_uuid = s.session_uuid)');
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
if (cursor) {
|
|
16
|
+
const c = cursorWhere(sortOrder, cursor);
|
|
17
|
+
conditions.push(c.sql);
|
|
18
|
+
params.push(...c.params);
|
|
19
|
+
}
|
|
20
|
+
return executePage(db, conditions, params, sortOrder, limit);
|
|
21
|
+
}
|
|
22
|
+
export function listRecentSessionsPage(db, options = {}) {
|
|
23
|
+
const { limit = DEFAULT_PAGE_SIZE, cursor } = options;
|
|
24
|
+
const conditions = ['s.message_count > 0'];
|
|
25
|
+
const params = [];
|
|
26
|
+
if (cursor) {
|
|
27
|
+
const c = cursorWhere('recent', cursor);
|
|
28
|
+
conditions.push(c.sql);
|
|
29
|
+
params.push(...c.params);
|
|
30
|
+
}
|
|
31
|
+
return executePage(db, conditions, params, 'recent', limit);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Per-cwd counts across the full project. Drives the chip strip's badges
|
|
35
|
+
* so they show the true distribution rather than just the loaded page.
|
|
36
|
+
* Honors the same `sources` filter as `listSessionsByIdentity`.
|
|
37
|
+
*/
|
|
38
|
+
export function listProjectDirectoryCounts(db, identityKey, options = {}) {
|
|
39
|
+
const { sources } = options;
|
|
40
|
+
const conditions = ['p.identity_key = ?', 's.message_count > 0'];
|
|
41
|
+
const params = [identityKey];
|
|
42
|
+
if (sources && sources.length > 0) {
|
|
43
|
+
const placeholders = sources.map(() => '?').join(',');
|
|
44
|
+
conditions.push(`src.name IN (${placeholders})`);
|
|
45
|
+
params.push(...sources);
|
|
46
|
+
}
|
|
15
47
|
const sql = `
|
|
16
|
-
|
|
48
|
+
SELECT
|
|
49
|
+
COALESCE(NULLIF(s.cwd, ''), '(unknown)') AS cwd,
|
|
50
|
+
COUNT(*) AS cnt,
|
|
51
|
+
MAX(s.started_at) AS last_at
|
|
52
|
+
FROM sessions s
|
|
53
|
+
JOIN sources src ON src.id = s.source_id
|
|
54
|
+
JOIN projects p ON p.id = s.project_id
|
|
17
55
|
WHERE ${conditions.join(' AND ')}
|
|
18
|
-
|
|
19
|
-
|
|
56
|
+
GROUP BY cwd
|
|
57
|
+
ORDER BY MAX(s.started_at) DESC
|
|
20
58
|
`;
|
|
21
|
-
params.push(limit);
|
|
22
59
|
const rows = db.prepare(sql).all(...params);
|
|
23
|
-
return rows.map(
|
|
60
|
+
return rows.map(r => ({ cwd: r.cwd, sessionCount: r.cnt, lastSessionAt: r.last_at }));
|
|
24
61
|
}
|
|
25
62
|
export function listPinnedSessionsByIdentity(db, identityKey) {
|
|
26
63
|
const rows = db.prepare(`
|
|
@@ -31,17 +68,84 @@ export function listPinnedSessionsByIdentity(db, identityKey) {
|
|
|
31
68
|
`).all(identityKey);
|
|
32
69
|
return rows.map(rowToSession);
|
|
33
70
|
}
|
|
71
|
+
function executePage(db, conditions, params, sortOrder, limit) {
|
|
72
|
+
const sql = `
|
|
73
|
+
${SESSION_SELECT}
|
|
74
|
+
WHERE ${conditions.join(' AND ')}
|
|
75
|
+
ORDER BY ${orderByClause(sortOrder)}
|
|
76
|
+
LIMIT ?
|
|
77
|
+
`;
|
|
78
|
+
// Fetch limit+1 so we can detect "more rows exist" without a count query.
|
|
79
|
+
const rows = db.prepare(sql).all(...params, limit + 1);
|
|
80
|
+
const hasMore = rows.length > limit;
|
|
81
|
+
const pageRows = hasMore ? rows.slice(0, limit) : rows;
|
|
82
|
+
const sessions = pageRows.map(rowToSession);
|
|
83
|
+
const last = sessions.at(-1);
|
|
84
|
+
const nextCursor = hasMore && last
|
|
85
|
+
? {
|
|
86
|
+
startedAt: last.startedAt,
|
|
87
|
+
sessionUuid: last.sessionUuid,
|
|
88
|
+
messageCount: last.messageCount,
|
|
89
|
+
title: last.title ?? '',
|
|
90
|
+
}
|
|
91
|
+
: null;
|
|
92
|
+
return { sessions, nextCursor };
|
|
93
|
+
}
|
|
34
94
|
function orderByClause(sortOrder) {
|
|
95
|
+
// session_uuid is the unique tiebreaker so the page boundary is deterministic
|
|
96
|
+
// and keyset pagination skips exactly the rows already shown.
|
|
97
|
+
switch (sortOrder) {
|
|
98
|
+
case 'oldest':
|
|
99
|
+
return 's.started_at ASC, s.session_uuid ASC';
|
|
100
|
+
case 'most_messages':
|
|
101
|
+
return 's.message_count DESC, s.started_at DESC, s.session_uuid ASC';
|
|
102
|
+
case 'title':
|
|
103
|
+
return "COALESCE(NULLIF(s.title, ''), '') ASC, s.started_at DESC, s.session_uuid ASC";
|
|
104
|
+
case 'recent':
|
|
105
|
+
default:
|
|
106
|
+
return 's.started_at DESC, s.session_uuid ASC';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function cursorWhere(sortOrder, c) {
|
|
110
|
+
const titleExpr = "COALESCE(NULLIF(s.title, ''), '')";
|
|
35
111
|
switch (sortOrder) {
|
|
36
112
|
case 'oldest':
|
|
37
|
-
return
|
|
113
|
+
return {
|
|
114
|
+
sql: '(s.started_at > ? OR (s.started_at = ? AND s.session_uuid > ?))',
|
|
115
|
+
params: [c.startedAt, c.startedAt, c.sessionUuid],
|
|
116
|
+
};
|
|
38
117
|
case 'most_messages':
|
|
39
|
-
return
|
|
118
|
+
return {
|
|
119
|
+
sql: `(
|
|
120
|
+
s.message_count < ?
|
|
121
|
+
OR (s.message_count = ? AND s.started_at < ?)
|
|
122
|
+
OR (s.message_count = ? AND s.started_at = ? AND s.session_uuid > ?)
|
|
123
|
+
)`,
|
|
124
|
+
params: [
|
|
125
|
+
c.messageCount,
|
|
126
|
+
c.messageCount, c.startedAt,
|
|
127
|
+
c.messageCount, c.startedAt, c.sessionUuid,
|
|
128
|
+
],
|
|
129
|
+
};
|
|
40
130
|
case 'title':
|
|
41
|
-
return
|
|
131
|
+
return {
|
|
132
|
+
sql: `(
|
|
133
|
+
${titleExpr} > ?
|
|
134
|
+
OR (${titleExpr} = ? AND s.started_at < ?)
|
|
135
|
+
OR (${titleExpr} = ? AND s.started_at = ? AND s.session_uuid > ?)
|
|
136
|
+
)`,
|
|
137
|
+
params: [
|
|
138
|
+
c.title,
|
|
139
|
+
c.title, c.startedAt,
|
|
140
|
+
c.title, c.startedAt, c.sessionUuid,
|
|
141
|
+
],
|
|
142
|
+
};
|
|
42
143
|
case 'recent':
|
|
43
144
|
default:
|
|
44
|
-
return
|
|
145
|
+
return {
|
|
146
|
+
sql: '(s.started_at < ? OR (s.started_at = ? AND s.session_uuid > ?))',
|
|
147
|
+
params: [c.startedAt, c.startedAt, c.sessionUuid],
|
|
148
|
+
};
|
|
45
149
|
}
|
|
46
150
|
}
|
|
47
151
|
//# sourceMappingURL=sessions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/projects/sessions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/projects/sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type { FindingState, FindingRow, SessionWithFindingCounts, RiskByCategoryRow, OccurrenceBySession, DismissScope, FindingsChange, ScanStatus, } from './types.js';
|
|
2
|
+
export { REDACT_DETECTOR_VERSION, currentProfileString, parseProfile, profilesMatch, providersInProfile, } from './profile.js';
|
|
3
|
+
export type { ProfileOpts, ParsedProfile } from './profile.js';
|
|
4
|
+
export { insertFindings, deleteActiveFindings, deleteRefreshableFindings, updateSessionCounts, setSessionScanProfile, invalidateAllScanProfiles, invalidateSessionScanProfile, listSessionsNeedingScan, listFindings, listFindingsPage, listSessionsWithFindings, listSessionsWithFindingsPage, countSessionsWithFindings, occurrencesByValueHash, riskByCategory, lastScanCompletedAt, getFindingValue, getFindingValues, getAllowlists, isAllowlisted, addAllowlistSession, addAllowlistGlobal, removeAllowlistSession, removeAllowlistGlobal, listAllowlistEntries, countAllowlistEntries, dismissFinding, dismissFindings, undismissFinding, } from './repo.js';
|
|
5
|
+
export type { FindingFilter, SessionFindingFilter, FindingInput, AllowlistEntryRow, AllowlistSnapshot, Page, } from './repo.js';
|
|
6
|
+
export { scanSession, ScanError } from './scan.js';
|
|
7
|
+
export type { ScanResult, ScanSessionDeps } from './scan.js';
|
|
8
|
+
export { purgeFinding, purgeFindings, purgeEverywhere, orderForBulkPurge, PurgeError } from './purge.js';
|
|
9
|
+
export type { PurgeResult, PurgeDeps } from './purge.js';
|
|
10
|
+
export { makeScanWorker, waitForIdle } from './worker.js';
|
|
11
|
+
export type { ScanWorker, WorkerConfig } from './worker.js';
|
|
12
|
+
export { listBackups, deleteBackups, backupDirFor } from './maintenance.js';
|
|
13
|
+
export type { BackupFileInfo, DeleteBackupsResult, } from './maintenance.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,UAAU,GACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,kBAAkB,GACnB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE9D,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,IAAI,GACL,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAClD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE5D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACxG,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC3E,YAAY,EACV,cAAc,EACd,mBAAmB,GACpB,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { REDACT_DETECTOR_VERSION, currentProfileString, parseProfile, profilesMatch, providersInProfile, } from './profile.js';
|
|
2
|
+
export { insertFindings, deleteActiveFindings, deleteRefreshableFindings, updateSessionCounts, setSessionScanProfile, invalidateAllScanProfiles, invalidateSessionScanProfile, listSessionsNeedingScan, listFindings, listFindingsPage, listSessionsWithFindings, listSessionsWithFindingsPage, countSessionsWithFindings, occurrencesByValueHash, riskByCategory, lastScanCompletedAt, getFindingValue, getFindingValues, getAllowlists, isAllowlisted, addAllowlistSession, addAllowlistGlobal, removeAllowlistSession, removeAllowlistGlobal, listAllowlistEntries, countAllowlistEntries, dismissFinding, dismissFindings, undismissFinding, } from './repo.js';
|
|
3
|
+
export { scanSession, ScanError } from './scan.js';
|
|
4
|
+
export { purgeFinding, purgeFindings, purgeEverywhere, orderForBulkPurge, PurgeError } from './purge.js';
|
|
5
|
+
export { makeScanWorker, waitForIdle } from './worker.js';
|
|
6
|
+
export { listBackups, deleteBackups, backupDirFor } from './maintenance.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,kBAAkB,GACnB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,WAAW,CAAA;AAUlB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGlD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGxG,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGzD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export interface BackupFileInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
sizeBytes: number;
|
|
5
|
+
mtimeMs: number;
|
|
6
|
+
kind: 'auto' | 'manual';
|
|
7
|
+
}
|
|
8
|
+
export interface DeleteBackupsResult {
|
|
9
|
+
deleted: number;
|
|
10
|
+
bytesFreed: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function backupDirFor(db: Database.Database): string | null;
|
|
13
|
+
export declare function listBackups(db: Database.Database): BackupFileInfo[];
|
|
14
|
+
export declare function deleteBackups(db: Database.Database, names: readonly string[]): DeleteBackupsResult;
|
|
15
|
+
//# sourceMappingURL=maintenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../src/security/maintenance.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAS1C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,GAAG,IAAI,CAKjE;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,cAAc,EAAE,CAsBnE;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,mBAAmB,CAwBrB"}
|