@ai-studio-3d/vyasa 0.1.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 +69 -0
- package/data/common-kit.json +34 -0
- package/data/pricing.json +119 -0
- package/data/schema/AnalyticsData.json +214 -0
- package/data/schema/FoundationData.json +42 -0
- package/data/schema/KitData.json +321 -0
- package/data/schema/SearchData.json +173 -0
- package/data/schema/SessionDetailData.json +231 -0
- package/data/schema/SessionsListData.json +115 -0
- package/data/schema/WasteData.json +95 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +343 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/billing/index.d.ts +4 -0
- package/dist/core/billing/index.d.ts.map +1 -0
- package/dist/core/billing/index.js +43 -0
- package/dist/core/billing/index.js.map +1 -0
- package/dist/core/budget/index.d.ts +30 -0
- package/dist/core/budget/index.d.ts.map +1 -0
- package/dist/core/budget/index.js +61 -0
- package/dist/core/budget/index.js.map +1 -0
- package/dist/core/codex/index.d.ts +3 -0
- package/dist/core/codex/index.d.ts.map +1 -0
- package/dist/core/codex/index.js +212 -0
- package/dist/core/codex/index.js.map +1 -0
- package/dist/core/cursor/index.d.ts +3 -0
- package/dist/core/cursor/index.d.ts.map +1 -0
- package/dist/core/cursor/index.js +304 -0
- package/dist/core/cursor/index.js.map +1 -0
- package/dist/core/cursor/scan.d.ts +28 -0
- package/dist/core/cursor/scan.d.ts.map +1 -0
- package/dist/core/cursor/scan.js +79 -0
- package/dist/core/cursor/scan.js.map +1 -0
- package/dist/core/decisions/index.d.ts +21 -0
- package/dist/core/decisions/index.d.ts.map +1 -0
- package/dist/core/decisions/index.js +133 -0
- package/dist/core/decisions/index.js.map +1 -0
- package/dist/core/dlp/index.d.ts +7 -0
- package/dist/core/dlp/index.d.ts.map +1 -0
- package/dist/core/dlp/index.js +115 -0
- package/dist/core/dlp/index.js.map +1 -0
- package/dist/core/health/index.d.ts +10 -0
- package/dist/core/health/index.d.ts.map +1 -0
- package/dist/core/health/index.js +21 -0
- package/dist/core/health/index.js.map +1 -0
- package/dist/core/index/index.d.ts +9 -0
- package/dist/core/index/index.d.ts.map +1 -0
- package/dist/core/index/index.js +103 -0
- package/dist/core/index/index.js.map +1 -0
- package/dist/core/index/ingest.d.ts +16 -0
- package/dist/core/index/ingest.d.ts.map +1 -0
- package/dist/core/index/ingest.js +184 -0
- package/dist/core/index/ingest.js.map +1 -0
- package/dist/core/index/platforms.d.ts +21 -0
- package/dist/core/index/platforms.d.ts.map +1 -0
- package/dist/core/index/platforms.js +44 -0
- package/dist/core/index/platforms.js.map +1 -0
- package/dist/core/index/pricing-map.d.ts +10 -0
- package/dist/core/index/pricing-map.d.ts.map +1 -0
- package/dist/core/index/pricing-map.js +16 -0
- package/dist/core/index/pricing-map.js.map +1 -0
- package/dist/core/index/progress.d.ts +26 -0
- package/dist/core/index/progress.d.ts.map +1 -0
- package/dist/core/index/progress.js +59 -0
- package/dist/core/index/progress.js.map +1 -0
- package/dist/core/index/scan.d.ts +9 -0
- package/dist/core/index/scan.d.ts.map +1 -0
- package/dist/core/index/scan.js +42 -0
- package/dist/core/index/scan.js.map +1 -0
- package/dist/core/index/statements.d.ts +18 -0
- package/dist/core/index/statements.d.ts.map +1 -0
- package/dist/core/index/statements.js +82 -0
- package/dist/core/index/statements.js.map +1 -0
- package/dist/core/index/tail.d.ts +42 -0
- package/dist/core/index/tail.d.ts.map +1 -0
- package/dist/core/index/tail.js +123 -0
- package/dist/core/index/tail.js.map +1 -0
- package/dist/core/jsonl/index.d.ts +3 -0
- package/dist/core/jsonl/index.d.ts.map +1 -0
- package/dist/core/jsonl/index.js +106 -0
- package/dist/core/jsonl/index.js.map +1 -0
- package/dist/core/jsonl-validate/index.d.ts +10 -0
- package/dist/core/jsonl-validate/index.d.ts.map +1 -0
- package/dist/core/jsonl-validate/index.js +40 -0
- package/dist/core/jsonl-validate/index.js.map +1 -0
- package/dist/core/kit/detection.d.ts +94 -0
- package/dist/core/kit/detection.d.ts.map +1 -0
- package/dist/core/kit/detection.js +312 -0
- package/dist/core/kit/detection.js.map +1 -0
- package/dist/core/kit/index.d.ts +12 -0
- package/dist/core/kit/index.d.ts.map +1 -0
- package/dist/core/kit/index.js +131 -0
- package/dist/core/kit/index.js.map +1 -0
- package/dist/core/kit/scan.d.ts +28 -0
- package/dist/core/kit/scan.d.ts.map +1 -0
- package/dist/core/kit/scan.js +432 -0
- package/dist/core/kit/scan.js.map +1 -0
- package/dist/core/recap/index.d.ts +18 -0
- package/dist/core/recap/index.d.ts.map +1 -0
- package/dist/core/recap/index.js +88 -0
- package/dist/core/recap/index.js.map +1 -0
- package/dist/core/repetition/index.d.ts +5 -0
- package/dist/core/repetition/index.d.ts.map +1 -0
- package/dist/core/repetition/index.js +0 -0
- package/dist/core/repetition/index.js.map +1 -0
- package/dist/core/schema/index.d.ts +514 -0
- package/dist/core/schema/index.d.ts.map +1 -0
- package/dist/core/schema/index.js +2 -0
- package/dist/core/schema/index.js.map +1 -0
- package/dist/core/schema-watch/index.d.ts +34 -0
- package/dist/core/schema-watch/index.d.ts.map +1 -0
- package/dist/core/schema-watch/index.js +87 -0
- package/dist/core/schema-watch/index.js.map +1 -0
- package/dist/core/search/index.d.ts +44 -0
- package/dist/core/search/index.d.ts.map +1 -0
- package/dist/core/search/index.js +641 -0
- package/dist/core/search/index.js.map +1 -0
- package/dist/core/settings/index.d.ts +24 -0
- package/dist/core/settings/index.d.ts.map +1 -0
- package/dist/core/settings/index.js +76 -0
- package/dist/core/settings/index.js.map +1 -0
- package/dist/core/share/bundle.d.ts +40 -0
- package/dist/core/share/bundle.d.ts.map +1 -0
- package/dist/core/share/bundle.js +158 -0
- package/dist/core/share/bundle.js.map +1 -0
- package/dist/core/share/canonical/from-claude.d.ts +13 -0
- package/dist/core/share/canonical/from-claude.d.ts.map +1 -0
- package/dist/core/share/canonical/from-claude.js +129 -0
- package/dist/core/share/canonical/from-claude.js.map +1 -0
- package/dist/core/share/canonical/from-codex.d.ts +18 -0
- package/dist/core/share/canonical/from-codex.d.ts.map +1 -0
- package/dist/core/share/canonical/from-codex.js +183 -0
- package/dist/core/share/canonical/from-codex.js.map +1 -0
- package/dist/core/share/canonical/to-claude.d.ts +15 -0
- package/dist/core/share/canonical/to-claude.d.ts.map +1 -0
- package/dist/core/share/canonical/to-claude.js +146 -0
- package/dist/core/share/canonical/to-claude.js.map +1 -0
- package/dist/core/share/canonical/to-codex.d.ts +21 -0
- package/dist/core/share/canonical/to-codex.d.ts.map +1 -0
- package/dist/core/share/canonical/to-codex.js +124 -0
- package/dist/core/share/canonical/to-codex.js.map +1 -0
- package/dist/core/share/canonical/tool-map.d.ts +61 -0
- package/dist/core/share/canonical/tool-map.d.ts.map +1 -0
- package/dist/core/share/canonical/tool-map.js +299 -0
- package/dist/core/share/canonical/tool-map.js.map +1 -0
- package/dist/core/share/canonical/types.d.ts +57 -0
- package/dist/core/share/canonical/types.d.ts.map +1 -0
- package/dist/core/share/canonical/types.js +9 -0
- package/dist/core/share/canonical/types.js.map +1 -0
- package/dist/core/share/import.d.ts +28 -0
- package/dist/core/share/import.d.ts.map +1 -0
- package/dist/core/share/import.js +174 -0
- package/dist/core/share/import.js.map +1 -0
- package/dist/core/share/manifest.d.ts +37 -0
- package/dist/core/share/manifest.d.ts.map +1 -0
- package/dist/core/share/manifest.js +31 -0
- package/dist/core/share/manifest.js.map +1 -0
- package/dist/core/share/preview.d.ts +4 -0
- package/dist/core/share/preview.d.ts.map +1 -0
- package/dist/core/share/preview.js +153 -0
- package/dist/core/share/preview.js.map +1 -0
- package/dist/core/share/primer.d.ts +19 -0
- package/dist/core/share/primer.d.ts.map +1 -0
- package/dist/core/share/primer.js +196 -0
- package/dist/core/share/primer.js.map +1 -0
- package/dist/core/share/resume.d.ts +10 -0
- package/dist/core/share/resume.d.ts.map +1 -0
- package/dist/core/share/resume.js +58 -0
- package/dist/core/share/resume.js.map +1 -0
- package/dist/core/share/scrub.d.ts +10 -0
- package/dist/core/share/scrub.d.ts.map +1 -0
- package/dist/core/share/scrub.js +198 -0
- package/dist/core/share/scrub.js.map +1 -0
- package/dist/core/share/tar.d.ts +12 -0
- package/dist/core/share/tar.d.ts.map +1 -0
- package/dist/core/share/tar.js +78 -0
- package/dist/core/share/tar.js.map +1 -0
- package/dist/core/tags/index.d.ts +48 -0
- package/dist/core/tags/index.d.ts.map +1 -0
- package/dist/core/tags/index.js +113 -0
- package/dist/core/tags/index.js.map +1 -0
- package/dist/core/today/index.d.ts +25 -0
- package/dist/core/today/index.d.ts.map +1 -0
- package/dist/core/today/index.js +42 -0
- package/dist/core/today/index.js.map +1 -0
- package/dist/core/waste/abandoned.d.ts +12 -0
- package/dist/core/waste/abandoned.d.ts.map +1 -0
- package/dist/core/waste/abandoned.js +127 -0
- package/dist/core/waste/abandoned.js.map +1 -0
- package/dist/core/waste/cache-miss.d.ts +9 -0
- package/dist/core/waste/cache-miss.d.ts.map +1 -0
- package/dist/core/waste/cache-miss.js +84 -0
- package/dist/core/waste/cache-miss.js.map +1 -0
- package/dist/core/waste/index.d.ts +12 -0
- package/dist/core/waste/index.d.ts.map +1 -0
- package/dist/core/waste/index.js +45 -0
- package/dist/core/waste/index.js.map +1 -0
- package/dist/core/waste/wrong-model.d.ts +11 -0
- package/dist/core/waste/wrong-model.d.ts.map +1 -0
- package/dist/core/waste/wrong-model.js +104 -0
- package/dist/core/waste/wrong-model.js.map +1 -0
- package/dist/db/index.d.ts +10 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +29 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrate.d.ts +8 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +282 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/server/events.d.ts +4 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/events.js +54 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +238 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/foundation.d.ts +2 -0
- package/dist/server/routes/foundation.d.ts.map +1 -0
- package/dist/server/routes/foundation.js +2 -0
- package/dist/server/routes/foundation.js.map +1 -0
- package/dist/server/routes/search.d.ts +2 -0
- package/dist/server/routes/search.d.ts.map +1 -0
- package/dist/server/routes/search.js +2 -0
- package/dist/server/routes/search.js.map +1 -0
- package/dist/server/routes/sessions.d.ts +2 -0
- package/dist/server/routes/sessions.d.ts.map +1 -0
- package/dist/server/routes/sessions.js +2 -0
- package/dist/server/routes/sessions.js.map +1 -0
- package/dist/server/routes/waste.d.ts +2 -0
- package/dist/server/routes/waste.d.ts.map +1 -0
- package/dist/server/routes/waste.js +2 -0
- package/dist/server/routes/waste.js.map +1 -0
- package/dist/web/assets/index-Ba1VvTj0.js +37 -0
- package/dist/web/index.html +12 -0
- package/package.json +76 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { basename, dirname } from 'node:path';
|
|
2
|
+
import { parseJsonl } from '../jsonl/index.js';
|
|
3
|
+
import { parseCodex } from '../codex/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Synchronous ingest of a pre-parsed session.
|
|
6
|
+
* Must be called INSIDE a caller-supplied db.transaction() — does NOT wrap itself.
|
|
7
|
+
* Throws on any SQLite error so the caller's transaction rolls back cleanly.
|
|
8
|
+
*/
|
|
9
|
+
export function ingestFromParsed(db, stmts, pricingMap, filePath, mtimeMs, platform, parsed) {
|
|
10
|
+
const sessionId = parsed.sessionId;
|
|
11
|
+
// Codex sets parsed.project from session_meta.payload.cwd; Claude leaves it null.
|
|
12
|
+
const project = parsed.project ?? basename(dirname(filePath));
|
|
13
|
+
// Map from tool_use block id → tool_calls rowid (for matching tool_result)
|
|
14
|
+
const toolUseRowids = new Map();
|
|
15
|
+
// 1. Upsert session row (file_path lets the export feature locate the source JSONL later)
|
|
16
|
+
stmts.upsertSession.run(sessionId, project, platform, parsed.startedAt, parsed.endedAt, filePath);
|
|
17
|
+
// 1b. Capture Claude-native names (recomputed each ingest; never touches the user's custom_name)
|
|
18
|
+
stmts.upsertClaudeName.run(sessionId, parsed.claudeCustomTitle, parsed.claudeAiTitle);
|
|
19
|
+
// 2. Insert messages, usage, tool_calls, fts
|
|
20
|
+
for (let idx = 0; idx < parsed.records.length; idx++) {
|
|
21
|
+
const record = parsed.records[idx];
|
|
22
|
+
let contentJson;
|
|
23
|
+
let model = null;
|
|
24
|
+
const ftsContent = [];
|
|
25
|
+
const ftsToolInputs = [];
|
|
26
|
+
const ftsToolOutputs = [];
|
|
27
|
+
if (record.type === 'assistant') {
|
|
28
|
+
const ar = record;
|
|
29
|
+
model = ar.message.model;
|
|
30
|
+
contentJson = JSON.stringify(ar.message);
|
|
31
|
+
// Collect FTS text content (tool_use handled after message insert)
|
|
32
|
+
for (const block of ar.message.content) {
|
|
33
|
+
if (block.type === 'text') {
|
|
34
|
+
ftsContent.push(block.text.slice(0, 2000));
|
|
35
|
+
}
|
|
36
|
+
else if (block.type === 'tool_use') {
|
|
37
|
+
ftsToolInputs.push(block.name + ' ' + JSON.stringify(block.input).slice(0, 1000));
|
|
38
|
+
}
|
|
39
|
+
// thinking blocks: internal reasoning, never user-searchable — skip FTS entirely
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (record.type === 'user') {
|
|
43
|
+
const ur = record;
|
|
44
|
+
contentJson = JSON.stringify(ur.message);
|
|
45
|
+
if (typeof ur.message.content === 'string') {
|
|
46
|
+
ftsContent.push(ur.message.content);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
for (const block of ur.message.content) {
|
|
50
|
+
if (block.type === 'text') {
|
|
51
|
+
ftsContent.push(block.text);
|
|
52
|
+
}
|
|
53
|
+
else if (block.type === 'tool_result') {
|
|
54
|
+
// F1: index tool-result output text so search can recall it. Cap per-result at 600
|
|
55
|
+
// chars to keep tokenization bounded (full output still lives in tool_calls.output_json).
|
|
56
|
+
const text = typeof block.content === 'string'
|
|
57
|
+
? block.content
|
|
58
|
+
: JSON.stringify(block.content);
|
|
59
|
+
if (text)
|
|
60
|
+
ftsToolOutputs.push(text.slice(0, 600));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// system record — include compactMetadata so Phase 4 can read preTokens/postTokens
|
|
67
|
+
contentJson = JSON.stringify({
|
|
68
|
+
subtype: record.subtype,
|
|
69
|
+
content: record.content,
|
|
70
|
+
isMeta: record.isMeta,
|
|
71
|
+
compactMetadata: record.compactMetadata,
|
|
72
|
+
});
|
|
73
|
+
if (record.content)
|
|
74
|
+
ftsContent.push(record.content);
|
|
75
|
+
}
|
|
76
|
+
// Insert message row FIRST — usage and tool_calls have FK on messages.id
|
|
77
|
+
// F3: user records carry a per-record permissionMode; assistant/system records don't.
|
|
78
|
+
const permissionMode = record.type === 'user' ? record.permissionMode ?? null : null;
|
|
79
|
+
stmts.insertMessage.run(record.uuid, sessionId, idx, record.type, record.timestamp, model, contentJson, permissionMode);
|
|
80
|
+
// Now insert dependent rows for assistant records
|
|
81
|
+
if (record.type === 'assistant') {
|
|
82
|
+
const ar = record;
|
|
83
|
+
// Insert usage
|
|
84
|
+
if (ar.message.usage != null) {
|
|
85
|
+
const u = ar.message.usage;
|
|
86
|
+
stmts.insertUsage.run(ar.uuid, u.input_tokens, u.output_tokens, u.cache_creation_input_tokens, u.cache_read_input_tokens);
|
|
87
|
+
}
|
|
88
|
+
// Insert tool_calls and record rowids for later tool_result matching
|
|
89
|
+
for (const block of ar.message.content) {
|
|
90
|
+
if (block.type === 'tool_use') {
|
|
91
|
+
const result = stmts.insertToolCall.run(ar.uuid, block.name, JSON.stringify(block.input));
|
|
92
|
+
toolUseRowids.set(block.id, Number(result.lastInsertRowid));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Match tool_result outputs for user records (tool_calls already inserted above)
|
|
97
|
+
if (record.type === 'user') {
|
|
98
|
+
const ur = record;
|
|
99
|
+
// Duration (when present) lives on the user record's top-level toolUseResult object
|
|
100
|
+
// (e.g. WebFetch's durationMs). Shared across the record's tool_result blocks — Claude
|
|
101
|
+
// emits one tool_result per user record in practice, so this is a safe association.
|
|
102
|
+
const tur = ur.toolUseResult;
|
|
103
|
+
const durationMs = tur && typeof tur === 'object' && typeof tur.durationMs === 'number'
|
|
104
|
+
? tur.durationMs
|
|
105
|
+
: null;
|
|
106
|
+
if (typeof ur.message.content !== 'string') {
|
|
107
|
+
for (const block of ur.message.content) {
|
|
108
|
+
if (block.type === 'tool_result') {
|
|
109
|
+
const rowid = toolUseRowids.get(block.tool_use_id);
|
|
110
|
+
if (rowid !== undefined) {
|
|
111
|
+
const outputJson = typeof block.content === 'string'
|
|
112
|
+
? block.content
|
|
113
|
+
: JSON.stringify(block.content);
|
|
114
|
+
stmts.updateToolCallOutput.run(outputJson, rowid);
|
|
115
|
+
// F4: capture error signal + duration onto the matched tool_call. is_error rides on
|
|
116
|
+
// the tool_result content block itself (confirmed in real Claude JSONL).
|
|
117
|
+
if (block.is_error === true) {
|
|
118
|
+
stmts.setToolCallError.run(outputJson.slice(0, 2000), durationMs, rowid);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const ftsText = ftsContent.join(' ');
|
|
126
|
+
const ftsInputs = ftsToolInputs.join(' ');
|
|
127
|
+
const ftsOutputs = ftsToolOutputs.join(' ');
|
|
128
|
+
// Skip FTS for messages with no meaningful content (e.g. empty user turns)
|
|
129
|
+
if (ftsText.length > 10 || ftsInputs.length > 10 || ftsOutputs.length > 10) {
|
|
130
|
+
stmts.insertFts.run(sessionId, record.uuid, ftsText, ftsInputs, ftsOutputs);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const totals = stmts.sumUsage.get(sessionId);
|
|
134
|
+
const ti = totals.ti ?? 0;
|
|
135
|
+
const to_ = totals.to_ ?? 0;
|
|
136
|
+
const tc = totals.tc ?? 0;
|
|
137
|
+
const tr = totals.tr ?? 0;
|
|
138
|
+
// Cost per assistant record — accurate for mixed-model sessions
|
|
139
|
+
let totalCostCents = 0;
|
|
140
|
+
for (const r of parsed.records) {
|
|
141
|
+
if (r.type !== 'assistant')
|
|
142
|
+
continue;
|
|
143
|
+
const ar = r;
|
|
144
|
+
if (ar.message.usage == null)
|
|
145
|
+
continue;
|
|
146
|
+
const pricing = pricingMap.get(ar.message.model);
|
|
147
|
+
if (!pricing)
|
|
148
|
+
continue;
|
|
149
|
+
const u = ar.message.usage;
|
|
150
|
+
totalCostCents +=
|
|
151
|
+
((u.input_tokens * pricing.input_per_mtok +
|
|
152
|
+
u.output_tokens * pricing.output_per_mtok +
|
|
153
|
+
u.cache_creation_input_tokens * pricing.cache_write_per_mtok +
|
|
154
|
+
u.cache_read_input_tokens * pricing.cache_read_per_mtok) /
|
|
155
|
+
1_000_000) *
|
|
156
|
+
100;
|
|
157
|
+
}
|
|
158
|
+
// last_outcome: ignore trailing system records (e.g. compact_boundary) when determining outcome
|
|
159
|
+
const lastMeaningfulRecord = [...parsed.records].reverse().find(r => r.type !== 'system');
|
|
160
|
+
const lastOutcome = lastMeaningfulRecord?.type === 'assistant' ? 'completed' : 'abandoned';
|
|
161
|
+
stmts.updateSession.run(parsed.records.length, ti, to_, tc, tr, totalCostCents, lastOutcome, sessionId);
|
|
162
|
+
// 4. Upsert file index
|
|
163
|
+
stmts.upsertFileIndex.run(filePath, mtimeMs);
|
|
164
|
+
// 5. Write parse errors (non-fatal — best-effort inside the caller's transaction)
|
|
165
|
+
for (const e of parsed.parseErrors) {
|
|
166
|
+
stmts.insertParseError.run(filePath, e.lineNum, e.recordType, e.error, e.sampleJson);
|
|
167
|
+
}
|
|
168
|
+
// 6. Upsert schema fingerprint observations (non-critical — inside caller's transaction)
|
|
169
|
+
for (const [fp, meta] of parsed.fingerprints.entries()) {
|
|
170
|
+
stmts.upsertFingerprint.run(platform, fp, filePath, meta.firstSeenLine);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Async wrapper — parses and ingests a single file inside its own transaction.
|
|
175
|
+
* Preserved for backward compatibility with any tests calling ingestFile directly.
|
|
176
|
+
*/
|
|
177
|
+
export async function ingestFile(db, filePath, mtimeMs, platform = 'claude-code', stmts, pricingMap) {
|
|
178
|
+
const parse = platform === 'codex' ? parseCodex : parseJsonl;
|
|
179
|
+
const parsed = await parse(filePath);
|
|
180
|
+
if (parsed.sessionId === null)
|
|
181
|
+
return;
|
|
182
|
+
db.transaction(() => ingestFromParsed(db, stmts, pricingMap, filePath, mtimeMs, platform, parsed))();
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../../src/core/index/ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ParsedSession } from '../schema/index.js';
|
|
2
|
+
export interface PlatformAdapter {
|
|
3
|
+
id: 'claude-code' | 'codex' | 'cursor';
|
|
4
|
+
rootDir: string;
|
|
5
|
+
scan(): Promise<Array<{
|
|
6
|
+
path: string;
|
|
7
|
+
mtimeMs: number;
|
|
8
|
+
}>>;
|
|
9
|
+
parse(file: string): Promise<ParsedSession>;
|
|
10
|
+
}
|
|
11
|
+
export declare const claudeAdapter: PlatformAdapter;
|
|
12
|
+
export declare const codexAdapter: PlatformAdapter;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve Cursor's workspaceStorage directory for the current OS. The actual
|
|
15
|
+
* conversation data lives in `../globalStorage/state.vscdb`; we point rootDir
|
|
16
|
+
* at workspaceStorage to preserve the per-project mapping (workspace.json
|
|
17
|
+
* sibling files), and the scan/parse helpers derive globalStorage from it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function cursorWorkspaceStorageDir(): string;
|
|
20
|
+
export declare const cursorAdapter: PlatformAdapter;
|
|
21
|
+
//# sourceMappingURL=platforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platforms.d.ts","sourceRoot":"","sources":["../../../src/core/index/platforms.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAA;IACtC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IACzD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;CAC5C;AAED,eAAO,MAAM,aAAa,EAAE,eAK3B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,eAK1B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAWlD;AAED,eAAO,MAAM,aAAa,EAAE,eAK3B,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { homedir, platform } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { scanFiles } from './scan.js';
|
|
4
|
+
import { parseJsonl } from '../jsonl/index.js';
|
|
5
|
+
import { parseCodex } from '../codex/index.js';
|
|
6
|
+
import { parseCursor } from '../cursor/index.js';
|
|
7
|
+
import { scanCursorWorkspaces } from '../cursor/scan.js';
|
|
8
|
+
export const claudeAdapter = {
|
|
9
|
+
id: 'claude-code',
|
|
10
|
+
rootDir: join(homedir(), '.claude', 'projects'),
|
|
11
|
+
scan() { return scanFiles(this.rootDir); },
|
|
12
|
+
parse: parseJsonl,
|
|
13
|
+
};
|
|
14
|
+
export const codexAdapter = {
|
|
15
|
+
id: 'codex',
|
|
16
|
+
rootDir: join(homedir(), '.codex', 'sessions'),
|
|
17
|
+
scan() { return scanFiles(this.rootDir); },
|
|
18
|
+
parse: parseCodex,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Resolve Cursor's workspaceStorage directory for the current OS. The actual
|
|
22
|
+
* conversation data lives in `../globalStorage/state.vscdb`; we point rootDir
|
|
23
|
+
* at workspaceStorage to preserve the per-project mapping (workspace.json
|
|
24
|
+
* sibling files), and the scan/parse helpers derive globalStorage from it.
|
|
25
|
+
*/
|
|
26
|
+
export function cursorWorkspaceStorageDir() {
|
|
27
|
+
switch (platform()) {
|
|
28
|
+
case 'darwin':
|
|
29
|
+
return join(homedir(), 'Library', 'Application Support', 'Cursor', 'User', 'workspaceStorage');
|
|
30
|
+
case 'linux':
|
|
31
|
+
return join(homedir(), '.config', 'Cursor', 'User', 'workspaceStorage');
|
|
32
|
+
case 'win32':
|
|
33
|
+
return join(process.env.APPDATA ?? '', 'Cursor', 'User', 'workspaceStorage');
|
|
34
|
+
default:
|
|
35
|
+
return join(homedir(), '.config', 'Cursor', 'User', 'workspaceStorage');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export const cursorAdapter = {
|
|
39
|
+
id: 'cursor',
|
|
40
|
+
rootDir: cursorWorkspaceStorageDir(),
|
|
41
|
+
scan() { return scanCursorWorkspaces(this.rootDir); },
|
|
42
|
+
parse: parseCursor,
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=platforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../../../src/core/index/platforms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAUxD,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,EAAE,EAAE,aAAa;IACjB,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC;IAC/C,IAAI,KAAK,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC;IACzC,KAAK,EAAE,UAAU;CAClB,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC3C,EAAE,EAAE,OAAO;IACX,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC;IAC9C,IAAI,KAAK,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC;IACzC,KAAK,EAAE,UAAU;CAClB,CAAA;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB;IACvC,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAA;QAChG,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAA;QACzE,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAA;QAC9E;YACE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC3E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,EAAE,EAAE,QAAQ;IACZ,OAAO,EAAE,yBAAyB,EAAE;IACpC,IAAI,KAAK,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC;IACpD,KAAK,EAAE,WAAW;CACnB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
export type PricingRow = {
|
|
3
|
+
model: string;
|
|
4
|
+
input_per_mtok: number;
|
|
5
|
+
output_per_mtok: number;
|
|
6
|
+
cache_write_per_mtok: number;
|
|
7
|
+
cache_read_per_mtok: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function loadPricingMap(db: Database.Database): Map<string, PricingRow>;
|
|
10
|
+
//# sourceMappingURL=pricing-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing-map.d.ts","sourceRoot":"","sources":["../../../src/core/index/pricing-map.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAErC,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,mBAAmB,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAiB7E"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function loadPricingMap(db) {
|
|
2
|
+
// Select all pricing rows, keep the latest period_start per model
|
|
3
|
+
const rows = db
|
|
4
|
+
.prepare(`SELECT model, input_per_mtok, output_per_mtok, cache_write_per_mtok, cache_read_per_mtok
|
|
5
|
+
FROM pricing
|
|
6
|
+
WHERE (model, period_start) IN (
|
|
7
|
+
SELECT model, MAX(period_start) FROM pricing GROUP BY model
|
|
8
|
+
)`)
|
|
9
|
+
.all();
|
|
10
|
+
const map = new Map();
|
|
11
|
+
for (const row of rows) {
|
|
12
|
+
map.set(row.model, row);
|
|
13
|
+
}
|
|
14
|
+
return map;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=pricing-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing-map.js","sourceRoot":"","sources":["../../../src/core/index/pricing-map.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,cAAc,CAAC,EAAqB;IAClD,kEAAkE;IAClE,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;;SAIG,CACJ;SACA,GAAG,EAAkB,CAAA;IAExB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAA;IACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACzB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type IndexPhase = 'scanning' | 'indexing' | 'idle';
|
|
2
|
+
export interface IndexProgressSnapshot {
|
|
3
|
+
phase: IndexPhase;
|
|
4
|
+
filesScanned: number;
|
|
5
|
+
filesIngested: number;
|
|
6
|
+
filesTotal: number;
|
|
7
|
+
currentFile: string | null;
|
|
8
|
+
errorCount: number;
|
|
9
|
+
startedAt: number | null;
|
|
10
|
+
lastUpdate: number;
|
|
11
|
+
durationMs: number;
|
|
12
|
+
}
|
|
13
|
+
declare class IndexProgressState {
|
|
14
|
+
private snap;
|
|
15
|
+
private _running;
|
|
16
|
+
begin(total: number): boolean;
|
|
17
|
+
setPhase(phase: IndexPhase): void;
|
|
18
|
+
filesCompleted(count: number): void;
|
|
19
|
+
recordError(): void;
|
|
20
|
+
finish(): void;
|
|
21
|
+
get(): IndexProgressSnapshot;
|
|
22
|
+
isRunning(): boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare const indexProgress: IndexProgressState;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/core/index/progress.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAA;AAEzD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,IAAI,CAUX;IACD,OAAO,CAAC,QAAQ,CAAQ;IAExB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAiB7B,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAKjC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMnC,WAAW,IAAI,IAAI;IAInB,MAAM,IAAI,IAAI;IAOd,GAAG,IAAI,qBAAqB;IAI5B,SAAS,IAAI,OAAO;CAGrB;AAED,eAAO,MAAM,aAAa,oBAA2B,CAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
class IndexProgressState {
|
|
2
|
+
snap = {
|
|
3
|
+
phase: 'idle',
|
|
4
|
+
filesScanned: 0,
|
|
5
|
+
filesIngested: 0,
|
|
6
|
+
filesTotal: 0,
|
|
7
|
+
currentFile: null,
|
|
8
|
+
errorCount: 0,
|
|
9
|
+
startedAt: null,
|
|
10
|
+
lastUpdate: Date.now(),
|
|
11
|
+
durationMs: 0,
|
|
12
|
+
};
|
|
13
|
+
_running = false;
|
|
14
|
+
begin(total) {
|
|
15
|
+
if (this._running)
|
|
16
|
+
return false;
|
|
17
|
+
this._running = true;
|
|
18
|
+
this.snap = {
|
|
19
|
+
phase: 'scanning',
|
|
20
|
+
filesScanned: 0,
|
|
21
|
+
filesIngested: 0,
|
|
22
|
+
filesTotal: total,
|
|
23
|
+
currentFile: null,
|
|
24
|
+
errorCount: 0,
|
|
25
|
+
startedAt: Date.now(),
|
|
26
|
+
lastUpdate: Date.now(),
|
|
27
|
+
durationMs: 0,
|
|
28
|
+
};
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
setPhase(phase) {
|
|
32
|
+
this.snap.phase = phase;
|
|
33
|
+
this.snap.lastUpdate = Date.now();
|
|
34
|
+
}
|
|
35
|
+
filesCompleted(count) {
|
|
36
|
+
this.snap.filesIngested += count;
|
|
37
|
+
this.snap.lastUpdate = Date.now();
|
|
38
|
+
if (this.snap.startedAt)
|
|
39
|
+
this.snap.durationMs = Date.now() - this.snap.startedAt;
|
|
40
|
+
}
|
|
41
|
+
recordError() {
|
|
42
|
+
this.snap.errorCount++;
|
|
43
|
+
}
|
|
44
|
+
finish() {
|
|
45
|
+
this.snap.phase = 'idle';
|
|
46
|
+
this._running = false;
|
|
47
|
+
this.snap.lastUpdate = Date.now();
|
|
48
|
+
if (this.snap.startedAt)
|
|
49
|
+
this.snap.durationMs = Date.now() - this.snap.startedAt;
|
|
50
|
+
}
|
|
51
|
+
get() {
|
|
52
|
+
return { ...this.snap };
|
|
53
|
+
}
|
|
54
|
+
isRunning() {
|
|
55
|
+
return this._running;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const indexProgress = new IndexProgressState();
|
|
59
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../src/core/index/progress.ts"],"names":[],"mappings":"AAcA,MAAM,kBAAkB;IACd,IAAI,GAA0B;QACpC,KAAK,EAAE,MAAM;QACb,YAAY,EAAE,CAAC;QACf,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;QACtB,UAAU,EAAE,CAAC;KACd,CAAA;IACO,QAAQ,GAAG,KAAK,CAAA;IAExB,KAAK,CAAC,KAAa;QACjB,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG;YACV,KAAK,EAAE,UAAU;YACjB,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,UAAU,EAAE,CAAC;SACd,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,KAAiB;QACxB,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACnC,CAAC;IAED,cAAc,CAAC,KAAa;QAC1B,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,KAAK,CAAA;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACjC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAA;IAClF,CAAC;IAED,WAAW;QACT,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAA;IACxB,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QACrB,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACjC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAA;IAClF,CAAC;IAED,GAAG;QACD,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IACzB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,kBAAkB,EAAE,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively walks projectsDir and returns all *.jsonl files with their mtime.
|
|
3
|
+
* Returns [] if projectsDir does not exist.
|
|
4
|
+
*/
|
|
5
|
+
export declare function scanFiles(projectsDir: string): Promise<Array<{
|
|
6
|
+
path: string;
|
|
7
|
+
mtimeMs: number;
|
|
8
|
+
}>>;
|
|
9
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/core/index/scan.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAgCnD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively walks projectsDir and returns all *.jsonl files with their mtime.
|
|
5
|
+
* Returns [] if projectsDir does not exist.
|
|
6
|
+
*/
|
|
7
|
+
export async function scanFiles(projectsDir) {
|
|
8
|
+
const results = [];
|
|
9
|
+
async function walk(dir) {
|
|
10
|
+
let entries;
|
|
11
|
+
try {
|
|
12
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
const e = err;
|
|
16
|
+
if (e.code === 'ENOENT')
|
|
17
|
+
return;
|
|
18
|
+
throw err;
|
|
19
|
+
}
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const fullPath = join(dir, entry.name);
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
await walk(fullPath);
|
|
24
|
+
}
|
|
25
|
+
else if (entry.isFile() && entry.name.endsWith('.jsonl')) {
|
|
26
|
+
let s;
|
|
27
|
+
try {
|
|
28
|
+
s = await stat(fullPath);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (err.code === 'ENOENT')
|
|
32
|
+
continue;
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
results.push({ path: fullPath, mtimeMs: s.mtimeMs });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
await walk(projectsDir);
|
|
40
|
+
return results;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/core/index/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,WAAmB;IAEnB,MAAM,OAAO,GAA6C,EAAE,CAAA;IAE5D,KAAK,UAAU,IAAI,CAAC,GAAW;QAC7B,IAAI,OAAO,CAAA;QACX,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QACvD,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAA4B,CAAA;YACtC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAM;YAC/B,MAAM,GAAG,CAAA;QACX,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YACtC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;YACtB,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3D,IAAI,CAAC,CAAA;gBACL,IAAI,CAAC;oBACH,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;gBAC1B,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;wBAAE,SAAQ;oBAC9D,MAAM,GAAG,CAAA;gBACX,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,WAAW,CAAC,CAAA;IACvB,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
export interface IngestStatements {
|
|
3
|
+
upsertSession: Database.Statement;
|
|
4
|
+
upsertClaudeName: Database.Statement;
|
|
5
|
+
insertMessage: Database.Statement;
|
|
6
|
+
insertUsage: Database.Statement;
|
|
7
|
+
insertToolCall: Database.Statement;
|
|
8
|
+
updateToolCallOutput: Database.Statement;
|
|
9
|
+
setToolCallError: Database.Statement;
|
|
10
|
+
insertFts: Database.Statement;
|
|
11
|
+
updateSession: Database.Statement;
|
|
12
|
+
upsertFileIndex: Database.Statement;
|
|
13
|
+
insertParseError: Database.Statement;
|
|
14
|
+
upsertFingerprint: Database.Statement;
|
|
15
|
+
sumUsage: Database.Statement;
|
|
16
|
+
}
|
|
17
|
+
export declare function prepareIngestStatements(db: Database.Database): IngestStatements;
|
|
18
|
+
//# sourceMappingURL=statements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../../src/core/index/statements.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAErC,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAA;IACjC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAA;IACpC,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAA;IACjC,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAA;IAC/B,cAAc,EAAE,QAAQ,CAAC,SAAS,CAAA;IAClC,oBAAoB,EAAE,QAAQ,CAAC,SAAS,CAAA;IACxC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAA;IACpC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAA;IAC7B,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAA;IACjC,eAAe,EAAE,QAAQ,CAAC,SAAS,CAAA;IACnC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAA;IACpC,iBAAiB,EAAE,QAAQ,CAAC,SAAS,CAAA;IACrC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAA;CAC7B;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,gBAAgB,CA8F/E"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export function prepareIngestStatements(db) {
|
|
2
|
+
return {
|
|
3
|
+
upsertSession: db.prepare(`
|
|
4
|
+
INSERT OR REPLACE INTO sessions
|
|
5
|
+
(id, project, platform, started_at, ended_at, file_path, message_count,
|
|
6
|
+
total_input_tokens, total_output_tokens,
|
|
7
|
+
total_cache_creation, total_cache_read,
|
|
8
|
+
total_cost_cents, last_outcome)
|
|
9
|
+
VALUES (?, ?, ?, ?, ?, ?, 0, 0, 0, 0, 0, 0, NULL)
|
|
10
|
+
`),
|
|
11
|
+
// Captures Claude-native names into the FK-free session_meta table. Only ever writes the
|
|
12
|
+
// claude_* columns — never custom_name — so the user's override survives every re-ingest.
|
|
13
|
+
upsertClaudeName: db.prepare(`
|
|
14
|
+
INSERT INTO session_meta (session_id, claude_custom_title, claude_ai_title)
|
|
15
|
+
VALUES (?, ?, ?)
|
|
16
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
17
|
+
-- COALESCE keeps the last-known title if a partial/rotated reparse finds none,
|
|
18
|
+
-- rather than clobbering it to NULL (Claude titles are append-only latest-wins).
|
|
19
|
+
claude_custom_title = COALESCE(excluded.claude_custom_title, claude_custom_title),
|
|
20
|
+
claude_ai_title = COALESCE(excluded.claude_ai_title, claude_ai_title),
|
|
21
|
+
updated_at = datetime('now')
|
|
22
|
+
`),
|
|
23
|
+
insertMessage: db.prepare(`
|
|
24
|
+
INSERT OR IGNORE INTO messages (id, session_id, idx, role, ts, model, content_json, permission_mode)
|
|
25
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
26
|
+
`),
|
|
27
|
+
insertUsage: db.prepare(`
|
|
28
|
+
INSERT OR IGNORE INTO usage (message_id, input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens)
|
|
29
|
+
VALUES (?, ?, ?, ?, ?)
|
|
30
|
+
`),
|
|
31
|
+
insertToolCall: db.prepare(`
|
|
32
|
+
INSERT INTO tool_calls (message_id, tool, input_json)
|
|
33
|
+
VALUES (?, ?, ?)
|
|
34
|
+
`),
|
|
35
|
+
updateToolCallOutput: db.prepare(`
|
|
36
|
+
UPDATE tool_calls SET output_json = ? WHERE id = ?
|
|
37
|
+
`),
|
|
38
|
+
// F4: record a tool_call's error text + duration (duration may be null). Set when a matched
|
|
39
|
+
// tool_result carries is_error === true.
|
|
40
|
+
setToolCallError: db.prepare(`
|
|
41
|
+
UPDATE tool_calls SET error = ?, duration_ms = ? WHERE id = ?
|
|
42
|
+
`),
|
|
43
|
+
// Plain INSERT — cascade-delete on sessions cleans FTS5 via messages_fts_delete trigger before re-ingest
|
|
44
|
+
insertFts: db.prepare(`
|
|
45
|
+
INSERT INTO messages_fts (session_id, message_id, content, tool_inputs, tool_outputs, errors)
|
|
46
|
+
VALUES (?, ?, ?, ?, ?, '')
|
|
47
|
+
`),
|
|
48
|
+
updateSession: db.prepare(`
|
|
49
|
+
UPDATE sessions
|
|
50
|
+
SET message_count = ?,
|
|
51
|
+
total_input_tokens = ?,
|
|
52
|
+
total_output_tokens = ?,
|
|
53
|
+
total_cache_creation = ?,
|
|
54
|
+
total_cache_read = ?,
|
|
55
|
+
total_cost_cents = ?,
|
|
56
|
+
last_outcome = ?
|
|
57
|
+
WHERE id = ?
|
|
58
|
+
`),
|
|
59
|
+
upsertFileIndex: db.prepare(`
|
|
60
|
+
INSERT OR REPLACE INTO _file_index (path, mtime_ms) VALUES (?, ?)
|
|
61
|
+
`),
|
|
62
|
+
insertParseError: db.prepare(`INSERT INTO parse_errors (file_path, line_num, record_type, error, sample_json) VALUES (?, ?, ?, ?, ?)`),
|
|
63
|
+
upsertFingerprint: db.prepare(`
|
|
64
|
+
INSERT INTO _schema_observations (platform, fingerprint, first_seen_file, first_seen_line, last_seen, count)
|
|
65
|
+
VALUES (?, ?, ?, ?, datetime('now'), 1)
|
|
66
|
+
ON CONFLICT(platform, fingerprint) DO UPDATE SET
|
|
67
|
+
count = count + 1,
|
|
68
|
+
last_seen = datetime('now')
|
|
69
|
+
`),
|
|
70
|
+
sumUsage: db.prepare(`
|
|
71
|
+
SELECT
|
|
72
|
+
SUM(u.input_tokens) as ti,
|
|
73
|
+
SUM(u.output_tokens) as to_,
|
|
74
|
+
SUM(u.cache_creation_tokens) as tc,
|
|
75
|
+
SUM(u.cache_read_tokens) as tr
|
|
76
|
+
FROM usage u
|
|
77
|
+
JOIN messages m ON u.message_id = m.id
|
|
78
|
+
WHERE m.session_id = ?
|
|
79
|
+
`),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=statements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statements.js","sourceRoot":"","sources":["../../../src/core/index/statements.ts"],"names":[],"mappings":"AAkBA,MAAM,UAAU,uBAAuB,CAAC,EAAqB;IAC3D,OAAO;QACL,aAAa,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;;;KAOzB,CAAC;QAEF,yFAAyF;QACzF,0FAA0F;QAC1F,gBAAgB,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;;;;;KAS5B,CAAC;QAEF,aAAa,EAAE,EAAE,CAAC,OAAO,CAAC;;;KAGzB,CAAC;QAEF,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC;;;KAGvB,CAAC;QAEF,cAAc,EAAE,EAAE,CAAC,OAAO,CAAC;;;KAG1B,CAAC;QAEF,oBAAoB,EAAE,EAAE,CAAC,OAAO,CAAC;;KAEhC,CAAC;QAEF,4FAA4F;QAC5F,yCAAyC;QACzC,gBAAgB,EAAE,EAAE,CAAC,OAAO,CAAC;;KAE5B,CAAC;QAEF,yGAAyG;QACzG,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC;;;KAGrB,CAAC;QAEF,aAAa,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;KAUzB,CAAC;QAEF,eAAe,EAAE,EAAE,CAAC,OAAO,CAAC;;KAE3B,CAAC;QAEF,gBAAgB,EAAE,EAAE,CAAC,OAAO,CAC1B,wGAAwG,CACzG;QAED,iBAAiB,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;;KAM7B,CAAC;QAEF,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC;;;;;;;;;KASpB,CAAC;KACH,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import Database from 'better-sqlite3';
|
|
3
|
+
export type TailPlatform = 'claude-code' | 'codex';
|
|
4
|
+
export interface TailRoot {
|
|
5
|
+
rootDir: string;
|
|
6
|
+
platform: TailPlatform;
|
|
7
|
+
}
|
|
8
|
+
export interface SessionUpdatedEvent {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
platform: TailPlatform;
|
|
11
|
+
path: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Watches `~/.claude/projects/**\/*.jsonl` and `~/.codex/sessions/**\/*.jsonl`
|
|
15
|
+
* for live writes. Re-ingests changed files (debounced 300ms) and emits
|
|
16
|
+
* `'session-updated'` so the dashboard can refresh.
|
|
17
|
+
*
|
|
18
|
+
* Construction is cheap — call `.start()` after `buildIndex` finishes so we
|
|
19
|
+
* don't race with the initial bulk ingest.
|
|
20
|
+
*/
|
|
21
|
+
export declare class TailWatcher extends EventEmitter {
|
|
22
|
+
private readonly db;
|
|
23
|
+
private readonly roots;
|
|
24
|
+
private readonly stmts;
|
|
25
|
+
private readonly pricingMap;
|
|
26
|
+
private watchers;
|
|
27
|
+
private timers;
|
|
28
|
+
private inFlight;
|
|
29
|
+
private started;
|
|
30
|
+
private closed;
|
|
31
|
+
constructor(db: Database.Database, roots: TailRoot[]);
|
|
32
|
+
/**
|
|
33
|
+
* Begin watching. Safe to call once. With `ignoreInitial: true` chokidar
|
|
34
|
+
* skips the existing tree and only fires on subsequent add/change events.
|
|
35
|
+
*/
|
|
36
|
+
start(): void;
|
|
37
|
+
/** Debounce per-path so burst writes during a single turn coalesce into one ingest. */
|
|
38
|
+
private schedule;
|
|
39
|
+
private ingest;
|
|
40
|
+
close(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=tail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail.d.ts","sourceRoot":"","sources":["../../../src/core/index/tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AASrC,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAA;AAElD,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,YAAY,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;CACb;AAMD;;;;;;;GAOG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAmB;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAAQ;gBAEV,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;IASpD;;;OAGG;IACH,KAAK,IAAI,IAAI;IAoBb,uFAAuF;IACvF,OAAO,CAAC,QAAQ;YAkBF,MAAM;IA0Bd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B"}
|