@tracemarketplace/shared 0.0.8 → 0.0.10

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.
Files changed (71) hide show
  1. package/dist/extractor-claude-code.test.js +63 -0
  2. package/dist/extractor-claude-code.test.js.map +1 -1
  3. package/dist/extractor-codex.test.d.ts +2 -0
  4. package/dist/extractor-codex.test.d.ts.map +1 -0
  5. package/dist/extractor-codex.test.js +212 -0
  6. package/dist/extractor-codex.test.js.map +1 -0
  7. package/dist/extractor-cursor.test.d.ts +2 -0
  8. package/dist/extractor-cursor.test.d.ts.map +1 -0
  9. package/dist/extractor-cursor.test.js +120 -0
  10. package/dist/extractor-cursor.test.js.map +1 -0
  11. package/dist/extractors/claude-code.d.ts.map +1 -1
  12. package/dist/extractors/claude-code.js +11 -5
  13. package/dist/extractors/claude-code.js.map +1 -1
  14. package/dist/extractors/codex.d.ts.map +1 -1
  15. package/dist/extractors/codex.js +63 -35
  16. package/dist/extractors/codex.js.map +1 -1
  17. package/dist/extractors/common.d.ts +14 -0
  18. package/dist/extractors/common.d.ts.map +1 -0
  19. package/dist/extractors/common.js +100 -0
  20. package/dist/extractors/common.js.map +1 -0
  21. package/dist/extractors/cursor.d.ts.map +1 -1
  22. package/dist/extractors/cursor.js +205 -45
  23. package/dist/extractors/cursor.js.map +1 -1
  24. package/dist/hash.d.ts.map +1 -1
  25. package/dist/hash.js +35 -2
  26. package/dist/hash.js.map +1 -1
  27. package/dist/hash.test.js +29 -2
  28. package/dist/hash.test.js.map +1 -1
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/redact.d.ts +12 -0
  34. package/dist/redact.d.ts.map +1 -1
  35. package/dist/redact.js +120 -38
  36. package/dist/redact.js.map +1 -1
  37. package/dist/redact.test.d.ts +2 -0
  38. package/dist/redact.test.d.ts.map +1 -0
  39. package/dist/redact.test.js +96 -0
  40. package/dist/redact.test.js.map +1 -0
  41. package/dist/turn-actors.d.ts +4 -0
  42. package/dist/turn-actors.d.ts.map +1 -0
  43. package/dist/turn-actors.js +57 -0
  44. package/dist/turn-actors.js.map +1 -0
  45. package/dist/turn-actors.test.d.ts +2 -0
  46. package/dist/turn-actors.test.d.ts.map +1 -0
  47. package/dist/turn-actors.test.js +65 -0
  48. package/dist/turn-actors.test.js.map +1 -0
  49. package/dist/types.d.ts +5 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/validators.d.ts +24 -0
  52. package/dist/validators.d.ts.map +1 -1
  53. package/dist/validators.js +3 -0
  54. package/dist/validators.js.map +1 -1
  55. package/package.json +5 -2
  56. package/src/extractor-claude-code.test.ts +69 -0
  57. package/src/extractor-codex.test.ts +225 -0
  58. package/src/extractor-cursor.test.ts +141 -0
  59. package/src/extractors/claude-code.ts +12 -5
  60. package/src/extractors/codex.ts +69 -38
  61. package/src/extractors/common.ts +139 -0
  62. package/src/extractors/cursor.ts +294 -52
  63. package/src/hash.test.ts +31 -2
  64. package/src/hash.ts +38 -3
  65. package/src/index.ts +1 -0
  66. package/src/redact.test.ts +100 -0
  67. package/src/redact.ts +175 -58
  68. package/src/turn-actors.test.ts +71 -0
  69. package/src/turn-actors.ts +73 -0
  70. package/src/types.ts +6 -0
  71. package/src/validators.ts +3 -0
