@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,212 @@
|
|
|
1
|
+
import { createReadStream } from 'node:fs';
|
|
2
|
+
import { createInterface } from 'node:readline';
|
|
3
|
+
import { assertString, assertObject, optionalString, } from '../jsonl-validate/index.js';
|
|
4
|
+
import { recordFingerprint } from '../schema-watch/index.js';
|
|
5
|
+
function mapCodexUsage(raw) {
|
|
6
|
+
return {
|
|
7
|
+
input_tokens: raw.input_tokens - raw.cached_input_tokens,
|
|
8
|
+
output_tokens: raw.output_tokens + raw.reasoning_output_tokens,
|
|
9
|
+
cache_creation_input_tokens: 0,
|
|
10
|
+
cache_read_input_tokens: raw.cached_input_tokens,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
// ─── Unique-id helpers ─────────────────────────────────────────────────────────
|
|
14
|
+
let _uidCounter = 0;
|
|
15
|
+
function uid(prefix) {
|
|
16
|
+
return `${prefix}-${Date.now()}-${++_uidCounter}`;
|
|
17
|
+
}
|
|
18
|
+
// ─── Main parser ───────────────────────────────────────────────────────────────
|
|
19
|
+
export async function parseCodex(filePath) {
|
|
20
|
+
const records = [];
|
|
21
|
+
const parseErrors = [];
|
|
22
|
+
const fingerprints = new Map();
|
|
23
|
+
let sessionId = null;
|
|
24
|
+
let project = null;
|
|
25
|
+
let startedAt = null;
|
|
26
|
+
let endedAt = null;
|
|
27
|
+
let currentModel = 'unknown';
|
|
28
|
+
let messageCount = 0;
|
|
29
|
+
// Token attribution: index of last assistant record (in records[]) whose usage is still pending
|
|
30
|
+
let pendingAssistantIdx = null;
|
|
31
|
+
let lineNum = 0;
|
|
32
|
+
const rl = createInterface({
|
|
33
|
+
input: createReadStream(filePath, { encoding: 'utf8' }),
|
|
34
|
+
crlfDelay: Infinity,
|
|
35
|
+
});
|
|
36
|
+
for await (const line of rl) {
|
|
37
|
+
lineNum++;
|
|
38
|
+
const trimmed = line.trim();
|
|
39
|
+
if (!trimmed)
|
|
40
|
+
continue;
|
|
41
|
+
let raw;
|
|
42
|
+
try {
|
|
43
|
+
raw = JSON.parse(trimmed);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// skip malformed JSON lines silently
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const topType = raw['type'];
|
|
50
|
+
if (!topType)
|
|
51
|
+
continue;
|
|
52
|
+
// Track the last-processed line's timestamp for endedAt
|
|
53
|
+
const topTs = optionalString(raw['timestamp'], `line ${lineNum}: timestamp`);
|
|
54
|
+
if (topTs)
|
|
55
|
+
endedAt = topTs;
|
|
56
|
+
try {
|
|
57
|
+
// Collect fingerprint for drift detection
|
|
58
|
+
const fp = recordFingerprint(raw);
|
|
59
|
+
if (!fingerprints.has(fp)) {
|
|
60
|
+
fingerprints.set(fp, { firstSeenLine: lineNum });
|
|
61
|
+
}
|
|
62
|
+
if (topType === 'session_meta') {
|
|
63
|
+
const payload = assertObject(raw['payload'], `line ${lineNum}: session_meta.payload`);
|
|
64
|
+
sessionId = assertString(payload['id'], `line ${lineNum}: session_meta.payload.id`);
|
|
65
|
+
startedAt = assertString(payload['timestamp'], `line ${lineNum}: session_meta.payload.timestamp`);
|
|
66
|
+
project = optionalString(payload['cwd'], `line ${lineNum}: session_meta.payload.cwd`) ?? null;
|
|
67
|
+
}
|
|
68
|
+
else if (topType === 'turn_context') {
|
|
69
|
+
const payload = assertObject(raw['payload'], `line ${lineNum}: turn_context.payload`);
|
|
70
|
+
const model = optionalString(payload['model'], `line ${lineNum}: turn_context.payload.model`);
|
|
71
|
+
if (model)
|
|
72
|
+
currentModel = model;
|
|
73
|
+
}
|
|
74
|
+
else if (topType === 'response_item') {
|
|
75
|
+
const payload = assertObject(raw['payload'], `line ${lineNum}: response_item.payload`);
|
|
76
|
+
const itemType = assertString(payload['type'], `line ${lineNum}: response_item.payload.type`);
|
|
77
|
+
if (itemType === 'message') {
|
|
78
|
+
const rawRole = assertString(payload['role'], `line ${lineNum}: response_item.payload.role`);
|
|
79
|
+
// Map developer → system
|
|
80
|
+
const role = rawRole === 'developer' ? 'system' : rawRole;
|
|
81
|
+
// Collect content text from content array
|
|
82
|
+
const rawContent = payload['content'];
|
|
83
|
+
const contentItems = Array.isArray(rawContent) ? rawContent : [];
|
|
84
|
+
const textParts = [];
|
|
85
|
+
for (const item of contentItems) {
|
|
86
|
+
if (item && typeof item === 'object' && !Array.isArray(item)) {
|
|
87
|
+
const itemObj = item;
|
|
88
|
+
const text = optionalString(itemObj['text'], `line ${lineNum}: content[].text`);
|
|
89
|
+
if (text)
|
|
90
|
+
textParts.push(text);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const messageText = textParts.join('');
|
|
94
|
+
messageCount++;
|
|
95
|
+
if (role === 'user') {
|
|
96
|
+
const record = {
|
|
97
|
+
type: 'user',
|
|
98
|
+
uuid: uid('codex-user'),
|
|
99
|
+
parentUuid: null,
|
|
100
|
+
sessionId: sessionId ?? '',
|
|
101
|
+
timestamp: topTs ?? new Date().toISOString(),
|
|
102
|
+
isSidechain: false,
|
|
103
|
+
message: {
|
|
104
|
+
role: 'user',
|
|
105
|
+
content: messageText,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
records.push(record);
|
|
109
|
+
if (startedAt === null)
|
|
110
|
+
startedAt = record.timestamp;
|
|
111
|
+
}
|
|
112
|
+
else if (role === 'assistant') {
|
|
113
|
+
const record = {
|
|
114
|
+
type: 'assistant',
|
|
115
|
+
uuid: uid('codex-asst'),
|
|
116
|
+
parentUuid: null,
|
|
117
|
+
sessionId: sessionId ?? '',
|
|
118
|
+
timestamp: topTs ?? new Date().toISOString(),
|
|
119
|
+
isSidechain: false,
|
|
120
|
+
message: {
|
|
121
|
+
role: 'assistant',
|
|
122
|
+
model: currentModel,
|
|
123
|
+
id: uid('asst-msg'),
|
|
124
|
+
content: [{ type: 'text', text: messageText }],
|
|
125
|
+
usage: undefined,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
records.push(record);
|
|
129
|
+
// Track this assistant record for upcoming token_count attribution
|
|
130
|
+
pendingAssistantIdx = records.length - 1;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// role === 'system' (from developer)
|
|
134
|
+
const record = {
|
|
135
|
+
type: 'system',
|
|
136
|
+
subtype: 'developer',
|
|
137
|
+
uuid: uid('codex-sys'),
|
|
138
|
+
sessionId: sessionId ?? '',
|
|
139
|
+
timestamp: topTs ?? new Date().toISOString(),
|
|
140
|
+
content: messageText,
|
|
141
|
+
isMeta: false,
|
|
142
|
+
};
|
|
143
|
+
records.push(record);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (itemType === 'function_call' ||
|
|
147
|
+
itemType === 'function_call_output' ||
|
|
148
|
+
itemType === 'custom_tool_call' ||
|
|
149
|
+
itemType === 'custom_tool_call_output') {
|
|
150
|
+
// tool calls tracked but not stored as ParsedRecord in V2 first cut.
|
|
151
|
+
// F4 note: Codex function_call_output carries no normalized is_error/duration that's
|
|
152
|
+
// trivially available here (exit codes are buried in stringified payloads), and tool calls
|
|
153
|
+
// aren't persisted as tool_calls rows on this path — so Codex run-health is OUT OF SCOPE
|
|
154
|
+
// for this pass. Revisit when Codex tool calls get first-class ParsedRecord/tool_calls rows.
|
|
155
|
+
messageCount++;
|
|
156
|
+
}
|
|
157
|
+
else if (itemType === 'reasoning') {
|
|
158
|
+
// skip silently — encrypted blob, not useful
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else if (topType === 'event_msg') {
|
|
162
|
+
const payload = assertObject(raw['payload'], `line ${lineNum}: event_msg.payload`);
|
|
163
|
+
const evType = optionalString(payload['type'], `line ${lineNum}: event_msg.payload.type`);
|
|
164
|
+
if (evType === 'token_count') {
|
|
165
|
+
const info = payload['info'];
|
|
166
|
+
if (info !== null && info !== undefined) {
|
|
167
|
+
const infoObj = assertObject(info, `line ${lineNum}: event_msg.payload.info`);
|
|
168
|
+
const lastUsageRaw = infoObj['last_token_usage'];
|
|
169
|
+
if (lastUsageRaw !== null && lastUsageRaw !== undefined) {
|
|
170
|
+
const lastUsage = assertObject(lastUsageRaw, `line ${lineNum}: event_msg.payload.info.last_token_usage`);
|
|
171
|
+
if (pendingAssistantIdx !== null) {
|
|
172
|
+
const usage = mapCodexUsage(lastUsage);
|
|
173
|
+
const ar = records[pendingAssistantIdx];
|
|
174
|
+
ar.message.usage = usage;
|
|
175
|
+
pendingAssistantIdx = null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// other event_msg types: skip
|
|
181
|
+
}
|
|
182
|
+
else if (topType === 'compacted') {
|
|
183
|
+
// skip silently
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (e) {
|
|
187
|
+
parseErrors.push({
|
|
188
|
+
lineNum,
|
|
189
|
+
recordType: topType ?? null,
|
|
190
|
+
error: e.message,
|
|
191
|
+
sampleJson: trimmed.slice(0, 200),
|
|
192
|
+
});
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const usageRecords = records.filter((r) => r.type === 'assistant' && r.message.usage != null);
|
|
197
|
+
return {
|
|
198
|
+
sessionId,
|
|
199
|
+
filePath,
|
|
200
|
+
project,
|
|
201
|
+
records,
|
|
202
|
+
usageRecords,
|
|
203
|
+
startedAt,
|
|
204
|
+
endedAt,
|
|
205
|
+
// Codex has no native session title/rename concept.
|
|
206
|
+
claudeCustomTitle: null,
|
|
207
|
+
claudeAiTitle: null,
|
|
208
|
+
parseErrors,
|
|
209
|
+
fingerprints,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/codex/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/cursor/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,aAAa,EAKd,MAAM,oBAAoB,CAAA;AA6K3B,wBAAsB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8L/E"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import Database from 'better-sqlite3';
|
|
5
|
+
// ─── SQLite value helpers ────────────────────────────────────────────────────
|
|
6
|
+
// cursorDiskKV.value is TEXT or BLOB and occasionally NULL (deleted bubbles,
|
|
7
|
+
// placeholder rows). Centralize the null-check so call sites never blow up
|
|
8
|
+
// calling .toString() on a null — and so the catch blocks can safely log a
|
|
9
|
+
// sample without double-throwing.
|
|
10
|
+
function blobToString(v) {
|
|
11
|
+
if (v == null)
|
|
12
|
+
return null;
|
|
13
|
+
return typeof v === 'string' ? v : v.toString('utf8');
|
|
14
|
+
}
|
|
15
|
+
function parseSyntheticPath(syntheticPath) {
|
|
16
|
+
const hashIdx = syntheticPath.lastIndexOf('#');
|
|
17
|
+
if (hashIdx === -1) {
|
|
18
|
+
throw new Error(`cursor: bad synthetic path (missing '#'): ${syntheticPath}`);
|
|
19
|
+
}
|
|
20
|
+
const vscdbPath = syntheticPath.slice(0, hashIdx);
|
|
21
|
+
const composerId = syntheticPath.slice(hashIdx + 1);
|
|
22
|
+
if (!vscdbPath || !composerId) {
|
|
23
|
+
throw new Error(`cursor: bad synthetic path (empty side): ${syntheticPath}`);
|
|
24
|
+
}
|
|
25
|
+
return { vscdbPath, composerId };
|
|
26
|
+
}
|
|
27
|
+
let _workspaceMapCache = null;
|
|
28
|
+
/** Strip URI scheme from a `workspace.json` folder URI so it reads naturally in the UI.
|
|
29
|
+
* Handles file://, vscode-remote://, vscode-vfs://, etc. */
|
|
30
|
+
function uriToDisplayPath(folder) {
|
|
31
|
+
const schemeEnd = folder.indexOf('://');
|
|
32
|
+
if (schemeEnd < 0)
|
|
33
|
+
return folder;
|
|
34
|
+
const rest = folder.slice(schemeEnd + 3);
|
|
35
|
+
try {
|
|
36
|
+
return decodeURIComponent(rest);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return rest;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function buildWorkspaceMap(globalDbPath) {
|
|
43
|
+
// workspaceStorage is sibling of globalStorage under User/
|
|
44
|
+
const userDir = dirname(dirname(globalDbPath));
|
|
45
|
+
const wsRoot = join(userDir, 'workspaceStorage');
|
|
46
|
+
let wsRootMtime;
|
|
47
|
+
try {
|
|
48
|
+
wsRootMtime = (await stat(wsRoot)).mtimeMs;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return { composerToProject: new Map() };
|
|
52
|
+
}
|
|
53
|
+
const cached = _workspaceMapCache;
|
|
54
|
+
if (cached && cached.wsRoot === wsRoot && cached.mtimeMs === wsRootMtime) {
|
|
55
|
+
return cached.map;
|
|
56
|
+
}
|
|
57
|
+
const map = { composerToProject: new Map() };
|
|
58
|
+
let entries;
|
|
59
|
+
try {
|
|
60
|
+
entries = await readdir(wsRoot);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return map;
|
|
64
|
+
}
|
|
65
|
+
for (const dir of entries) {
|
|
66
|
+
const wsJsonPath = join(wsRoot, dir, 'workspace.json');
|
|
67
|
+
const vscdbPath = join(wsRoot, dir, 'state.vscdb');
|
|
68
|
+
if (!existsSync(wsJsonPath) || !existsSync(vscdbPath))
|
|
69
|
+
continue;
|
|
70
|
+
let folder = null;
|
|
71
|
+
try {
|
|
72
|
+
const wsJson = JSON.parse(await readFile(wsJsonPath, 'utf8'));
|
|
73
|
+
if (typeof wsJson === 'object' && wsJson !== null && typeof wsJson.folder === 'string') {
|
|
74
|
+
folder = wsJson.folder;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (!folder)
|
|
81
|
+
continue;
|
|
82
|
+
const projectPath = uriToDisplayPath(folder);
|
|
83
|
+
try {
|
|
84
|
+
const wsDb = new Database(vscdbPath, { readonly: true, fileMustExist: true });
|
|
85
|
+
try {
|
|
86
|
+
const row = wsDb
|
|
87
|
+
.prepare("SELECT value FROM ItemTable WHERE key = 'composer.composerData'")
|
|
88
|
+
.get();
|
|
89
|
+
if (!row)
|
|
90
|
+
continue;
|
|
91
|
+
const text = blobToString(row.value);
|
|
92
|
+
if (text === null)
|
|
93
|
+
continue;
|
|
94
|
+
const cd = JSON.parse(text);
|
|
95
|
+
if (Array.isArray(cd.allComposers)) {
|
|
96
|
+
for (const c of cd.allComposers) {
|
|
97
|
+
// Last-write-wins if two workspaces claim the same composerId (rare).
|
|
98
|
+
// readdir order is non-deterministic; flip behavior here if it ever surprises someone.
|
|
99
|
+
if (typeof c.composerId === 'string') {
|
|
100
|
+
map.composerToProject.set(c.composerId, projectPath);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
wsDb.close();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Skip workspaces with corrupt or locked DBs
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
_workspaceMapCache = { wsRoot, mtimeMs: wsRootMtime, map };
|
|
115
|
+
return map;
|
|
116
|
+
}
|
|
117
|
+
// ─── Unique-id helper ──────────────────────────────────────────────────────────
|
|
118
|
+
let _uidCounter = 0;
|
|
119
|
+
function uid(prefix) {
|
|
120
|
+
return `${prefix}-${Date.now()}-${++_uidCounter}`;
|
|
121
|
+
}
|
|
122
|
+
function isMsEpoch(n) {
|
|
123
|
+
return typeof n === 'number' && Number.isFinite(n) && n > 1e12;
|
|
124
|
+
}
|
|
125
|
+
// ─── Main parser ───────────────────────────────────────────────────────────────
|
|
126
|
+
export async function parseCursor(syntheticPath) {
|
|
127
|
+
const { vscdbPath, composerId } = parseSyntheticPath(syntheticPath);
|
|
128
|
+
const parseErrors = [];
|
|
129
|
+
const records = [];
|
|
130
|
+
let startedAt = null;
|
|
131
|
+
let endedAt = null;
|
|
132
|
+
// Hoisted so the final fallback (after the DB block) can reach them.
|
|
133
|
+
let composerCreatedIso = null;
|
|
134
|
+
let composerUpdatedIso = null;
|
|
135
|
+
// Resolve project (best-effort) and fall back to vscdb mtime for timestamps
|
|
136
|
+
const workspaceMap = await buildWorkspaceMap(vscdbPath);
|
|
137
|
+
const project = workspaceMap.composerToProject.get(composerId) ?? null;
|
|
138
|
+
let vscdbMtimeIso = null;
|
|
139
|
+
try {
|
|
140
|
+
const s = await stat(vscdbPath);
|
|
141
|
+
vscdbMtimeIso = new Date(s.mtimeMs).toISOString();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
/* ignored — we'll just leave start/end null */
|
|
145
|
+
}
|
|
146
|
+
const db = new Database(vscdbPath, { readonly: true, fileMustExist: true });
|
|
147
|
+
try {
|
|
148
|
+
// Fetch composer metadata (createdAt, lastUpdatedAt, name)
|
|
149
|
+
const compRow = db
|
|
150
|
+
.prepare("SELECT value FROM cursorDiskKV WHERE key = 'composerData:' || ?")
|
|
151
|
+
.get(composerId);
|
|
152
|
+
let meta = null;
|
|
153
|
+
if (compRow) {
|
|
154
|
+
const compJson = blobToString(compRow.value);
|
|
155
|
+
if (compJson !== null) {
|
|
156
|
+
try {
|
|
157
|
+
meta = JSON.parse(compJson);
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
parseErrors.push({
|
|
161
|
+
lineNum: 0,
|
|
162
|
+
recordType: 'composerData',
|
|
163
|
+
error: e.message,
|
|
164
|
+
sampleJson: compJson.slice(0, 200),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Seed composer-level timestamps. Cursor stores ms epoch; magnitude check
|
|
170
|
+
// (>1e12 ≈ year 2001+) guards against schema drift to seconds-epoch silently
|
|
171
|
+
// mislabeling 2026 sessions as 1970 artifacts.
|
|
172
|
+
composerCreatedIso = isMsEpoch(meta?.createdAt) ? new Date(meta.createdAt).toISOString() : null;
|
|
173
|
+
composerUpdatedIso = isMsEpoch(meta?.lastUpdatedAt)
|
|
174
|
+
? new Date(meta.lastUpdatedAt).toISOString()
|
|
175
|
+
: null;
|
|
176
|
+
// Fetch bubbles in insertion order (rowid is monotonic on inserts)
|
|
177
|
+
const bubbleRows = db
|
|
178
|
+
.prepare("SELECT key, value FROM cursorDiskKV WHERE key LIKE 'bubbleId:' || ? || ':%' ORDER BY rowid ASC")
|
|
179
|
+
.all(composerId);
|
|
180
|
+
for (let i = 0; i < bubbleRows.length; i++) {
|
|
181
|
+
const row = bubbleRows[i];
|
|
182
|
+
const bubbleJson = blobToString(row.value);
|
|
183
|
+
if (bubbleJson === null) {
|
|
184
|
+
// Empty/null bubble row — skip without noisy error (common for deleted
|
|
185
|
+
// or placeholder bubbles; the surrounding session is still valid).
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
let bubble;
|
|
189
|
+
try {
|
|
190
|
+
bubble = JSON.parse(bubbleJson);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
parseErrors.push({
|
|
194
|
+
lineNum: i + 1,
|
|
195
|
+
recordType: 'bubbleId',
|
|
196
|
+
error: e.message,
|
|
197
|
+
sampleJson: bubbleJson.slice(0, 200),
|
|
198
|
+
});
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
// Role detection: type 1 = user, 2 = assistant; skip anything else
|
|
202
|
+
if (bubble.type !== 1 && bubble.type !== 2) {
|
|
203
|
+
parseErrors.push({
|
|
204
|
+
lineNum: i + 1,
|
|
205
|
+
recordType: 'bubbleId',
|
|
206
|
+
error: `unknown bubble type: ${String(bubble.type)}`,
|
|
207
|
+
sampleJson: JSON.stringify(bubble).slice(0, 200),
|
|
208
|
+
});
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
// Skip bubbles with no text content — they're typically empty placeholders
|
|
212
|
+
// (e.g. tool-result-only bubbles which we can't render anyway in lossy mode).
|
|
213
|
+
const text = typeof bubble.text === 'string' ? bubble.text : '';
|
|
214
|
+
if (text.length === 0)
|
|
215
|
+
continue;
|
|
216
|
+
// Timestamp: bubble.createdAt (ISO string) when present, otherwise fall
|
|
217
|
+
// back to composer/vscdb mtime — anything to keep the row sortable.
|
|
218
|
+
const ts = (typeof bubble.createdAt === 'string' && bubble.createdAt) ||
|
|
219
|
+
composerCreatedIso ||
|
|
220
|
+
vscdbMtimeIso ||
|
|
221
|
+
new Date().toISOString();
|
|
222
|
+
const bubbleUuid = bubble.bubbleId ?? uid('cursor-bubble');
|
|
223
|
+
const model = bubble.modelInfo?.modelName && bubble.modelInfo.modelName !== 'default'
|
|
224
|
+
? bubble.modelInfo.modelName
|
|
225
|
+
: 'cursor-default';
|
|
226
|
+
if (bubble.type === 1) {
|
|
227
|
+
const rec = {
|
|
228
|
+
type: 'user',
|
|
229
|
+
uuid: bubbleUuid,
|
|
230
|
+
parentUuid: null,
|
|
231
|
+
sessionId: composerId,
|
|
232
|
+
timestamp: ts,
|
|
233
|
+
isSidechain: false,
|
|
234
|
+
message: {
|
|
235
|
+
role: 'user',
|
|
236
|
+
content: text,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
records.push(rec);
|
|
240
|
+
if (startedAt === null)
|
|
241
|
+
startedAt = ts;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// type === 2: assistant
|
|
245
|
+
// tokenCount: per-bubble counts when Cursor exposes them. We don't have
|
|
246
|
+
// cache hit/miss signals so cache fields are zero.
|
|
247
|
+
const tc = bubble.tokenCount;
|
|
248
|
+
const hasTokens = tc && ((tc.inputTokens ?? 0) > 0 || (tc.outputTokens ?? 0) > 0);
|
|
249
|
+
const rec = {
|
|
250
|
+
type: 'assistant',
|
|
251
|
+
uuid: bubbleUuid,
|
|
252
|
+
parentUuid: null,
|
|
253
|
+
sessionId: composerId,
|
|
254
|
+
timestamp: ts,
|
|
255
|
+
isSidechain: false,
|
|
256
|
+
message: {
|
|
257
|
+
role: 'assistant',
|
|
258
|
+
model,
|
|
259
|
+
id: uid('cursor-asst-msg'),
|
|
260
|
+
content: [{ type: 'text', text }],
|
|
261
|
+
usage: hasTokens
|
|
262
|
+
? {
|
|
263
|
+
input_tokens: tc.inputTokens ?? 0,
|
|
264
|
+
output_tokens: tc.outputTokens ?? 0,
|
|
265
|
+
cache_creation_input_tokens: 0,
|
|
266
|
+
cache_read_input_tokens: 0,
|
|
267
|
+
}
|
|
268
|
+
: undefined,
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
records.push(rec);
|
|
272
|
+
}
|
|
273
|
+
endedAt = ts;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
db.close();
|
|
278
|
+
}
|
|
279
|
+
// Anchor session start/end: prefer bubble-derived times set during the loop
|
|
280
|
+
// (startedAt is set from the first user record, endedAt from the last record).
|
|
281
|
+
// Fall back to composer metadata, then to vscdb mtime.
|
|
282
|
+
if (startedAt === null)
|
|
283
|
+
startedAt = composerCreatedIso ?? vscdbMtimeIso;
|
|
284
|
+
if (endedAt === null)
|
|
285
|
+
endedAt = composerUpdatedIso ?? composerCreatedIso ?? vscdbMtimeIso;
|
|
286
|
+
const usageRecords = records.filter((r) => r.type === 'assistant' && r.message.usage != null);
|
|
287
|
+
return {
|
|
288
|
+
sessionId: composerId,
|
|
289
|
+
filePath: syntheticPath,
|
|
290
|
+
project,
|
|
291
|
+
records,
|
|
292
|
+
usageRecords,
|
|
293
|
+
startedAt,
|
|
294
|
+
endedAt,
|
|
295
|
+
// Cursor has no native session title/rename concept.
|
|
296
|
+
claudeCustomTitle: null,
|
|
297
|
+
claudeAiTitle: null,
|
|
298
|
+
parseErrors,
|
|
299
|
+
// Cursor fingerprints not tracked — schema-drift watcher targets Claude/Codex
|
|
300
|
+
// upstream type bumps and Cursor stores opaque blobs, not record types.
|
|
301
|
+
fingerprints: new Map(),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/cursor/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor stores chat data in TWO places (current schema, late-2025/early-2026):
|
|
3
|
+
*
|
|
4
|
+
* 1. ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
|
|
5
|
+
* • cursorDiskKV rows keyed `composerData:<id>` and `bubbleId:<composerId>:<bubbleId>`
|
|
6
|
+
* • This is where the actual conversation data lives.
|
|
7
|
+
*
|
|
8
|
+
* 2. ~/Library/Application Support/Cursor/User/workspaceStorage/<hash>/state.vscdb
|
|
9
|
+
* • workspace.json sibling holds the `folder` URI (project mapping)
|
|
10
|
+
* • ItemTable['composer.composerData'] lists composer IDs for that workspace
|
|
11
|
+
* • cursorDiskKV in workspace storage is empty in this version
|
|
12
|
+
*
|
|
13
|
+
* scan() returns one entry per composer using synthetic path encoding
|
|
14
|
+
* `<global-vscdb-path>#<composerId>`. The parser splits on '#' and queries
|
|
15
|
+
* the global DB for that one composer. mtime is the global vscdb mtime —
|
|
16
|
+
* coarse (any Cursor write marks all composers dirty) but acceptable: a single
|
|
17
|
+
* composer parses in milliseconds and the indexer's mtime-skip keeps unchanged
|
|
18
|
+
* sessions out of re-ingest.
|
|
19
|
+
*
|
|
20
|
+
* `rootDir` is the workspaceStorage directory (kept for API symmetry with
|
|
21
|
+
* other adapters); the global DB is resolved as its sibling at
|
|
22
|
+
* `../globalStorage/state.vscdb`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function scanCursorWorkspaces(rootDir: string): Promise<Array<{
|
|
25
|
+
path: string;
|
|
26
|
+
mtimeMs: number;
|
|
27
|
+
}>>;
|
|
28
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/core/cursor/scan.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAoDnD"}
|