@ascenda-one/history-import 0.1.12
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 +127 -0
- package/dist/cli.js +3889 -0
- package/dist/cli.js.map +1 -0
- package/dist/daySlice.js +98 -0
- package/dist/daySlice.js.map +1 -0
- package/dist/extractors/claudeCode.js +779 -0
- package/dist/extractors/claudeCode.js.map +1 -0
- package/dist/extractors/cursor.js +601 -0
- package/dist/extractors/cursor.js.map +1 -0
- package/dist/extractors/git.js +9 -0
- package/dist/extractors/git.js.map +1 -0
- package/dist/extractors/vscode.js +615 -0
- package/dist/extractors/vscode.js.map +1 -0
- package/dist/localHandoff.js +238 -0
- package/dist/localHandoff.js.map +1 -0
- package/dist/retention.js +68 -0
- package/dist/retention.js.map +1 -0
- package/dist/scan.js +220 -0
- package/dist/scan.js.map +1 -0
- package/dist/ship.js +208 -0
- package/dist/ship.js.map +1 -0
- package/dist/staging.js +121 -0
- package/dist/staging.js.map +1 -0
- package/dist/stores.js +25 -0
- package/dist/stores.js.map +1 -0
- package/dist/types.js +74 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeCode.js","sourceRoot":"","sources":["../../src/extractors/claudeCode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor extractor — second in the evaporation order (no purge observed, but
|
|
3
|
+
* the richest per-message structure: 71-field bubbles with tokenCount,
|
|
4
|
+
* human-vs-AI edit attribution, and post-edit lint state).
|
|
5
|
+
*
|
|
6
|
+
* Store: `state.vscdb` (SQLite, WAL). Extraction reads the STAGED copy only
|
|
7
|
+
* — `snapshotDir` is the directory `src/staging.ts` copied `state.vscdb`
|
|
8
|
+
* (plus its `-wal`/`-shm` siblings) into. Unlike `scan.ts`'s live read
|
|
9
|
+
* (`mode=ro&immutable=1`, because it can't safely mutate the real file),
|
|
10
|
+
* this file opens the staged copy PLAIN: it is our own throwaway copy, so
|
|
11
|
+
* letting SQLite replay the WAL and create its own `-shm` is not just safe,
|
|
12
|
+
* it is required — `immutable=1` tells SQLite the file will not change and,
|
|
13
|
+
* per its own docs, is licensed to ignore the WAL entirely. Opening a WAL-mode
|
|
14
|
+
* db immutable would silently read PAST the very transactions `staging.ts`
|
|
15
|
+
* copied the `-wal` sibling to preserve — exactly the newest sessions a user
|
|
16
|
+
* would notice missing. Read-write on a private copy has no such trap.
|
|
17
|
+
*
|
|
18
|
+
* Tables (observed 2026-08-18, Cursor installed 2026-02-24, 147
|
|
19
|
+
* composerHeaders / 146 composerData / 17,727 bubbles):
|
|
20
|
+
* - `composerHeaders` — one row per conversation. `composerId`, `createdAt`,
|
|
21
|
+
* `lastUpdatedAt` and `isSubagent` are real columns; everything else
|
|
22
|
+
* (`totalLinesAdded`/`totalLinesRemoved`/`filesChangedCount`,
|
|
23
|
+
* `contextUsagePercent`, `unifiedMode`, `trackedGitRepos`,
|
|
24
|
+
* `workspaceIdentifier`, `subagentInfo`) lives inside a `value` TEXT
|
|
25
|
+
* column holding one JSON blob per row. That blob self-labels
|
|
26
|
+
* `"type": "head"` — the closest thing to a version tag a header carries,
|
|
27
|
+
* dispatched on the same way `_v` is (see `sniffCursorHeaderRow`).
|
|
28
|
+
* - `cursorDiskKV` — a flat key/value table. `composerData:<id>` (146 rows,
|
|
29
|
+
* duplicates each header's own bubble list plus full prompt/response text)
|
|
30
|
+
* is deliberately never read: nothing this extractor needs isn't already
|
|
31
|
+
* on `composerHeaders` or the bubbles. `bubbleId:<composerId>:<bubbleId>`
|
|
32
|
+
* (17,727 rows) are the message bubbles; each is a 71-field JSON blob
|
|
33
|
+
* self-labelling `_v` (uniformly 3 on the verified store), `type` (1 =
|
|
34
|
+
* human message, 603 observed; 2 = assistant turn, 17,124 observed —
|
|
35
|
+
* Cursor fragments one assistant reply across many bubbles, tool calls
|
|
36
|
+
* and thinking included, unlike Claude Code's near-1:1 line ratio),
|
|
37
|
+
* `tokenCount`, `humanChanges`/`approximateLintErrors` (both empty-array
|
|
38
|
+
* on the verified store — the fields exist and are read regardless, since
|
|
39
|
+
* a machine with real usage of Cursor's diff-review flow would populate
|
|
40
|
+
* them), and `modelInfo.modelName`.
|
|
41
|
+
*
|
|
42
|
+
* Content never enters this process, not just "never leaves the machine":
|
|
43
|
+
* every bubble query below selects individual `json_extract`/
|
|
44
|
+
* `json_array_length` scalars, never the bubble's own `value` column, so the
|
|
45
|
+
* 71-field blob's `text`/`richText`/`allThinkingBlocks`/`gitDiffs` — the
|
|
46
|
+
* fields that actually hold prompt and response content — are never even
|
|
47
|
+
* parsed into a JS object, let alone shipped. `composerHeaders.value` IS read
|
|
48
|
+
* whole (it is one order of magnitude smaller — 147 rows, not 17,727 — and
|
|
49
|
+
* has no prompt/response text field, only `name`/`subtitle` UI labels similar
|
|
50
|
+
* in kind to the `cwd`/`gitBranch` fields the Claude extractor already reads
|
|
51
|
+
* directly off transcript lines).
|
|
52
|
+
*
|
|
53
|
+
* Cursor's own subagent feature (`isSubagent: 1`, ~19% of headers on the
|
|
54
|
+
* verified store — Cursor's "explore" agent spawned via a tool call) is the
|
|
55
|
+
* same shape as Claude Code's Task-tool subagents and gets the same fix:
|
|
56
|
+
* `subagentInfo.parentComposerId` links a subagent composer back to the one
|
|
57
|
+
* a human was actually driving. Its single task-instruction bubble is not
|
|
58
|
+
* something a human typed (never `ai_prompt_submitted`, never `promptCount`);
|
|
59
|
+
* its real work still happened in service of the parent, so token/turn
|
|
60
|
+
* counts fold into the parent's `subagent*` breakdown instead of vanishing
|
|
61
|
+
* or inflating the parent's own numbers silently.
|
|
62
|
+
*
|
|
63
|
+
* SQLite access shells to `/usr/bin/sqlite3` (`scan.ts`'s precedent) rather
|
|
64
|
+
* than adding `better-sqlite3`: this package ships as an `npx`-run CLI, and
|
|
65
|
+
* a native module would need a prebuilt binary per platform/Node ABI before
|
|
66
|
+
* the first real user could run `import` at all. macOS ships `sqlite3` with
|
|
67
|
+
* JSON1 compiled in, so `json_extract`/`json_array_length` are available
|
|
68
|
+
* without a `.load` — verified against the real store while writing this.
|
|
69
|
+
*
|
|
70
|
+
* Session-level events come from `composerHeaders` alone (outcome metrics
|
|
71
|
+
* are already folded there); bubbles are aggregated per composer for
|
|
72
|
+
* prompt-iteration counts, token totals, and human/AI attribution — NEVER
|
|
73
|
+
* emitted as their own event (17,727 of them on one observed machine).
|
|
74
|
+
*/
|
|
75
|
+
import * as fs from "node:fs/promises";
|
|
76
|
+
import * as path from "node:path";
|
|
77
|
+
import { execFile } from "node:child_process";
|
|
78
|
+
import { promisify } from "node:util";
|
|
79
|
+
import { bucketDurationMs, isAfterHours } from "@ascenda-one/tool-kit";
|
|
80
|
+
import { HISTORICAL_PROVENANCE } from "../types.js";
|
|
81
|
+
import { sliceSessionByLocalDay } from "../daySlice.js";
|
|
82
|
+
const execFileAsync = promisify(execFile);
|
|
83
|
+
/** Bubble schema version this extractor knows how to read (`_v` on
|
|
84
|
+
* `bubbleId:<composer>:<bubble>` records). Every bubble on the verified
|
|
85
|
+
* 17,727-bubble store self-labels `_v: 3`; a bubble outside this set is
|
|
86
|
+
* unparsed — none of its fields are trusted, only counted. */
|
|
87
|
+
export const KNOWN_CURSOR_BUBBLE_VERSIONS = new Set([3]);
|
|
88
|
+
/** `value.type` on `composerHeaders` rows. composerHeaders carries no `_v`,
|
|
89
|
+
* so this field is the nearest thing to a self-labelled version and is
|
|
90
|
+
* dispatched on the same way. Every row on the verified store is `"head"`. */
|
|
91
|
+
export const KNOWN_CURSOR_HEADER_TYPES = new Set(["head"]);
|
|
92
|
+
/** Bubble `type`: 1 = a human message, 2 = an assistant turn. */
|
|
93
|
+
const BUBBLE_TYPE_USER = 1;
|
|
94
|
+
const BUBBLE_TYPE_ASSISTANT = 2;
|
|
95
|
+
function asNumber(value) {
|
|
96
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
97
|
+
}
|
|
98
|
+
/** Most-frequent key in a counted map, or null for an empty one. Shared by
|
|
99
|
+
* `primaryModel` and the session's dominant bubble `_v`. */
|
|
100
|
+
function pickTop(counts) {
|
|
101
|
+
let best = null;
|
|
102
|
+
let bestCount = 0;
|
|
103
|
+
for (const [key, count] of counts) {
|
|
104
|
+
if (count > bestCount) {
|
|
105
|
+
best = key;
|
|
106
|
+
bestCount = count;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return best;
|
|
110
|
+
}
|
|
111
|
+
const MAX_QUERY_BUFFER = 256 * 1024 * 1024; // 256 MB — generous headroom over
|
|
112
|
+
// the ~17k-bubble/147-header verified store; a raised ceiling here is cheap
|
|
113
|
+
// insurance against `stdout maxBuffer exceeded`, not a scale promise (see
|
|
114
|
+
// the module doc's native-module tradeoff note for what happens past it).
|
|
115
|
+
async function queryJson(dbPath, sql) {
|
|
116
|
+
const { stdout } = await execFileAsync("sqlite3", ["-json", dbPath, sql], {
|
|
117
|
+
maxBuffer: MAX_QUERY_BUFFER
|
|
118
|
+
});
|
|
119
|
+
const trimmed = stdout.trim();
|
|
120
|
+
if (trimmed === "")
|
|
121
|
+
return [];
|
|
122
|
+
return JSON.parse(trimmed);
|
|
123
|
+
}
|
|
124
|
+
const HEADER_QUERY = `
|
|
125
|
+
SELECT
|
|
126
|
+
composerId,
|
|
127
|
+
createdAt,
|
|
128
|
+
lastUpdatedAt,
|
|
129
|
+
recency,
|
|
130
|
+
checkpointAt,
|
|
131
|
+
isSubagent,
|
|
132
|
+
json_extract(value,'$.type') AS recordType,
|
|
133
|
+
json_extract(value,'$.totalLinesAdded') AS linesAdded,
|
|
134
|
+
json_extract(value,'$.totalLinesRemoved') AS linesRemoved,
|
|
135
|
+
json_extract(value,'$.filesChangedCount') AS filesChangedCount,
|
|
136
|
+
json_extract(value,'$.contextUsagePercent') AS contextUsagePercent,
|
|
137
|
+
json_extract(value,'$.unifiedMode') AS mode,
|
|
138
|
+
json_extract(value,'$.trackedGitRepos') AS trackedGitReposJson,
|
|
139
|
+
json_extract(value,'$.workspaceIdentifier.uri.fsPath') AS workspaceFsPath,
|
|
140
|
+
json_extract(value,'$.subagentInfo.parentComposerId') AS parentComposerId
|
|
141
|
+
FROM composerHeaders;
|
|
142
|
+
`;
|
|
143
|
+
const BUBBLE_QUERY = `
|
|
144
|
+
SELECT
|
|
145
|
+
key,
|
|
146
|
+
json_extract(value,'$._v') AS v,
|
|
147
|
+
json_extract(value,'$.type') AS btype,
|
|
148
|
+
json_extract(value,'$.createdAt') AS createdAt,
|
|
149
|
+
json_extract(value,'$.tokenCount.inputTokens') AS inputTokens,
|
|
150
|
+
json_extract(value,'$.tokenCount.outputTokens') AS outputTokens,
|
|
151
|
+
coalesce(json_array_length(value,'$.humanChanges'),0) AS humanChangesCount,
|
|
152
|
+
coalesce(json_array_length(value,'$.approximateLintErrors'),0) AS lintErrorsCount,
|
|
153
|
+
json_extract(value,'$.modelInfo.modelName') AS modelName
|
|
154
|
+
FROM cursorDiskKV WHERE key LIKE 'bubbleId:%';
|
|
155
|
+
`;
|
|
156
|
+
function repoInfoOf(row) {
|
|
157
|
+
let repoRef = null;
|
|
158
|
+
let gitBranch = null;
|
|
159
|
+
if (row.trackedGitReposJson) {
|
|
160
|
+
try {
|
|
161
|
+
const repos = JSON.parse(row.trackedGitReposJson);
|
|
162
|
+
if (Array.isArray(repos) && repos.length > 0) {
|
|
163
|
+
const first = repos[0];
|
|
164
|
+
if (typeof first.repoPath === "string")
|
|
165
|
+
repoRef = first.repoPath;
|
|
166
|
+
const branches = first.branches;
|
|
167
|
+
if (Array.isArray(branches) && branches.length > 0) {
|
|
168
|
+
const branch = branches[0];
|
|
169
|
+
if (typeof branch.branchName === "string")
|
|
170
|
+
gitBranch = branch.branchName;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Malformed trackedGitRepos JSON — fall through to the workspace path.
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (!repoRef && row.workspaceFsPath)
|
|
179
|
+
repoRef = row.workspaceFsPath;
|
|
180
|
+
return { repoRef, gitBranch };
|
|
181
|
+
}
|
|
182
|
+
export function sniffCursorHeaderRow(row) {
|
|
183
|
+
if (row.recordType === null)
|
|
184
|
+
return { kind: "unparsed" };
|
|
185
|
+
if (!KNOWN_CURSOR_HEADER_TYPES.has(row.recordType)) {
|
|
186
|
+
return { kind: "unknown", type: row.recordType };
|
|
187
|
+
}
|
|
188
|
+
const { repoRef, gitBranch } = repoInfoOf(row);
|
|
189
|
+
return {
|
|
190
|
+
kind: "head",
|
|
191
|
+
linesAdded: asNumber(row.linesAdded),
|
|
192
|
+
linesRemoved: asNumber(row.linesRemoved),
|
|
193
|
+
filesChangedCount: asNumber(row.filesChangedCount),
|
|
194
|
+
contextUsagePercent: typeof row.contextUsagePercent === "number" ? row.contextUsagePercent : null,
|
|
195
|
+
mode: row.mode,
|
|
196
|
+
repoRef,
|
|
197
|
+
gitBranch,
|
|
198
|
+
isSubagent: row.isSubagent === 1,
|
|
199
|
+
parentComposerId: row.parentComposerId
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
export function sniffCursorBubbleRow(row) {
|
|
203
|
+
const parts = row.key.split(":");
|
|
204
|
+
const composerId = parts.length >= 3 && parts[0] === "bubbleId" ? parts[1] : null;
|
|
205
|
+
if (row.v === null || !KNOWN_CURSOR_BUBBLE_VERSIONS.has(row.v) || composerId === null) {
|
|
206
|
+
return { kind: "unparsed", composerId };
|
|
207
|
+
}
|
|
208
|
+
if (row.btype !== BUBBLE_TYPE_USER && row.btype !== BUBBLE_TYPE_ASSISTANT) {
|
|
209
|
+
return { kind: "unknown", composerId };
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
kind: row.btype === BUBBLE_TYPE_USER ? "user" : "assistant",
|
|
213
|
+
composerId,
|
|
214
|
+
createdAt: row.createdAt,
|
|
215
|
+
inputTokens: asNumber(row.inputTokens),
|
|
216
|
+
outputTokens: asNumber(row.outputTokens),
|
|
217
|
+
humanChangesCount: asNumber(row.humanChangesCount),
|
|
218
|
+
lintErrorsCount: asNumber(row.lintErrorsCount),
|
|
219
|
+
modelName: row.modelName,
|
|
220
|
+
sourceVersion: String(row.v)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function newFold(row, sniffed) {
|
|
224
|
+
return {
|
|
225
|
+
composerId: row.composerId,
|
|
226
|
+
createdAtMs: Number.isFinite(row.createdAt) ? row.createdAt : null,
|
|
227
|
+
lastUpdatedAtMs: Number.isFinite(row.lastUpdatedAt) ? row.lastUpdatedAt : null,
|
|
228
|
+
recencyMs: Number.isFinite(row.recency) ? row.recency : null,
|
|
229
|
+
checkpointAtMs: Number.isFinite(row.checkpointAt) ? row.checkpointAt : null,
|
|
230
|
+
lastBubbleMs: null,
|
|
231
|
+
mode: sniffed.mode,
|
|
232
|
+
linesAdded: sniffed.linesAdded,
|
|
233
|
+
linesRemoved: sniffed.linesRemoved,
|
|
234
|
+
filesChangedCount: sniffed.filesChangedCount,
|
|
235
|
+
contextUsagePercent: sniffed.contextUsagePercent,
|
|
236
|
+
repoRef: sniffed.repoRef,
|
|
237
|
+
gitBranch: sniffed.gitBranch,
|
|
238
|
+
humanPrompts: 0,
|
|
239
|
+
afterHoursPrompts: 0,
|
|
240
|
+
assistantTurns: 0,
|
|
241
|
+
inputTokens: 0,
|
|
242
|
+
outputTokens: 0,
|
|
243
|
+
humanChangesCount: 0,
|
|
244
|
+
lintErrorsCount: 0,
|
|
245
|
+
unknownBubbles: 0,
|
|
246
|
+
unparsedBubbles: 0,
|
|
247
|
+
ownBubbles: 0,
|
|
248
|
+
models: new Map(),
|
|
249
|
+
bubbleVersions: new Map(),
|
|
250
|
+
humanPromptTimestamps: [],
|
|
251
|
+
subagentComposerIds: new Set(),
|
|
252
|
+
subagentPromptCount: 0,
|
|
253
|
+
subagentAssistantTurns: 0,
|
|
254
|
+
subagentTokensTotal: 0
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The end of a composer's timeline, falling back when `lastUpdatedAt` is null.
|
|
259
|
+
*
|
|
260
|
+
* `lastUpdatedAt` is nullable and Cursor leaves it unset on real conversations
|
|
261
|
+
* — 42 of 151 headers on the reference machine. This function exists because
|
|
262
|
+
* the emit loop used to `continue` past exactly those, silently: no event, no
|
|
263
|
+
* counter, and no way to tell a dropped conversation from one that never
|
|
264
|
+
* happened. On that machine the 15 non-subagent casualties were all empty, so
|
|
265
|
+
* nothing was lost; nothing in the schema ties a null `lastUpdatedAt` to
|
|
266
|
+
* emptiness, so on another machine they would not be.
|
|
267
|
+
*
|
|
268
|
+
* Order is by how directly each field witnesses the conversation ending:
|
|
269
|
+
* - `bubbles` — the newest message's own timestamp. Content truth: a message
|
|
270
|
+
* exists and it happened then. Preferred over any header field.
|
|
271
|
+
* - `recency` — a millisecond epoch that equals `lastUpdatedAt` on all 109
|
|
272
|
+
* reference-machine headers carrying both, which is why it is trusted at
|
|
273
|
+
* all; the name still suggests it could track opening rather than editing,
|
|
274
|
+
* so a bubble outranks it.
|
|
275
|
+
* - `checkpointAt` — last, present on only 27 of the 42 and describing a
|
|
276
|
+
* checkpoint rather than the conversation.
|
|
277
|
+
*
|
|
278
|
+
* A candidate before `createdAtMs` is not an end and is skipped, so a
|
|
279
|
+
* repaired timeline can never invent a negative duration.
|
|
280
|
+
*/
|
|
281
|
+
export function resolveTimeline(fold) {
|
|
282
|
+
if (fold.createdAtMs === null)
|
|
283
|
+
return null;
|
|
284
|
+
if (fold.lastUpdatedAtMs !== null)
|
|
285
|
+
return { endedAtMs: fold.lastUpdatedAtMs, source: "header" };
|
|
286
|
+
const candidates = [
|
|
287
|
+
[fold.lastBubbleMs, "bubbles"],
|
|
288
|
+
[fold.recencyMs, "recency"],
|
|
289
|
+
[fold.checkpointAtMs, "checkpoint"]
|
|
290
|
+
];
|
|
291
|
+
for (const [ms, source] of candidates) {
|
|
292
|
+
if (ms !== null && Number.isFinite(ms) && ms >= fold.createdAtMs) {
|
|
293
|
+
return { endedAtMs: ms, source };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
function sessionDurationMs(fold) {
|
|
299
|
+
const timeline = resolveTimeline(fold);
|
|
300
|
+
if (timeline === null)
|
|
301
|
+
return null;
|
|
302
|
+
const ms = timeline.endedAtMs - fold.createdAtMs;
|
|
303
|
+
return Number.isFinite(ms) && ms >= 0 ? ms : null;
|
|
304
|
+
}
|
|
305
|
+
function durationBucketOf(fold) {
|
|
306
|
+
const ms = sessionDurationMs(fold);
|
|
307
|
+
if (ms === null)
|
|
308
|
+
return "unknown";
|
|
309
|
+
return bucketDurationMs(ms) ?? "unknown";
|
|
310
|
+
}
|
|
311
|
+
export async function* extractCursor(snapshotDir, extractionId) {
|
|
312
|
+
const dbPath = path.join(snapshotDir, "state.vscdb");
|
|
313
|
+
try {
|
|
314
|
+
await fs.stat(dbPath);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
return; // No staged Cursor db — Cursor isn't installed, or wasn't present at scan time.
|
|
318
|
+
}
|
|
319
|
+
let headerRows;
|
|
320
|
+
try {
|
|
321
|
+
headerRows = await queryJson(dbPath, HEADER_QUERY);
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
// The staged db exists but does not open, or `composerHeaders` is gone —
|
|
325
|
+
// a schema this extractor cannot read at all. Returning silently here is
|
|
326
|
+
// what made a store-format change indistinguishable from an unused store:
|
|
327
|
+
// no events, no marker, nothing to notice. Declare it instead. This is the
|
|
328
|
+
// same failure that hid VS Code's Feb-2026 `.jsonl` migration for months.
|
|
329
|
+
yield {
|
|
330
|
+
occurredAt: new Date().toISOString(),
|
|
331
|
+
store: "cursor",
|
|
332
|
+
sourceVersion: null,
|
|
333
|
+
sessionRef: null,
|
|
334
|
+
repoRef: null,
|
|
335
|
+
eventKind: "extraction_epoch",
|
|
336
|
+
metrics: {
|
|
337
|
+
sessionCount: 0,
|
|
338
|
+
schemaUnreadable: 1
|
|
339
|
+
},
|
|
340
|
+
provenance: HISTORICAL_PROVENANCE.derived,
|
|
341
|
+
extractionId
|
|
342
|
+
};
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const folds = new Map();
|
|
346
|
+
const subagentParentOf = new Map();
|
|
347
|
+
let unparsedComposerHeaders = 0;
|
|
348
|
+
let unknownComposerHeaderTypes = 0;
|
|
349
|
+
for (const row of headerRows) {
|
|
350
|
+
const sniffed = sniffCursorHeaderRow(row);
|
|
351
|
+
if (sniffed.kind === "unparsed") {
|
|
352
|
+
unparsedComposerHeaders += 1;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (sniffed.kind === "unknown") {
|
|
356
|
+
unknownComposerHeaderTypes += 1;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (sniffed.isSubagent) {
|
|
360
|
+
if (sniffed.parentComposerId)
|
|
361
|
+
subagentParentOf.set(row.composerId, sniffed.parentComposerId);
|
|
362
|
+
continue; // Never its own session — see the module doc's subagent note.
|
|
363
|
+
}
|
|
364
|
+
folds.set(row.composerId, newFold(row, sniffed));
|
|
365
|
+
}
|
|
366
|
+
let bubbleRows = [];
|
|
367
|
+
try {
|
|
368
|
+
bubbleRows = await queryJson(dbPath, BUBBLE_QUERY);
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
// cursorDiskKV missing or unreadable — sessions still emit off header data alone.
|
|
372
|
+
}
|
|
373
|
+
let orphanedSubagentBubbles = 0;
|
|
374
|
+
let orphanedBubbles = 0;
|
|
375
|
+
for (const row of bubbleRows) {
|
|
376
|
+
const sniffed = sniffCursorBubbleRow(row);
|
|
377
|
+
if (sniffed.kind === "unparsed") {
|
|
378
|
+
const fold = sniffed.composerId ? folds.get(sniffed.composerId) : undefined;
|
|
379
|
+
if (fold) {
|
|
380
|
+
fold.unparsedBubbles += 1;
|
|
381
|
+
fold.ownBubbles += 1;
|
|
382
|
+
}
|
|
383
|
+
else if (sniffed.composerId && subagentParentOf.has(sniffed.composerId)) {
|
|
384
|
+
// Unparsed bubble under a subagent — nothing to trust, but still
|
|
385
|
+
// attribute the count to the parent so it isn't invisible.
|
|
386
|
+
const parent = folds.get(subagentParentOf.get(sniffed.composerId));
|
|
387
|
+
if (parent)
|
|
388
|
+
parent.unparsedBubbles += 1;
|
|
389
|
+
}
|
|
390
|
+
else
|
|
391
|
+
orphanedBubbles += 1;
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
const ownFold = folds.get(sniffed.composerId);
|
|
395
|
+
if (ownFold) {
|
|
396
|
+
ownFold.ownBubbles += 1;
|
|
397
|
+
if (sniffed.kind === "unknown") {
|
|
398
|
+
ownFold.unknownBubbles += 1;
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
ownFold.bubbleVersions.set(sniffed.sourceVersion, (ownFold.bubbleVersions.get(sniffed.sourceVersion) ?? 0) + 1);
|
|
402
|
+
ownFold.inputTokens += sniffed.inputTokens;
|
|
403
|
+
ownFold.outputTokens += sniffed.outputTokens;
|
|
404
|
+
ownFold.humanChangesCount += sniffed.humanChangesCount;
|
|
405
|
+
ownFold.lintErrorsCount += sniffed.lintErrorsCount;
|
|
406
|
+
if (sniffed.modelName) {
|
|
407
|
+
ownFold.models.set(sniffed.modelName, (ownFold.models.get(sniffed.modelName) ?? 0) + 1);
|
|
408
|
+
}
|
|
409
|
+
if (sniffed.createdAt) {
|
|
410
|
+
const ms = Date.parse(sniffed.createdAt);
|
|
411
|
+
if (Number.isFinite(ms) && (ownFold.lastBubbleMs === null || ms > ownFold.lastBubbleMs)) {
|
|
412
|
+
ownFold.lastBubbleMs = ms;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (sniffed.kind === "user") {
|
|
416
|
+
ownFold.humanPrompts += 1;
|
|
417
|
+
if (sniffed.createdAt && isAfterHours(new Date(sniffed.createdAt))) {
|
|
418
|
+
ownFold.afterHoursPrompts += 1;
|
|
419
|
+
}
|
|
420
|
+
ownFold.humanPromptTimestamps.push(sniffed.createdAt);
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
ownFold.assistantTurns += 1;
|
|
424
|
+
}
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
const parentId = subagentParentOf.get(sniffed.composerId);
|
|
428
|
+
const parentFold = parentId ? folds.get(parentId) : undefined;
|
|
429
|
+
if (!parentFold) {
|
|
430
|
+
orphanedSubagentBubbles += parentId ? 1 : 0;
|
|
431
|
+
orphanedBubbles += parentId ? 0 : 1;
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (sniffed.kind === "unknown") {
|
|
435
|
+
parentFold.unknownBubbles += 1;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
parentFold.subagentComposerIds.add(sniffed.composerId);
|
|
439
|
+
parentFold.subagentTokensTotal += sniffed.inputTokens + sniffed.outputTokens;
|
|
440
|
+
if (sniffed.kind === "user") {
|
|
441
|
+
// A subagent's task instruction, not a human prompt — counted for
|
|
442
|
+
// visibility, never an ai_prompt_submitted, never promptCount.
|
|
443
|
+
parentFold.subagentPromptCount += 1;
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
parentFold.subagentAssistantTurns += 1;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
let windowOldest = null;
|
|
450
|
+
let windowNewest = null;
|
|
451
|
+
let sessionCount = 0;
|
|
452
|
+
/** Sessions whose end timestamp came from a fallback, by source. */
|
|
453
|
+
const derivedTimelines = new Map();
|
|
454
|
+
/** Composers no fallback could date — the loud version of the old silent
|
|
455
|
+
* `continue`. Non-zero means conversations are missing from this import. */
|
|
456
|
+
let sessionsWithoutTimeline = 0;
|
|
457
|
+
/** Conversations opened and never used. Not sessions (a window nobody
|
|
458
|
+
* typed into is not work), but counted, because "excluded by rule" and
|
|
459
|
+
* "lost at a boundary" must not look alike. */
|
|
460
|
+
let emptyComposers = 0;
|
|
461
|
+
for (const composerId of [...folds.keys()].sort()) {
|
|
462
|
+
const fold = folds.get(composerId);
|
|
463
|
+
// Emptiness is decided before dating, so an empty conversation is
|
|
464
|
+
// reported as empty rather than as one nothing could date. The two are
|
|
465
|
+
// different findings: one is this extractor applying a rule, the other
|
|
466
|
+
// is it failing to read a store.
|
|
467
|
+
if (fold.ownBubbles === 0 && fold.subagentComposerIds.size === 0) {
|
|
468
|
+
emptyComposers += 1;
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
const timeline = resolveTimeline(fold);
|
|
472
|
+
if (timeline === null) {
|
|
473
|
+
sessionsWithoutTimeline += 1;
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
if (timeline.source !== "header") {
|
|
477
|
+
derivedTimelines.set(timeline.source, (derivedTimelines.get(timeline.source) ?? 0) + 1);
|
|
478
|
+
}
|
|
479
|
+
const startedAt = new Date(fold.createdAtMs).toISOString();
|
|
480
|
+
const endedAt = new Date(timeline.endedAtMs).toISOString();
|
|
481
|
+
sessionCount += 1;
|
|
482
|
+
if (!windowOldest || startedAt < windowOldest)
|
|
483
|
+
windowOldest = startedAt;
|
|
484
|
+
if (!windowNewest || endedAt > windowNewest)
|
|
485
|
+
windowNewest = endedAt;
|
|
486
|
+
const sourceVersion = pickTop(fold.bubbleVersions);
|
|
487
|
+
for (const ts of fold.humanPromptTimestamps) {
|
|
488
|
+
if (!ts)
|
|
489
|
+
continue;
|
|
490
|
+
yield {
|
|
491
|
+
occurredAt: ts,
|
|
492
|
+
store: "cursor",
|
|
493
|
+
sourceVersion,
|
|
494
|
+
sessionRef: fold.composerId,
|
|
495
|
+
repoRef: fold.repoRef,
|
|
496
|
+
eventKind: "ai_prompt_submitted",
|
|
497
|
+
metrics: {},
|
|
498
|
+
provenance: HISTORICAL_PROVENANCE.direct,
|
|
499
|
+
extractionId
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
const durationMs = sessionDurationMs(fold);
|
|
503
|
+
const sessionMetrics = {
|
|
504
|
+
promptCount: fold.humanPrompts,
|
|
505
|
+
assistantTurns: fold.assistantTurns,
|
|
506
|
+
inputTokens: fold.inputTokens,
|
|
507
|
+
outputTokens: fold.outputTokens,
|
|
508
|
+
linesAdded: fold.linesAdded,
|
|
509
|
+
linesRemoved: fold.linesRemoved,
|
|
510
|
+
filesChangedCount: fold.filesChangedCount,
|
|
511
|
+
humanChangesCount: fold.humanChangesCount,
|
|
512
|
+
approximateLintErrorsCount: fold.lintErrorsCount,
|
|
513
|
+
durationBucket: durationBucketOf(fold),
|
|
514
|
+
afterHoursPrompts: fold.afterHoursPrompts,
|
|
515
|
+
unknownBubbles: fold.unknownBubbles,
|
|
516
|
+
unparsedBubbles: fold.unparsedBubbles,
|
|
517
|
+
modelCount: fold.models.size,
|
|
518
|
+
subagentComposers: fold.subagentComposerIds.size,
|
|
519
|
+
subagentPrompts: fold.subagentPromptCount,
|
|
520
|
+
subagentAssistantTurns: fold.subagentAssistantTurns,
|
|
521
|
+
subagentTokensTotal: fold.subagentTokensTotal,
|
|
522
|
+
sessionStartedAt: startedAt
|
|
523
|
+
};
|
|
524
|
+
if (durationMs !== null)
|
|
525
|
+
sessionMetrics.sessionMinutes = Math.round(durationMs / 60_000);
|
|
526
|
+
if (fold.mode)
|
|
527
|
+
sessionMetrics.mode = fold.mode;
|
|
528
|
+
if (fold.contextUsagePercent !== null) {
|
|
529
|
+
sessionMetrics.contextUsagePercent = Math.round(fold.contextUsagePercent * 100) / 100;
|
|
530
|
+
}
|
|
531
|
+
const primaryModel = pickTop(fold.models);
|
|
532
|
+
if (primaryModel)
|
|
533
|
+
sessionMetrics.primaryModel = primaryModel;
|
|
534
|
+
if (fold.gitBranch)
|
|
535
|
+
sessionMetrics.gitBranch = fold.gitBranch;
|
|
536
|
+
yield {
|
|
537
|
+
occurredAt: endedAt,
|
|
538
|
+
store: "cursor",
|
|
539
|
+
sourceVersion,
|
|
540
|
+
sessionRef: fold.composerId,
|
|
541
|
+
repoRef: fold.repoRef,
|
|
542
|
+
eventKind: "create_focus_session",
|
|
543
|
+
metrics: sessionMetrics,
|
|
544
|
+
dayBreakdown: sliceSessionByLocalDay(fold.humanPromptTimestamps),
|
|
545
|
+
provenance: HISTORICAL_PROVENANCE.derived,
|
|
546
|
+
extractionId
|
|
547
|
+
};
|
|
548
|
+
if (fold.afterHoursPrompts > 0) {
|
|
549
|
+
yield {
|
|
550
|
+
occurredAt: endedAt,
|
|
551
|
+
store: "cursor",
|
|
552
|
+
sourceVersion,
|
|
553
|
+
sessionRef: fold.composerId,
|
|
554
|
+
repoRef: fold.repoRef,
|
|
555
|
+
eventKind: "after_hours_ai_session",
|
|
556
|
+
metrics: { afterHoursPrompts: fold.afterHoursPrompts },
|
|
557
|
+
provenance: HISTORICAL_PROVENANCE.derived,
|
|
558
|
+
extractionId
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
// As above: an unreadable store is a finding, not a reason to stay quiet.
|
|
563
|
+
// Without this, a db that opens but whose rows no longer sniff renders as an
|
|
564
|
+
// empty history rather than as a store nobody can read any more.
|
|
565
|
+
// `sessionsWithoutTimeline` counts here too: a composer no fallback could
|
|
566
|
+
// date is a conversation this import does not contain, which is precisely
|
|
567
|
+
// the thing the marker exists to declare.
|
|
568
|
+
const readFailures = unparsedComposerHeaders +
|
|
569
|
+
unknownComposerHeaderTypes +
|
|
570
|
+
orphanedSubagentBubbles +
|
|
571
|
+
orphanedBubbles +
|
|
572
|
+
sessionsWithoutTimeline;
|
|
573
|
+
if ((windowOldest && windowNewest) || readFailures > 0) {
|
|
574
|
+
const window = windowOldest && windowNewest ? { windowOldest, windowNewest } : {};
|
|
575
|
+
yield {
|
|
576
|
+
occurredAt: windowNewest ?? new Date().toISOString(),
|
|
577
|
+
store: "cursor",
|
|
578
|
+
sourceVersion: null,
|
|
579
|
+
sessionRef: null,
|
|
580
|
+
repoRef: null,
|
|
581
|
+
eventKind: "extraction_epoch",
|
|
582
|
+
metrics: {
|
|
583
|
+
...window,
|
|
584
|
+
sessionCount,
|
|
585
|
+
schemaUnreadable: 0,
|
|
586
|
+
unparsedComposerHeaders,
|
|
587
|
+
unknownComposerHeaderTypes,
|
|
588
|
+
orphanedSubagentBubbles,
|
|
589
|
+
orphanedBubbles,
|
|
590
|
+
sessionsWithoutTimeline,
|
|
591
|
+
emptyComposers,
|
|
592
|
+
sessionsFromBubbleTimeline: derivedTimelines.get("bubbles") ?? 0,
|
|
593
|
+
sessionsFromRecencyTimeline: derivedTimelines.get("recency") ?? 0,
|
|
594
|
+
sessionsFromCheckpointTimeline: derivedTimelines.get("checkpoint") ?? 0
|
|
595
|
+
},
|
|
596
|
+
provenance: HISTORICAL_PROVENANCE.derived,
|
|
597
|
+
extractionId
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
//# sourceMappingURL=cursor.js.map
|