@@ -1,5 +1,15 @@
1
1
  import { randomUUID } from "crypto";
2
2
  import { hashString, computeContentHash } from "../hash.js";
3
+ import { collectTraceMetrics, createPassiveEnvState, extractTextFragments, pushUniqueTextBlock, } from "./common.js";
4
+ function toNumber(value) {
5
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
6
+ }
7
+ function extractExitCode(output) {
8
+ if (!output)
9
+ return null;
10
+ const match = output.match(/Process exited with code (\d+)/);
11
+ return match ? Number.parseInt(match[1], 10) : null;
12
+ }
3
13
  export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
4
14
  const events = [];
5
15
  for (const line of rolloutFileBuffer.toString("utf-8").split("\n")) {
@@ -21,6 +31,10 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
21
31
  let currentBlocks = [];
22
32
  let taskTimestamp = null;
23
33
  let currentModel = null;
34
+ let currentTaskLastTimestamp = null;
35
+ let totalInputTokens = null;
36
+ let totalOutputTokens = null;
37
+ let totalCacheReadTokens = null;
24
38
  for (const event of events) {
25
39
  const type = event["type"];
26
40
  const payload = (event["payload"] ?? {});
@@ -31,6 +45,7 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
31
45
  currentUserMessage = null;
32
46
  currentBlocks = [];
33
47
  taskTimestamp = timestamp;
48
+ currentTaskLastTimestamp = timestamp;
34
49
  continue;
35
50
  }
36
51
  if (type === "event_msg" && payload["type"] === "task_complete") {
@@ -49,16 +64,14 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
49
64
  }
50
65
  const lastMsg = payload["last_agent_message"];
51
66
  if (lastMsg) {
52
- const alreadyCaptured = currentBlocks.some(b => b.type === "text" && b.text === lastMsg);
53
- if (!alreadyCaptured)
54
- currentBlocks.push({ type: "text", text: lastMsg });
67
+ pushUniqueTextBlock(currentBlocks, "text", lastMsg);
55
68
  }
56
69
  if (currentBlocks.length > 0) {
57
70
  turns.push({
58
71
  turn_id: currentTurnId ?? randomUUID(),
59
72
  parent_turn_id: currentUserMessage ? "user_" + currentTurnId : null,
60
73
  role: "assistant",
61
- timestamp: taskTimestamp,
74
+ timestamp: currentTaskLastTimestamp ?? timestamp ?? taskTimestamp,
62
75
  content: currentBlocks,
63
76
  model: currentModel,
64
77
  usage: null,
@@ -72,10 +85,13 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
72
85
  currentBlocks = [];
73
86
  taskTimestamp = null;
74
87
  currentModel = null;
88
+ currentTaskLastTimestamp = null;
75
89
  continue;
76
90
  }
77
91
  if (!inTask)
78
92
  continue;
93
+ if (timestamp)
94
+ currentTaskLastTimestamp = timestamp;
79
95
  if (type === "turn_context") {
80
96
  currentModel = payload["model"] ?? null;
81
97
  continue;
@@ -86,17 +102,43 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
86
102
  currentUserMessage = payload["message"] ?? "";
87
103
  break;
88
104
  case "agent_reasoning":
89
- if (payload["text"])
90
- currentBlocks.push({ type: "thinking", text: payload["text"] });
105
+ pushUniqueTextBlock(currentBlocks, "thinking", payload["text"]);
91
106
  break;
92
107
  case "agent_message":
93
- if (payload["message"])
94
- currentBlocks.push({ type: "text", text: payload["message"] });
108
+ pushUniqueTextBlock(currentBlocks, "text", payload["message"]);
95
109
  break;
110
+ case "token_count": {
111
+ const info = (payload["info"] ?? {});
112
+ const usage = (info["total_token_usage"] ?? {});
113
+ totalInputTokens = toNumber(usage["input_tokens"]) ?? totalInputTokens;
114
+ totalOutputTokens = toNumber(usage["output_tokens"]) ?? totalOutputTokens;
115
+ totalCacheReadTokens =
116
+ toNumber(usage["cached_input_tokens"]) ?? totalCacheReadTokens;
117
+ break;
118
+ }
96
119
  }
97
120
  }
98
121
  else if (type === "response_item") {
99
122
  switch (payload["type"]) {
123
+ case "message": {
124
+ const role = payload["role"];
125
+ const texts = extractTextFragments(payload["content"]);
126
+ if (role === "assistant") {
127
+ for (const text of texts) {
128
+ pushUniqueTextBlock(currentBlocks, "text", text);
129
+ }
130
+ }
131
+ else if (role === "user" && !currentUserMessage) {
132
+ currentUserMessage = texts.join("\n\n") || currentUserMessage;
133
+ }
134
+ break;
135
+ }
136
+ case "reasoning": {
137
+ const reasoningText = extractTextFragments(payload["content"]).join("\n\n") ||
138
+ extractTextFragments(payload["summary"]).join("\n\n");
139
+ pushUniqueTextBlock(currentBlocks, "thinking", reasoningText);
140
+ break;
141
+ }
100
142
  case "function_call": {
101
143
  const callId = payload["call_id"] ?? randomUUID();
102
144
  let toolInput = {};
@@ -116,15 +158,13 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
116
158
  }
117
159
  case "function_call_output": {
118
160
  const output = payload["output"];
119
- const isError = typeof output === "string"
120
- && output.includes("Process exited with code")
121
- && !output.includes("code 0");
161
+ const exitCode = extractExitCode(output);
122
162
  currentBlocks.push({
123
163
  type: "tool_result",
124
164
  tool_call_id: payload["call_id"] ?? "",
125
- is_error: isError,
165
+ is_error: exitCode !== null ? exitCode !== 0 : false,
126
166
  result_content: output ?? null,
127
- exit_code: null,
167
+ exit_code: exitCode,
128
168
  });
129
169
  break;
130
170
  }
@@ -141,11 +181,7 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
141
181
  }
142
182
  }
143
183
  }
144
- const allBlocks = turns.flatMap(t => t.content);
145
- const toolCallCount = allBlocks.filter(b => b.type === "tool_use").length;
146
- const hasFileChanges = allBlocks.some(b => b.type === "tool_use" && ["write_file", "file_change", "create_file"].includes(b.tool_name));
147
- const hasShellCommands = allBlocks.some(b => b.type === "tool_use" && ["exec_command", "bash", "shell"].includes(b.tool_name));
148
- const hasThinking = allBlocks.some(b => b.type === "thinking");
184
+ const metrics = collectTraceMetrics(turns);
149
185
  const startedAt = sessionMetaPayload["timestamp"] ?? events[0]?.["timestamp"] ?? new Date().toISOString();
150
186
  const endedAt = events[events.length - 1]?.["timestamp"] ?? new Date().toISOString();
151
187
  const partialTrace = {
@@ -163,24 +199,16 @@ export async function extractCodex(rolloutFileBuffer, submittedBy = "unknown") {
163
199
  ended_at: endedAt,
164
200
  turns,
165
201
  turn_count: turns.length,
166
- tool_call_count: toolCallCount,
167
- has_tool_calls: toolCallCount > 0,
168
- has_thinking_blocks: hasThinking,
169
- has_file_changes: hasFileChanges,
170
- has_shell_commands: hasShellCommands,
171
- total_input_tokens: null,
172
- total_output_tokens: null,
173
- total_cache_read_tokens: null,
202
+ tool_call_count: metrics.toolCallCount,
203
+ has_tool_calls: metrics.toolCallCount > 0,
204
+ has_thinking_blocks: metrics.hasThinkingBlocks,
205
+ has_file_changes: metrics.hasFileChanges,
206
+ has_shell_commands: metrics.hasShellCommands,
207
+ total_input_tokens: totalInputTokens,
208
+ total_output_tokens: totalOutputTokens,
209
+ total_cache_read_tokens: totalCacheReadTokens,
174
210
  content_fidelity: "full",
175
- env_state: {
176
- git_branch: null,
177
- inferred_file_tree: null,
178
- inferred_changed_files: null,
179
- inferred_error_files: null,
180
- shell_exit_codes: null,
181
- open_files_in_editor: null,
182
- extraction_method: "passive",
183
- },
211
+ env_state: createPassiveEnvState(),
184
212
  score: null,
185
213
  raw_r2_key: "",
186
214
  normalized_r2_key: "",
@@ -1 +1 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/extractors/codex.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/extractors/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ContentBlock, EnvState, Turn } from "../types.js";
2
+ export declare function isShellToolName(toolName: string): boolean;
3
+ export declare function isFileMutationTool(toolName: string, toolInput: Record<string, unknown>): boolean;
4
+ export declare function collectTraceMetrics(turns: Turn[]): {
5
+ toolCallCount: number;
6
+ hasFileChanges: boolean;
7
+ hasShellCommands: boolean;
8
+ hasThinkingBlocks: boolean;
9
+ };
10
+ export declare function createPassiveEnvState(overrides?: Partial<EnvState>): EnvState;
11
+ export declare function extractTextFragments(value: unknown): string[];
12
+ export declare function pushUniqueTextBlock(blocks: ContentBlock[], type: "text" | "thinking", text: string | null | undefined): void;
13
+ export declare function normalizeTimestamp(value: unknown): string | null;
14
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/extractors/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AA0BhE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAiBT;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE;;;;;EAehD;AAED,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,OAAO,CAAC,QAAQ,CAAM,GAChC,QAAQ,CAWV;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CA2B7D;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EAAE,EACtB,IAAI,EAAE,MAAM,GAAG,UAAU,EACzB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,IAAI,CAUN;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAShE"}
@@ -0,0 +1,100 @@
1
+ const SHELL_TOOL_NAMES = ["exec_command", "bash", "shell", "write_stdin"];
2
+ const FILE_MUTATION_TOOL_NAMES = [
3
+ "apply_patch",
4
+ "write_file",
5
+ "create_file",
6
+ "delete_file",
7
+ "rename_file",
8
+ "move_file",
9
+ "file_change",
10
+ "edit",
11
+ "edit_file",
12
+ "multiedit",
13
+ "write",
14
+ ];
15
+ function normalizeToolName(toolName) {
16
+ return toolName.trim().toLowerCase();
17
+ }
18
+ function toolNameMatches(toolName, candidate) {
19
+ const normalized = normalizeToolName(toolName);
20
+ return normalized === candidate || normalized.endsWith(`.${candidate}`);
21
+ }
22
+ export function isShellToolName(toolName) {
23
+ return SHELL_TOOL_NAMES.some((candidate) => toolNameMatches(toolName, candidate));
24
+ }
25
+ export function isFileMutationTool(toolName, toolInput) {
26
+ if (FILE_MUTATION_TOOL_NAMES.some((candidate) => toolNameMatches(toolName, candidate))) {
27
+ return true;
28
+ }
29
+ if (!isShellToolName(toolName))
30
+ return false;
31
+ const command = typeof toolInput.cmd === "string"
32
+ ? toolInput.cmd
33
+ : typeof toolInput.command === "string"
34
+ ? toolInput.command
35
+ : null;
36
+ return command !== null && /\bapply_patch\b|\bsed\s+-i\b|\bperl\s+-pi\b/.test(command);
37
+ }
38
+ export function collectTraceMetrics(turns) {
39
+ const allBlocks = turns.flatMap((turn) => turn.content);
40
+ const toolUses = allBlocks.filter((block) => block.type === "tool_use");
41
+ return {
42
+ toolCallCount: toolUses.length,
43
+ hasFileChanges: toolUses.some((block) => isFileMutationTool(block.tool_name, block.tool_input)),
44
+ hasShellCommands: toolUses.some((block) => isShellToolName(block.tool_name)),
45
+ hasThinkingBlocks: allBlocks.some((block) => block.type === "thinking"),
46
+ };
47
+ }
48
+ export function createPassiveEnvState(overrides = {}) {
49
+ return {
50
+ git_branch: null,
51
+ inferred_file_tree: null,
52
+ inferred_changed_files: null,
53
+ inferred_error_files: null,
54
+ shell_exit_codes: null,
55
+ open_files_in_editor: null,
56
+ extraction_method: "passive",
57
+ ...overrides,
58
+ };
59
+ }
60
+ export function extractTextFragments(value) {
61
+ if (typeof value === "string") {
62
+ return value.trim() ? [value] : [];
63
+ }
64
+ if (Array.isArray(value)) {
65
+ return value.flatMap((item) => extractTextFragments(item));
66
+ }
67
+ if (!value || typeof value !== "object") {
68
+ return [];
69
+ }
70
+ const record = value;
71
+ if (typeof record.text === "string" && record.text.trim()) {
72
+ return [record.text];
73
+ }
74
+ const nested = [];
75
+ for (const key of ["content", "summary", "thinking", "message"]) {
76
+ if (key in record) {
77
+ nested.push(...extractTextFragments(record[key]));
78
+ }
79
+ }
80
+ return nested;
81
+ }
82
+ export function pushUniqueTextBlock(blocks, type, text) {
83
+ const normalized = text?.trim();
84
+ if (!normalized)
85
+ return;
86
+ const exists = blocks.some((block) => block.type === type && block.text === normalized);
87
+ if (!exists) {
88
+ blocks.push({ type, text: normalized });
89
+ }
90
+ }
91
+ export function normalizeTimestamp(value) {
92
+ if (typeof value === "string" && value.trim())
93
+ return value;
94
+ if (typeof value === "number" && Number.isFinite(value)) {
95
+ const millis = value > 1_000_000_000_000 ? value : value * 1000;
96
+ return new Date(millis).toISOString();
97
+ }
98
+ return null;
99
+ }
100
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/extractors/common.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/extractors/cursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAErE,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,SAAY,GACtB,OAAO,CAAC,eAAe,CAAC,CA6G1B"}
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/extractors/cursor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,eAAe,EAAoB,MAAM,aAAa,CAAC;AAsPnF,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,SAAY,GACtB,OAAO,CAAC,eAAe,CAAC,CA2G1B"}
@@ -1,4 +1,164 @@
1
1
  import { hashString, computeContentHash } from "../hash.js";
2
+ import { collectTraceMetrics, createPassiveEnvState, extractTextFragments, normalizeTimestamp, pushUniqueTextBlock, } from "./common.js";
3
+ function toNumber(value) {
4
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
5
+ }
6
+ function hasCursorConversationPayload(blob) {
7
+ return Boolean(blob.role ||
8
+ blob.text ||
9
+ blob.content ||
10
+ blob.message ||
11
+ blob.markdown ||
12
+ blob.thinking ||
13
+ blob.usage ||
14
+ blob.tokenCount ||
15
+ blob.model ||
16
+ blob.modelName ||
17
+ blob.context?.openFiles ||
18
+ blob.openFiles ||
19
+ blob.relevantFiles ||
20
+ blob.recentlyViewedFiles ||
21
+ blob.workspaceUris ||
22
+ blob.attachedFolders ||
23
+ blob.attachedFoldersNew);
24
+ }
25
+ function readCursorBlob(db, sessionId, bubbleId) {
26
+ const keys = [
27
+ `bubbleId:${sessionId}:${bubbleId}`,
28
+ `agentKv:blob:${bubbleId}`,
29
+ ];
30
+ for (const key of keys) {
31
+ const row = db
32
+ .prepare("SELECT value FROM cursorDiskKV WHERE key = ?")
33
+ .get(key);
34
+ if (!row)
35
+ continue;
36
+ try {
37
+ const blob = JSON.parse(row.value);
38
+ if (hasCursorConversationPayload(blob))
39
+ return blob;
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ return null;
46
+ }
47
+ function cursorRole(header, blob) {
48
+ const role = blob.role?.toLowerCase();
49
+ if (role === "user" || role === "assistant")
50
+ return role;
51
+ const type = typeof blob.type === "number" ? blob.type : header.type;
52
+ return type === 1 ? "user" : "assistant";
53
+ }
54
+ function extractCursorTokenUsage(blob) {
55
+ const usage = blob.usage;
56
+ const tokenCount = blob.tokenCount;
57
+ const inputTokens = toNumber(usage?.promptTokens) ?? toNumber(tokenCount?.inputTokens);
58
+ const outputTokens = toNumber(usage?.completionTokens) ?? toNumber(tokenCount?.outputTokens);
59
+ if (inputTokens === null && outputTokens === null) {
60
+ return null;
61
+ }
62
+ return {
63
+ input_tokens: inputTokens ?? 0,
64
+ output_tokens: outputTokens ?? 0,
65
+ cache_read_input_tokens: null,
66
+ cache_creation_input_tokens: null,
67
+ reasoning_tokens: null,
68
+ };
69
+ }
70
+ function normalizeCursorPath(value) {
71
+ if (!value.startsWith("file://"))
72
+ return value;
73
+ try {
74
+ return decodeURIComponent(new URL(value).pathname);
75
+ }
76
+ catch {
77
+ return value;
78
+ }
79
+ }
80
+ function extractCursorPaths(value) {
81
+ if (typeof value === "string") {
82
+ return value ? [normalizeCursorPath(value)] : [];
83
+ }
84
+ if (Array.isArray(value)) {
85
+ return value.flatMap((item) => extractCursorPaths(item));
86
+ }
87
+ if (!value || typeof value !== "object") {
88
+ return [];
89
+ }
90
+ const record = value;
91
+ const paths = [];
92
+ for (const key of [
93
+ "path",
94
+ "uri",
95
+ "absolutePath",
96
+ "relativeWorkspacePath",
97
+ "relativePath",
98
+ "filePath",
99
+ ]) {
100
+ if (key in record) {
101
+ paths.push(...extractCursorPaths(record[key]));
102
+ }
103
+ }
104
+ return paths;
105
+ }
106
+ function collectCursorOpenFiles(blob) {
107
+ const paths = [
108
+ blob.context?.openFiles,
109
+ blob.openFiles,
110
+ blob.relevantFiles,
111
+ blob.recentlyViewedFiles,
112
+ blob.workspaceUris,
113
+ blob.attachedFolders,
114
+ blob.attachedFoldersNew,
115
+ ].flatMap((value) => extractCursorPaths(value));
116
+ return Array.from(new Set(paths.filter(Boolean)));
117
+ }
118
+ function extractCursorBlocks(blob) {
119
+ const blocks = [];
120
+ const thinkingText = extractTextFragments(blob.thinking).join("\n\n");
121
+ pushUniqueTextBlock(blocks, "thinking", thinkingText);
122
+ const messageText = [
123
+ blob.text,
124
+ blob.content,
125
+ blob.message,
126
+ blob.markdown,
127
+ ].find((value) => typeof value === "string" && value.trim().length > 0);
128
+ pushUniqueTextBlock(blocks, "text", messageText ?? null);
129
+ return blocks;
130
+ }
131
+ function mergeUsage(left, right) {
132
+ if (!left && !right)
133
+ return null;
134
+ return {
135
+ input_tokens: (left?.input_tokens ?? 0) + (right?.input_tokens ?? 0),
136
+ output_tokens: (left?.output_tokens ?? 0) + (right?.output_tokens ?? 0),
137
+ cache_read_input_tokens: null,
138
+ cache_creation_input_tokens: null,
139
+ reasoning_tokens: null,
140
+ };
141
+ }
142
+ function appendCursorTurn(turns, nextTurn) {
143
+ const previousTurn = turns[turns.length - 1];
144
+ if (!previousTurn || previousTurn.role !== nextTurn.role) {
145
+ turns.push(nextTurn);
146
+ return;
147
+ }
148
+ const previousBubbleIds = Array.isArray(previousTurn.source_metadata.bubbleIds)
149
+ ? previousTurn.source_metadata.bubbleIds
150
+ : [previousTurn.source_metadata.bubbleId].filter(Boolean);
151
+ turns[turns.length - 1] = {
152
+ ...previousTurn,
153
+ content: [...previousTurn.content, ...nextTurn.content],
154
+ usage: mergeUsage(previousTurn.usage, nextTurn.usage),
155
+ model: previousTurn.model ?? nextTurn.model,
156
+ source_metadata: {
157
+ ...previousTurn.source_metadata,
158
+ bubbleIds: [...previousBubbleIds, nextTurn.source_metadata.bubbleId].filter(Boolean),
159
+ },
160
+ };
161
+ }
2
162
  export async function extractCursor(dbPath, sessionId, submittedBy = "unknown") {
3
163
  const Database = (await import("better-sqlite3")).default;
4
164
  const db = new Database(dbPath, { readonly: true });
@@ -9,52 +169,56 @@ export async function extractCursor(dbPath, sessionId, submittedBy = "unknown")
9
169
  if (!composerRow)
10
170
  throw new Error(`Session ${sessionId} not found in cursor DB`);
11
171
  const composerData = JSON.parse(composerRow.value);
12
- const headers = composerData.fullConversationHeadersOnly ?? [];
172
+ const headers = (composerData.fullConversationHeadersOnly ?? []);
13
173
  const turns = [];
14
174
  const openFiles = [];
175
+ let totalInputTokens = 0;
176
+ let totalOutputTokens = 0;
15
177
  for (const header of headers) {
16
178
  const bubbleId = header.bubbleId ?? header.id;
17
179
  if (!bubbleId)
18
180
  continue;
19
- const blobRow = db
20
- .prepare("SELECT value FROM cursorDiskKV WHERE key = ?")
21
- .get(`agentKv:blob:${bubbleId}`);
22
- if (!blobRow)
181
+ const blob = readCursorBlob(db, sessionId, bubbleId);
182
+ if (!blob)
23
183
  continue;
24
- const blob = JSON.parse(blobRow.value);
25
- const role = blob.type === "user" || blob.role === "user" ? "user" : "assistant";
26
- const text = blob.text ?? blob.content ?? blob.message ?? "";
27
- if (blob.context?.openFiles) {
28
- openFiles.push(...blob.context.openFiles.map((f) => (typeof f === "string" ? f : f.path ?? "")));
184
+ const role = cursorRole(header, blob);
185
+ const tokenUsage = extractCursorTokenUsage(blob);
186
+ if (tokenUsage) {
187
+ totalInputTokens += tokenUsage.input_tokens;
188
+ totalOutputTokens += tokenUsage.output_tokens;
29
189
  }
30
- const tokenUsage = blob.usage
31
- ? {
32
- input_tokens: blob.usage.promptTokens ?? 0,
33
- output_tokens: blob.usage.completionTokens ?? 0,
34
- cache_read_input_tokens: null,
35
- cache_creation_input_tokens: null,
36
- reasoning_tokens: null,
37
- }
38
- : null;
39
- turns.push({
190
+ openFiles.push(...collectCursorOpenFiles(blob));
191
+ const content = extractCursorBlocks(blob);
192
+ if (content.length === 0)
193
+ continue;
194
+ appendCursorTurn(turns, {
40
195
  turn_id: bubbleId,
41
196
  parent_turn_id: null,
42
197
  role,
43
- timestamp: blob.createdAt ?? header.createdAt ?? null,
44
- content: [{ type: "text", text }],
45
- model: blob.model ?? null,
198
+ timestamp: normalizeTimestamp(blob.createdAt ?? header.createdAt),
199
+ content,
200
+ model: blob.model ?? blob.modelName ?? null,
46
201
  usage: tokenUsage,
47
- source_metadata: { bubbleId, type: blob.type },
202
+ source_metadata: { bubbleId, type: blob.type ?? header.type ?? null },
48
203
  });
49
204
  }
50
- db.close();
51
- const startedAt = turns[0]?.timestamp ?? new Date().toISOString();
52
- const endedAt = turns[turns.length - 1]?.timestamp ?? new Date().toISOString();
205
+ if (turns.length === 0) {
206
+ throw new Error(`Session ${sessionId} contained no readable conversation bubbles`);
207
+ }
208
+ const metrics = collectTraceMetrics(turns);
209
+ const startedAt = turns[0]?.timestamp ??
210
+ normalizeTimestamp(composerData.createdAt) ??
211
+ new Date().toISOString();
212
+ const endedAt = turns[turns.length - 1]?.timestamp ??
213
+ normalizeTimestamp(composerData.createdAt) ??
214
+ new Date().toISOString();
53
215
  const partialTrace = {
54
216
  schema_version: "1.0",
55
217
  source_tool: "cursor",
56
218
  source_session_id: sessionId,
57
- source_version: null,
219
+ source_version: typeof composerData._v === "number" || typeof composerData._v === "string"
220
+ ? String(composerData._v)
221
+ : null,
58
222
  submitted_by: submittedBy,
59
223
  submitted_at: new Date().toISOString(),
60
224
  extracted_at: new Date().toISOString(),
@@ -65,24 +229,18 @@ export async function extractCursor(dbPath, sessionId, submittedBy = "unknown")
65
229
  ended_at: endedAt,
66
230
  turns,
67
231
  turn_count: turns.length,
68
- tool_call_count: 0,
69
- has_tool_calls: false,
70
- has_thinking_blocks: false,
71
- has_file_changes: false,
72
- has_shell_commands: false,
73
- total_input_tokens: null,
74
- total_output_tokens: null,
232
+ tool_call_count: metrics.toolCallCount,
233
+ has_tool_calls: metrics.toolCallCount > 0,
234
+ has_thinking_blocks: metrics.hasThinkingBlocks,
235
+ has_file_changes: metrics.hasFileChanges,
236
+ has_shell_commands: metrics.hasShellCommands,
237
+ total_input_tokens: totalInputTokens || null,
238
+ total_output_tokens: totalOutputTokens || null,
75
239
  total_cache_read_tokens: null,
76
240
  content_fidelity: "chat_only",
77
- env_state: {
78
- git_branch: null,
79
- inferred_file_tree: null,
80
- inferred_changed_files: null,
81
- inferred_error_files: null,
82
- shell_exit_codes: null,
83
- open_files_in_editor: openFiles.length > 0 ? openFiles : null,
84
- extraction_method: "passive",
85
- },
241
+ env_state: createPassiveEnvState({
242
+ open_files_in_editor: openFiles.length > 0 ? Array.from(new Set(openFiles)) : null,
243
+ }),
86
244
  score: null,
87
245
  raw_r2_key: "",
88
246
  normalized_r2_key: "",
@@ -92,8 +250,10 @@ export async function extractCursor(dbPath, sessionId, submittedBy = "unknown")
92
250
  return { ...partialTrace, trace_id: traceId };
93
251
  }
94
252
  catch (err) {
95
- db.close();
96
253
  throw err;
97
254
  }
255
+ finally {
256
+ db.close();
257
+ }
98
258
  }
99
259
  //# sourceMappingURL=cursor.js.map