@cairn-tool/cairn 3.0.0 → 3.2.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 +6 -3
- package/dist/agent/types.d.ts +2 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/archive/run.d.ts +14 -7
- package/dist/archive/run.js +4 -1
- package/dist/archive/run.js.map +1 -1
- package/dist/archive/sets.d.ts +26 -1
- package/dist/archive/sets.js +108 -0
- package/dist/archive/sets.js.map +1 -1
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/archive.js +11 -5
- package/dist/commands/archive.js.map +1 -1
- package/dist/commands/jira.d.ts +17 -0
- package/dist/commands/jira.js +195 -0
- package/dist/commands/jira.js.map +1 -0
- package/dist/contract/registry.js +38 -1
- package/dist/contract/registry.js.map +1 -1
- package/dist/contract/schemas/index.js +2 -0
- package/dist/contract/schemas/index.js.map +1 -1
- package/dist/contract/schemas/jira.d.ts +2 -0
- package/dist/contract/schemas/jira.js +102 -0
- package/dist/contract/schemas/jira.js.map +1 -0
- package/dist/jira/adf/diagnostics.d.ts +77 -0
- package/dist/jira/adf/diagnostics.js +100 -0
- package/dist/jira/adf/diagnostics.js.map +1 -0
- package/dist/jira/adf/from-markdown.d.ts +6 -0
- package/dist/jira/adf/from-markdown.js +650 -0
- package/dist/jira/adf/from-markdown.js.map +1 -0
- package/dist/jira/adf/inspect.d.ts +11 -0
- package/dist/jira/adf/inspect.js +56 -0
- package/dist/jira/adf/inspect.js.map +1 -0
- package/dist/jira/adf/profile.d.ts +101 -0
- package/dist/jira/adf/profile.js +248 -0
- package/dist/jira/adf/profile.js.map +1 -0
- package/dist/jira/adf/read.d.ts +33 -0
- package/dist/jira/adf/read.js +250 -0
- package/dist/jira/adf/read.js.map +1 -0
- package/dist/jira/adf/serialize.d.ts +5 -0
- package/dist/jira/adf/serialize.js +54 -0
- package/dist/jira/adf/serialize.js.map +1 -0
- package/dist/jira/adf/to-markdown.d.ts +14 -0
- package/dist/jira/adf/to-markdown.js +512 -0
- package/dist/jira/adf/to-markdown.js.map +1 -0
- package/dist/jira/adf/types.d.ts +73 -0
- package/dist/jira/adf/types.js +2 -0
- package/dist/jira/adf/types.js.map +1 -0
- package/dist/jira/adf/validate.d.ts +7 -0
- package/dist/jira/adf/validate.js +182 -0
- package/dist/jira/adf/validate.js.map +1 -0
- package/dist/mapping-quality.d.ts +18 -0
- package/dist/mapping-quality.js +12 -0
- package/dist/mapping-quality.js.map +1 -0
- package/dist/usage/providers/cursor.d.ts +2 -0
- package/dist/usage/providers/cursor.js +570 -0
- package/dist/usage/providers/cursor.js.map +1 -0
- package/dist/usage/providers/index.js +2 -0
- package/dist/usage/providers/index.js.map +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { addTokens, emptyBucket, emptyTokens, utcDay } from "../events.js";
|
|
4
|
+
import { loadSqlite } from "../../sqlite.js";
|
|
5
|
+
/**
|
|
6
|
+
* Cursor's editor store.
|
|
7
|
+
*
|
|
8
|
+
* Everything is one SQLite database inside the Electron user-data directory:
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* User/globalStorage/state.vscdb
|
|
12
|
+
* ItemTable(key, value) -- settings, and the legacy conversation index
|
|
13
|
+
* cursorDiskKV(key, value) -- the corpus, keyed by prefix
|
|
14
|
+
* composerHeaders(composerId, workspaceId, createdAt, lastUpdatedAt,
|
|
15
|
+
* isArchived, isSubagent, recency, checkpointAt, value)
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* A conversation is a *composer*, and `composerId` joins every prefix:
|
|
19
|
+
* `composerData:<id>` is the conversation, `bubbleId:<id>:<bubbleId>` its turns.
|
|
20
|
+
*
|
|
21
|
+
* **Cursor stopped writing token counters.** `bubbleId` records carry
|
|
22
|
+
* `tokenCount.{inputTokens,outputTokens}`, and those are genuine per-request
|
|
23
|
+
* figures -- but on a real corpus every nonzero one falls between 2025-06-17 and
|
|
24
|
+
* 2025-12-23. Newer conversations carry the field with zeroes in it and settle
|
|
25
|
+
* usage server-side, behind each bubble's `usageUuid`. So this provider reports
|
|
26
|
+
* real tokens for the window Cursor wrote them and zero afterwards, which is a
|
|
27
|
+
* fact about the host rather than a gap in the parser. See
|
|
28
|
+
* `docs/providers/cursor/usage-logs.md`.
|
|
29
|
+
*
|
|
30
|
+
* The schema has only ever had `inputTokens` and `outputTokens`: there is no
|
|
31
|
+
* cache, reasoning, or web-tool breakdown to read, hence `cacheTokens: false`.
|
|
32
|
+
*
|
|
33
|
+
* `contextTokensUsed` is deliberately **not** read. It is the size of the most
|
|
34
|
+
* recent turn's context, overwritten every turn and excluding output, so it can
|
|
35
|
+
* be neither summed (like Antigravity's) nor differenced (like Codex's). It is
|
|
36
|
+
* the one figure here that would have no defensible interpretation.
|
|
37
|
+
*
|
|
38
|
+
* This is the third provider reading somebody else's live database, so it
|
|
39
|
+
* follows the rules the other two set: open read-only through the **shared**
|
|
40
|
+
* `loadSqlite()`, never a second loader, and treat every failure -- a missing
|
|
41
|
+
* table, a renamed column, a runtime with no `node:sqlite` -- as an empty store
|
|
42
|
+
* rather than an exception.
|
|
43
|
+
*/
|
|
44
|
+
const STORE = path.join("User", "globalStorage", "state.vscdb");
|
|
45
|
+
/** The synthetic shard every conversation is filed under; there is one store. */
|
|
46
|
+
const SHARD = "composer";
|
|
47
|
+
/** `ItemTable` key holding the pre-`composerHeaders` conversation index. */
|
|
48
|
+
const LEGACY_INDEX = "composer.composerHeaders";
|
|
49
|
+
/**
|
|
50
|
+
* Prefix bounds for a `cursorDiskKV` key range.
|
|
51
|
+
*
|
|
52
|
+
* `;` is `:` plus one, so `[<prefix>:, <prefix>;)` is exactly the keys under a
|
|
53
|
+
* prefix. A range comparison uses the UNIQUE index on `key` unambiguously; the
|
|
54
|
+
* table holds roughly 450k rows and 5 GB of values, and an unconstrained scan of
|
|
55
|
+
* it is minutes rather than milliseconds.
|
|
56
|
+
*/
|
|
57
|
+
function prefixRange(prefix) {
|
|
58
|
+
return [`${prefix}:`, `${prefix};`];
|
|
59
|
+
}
|
|
60
|
+
function text(value) {
|
|
61
|
+
return typeof value === "string" && value ? value : null;
|
|
62
|
+
}
|
|
63
|
+
function count(value) {
|
|
64
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
65
|
+
return value;
|
|
66
|
+
if (typeof value === "bigint")
|
|
67
|
+
return Number(value);
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
/** An epoch-millisecond column as the ISO string every event carries. */
|
|
71
|
+
function isoAt(value) {
|
|
72
|
+
const ms = count(value);
|
|
73
|
+
if (!ms)
|
|
74
|
+
return null;
|
|
75
|
+
const at = new Date(ms);
|
|
76
|
+
return Number.isNaN(at.getTime()) ? null : at.toISOString();
|
|
77
|
+
}
|
|
78
|
+
function parseJson(value) {
|
|
79
|
+
const raw = text(value);
|
|
80
|
+
if (!raw)
|
|
81
|
+
return null;
|
|
82
|
+
try {
|
|
83
|
+
const parsed = JSON.parse(raw);
|
|
84
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
85
|
+
? parsed
|
|
86
|
+
: null;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function record(value) {
|
|
93
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
94
|
+
? value
|
|
95
|
+
: null;
|
|
96
|
+
}
|
|
97
|
+
function openDatabase(file) {
|
|
98
|
+
const sqlite = loadSqlite();
|
|
99
|
+
if (!sqlite)
|
|
100
|
+
return null;
|
|
101
|
+
try {
|
|
102
|
+
// The URI form, because the store has live `-wal`/`-shm` sidecars and this
|
|
103
|
+
// is somebody else's database: it is never opened for writing.
|
|
104
|
+
return new sqlite.DatabaseSync(`file:${file}?mode=ro`, { readOnly: true });
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function closeQuietly(db) {
|
|
111
|
+
try {
|
|
112
|
+
db.close();
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Closing a read-only handle cannot lose anything.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function query(db, sql, ...parameters) {
|
|
119
|
+
try {
|
|
120
|
+
return db.prepare(sql).all(...parameters);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// A renamed column, or a table this version of Cursor does not have, costs
|
|
124
|
+
// exactly what it names rather than the whole provider. `composerHeaders`
|
|
125
|
+
// is itself recent, and older stores keep that index in `ItemTable`.
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function blank(id) {
|
|
130
|
+
return {
|
|
131
|
+
id,
|
|
132
|
+
createdAt: 0,
|
|
133
|
+
lastUpdatedAt: 0,
|
|
134
|
+
bubbles: 0,
|
|
135
|
+
kind: "main",
|
|
136
|
+
parentId: null,
|
|
137
|
+
agentType: null,
|
|
138
|
+
agentPath: null,
|
|
139
|
+
project: "",
|
|
140
|
+
title: null,
|
|
141
|
+
model: null,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The absolute working directory a conversation ran in.
|
|
146
|
+
*
|
|
147
|
+
* `workspaceIdentifier.uri.fsPath` is carried inside the store itself, so
|
|
148
|
+
* project identity never depends on reading `User/workspaceStorage/<id>/`, and
|
|
149
|
+
* never on the `~/.cursor/projects/<slug>` directory names -- those replace both
|
|
150
|
+
* separators and dots and are lossy in both directions, the same trap
|
|
151
|
+
* `claude-code.ts` documents for its own slugs.
|
|
152
|
+
*
|
|
153
|
+
* A multi-root window carries `configPath` instead, naming a `.code-workspace`
|
|
154
|
+
* document rather than a directory. That is several folders, and a
|
|
155
|
+
* `FileAggregate` has exactly one `project`, so it is left unset rather than
|
|
156
|
+
* having one of them picked arbitrarily.
|
|
157
|
+
*/
|
|
158
|
+
function projectOf(identifier) {
|
|
159
|
+
const uri = record(identifier?.uri);
|
|
160
|
+
return text(uri?.fsPath) ?? text(uri?.path) ?? "";
|
|
161
|
+
}
|
|
162
|
+
/** Fills in whatever a conversation-index entry knows. */
|
|
163
|
+
function applyIdentity(into, entry) {
|
|
164
|
+
const identifier = record(entry.workspaceIdentifier);
|
|
165
|
+
if (identifier && !into.project)
|
|
166
|
+
into.project = projectOf(identifier);
|
|
167
|
+
if (!into.title)
|
|
168
|
+
into.title = text(entry.name);
|
|
169
|
+
into.createdAt ||= count(entry.createdAt);
|
|
170
|
+
into.lastUpdatedAt = Math.max(into.lastUpdatedAt, count(entry.lastUpdatedAt));
|
|
171
|
+
const subagent = record(entry.subagentInfo);
|
|
172
|
+
if (!subagent)
|
|
173
|
+
return;
|
|
174
|
+
into.kind = "subagent";
|
|
175
|
+
into.parentId ??= text(subagent.parentComposerId) ?? text(subagent.rootParentConversationId);
|
|
176
|
+
// The reusable role, and the task-specific id for this one run -- the same
|
|
177
|
+
// split Codex records as `agent_role` and `agent_path`.
|
|
178
|
+
into.agentType ??= text(subagent.subagentTypeName);
|
|
179
|
+
into.agentPath ??= text(subagent.toolCallId);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Every conversation in the store, with a freshness key derived from its rows.
|
|
183
|
+
*
|
|
184
|
+
* **Discovery is over `composerData:` keys, not the `composerHeaders` table.**
|
|
185
|
+
* That table is recent and holds only the conversations Cursor has migrated into
|
|
186
|
+
* it: on a real corpus it names 1,023 of 1,616 conversations, and 161 of the 229
|
|
187
|
+
* that carry token counters are absent from it *and* from the legacy
|
|
188
|
+
* `ItemTable` index beside it -- 61% of all the tokens on this machine. Both
|
|
189
|
+
* indexes are therefore read only to *enrich* a conversation with the identity
|
|
190
|
+
* they alone carry (workspace, subagent role), never to decide it exists.
|
|
191
|
+
*
|
|
192
|
+
* The freshness key has to be synthesized for the same reason OpenCode's does:
|
|
193
|
+
* the file's mtime is one value shared by every conversation, so any write would
|
|
194
|
+
* invalidate all of them and force a full re-parse on every scan. `mtimeMs` is
|
|
195
|
+
* the latest timestamp the conversation carries and `bubbles` fingerprints its
|
|
196
|
+
* turn count, because `isFresh` compares exactly the pair `(size, mtimeMs)` and
|
|
197
|
+
* neither half alone catches every edit.
|
|
198
|
+
*/
|
|
199
|
+
function readIndex(db) {
|
|
200
|
+
const conversations = new Map();
|
|
201
|
+
const at = (id) => {
|
|
202
|
+
let found = conversations.get(id);
|
|
203
|
+
if (!found)
|
|
204
|
+
conversations.set(id, (found = blank(id)));
|
|
205
|
+
return found;
|
|
206
|
+
};
|
|
207
|
+
const [dataLow, dataHigh] = prefixRange("composerData");
|
|
208
|
+
for (const row of query(db, `SELECT substr(key, ?) AS id,
|
|
209
|
+
json_extract(value, '$.createdAt') AS created,
|
|
210
|
+
json_extract(value, '$.lastUpdatedAt') AS updated,
|
|
211
|
+
json_extract(value, '$.modelConfig.modelName') AS model,
|
|
212
|
+
json_extract(value, '$.usageData') AS usage,
|
|
213
|
+
json_extract(value, '$.name') AS name,
|
|
214
|
+
json_extract(value, '$.workspaceIdentifier.uri.fsPath') AS project
|
|
215
|
+
FROM cursorDiskKV WHERE key >= ? AND key < ?`, dataLow.length + 1, dataLow, dataHigh)) {
|
|
216
|
+
const id = text(row.id);
|
|
217
|
+
if (!id)
|
|
218
|
+
continue;
|
|
219
|
+
const conversation = at(id);
|
|
220
|
+
conversation.createdAt = count(row.created);
|
|
221
|
+
conversation.lastUpdatedAt = count(row.updated);
|
|
222
|
+
conversation.title = text(row.name);
|
|
223
|
+
// The conversation carries its own workspace on about a fifth of rows, and
|
|
224
|
+
// is the only source of one for a conversation neither index knows about.
|
|
225
|
+
conversation.project = text(row.project) ?? "";
|
|
226
|
+
// `modelConfig` postdates the token era, so the legacy `usageData` map is
|
|
227
|
+
// the fallback -- but only when it names exactly one model, since a
|
|
228
|
+
// conversation that used several cannot attribute a bubble to one of them.
|
|
229
|
+
conversation.model = text(row.model) ?? soleModel(row.usage);
|
|
230
|
+
}
|
|
231
|
+
// Turn counts, index-only: nothing but `key` is touched, so this reads the
|
|
232
|
+
// UNIQUE index rather than 1.3 GB of turn bodies.
|
|
233
|
+
const [bubbleLow, bubbleHigh] = prefixRange("bubbleId");
|
|
234
|
+
for (const row of query(db, `SELECT substr(key, ?, instr(substr(key, ?), ':') - 1) AS id, count(*) AS turns
|
|
235
|
+
FROM cursorDiskKV WHERE key >= ? AND key < ? GROUP BY id`, bubbleLow.length + 1, bubbleLow.length + 1, bubbleLow, bubbleHigh)) {
|
|
236
|
+
const id = text(row.id);
|
|
237
|
+
if (!id)
|
|
238
|
+
continue;
|
|
239
|
+
at(id).bubbles = count(row.turns);
|
|
240
|
+
}
|
|
241
|
+
for (const row of query(db, "SELECT composerId, isSubagent, createdAt, lastUpdatedAt, value FROM composerHeaders")) {
|
|
242
|
+
const id = text(row.composerId);
|
|
243
|
+
if (!id)
|
|
244
|
+
continue;
|
|
245
|
+
const conversation = at(id);
|
|
246
|
+
if (count(row.isSubagent) === 1)
|
|
247
|
+
conversation.kind = "subagent";
|
|
248
|
+
conversation.createdAt ||= count(row.createdAt);
|
|
249
|
+
conversation.lastUpdatedAt = Math.max(conversation.lastUpdatedAt, count(row.lastUpdatedAt));
|
|
250
|
+
const entry = parseJson(row.value);
|
|
251
|
+
if (entry)
|
|
252
|
+
applyIdentity(conversation, entry);
|
|
253
|
+
}
|
|
254
|
+
for (const entry of legacyIndex(db)) {
|
|
255
|
+
const id = text(entry.composerId);
|
|
256
|
+
if (!id)
|
|
257
|
+
continue;
|
|
258
|
+
applyIdentity(at(id), entry);
|
|
259
|
+
}
|
|
260
|
+
return conversations;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* The pre-`composerHeaders` conversation index, a JSON blob in `ItemTable`.
|
|
264
|
+
*
|
|
265
|
+
* Cursor gates the table by a separate `composer.composerHeaders.tableGateEnabled`
|
|
266
|
+
* flag and did not backfill it, so both live side by side and both are read.
|
|
267
|
+
*/
|
|
268
|
+
function legacyIndex(db) {
|
|
269
|
+
const rows = query(db, "SELECT value FROM ItemTable WHERE key = ?", LEGACY_INDEX);
|
|
270
|
+
const blob = parseJson(rows[0]?.value);
|
|
271
|
+
const all = blob?.allComposers;
|
|
272
|
+
if (!Array.isArray(all))
|
|
273
|
+
return [];
|
|
274
|
+
return all.filter((entry) => record(entry) !== null);
|
|
275
|
+
}
|
|
276
|
+
/** The single model a legacy `usageData` map names, or null when it names 0 or 2+. */
|
|
277
|
+
function soleModel(value) {
|
|
278
|
+
const usage = parseJson(value);
|
|
279
|
+
if (!usage)
|
|
280
|
+
return null;
|
|
281
|
+
const names = Object.keys(usage);
|
|
282
|
+
return names.length === 1 ? names[0] : null;
|
|
283
|
+
}
|
|
284
|
+
/** Cursor's own subagent-spawning builtin, the counterpart of OpenCode's `task`. */
|
|
285
|
+
const SPAWN_TOOL = "task_v2";
|
|
286
|
+
/**
|
|
287
|
+
* Cursor's flattened MCP tool name, in the form `classifyTool` understands.
|
|
288
|
+
*
|
|
289
|
+
* A call is recorded as `mcp-<server>-<tool>`, and on a real corpus the server
|
|
290
|
+
* half is sometimes repeated (`mcp-cursor-ide-browser-cursor-ide-browser-browser_lock`)
|
|
291
|
+
* while the separator also occurs inside both halves. So an MCP call can be told
|
|
292
|
+
* apart from a builtin, which is why `mcp` is a declared capability here and not
|
|
293
|
+
* for OpenCode or Gemini CLI, whose tool records name no server at all. But the
|
|
294
|
+
* boundary within the remainder is not recoverable. Rewriting to `mcp__<rest>`
|
|
295
|
+
* with no second separator makes `classifyTool` report `kind: "mcp"` with the
|
|
296
|
+
* whole flattened name as the server, which is exactly as much as is known.
|
|
297
|
+
*/
|
|
298
|
+
function normalizeTool(name) {
|
|
299
|
+
if (!name.startsWith("mcp-"))
|
|
300
|
+
return name;
|
|
301
|
+
const rest = name.slice("mcp-".length);
|
|
302
|
+
return rest ? `mcp__${rest}` : name;
|
|
303
|
+
}
|
|
304
|
+
function bucketFor(building, timestamp) {
|
|
305
|
+
if (!timestamp)
|
|
306
|
+
return null;
|
|
307
|
+
const day = utcDay(timestamp);
|
|
308
|
+
if (!day)
|
|
309
|
+
return null;
|
|
310
|
+
const aggregate = building.aggregate;
|
|
311
|
+
if (!aggregate.firstTs || timestamp < aggregate.firstTs)
|
|
312
|
+
aggregate.firstTs = timestamp;
|
|
313
|
+
if (!aggregate.lastTs || timestamp > aggregate.lastTs)
|
|
314
|
+
aggregate.lastTs = timestamp;
|
|
315
|
+
return (aggregate.days[day] ??= emptyBucket());
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* One turn's token counters.
|
|
319
|
+
*
|
|
320
|
+
* Only `input` and `output` are ever populated: no other counter has existed in
|
|
321
|
+
* this schema. A caller only reaches here for a turn whose counters are nonzero.
|
|
322
|
+
*/
|
|
323
|
+
function readUsage(input, output) {
|
|
324
|
+
const totals = emptyTokens();
|
|
325
|
+
totals.input = input;
|
|
326
|
+
totals.output = output;
|
|
327
|
+
totals.requests = 1;
|
|
328
|
+
return totals;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* One conversation's turns.
|
|
332
|
+
*
|
|
333
|
+
* The projection is done in SQL rather than in JavaScript on purpose: a turn
|
|
334
|
+
* body averages 9 KB and the corpus holds 1.3 GB of them, so selecting `value`
|
|
335
|
+
* and picking fields off it here would move a whole conversation across the
|
|
336
|
+
* boundary in order to read seven scalars.
|
|
337
|
+
*/
|
|
338
|
+
function applyBubbles(db, conversation, roles, building) {
|
|
339
|
+
const [low, high] = prefixRange(`bubbleId:${conversation.id}`);
|
|
340
|
+
const fallback = isoAt(conversation.createdAt);
|
|
341
|
+
const model = conversation.model ?? "(unknown)";
|
|
342
|
+
for (const row of query(db, `SELECT json_extract(value, '$.type') AS kind,
|
|
343
|
+
json_extract(value, '$.tokenCount.inputTokens') AS input,
|
|
344
|
+
json_extract(value, '$.tokenCount.outputTokens') AS output,
|
|
345
|
+
json_extract(value, '$.timingInfo.clientRpcSendTime') AS ts,
|
|
346
|
+
json_extract(value, '$.toolFormerData.name') AS tool,
|
|
347
|
+
json_extract(value, '$.toolFormerData.status') AS status,
|
|
348
|
+
json_extract(value, '$.toolFormerData.toolCallId') AS call
|
|
349
|
+
FROM cursorDiskKV WHERE key >= ? AND key < ?`, low, high)) {
|
|
350
|
+
// All but a fraction of a percent of turns carry no timestamp of their own,
|
|
351
|
+
// so the conversation's creation instant is the anchor. Day rollups are
|
|
352
|
+
// therefore per conversation rather than per turn: coarser than every other
|
|
353
|
+
// provider, and documented as such.
|
|
354
|
+
const ts = isoAt(row.ts) ?? fallback;
|
|
355
|
+
const bucket = bucketFor(building, ts);
|
|
356
|
+
if (!bucket || !ts)
|
|
357
|
+
continue;
|
|
358
|
+
if (count(row.kind) === 1) {
|
|
359
|
+
bucket.prompts += 1;
|
|
360
|
+
building.events.push({ ts, kind: "prompt" });
|
|
361
|
+
}
|
|
362
|
+
const input = count(row.input);
|
|
363
|
+
const output = count(row.output);
|
|
364
|
+
// A turn whose counters are absent or all zero emits no response at all.
|
|
365
|
+
// Every turn after 2025 is one of those, and counting them would report a
|
|
366
|
+
// request against no tokens, the same suppression `codex.ts` applies to a
|
|
367
|
+
// zero delta.
|
|
368
|
+
if (input > 0 || output > 0) {
|
|
369
|
+
const totals = readUsage(input, output);
|
|
370
|
+
addTokens((bucket.models[model] ??= emptyTokens()), totals);
|
|
371
|
+
building.events.push({ ts, kind: "response", model, tokens: totals });
|
|
372
|
+
}
|
|
373
|
+
const tool = text(row.tool);
|
|
374
|
+
if (!tool)
|
|
375
|
+
continue;
|
|
376
|
+
const name = normalizeTool(tool);
|
|
377
|
+
bucket.tools[name] = (bucket.tools[name] ?? 0) + 1;
|
|
378
|
+
building.events.push({ ts, kind: "tool_use", tool: name });
|
|
379
|
+
if (tool === SPAWN_TOOL) {
|
|
380
|
+
// The parent's call does not name the role, but the conversation it
|
|
381
|
+
// spawned does, and that conversation's `subagentInfo.toolCallId` points
|
|
382
|
+
// back at this exact call, so the join is by identifier not by guess.
|
|
383
|
+
const role = roles.get(text(row.call) ?? "") ?? "(unrecorded)";
|
|
384
|
+
(bucket.agents[role] ??= { count: 0, maxDepth: 0 }).count += 1;
|
|
385
|
+
building.events.push({ ts, kind: "agent", name: role });
|
|
386
|
+
}
|
|
387
|
+
if (text(row.status) === "error") {
|
|
388
|
+
bucket.errors += 1;
|
|
389
|
+
building.events.push({ ts, kind: "error" });
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
let store = null;
|
|
394
|
+
function storeKey(file) {
|
|
395
|
+
try {
|
|
396
|
+
const stats = fs.statSync(file);
|
|
397
|
+
// The path is part of the key, not just the stat: two stores can share a
|
|
398
|
+
// size and an mtime, and the memo holds only one entry.
|
|
399
|
+
return `${file}${stats.mtimeMs}${stats.size}`;
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
return "";
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* The index, built once and memoized, with the handle it was built from.
|
|
407
|
+
*
|
|
408
|
+
* Unlike OpenCode this does **not** reduce the whole store up front. That one is
|
|
409
|
+
* a few megabytes; this one is 5.65 GB, of which 1.3 GB is turn bodies and 3 GB
|
|
410
|
+
* is opaque blobs. Only the cheap index is built eagerly, and `parse` then reads
|
|
411
|
+
* one conversation's turns through the key range that serves it. The handle is
|
|
412
|
+
* memoized alongside it because `scan.ts` drives `parse` through a worker pool,
|
|
413
|
+
* and reopening the store per conversation would be the only expensive part
|
|
414
|
+
* left. The memo holds a single entry, so a `--provider all` run does not pin
|
|
415
|
+
* two stores in memory.
|
|
416
|
+
*/
|
|
417
|
+
function loadStore(file) {
|
|
418
|
+
const key = storeKey(file);
|
|
419
|
+
if (store && store.key === key)
|
|
420
|
+
return store;
|
|
421
|
+
if (store?.db)
|
|
422
|
+
closeQuietly(store.db);
|
|
423
|
+
const db = openDatabase(file);
|
|
424
|
+
const index = db ? readIndex(db) : new Map();
|
|
425
|
+
const roles = new Map();
|
|
426
|
+
for (const conversation of index.values()) {
|
|
427
|
+
if (conversation.agentPath && conversation.agentType) {
|
|
428
|
+
roles.set(conversation.agentPath, conversation.agentType);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
store = { key, db, index, roles };
|
|
432
|
+
return store;
|
|
433
|
+
}
|
|
434
|
+
function emptyAggregate(file, sessionId) {
|
|
435
|
+
return {
|
|
436
|
+
file: file.file,
|
|
437
|
+
size: file.size,
|
|
438
|
+
mtimeMs: file.mtimeMs,
|
|
439
|
+
provider: cursorProvider.name,
|
|
440
|
+
sessionId,
|
|
441
|
+
kind: file.kind,
|
|
442
|
+
project: "",
|
|
443
|
+
firstTs: "",
|
|
444
|
+
lastTs: "",
|
|
445
|
+
days: {},
|
|
446
|
+
malformedLines: 0,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
export const cursorProvider = {
|
|
450
|
+
name: "cursor",
|
|
451
|
+
title: "Cursor",
|
|
452
|
+
source: "The editor store at <user data>/User/globalStorage/state.vscdb",
|
|
453
|
+
capabilities: {
|
|
454
|
+
// Real per-request figures, but only for conversations from before Cursor
|
|
455
|
+
// stopped writing them in December 2025. See the note at the top.
|
|
456
|
+
tokens: true,
|
|
457
|
+
// `tokenCount` has only ever had `inputTokens` and `outputTokens`: no cache
|
|
458
|
+
// read, cache write, or reasoning counter has ever been recorded.
|
|
459
|
+
cacheTokens: false,
|
|
460
|
+
tools: true,
|
|
461
|
+
// No tool, capability, or turn field names a skill, and no record of one
|
|
462
|
+
// being invoked reaches the store.
|
|
463
|
+
skills: false,
|
|
464
|
+
subagents: true,
|
|
465
|
+
// Cursor runs five hook events out of `~/.cursor/hooks.json`, but no
|
|
466
|
+
// execution of one is written anywhere, the same as Codex.
|
|
467
|
+
hooks: false,
|
|
468
|
+
// A call is recorded as `mcp-<server>-<tool>`, so an MCP call can be told
|
|
469
|
+
// apart from a builtin even though the server boundary cannot be recovered.
|
|
470
|
+
mcp: true,
|
|
471
|
+
// A slash command reaches the store only as the prompt text it expanded to.
|
|
472
|
+
// `~/.cursor/prompt_history.json` is a most-recently-used list, not a log.
|
|
473
|
+
slashCommands: false,
|
|
474
|
+
projects: true,
|
|
475
|
+
},
|
|
476
|
+
/**
|
|
477
|
+
* The Electron user-data directory, guarded on the store inside it.
|
|
478
|
+
*
|
|
479
|
+
* Candidates are tried in order rather than switched on `process.platform`,
|
|
480
|
+
* which keeps the provider hermetic under `--logs` and under a suite that
|
|
481
|
+
* swaps `HOME`, and costs one `statSync` per miss.
|
|
482
|
+
*/
|
|
483
|
+
root(context) {
|
|
484
|
+
const override = context.override?.trim();
|
|
485
|
+
const appData = context.env.APPDATA?.trim();
|
|
486
|
+
const candidates = override
|
|
487
|
+
? [override]
|
|
488
|
+
: [
|
|
489
|
+
...(appData ? [path.join(appData, "Cursor")] : []),
|
|
490
|
+
path.join(context.home, "Library", "Application Support", "Cursor"),
|
|
491
|
+
path.join(context.home, ".config", "Cursor"),
|
|
492
|
+
];
|
|
493
|
+
for (const candidate of candidates) {
|
|
494
|
+
try {
|
|
495
|
+
if (fs.statSync(path.join(candidate, STORE)).isFile())
|
|
496
|
+
return candidate;
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
// Not this one. An absent candidate is the normal case on every
|
|
500
|
+
// platform but the one Cursor is installed on.
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return null;
|
|
504
|
+
},
|
|
505
|
+
/**
|
|
506
|
+
* One entry per conversation, out of a store with no filesystem unit below
|
|
507
|
+
* itself: the same synthesis OpenCode performs, and for the same reason. A
|
|
508
|
+
* `FileAggregate` carries exactly one session id, kind, project and time span,
|
|
509
|
+
* so collapsing the store into one entry would destroy `usage sessions`,
|
|
510
|
+
* `--last`, `--project`, and the main/subagent split.
|
|
511
|
+
*/
|
|
512
|
+
discover(root, options) {
|
|
513
|
+
const file = path.join(root, STORE);
|
|
514
|
+
const found = [];
|
|
515
|
+
for (const conversation of loadStore(file).index.values()) {
|
|
516
|
+
// Whether a conversation is a subagent is known from the index, so they
|
|
517
|
+
// are pruned before any turn is read: the fourth provider that can, after
|
|
518
|
+
// claude-code, gemini-cli and opencode.
|
|
519
|
+
if (!options.subagents && conversation.kind === "subagent")
|
|
520
|
+
continue;
|
|
521
|
+
const mtimeMs = Math.max(conversation.lastUpdatedAt, conversation.createdAt);
|
|
522
|
+
if (options.modifiedSince !== undefined && mtimeMs < options.modifiedSince)
|
|
523
|
+
continue;
|
|
524
|
+
found.push({
|
|
525
|
+
file,
|
|
526
|
+
relative: `${SHARD}/${conversation.id}`,
|
|
527
|
+
shard: SHARD,
|
|
528
|
+
kind: conversation.kind,
|
|
529
|
+
size: conversation.bubbles,
|
|
530
|
+
mtimeMs,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
// Byte comparison, never localeCompare: the order must not depend on the
|
|
534
|
+
// ICU build of the machine that ran the scan.
|
|
535
|
+
found.sort((a, b) => (a.relative < b.relative ? -1 : a.relative > b.relative ? 1 : 0));
|
|
536
|
+
return found;
|
|
537
|
+
},
|
|
538
|
+
async read(file) {
|
|
539
|
+
return (await cursorProvider.parse(file)).aggregate;
|
|
540
|
+
},
|
|
541
|
+
async parse(file) {
|
|
542
|
+
const sessionId = file.relative.slice(`${SHARD}/`.length);
|
|
543
|
+
const loaded = loadStore(file.file);
|
|
544
|
+
const conversation = loaded.index.get(sessionId);
|
|
545
|
+
// A conversation that vanished between discovery and parsing, or a store
|
|
546
|
+
// that would not open. Neither is fatal: it reports as an empty transcript.
|
|
547
|
+
if (!conversation || !loaded.db) {
|
|
548
|
+
return { aggregate: emptyAggregate(file, sessionId), events: [] };
|
|
549
|
+
}
|
|
550
|
+
const aggregate = emptyAggregate(file, sessionId);
|
|
551
|
+
aggregate.kind = conversation.kind;
|
|
552
|
+
aggregate.project = conversation.project;
|
|
553
|
+
if (conversation.parentId)
|
|
554
|
+
aggregate.parentSessionId = conversation.parentId;
|
|
555
|
+
if (conversation.agentType)
|
|
556
|
+
aggregate.agentType = conversation.agentType;
|
|
557
|
+
if (conversation.agentPath)
|
|
558
|
+
aggregate.agentPath = conversation.agentPath;
|
|
559
|
+
if (conversation.title)
|
|
560
|
+
aggregate.title = conversation.title;
|
|
561
|
+
const building = { aggregate, events: [] };
|
|
562
|
+
// Seed the span from the index, so a conversation whose turns are all
|
|
563
|
+
// untimed still reports the day it was created on.
|
|
564
|
+
bucketFor(building, isoAt(conversation.createdAt));
|
|
565
|
+
bucketFor(building, isoAt(conversation.lastUpdatedAt));
|
|
566
|
+
applyBubbles(loaded.db, conversation, loaded.roles, building);
|
|
567
|
+
return { aggregate, events: building.events };
|
|
568
|
+
},
|
|
569
|
+
};
|
|
570
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../src/usage/providers/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { antigravityProvider } from "./antigravity.js";
|
|
2
2
|
import { claudeCodeProvider } from "./claude-code.js";
|
|
3
3
|
import { codexProvider } from "./codex.js";
|
|
4
|
+
import { cursorProvider } from "./cursor.js";
|
|
4
5
|
import { geminiCliProvider } from "./gemini-cli.js";
|
|
5
6
|
import { opencodeProvider } from "./opencode.js";
|
|
6
7
|
/**
|
|
@@ -19,6 +20,7 @@ export const PROVIDERS = [
|
|
|
19
20
|
// the e2e suite pins the earlier entries by position.
|
|
20
21
|
geminiCliProvider,
|
|
21
22
|
opencodeProvider,
|
|
23
|
+
cursorProvider,
|
|
22
24
|
];
|
|
23
25
|
export const DEFAULT_PROVIDER = claudeCodeProvider.name;
|
|
24
26
|
/** Selects every registered provider rather than one. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/usage/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAA6B;IACjD,kBAAkB;IAClB,aAAa;IACb,mBAAmB;IACnB,4EAA4E;IAC5E,sDAAsD;IACtD,iBAAiB;IACjB,gBAAgB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/usage/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAA6B;IACjD,kBAAkB;IAClB,aAAa;IACb,mBAAmB;IACnB,4EAA4E;IAC5E,sDAAsD;IACtD,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,IAAI,CAAC;AAExD,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC;AAEnC,MAAM,UAAU,aAAa;IAC3B,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAwB;IACvD,MAAM,MAAM,GAAG,IAAI,IAAI,gBAAgB,CAAC;IACxC,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,qBAAqB,MAAM,YAAY,CAAC,GAAG,aAAa,EAAE,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACzF,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,QAAQ,CAAC,CAAC;AACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cairn-tool/cairn",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "An agent-agnostic CLI toolkit for working with markdown files and related assets",
|
|
6
6
|
"license": "MIT",
|
|
@@ -66,11 +66,13 @@
|
|
|
66
66
|
"remark-frontmatter": "^5.0.0",
|
|
67
67
|
"remark-gfm": "^4.0.1",
|
|
68
68
|
"remark-parse": "^11.0.0",
|
|
69
|
+
"remark-stringify": "^11.0.0",
|
|
69
70
|
"unified": "^11.0.5",
|
|
70
71
|
"unist-util-visit": "^5.1.0",
|
|
71
72
|
"yaml": "^2.8.2"
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
75
|
+
"@atlaskit/adf-schema": "^57.2.8",
|
|
74
76
|
"@commitlint/cli": "^21.2.2",
|
|
75
77
|
"@commitlint/config-conventional": "^21.2.0",
|
|
76
78
|
"@eslint/js": "^10.0.1",
|
|
@@ -80,6 +82,7 @@
|
|
|
80
82
|
"@types/katex": "^0.16.0",
|
|
81
83
|
"@types/mdast": "^4.0.4",
|
|
82
84
|
"@types/node": "^26.4.0",
|
|
85
|
+
"ajv-draft-04": "^1.0.0",
|
|
83
86
|
"eslint": "^10.9.1",
|
|
84
87
|
"eslint-config-prettier": "^10.1.8",
|
|
85
88
|
"husky": "^9.1.7",
|