codesesh 0.1.0 → 0.1.3
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 +83 -0
- package/dist/{chunk-H3D3GNQK.js → chunk-BQ22Y6H4.js} +142 -37
- package/dist/chunk-BQ22Y6H4.js.map +1 -0
- package/dist/{dist-KGHAVLGF.js → dist-RRY4LURU.js} +2 -2
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/web/assets/{index-Cbmq6KvN.js → index-D12EHlVg.js} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/logo.svg +78 -29
- package/package.json +36 -5
- package/.turbo/turbo-build.log +0 -16
- package/dist/chunk-H3D3GNQK.js.map +0 -1
- package/scripts/copy-web-dist.js +0 -31
- package/src/api/__tests__/handlers.test.ts +0 -191
- package/src/api/__tests__/routes.test.ts +0 -16
- package/src/api/handlers.ts +0 -76
- package/src/api/routes.ts +0 -13
- package/src/commands/serve.ts +0 -78
- package/src/index.ts +0 -203
- package/src/output.ts +0 -47
- package/src/server.ts +0 -56
- package/tsconfig.json +0 -9
- package/tsup.config.ts +0 -16
- /package/dist/{dist-KGHAVLGF.js.map → dist-RRY4LURU.js.map} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# CodeSesh
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://codesesh.xingkaixin.me/logo.svg" alt="CodeSesh" width="120" height="120">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center"><strong>One place to see every AI coding session you've ever had.</strong></p>
|
|
8
|
+
|
|
9
|
+
CodeSesh scans your local machine, finds every AI agent session (Claude Code, Cursor, Kimi, Codex, OpenCode), and surfaces them in a unified, beautiful Web UI.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx codesesh
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Your browser will open at `http://localhost:4321` with all your sessions ready to browse.
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Unified Timeline** — Browse sessions across all your AI agents in a single, searchable interface
|
|
22
|
+
- **Full Conversation Replay** — Read every message, tool call, and reasoning step exactly as it happened
|
|
23
|
+
- **Cost & Token Visibility** — See exactly how many tokens and dollars each session consumed
|
|
24
|
+
- **Zero Configuration** — Just run it. CodeSesh auto-discovers everything on your filesystem
|
|
25
|
+
- **100% Local & Private** — Nothing leaves your machine. No accounts, no cloud sync, no telemetry
|
|
26
|
+
|
|
27
|
+
## Supported Agents
|
|
28
|
+
|
|
29
|
+
| Agent | Status |
|
|
30
|
+
| ----------- | ------------ |
|
|
31
|
+
| Claude Code | ✅ Supported |
|
|
32
|
+
| Cursor | ✅ Supported |
|
|
33
|
+
| Kimi | ✅ Supported |
|
|
34
|
+
| Codex | ✅ Supported |
|
|
35
|
+
| OpenCode | ✅ Supported |
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Start the web UI (default port 4321)
|
|
41
|
+
npx codesesh
|
|
42
|
+
|
|
43
|
+
# Choose a custom port
|
|
44
|
+
npx codesesh --port 8080
|
|
45
|
+
|
|
46
|
+
# Only show sessions from the last 3 days
|
|
47
|
+
npx codesesh --days 3
|
|
48
|
+
|
|
49
|
+
# Filter to sessions from current project
|
|
50
|
+
npx codesesh --cwd .
|
|
51
|
+
|
|
52
|
+
# Only show specific agent
|
|
53
|
+
npx codesesh --agent claudecode
|
|
54
|
+
|
|
55
|
+
# Output JSON instead of starting server
|
|
56
|
+
npx codesesh --json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## CLI Options
|
|
60
|
+
|
|
61
|
+
| Flag | Alias | Default | Description |
|
|
62
|
+
| ----------- | ----- | ------- | ----------------------------------------------------------- |
|
|
63
|
+
| `--port` | `-p` | `4321` | HTTP server port |
|
|
64
|
+
| `--days` | `-d` | `7` | Only include sessions from the last N days (`0` = all time) |
|
|
65
|
+
| `--cwd` | — | — | Filter to sessions from a project directory |
|
|
66
|
+
| `--agent` | `-a` | all | Filter to specific agent(s), comma-separated |
|
|
67
|
+
| `--from` | — | — | Sessions created after this date `YYYY-MM-DD` |
|
|
68
|
+
| `--to` | — | — | Sessions created before this date `YYYY-MM-DD` |
|
|
69
|
+
| `--json` | `-j` | `false` | Output JSON and exit (no server) |
|
|
70
|
+
| `--no-open` | — | `false` | Don't auto-open the browser |
|
|
71
|
+
|
|
72
|
+
## Requirements
|
|
73
|
+
|
|
74
|
+
- Node.js 18+
|
|
75
|
+
|
|
76
|
+
## Links
|
|
77
|
+
|
|
78
|
+
- [GitHub](https://github.com/xingkaixin/codesesh)
|
|
79
|
+
- [Issues](https://github.com/xingkaixin/codesesh/issues)
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
MIT
|
|
@@ -494,6 +494,8 @@ var ClaudeCodeAgent = class extends BaseAgent {
|
|
|
494
494
|
let messageCount = 0;
|
|
495
495
|
let model = null;
|
|
496
496
|
let cwd = null;
|
|
497
|
+
let totalInputTokens = 0;
|
|
498
|
+
let totalOutputTokens = 0;
|
|
497
499
|
for (const line of lines) {
|
|
498
500
|
try {
|
|
499
501
|
const data = JSON.parse(line);
|
|
@@ -512,6 +514,13 @@ var ClaudeCodeAgent = class extends BaseAgent {
|
|
|
512
514
|
const m = msg["model"];
|
|
513
515
|
if (typeof m === "string" && m.trim()) model = m.trim();
|
|
514
516
|
}
|
|
517
|
+
if (role === "assistant") {
|
|
518
|
+
const usage = msg["usage"];
|
|
519
|
+
if (usage && typeof usage === "object") {
|
|
520
|
+
totalInputTokens += (usage["input_tokens"] ?? 0) + (usage["cache_creation_input_tokens"] ?? 0) + (usage["cache_read_input_tokens"] ?? 0);
|
|
521
|
+
totalOutputTokens += usage["output_tokens"] ?? 0;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
515
524
|
}
|
|
516
525
|
} catch {
|
|
517
526
|
}
|
|
@@ -529,8 +538,8 @@ var ClaudeCodeAgent = class extends BaseAgent {
|
|
|
529
538
|
time_updated: updatedAt,
|
|
530
539
|
stats: {
|
|
531
540
|
message_count: messageCount,
|
|
532
|
-
total_input_tokens:
|
|
533
|
-
total_output_tokens:
|
|
541
|
+
total_input_tokens: totalInputTokens,
|
|
542
|
+
total_output_tokens: totalOutputTokens,
|
|
534
543
|
total_cost: 0
|
|
535
544
|
}
|
|
536
545
|
};
|
|
@@ -1447,6 +1456,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1447
1456
|
const pendingToolCalls = /* @__PURE__ */ new Map();
|
|
1448
1457
|
const ignoredToolCallIds = /* @__PURE__ */ new Set();
|
|
1449
1458
|
let seq = 0;
|
|
1459
|
+
const fallbackTs = meta.createdAt;
|
|
1450
1460
|
for (const record of parseJsonlLines(content)) {
|
|
1451
1461
|
seq++;
|
|
1452
1462
|
try {
|
|
@@ -1459,8 +1469,8 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1459
1469
|
this.buildMessage({
|
|
1460
1470
|
messageId: `context-${seq}`,
|
|
1461
1471
|
role: "user",
|
|
1462
|
-
timestampMs:
|
|
1463
|
-
parts: [{ type: "text", text, time_created:
|
|
1472
|
+
timestampMs: fallbackTs,
|
|
1473
|
+
parts: [{ type: "text", text, time_created: fallbackTs }]
|
|
1464
1474
|
})
|
|
1465
1475
|
);
|
|
1466
1476
|
}
|
|
@@ -1470,7 +1480,8 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1470
1480
|
const { message, toolIndexes } = this.buildContextAssistantMessage(
|
|
1471
1481
|
record,
|
|
1472
1482
|
seq,
|
|
1473
|
-
ignoredToolCallIds
|
|
1483
|
+
ignoredToolCallIds,
|
|
1484
|
+
fallbackTs
|
|
1474
1485
|
);
|
|
1475
1486
|
if (!message) continue;
|
|
1476
1487
|
const msgIndex = messages.length;
|
|
@@ -1483,7 +1494,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1483
1494
|
if (role === "tool") {
|
|
1484
1495
|
const callId = String(record.tool_call_id ?? "").trim();
|
|
1485
1496
|
if (callId && ignoredToolCallIds.has(callId)) continue;
|
|
1486
|
-
const outputParts = normalizeToolOutputParts(record.content,
|
|
1497
|
+
const outputParts = normalizeToolOutputParts(record.content, fallbackTs);
|
|
1487
1498
|
if (callId && this.backfillToolOutput(messages, pendingToolCalls, callId, outputParts)) {
|
|
1488
1499
|
continue;
|
|
1489
1500
|
}
|
|
@@ -1492,7 +1503,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1492
1503
|
this.buildMessage({
|
|
1493
1504
|
messageId: `context-${seq}`,
|
|
1494
1505
|
role: "tool",
|
|
1495
|
-
timestampMs:
|
|
1506
|
+
timestampMs: fallbackTs,
|
|
1496
1507
|
parts: outputParts
|
|
1497
1508
|
})
|
|
1498
1509
|
);
|
|
@@ -1523,6 +1534,20 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1523
1534
|
const payload = message.payload ?? {};
|
|
1524
1535
|
const timestamp = Number(record.timestamp ?? 0);
|
|
1525
1536
|
const timestampMs = Number.isFinite(timestamp) ? Math.floor(timestamp * 1e3) : 0;
|
|
1537
|
+
const usage = message["usage"];
|
|
1538
|
+
if (usage && typeof usage === "object") {
|
|
1539
|
+
const inputTokens = Number(usage["input_tokens"] ?? 0);
|
|
1540
|
+
const outputTokens = Number(usage["output_tokens"] ?? 0);
|
|
1541
|
+
if (inputTokens || outputTokens) {
|
|
1542
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1543
|
+
const msg = messages[i];
|
|
1544
|
+
if (msg.role === "assistant" && !msg.tokens) {
|
|
1545
|
+
msg.tokens = { input: inputTokens, output: outputTokens };
|
|
1546
|
+
break;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1526
1551
|
if (msgType === "TurnBegin") {
|
|
1527
1552
|
const userInput = payload.user_input;
|
|
1528
1553
|
if (Array.isArray(userInput) && userInput.length > 0) {
|
|
@@ -1653,7 +1678,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1653
1678
|
parts: opts.parts
|
|
1654
1679
|
};
|
|
1655
1680
|
}
|
|
1656
|
-
buildContextAssistantMessage(record, seq, ignoredToolCallIds) {
|
|
1681
|
+
buildContextAssistantMessage(record, seq, ignoredToolCallIds, fallbackTs) {
|
|
1657
1682
|
const parts = [];
|
|
1658
1683
|
const toolIndexes = /* @__PURE__ */ new Map();
|
|
1659
1684
|
const content = record.content;
|
|
@@ -1664,10 +1689,10 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1664
1689
|
const partType = String(ci.type ?? "");
|
|
1665
1690
|
if (partType === "think") {
|
|
1666
1691
|
const text = String(ci.think ?? "");
|
|
1667
|
-
if (text.trim()) parts.push({ type: "reasoning", text, time_created:
|
|
1692
|
+
if (text.trim()) parts.push({ type: "reasoning", text, time_created: fallbackTs });
|
|
1668
1693
|
} else if (partType === "text") {
|
|
1669
1694
|
const text = String(ci.text ?? "");
|
|
1670
|
-
if (text.trim()) parts.push({ type: "text", text, time_created:
|
|
1695
|
+
if (text.trim()) parts.push({ type: "text", text, time_created: fallbackTs });
|
|
1671
1696
|
}
|
|
1672
1697
|
}
|
|
1673
1698
|
}
|
|
@@ -1691,7 +1716,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1691
1716
|
callID: callId,
|
|
1692
1717
|
title: mapToolTitle(toolName),
|
|
1693
1718
|
state: { arguments: normalizeToolArguments(function_.arguments), output: null },
|
|
1694
|
-
time_created:
|
|
1719
|
+
time_created: fallbackTs
|
|
1695
1720
|
};
|
|
1696
1721
|
toolIndexes.set(callId, parts.length);
|
|
1697
1722
|
parts.push(part);
|
|
@@ -1702,7 +1727,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1702
1727
|
message: this.buildMessage({
|
|
1703
1728
|
messageId: `context-${seq}`,
|
|
1704
1729
|
role: "assistant",
|
|
1705
|
-
timestampMs:
|
|
1730
|
+
timestampMs: fallbackTs,
|
|
1706
1731
|
parts: []
|
|
1707
1732
|
}),
|
|
1708
1733
|
toolIndexes
|
|
@@ -1712,7 +1737,7 @@ var KimiAgent = class extends BaseAgent {
|
|
|
1712
1737
|
const message = this.buildMessage({
|
|
1713
1738
|
messageId: `context-${seq}`,
|
|
1714
1739
|
role: "assistant",
|
|
1715
|
-
timestampMs:
|
|
1740
|
+
timestampMs: fallbackTs,
|
|
1716
1741
|
parts,
|
|
1717
1742
|
agent: "kimi",
|
|
1718
1743
|
mode: allTools ? "tool" : void 0
|
|
@@ -2119,6 +2144,11 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2119
2144
|
let currentAssistantIndex = null;
|
|
2120
2145
|
let latestAssistantTextIndex = null;
|
|
2121
2146
|
let pendingPlan = null;
|
|
2147
|
+
let prevCumulativeTotal = 0;
|
|
2148
|
+
let prevInput = 0;
|
|
2149
|
+
let prevCached = 0;
|
|
2150
|
+
let prevOutput = 0;
|
|
2151
|
+
let prevReasoning = 0;
|
|
2122
2152
|
for (const record of parseJsonlLines(content)) {
|
|
2123
2153
|
try {
|
|
2124
2154
|
const result = this.convertRecord(
|
|
@@ -2133,10 +2163,54 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2133
2163
|
currentAssistantIndex = result.currentAssistantIndex;
|
|
2134
2164
|
latestAssistantTextIndex = result.latestAssistantTextIndex;
|
|
2135
2165
|
pendingPlan = result.pendingPlan;
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2166
|
+
const recordType = String(record["type"] ?? "");
|
|
2167
|
+
if (recordType === "event_msg") {
|
|
2168
|
+
const payload = record["payload"] ?? {};
|
|
2169
|
+
if (String(payload["type"] ?? "") === "token_count") {
|
|
2170
|
+
const info = payload["info"];
|
|
2171
|
+
const totalUsage = info?.["total_token_usage"];
|
|
2172
|
+
const cumulativeTotal = Number(totalUsage?.["total_tokens"] ?? 0);
|
|
2173
|
+
if (cumulativeTotal > 0 && cumulativeTotal === prevCumulativeTotal) {
|
|
2174
|
+
} else {
|
|
2175
|
+
prevCumulativeTotal = cumulativeTotal;
|
|
2176
|
+
const lastUsage = info?.["last_token_usage"];
|
|
2177
|
+
let inputTokens = 0;
|
|
2178
|
+
let cachedInputTokens = 0;
|
|
2179
|
+
let outputTokens = 0;
|
|
2180
|
+
let reasoningTokens = 0;
|
|
2181
|
+
if (lastUsage) {
|
|
2182
|
+
inputTokens = Number(lastUsage["input_tokens"] ?? 0);
|
|
2183
|
+
cachedInputTokens = Number(lastUsage["cached_input_tokens"] ?? 0);
|
|
2184
|
+
outputTokens = Number(lastUsage["output_tokens"] ?? 0);
|
|
2185
|
+
reasoningTokens = Number(lastUsage["reasoning_output_tokens"] ?? 0);
|
|
2186
|
+
} else if (cumulativeTotal > 0 && totalUsage) {
|
|
2187
|
+
inputTokens = Number(totalUsage["input_tokens"] ?? 0) - prevInput;
|
|
2188
|
+
cachedInputTokens = Number(totalUsage["cached_input_tokens"] ?? 0) - prevCached;
|
|
2189
|
+
outputTokens = Number(totalUsage["output_tokens"] ?? 0) - prevOutput;
|
|
2190
|
+
reasoningTokens = Number(totalUsage["reasoning_output_tokens"] ?? 0) - prevReasoning;
|
|
2191
|
+
prevInput = Number(totalUsage["input_tokens"] ?? 0);
|
|
2192
|
+
prevCached = Number(totalUsage["cached_input_tokens"] ?? 0);
|
|
2193
|
+
prevOutput = Number(totalUsage["output_tokens"] ?? 0);
|
|
2194
|
+
prevReasoning = Number(totalUsage["reasoning_output_tokens"] ?? 0);
|
|
2195
|
+
}
|
|
2196
|
+
const uncachedInput = Math.max(0, inputTokens - cachedInputTokens);
|
|
2197
|
+
if (uncachedInput || outputTokens || reasoningTokens) {
|
|
2198
|
+
totalInputTokens += uncachedInput;
|
|
2199
|
+
totalOutputTokens += outputTokens + reasoningTokens;
|
|
2200
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2201
|
+
const msg = messages[i];
|
|
2202
|
+
if (msg.role === "assistant" && !msg.tokens) {
|
|
2203
|
+
msg.tokens = {
|
|
2204
|
+
input: uncachedInput,
|
|
2205
|
+
output: outputTokens + reasoningTokens
|
|
2206
|
+
};
|
|
2207
|
+
break;
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2140
2214
|
} catch {
|
|
2141
2215
|
}
|
|
2142
2216
|
}
|
|
@@ -2226,6 +2300,13 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2226
2300
|
let updatedAt = createdAt;
|
|
2227
2301
|
let messageCount = 0;
|
|
2228
2302
|
let model = null;
|
|
2303
|
+
let totalInputTokens = 0;
|
|
2304
|
+
let totalOutputTokens = 0;
|
|
2305
|
+
let scanPrevCumulativeTotal = 0;
|
|
2306
|
+
let scanPrevInput = 0;
|
|
2307
|
+
let scanPrevCached = 0;
|
|
2308
|
+
let scanPrevOutput = 0;
|
|
2309
|
+
let scanPrevReasoning = 0;
|
|
2229
2310
|
const COUNTED_TYPES = /* @__PURE__ */ new Set(["message", "function_call", "function_call_output"]);
|
|
2230
2311
|
for (const line of lines) {
|
|
2231
2312
|
try {
|
|
@@ -2249,6 +2330,40 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2249
2330
|
if (typeof m === "string" && m.trim()) model = m.trim();
|
|
2250
2331
|
}
|
|
2251
2332
|
}
|
|
2333
|
+
if (recordType === "event_msg") {
|
|
2334
|
+
const p = data["payload"] ?? {};
|
|
2335
|
+
if (String(p["type"] ?? "") === "token_count") {
|
|
2336
|
+
const info = p["info"];
|
|
2337
|
+
const totalUsage = info?.["total_token_usage"];
|
|
2338
|
+
const cumulativeTotal = Number(totalUsage?.["total_tokens"] ?? 0);
|
|
2339
|
+
if (cumulativeTotal > 0 && cumulativeTotal !== scanPrevCumulativeTotal) {
|
|
2340
|
+
scanPrevCumulativeTotal = cumulativeTotal;
|
|
2341
|
+
const lastUsage = info?.["last_token_usage"];
|
|
2342
|
+
let inputTokens = 0;
|
|
2343
|
+
let cachedInputTokens = 0;
|
|
2344
|
+
let outputTokens = 0;
|
|
2345
|
+
let reasoningTokens = 0;
|
|
2346
|
+
if (lastUsage) {
|
|
2347
|
+
inputTokens = Number(lastUsage["input_tokens"] ?? 0);
|
|
2348
|
+
cachedInputTokens = Number(lastUsage["cached_input_tokens"] ?? 0);
|
|
2349
|
+
outputTokens = Number(lastUsage["output_tokens"] ?? 0);
|
|
2350
|
+
reasoningTokens = Number(lastUsage["reasoning_output_tokens"] ?? 0);
|
|
2351
|
+
} else if (cumulativeTotal > 0 && totalUsage) {
|
|
2352
|
+
inputTokens = Number(totalUsage["input_tokens"] ?? 0) - scanPrevInput;
|
|
2353
|
+
cachedInputTokens = Number(totalUsage["cached_input_tokens"] ?? 0) - scanPrevCached;
|
|
2354
|
+
outputTokens = Number(totalUsage["output_tokens"] ?? 0) - scanPrevOutput;
|
|
2355
|
+
reasoningTokens = Number(totalUsage["reasoning_output_tokens"] ?? 0) - scanPrevReasoning;
|
|
2356
|
+
scanPrevInput = Number(totalUsage["input_tokens"] ?? 0);
|
|
2357
|
+
scanPrevCached = Number(totalUsage["cached_input_tokens"] ?? 0);
|
|
2358
|
+
scanPrevOutput = Number(totalUsage["output_tokens"] ?? 0);
|
|
2359
|
+
scanPrevReasoning = Number(totalUsage["reasoning_output_tokens"] ?? 0);
|
|
2360
|
+
}
|
|
2361
|
+
const uncachedInput = Math.max(0, inputTokens - cachedInputTokens);
|
|
2362
|
+
totalInputTokens += uncachedInput;
|
|
2363
|
+
totalOutputTokens += outputTokens + reasoningTokens;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2252
2367
|
} catch {
|
|
2253
2368
|
}
|
|
2254
2369
|
}
|
|
@@ -2262,8 +2377,8 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2262
2377
|
time_updated: updatedAt,
|
|
2263
2378
|
stats: {
|
|
2264
2379
|
message_count: messageCount,
|
|
2265
|
-
total_input_tokens:
|
|
2266
|
-
total_output_tokens:
|
|
2380
|
+
total_input_tokens: totalInputTokens,
|
|
2381
|
+
total_output_tokens: totalOutputTokens,
|
|
2267
2382
|
total_cost: 0
|
|
2268
2383
|
}
|
|
2269
2384
|
};
|
|
@@ -2294,21 +2409,6 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2294
2409
|
}
|
|
2295
2410
|
return null;
|
|
2296
2411
|
}
|
|
2297
|
-
// ---- Token usage extraction ----
|
|
2298
|
-
extractTokenUsage(record, accumulate) {
|
|
2299
|
-
const recordType = String(record["type"] ?? "");
|
|
2300
|
-
if (recordType !== "response_item") return;
|
|
2301
|
-
const payload = record["payload"] ?? {};
|
|
2302
|
-
const info = payload["info"];
|
|
2303
|
-
if (!info) return;
|
|
2304
|
-
const totalUsage = info["total_token_usage"];
|
|
2305
|
-
if (!totalUsage) return;
|
|
2306
|
-
const inputTokens = Number(totalUsage["input_tokens"] ?? 0);
|
|
2307
|
-
const outputTokens = Number(totalUsage["output_tokens"] ?? 0);
|
|
2308
|
-
if (inputTokens || outputTokens) {
|
|
2309
|
-
accumulate(inputTokens, outputTokens);
|
|
2310
|
-
}
|
|
2311
|
-
}
|
|
2312
2412
|
// ---- Record conversion ----
|
|
2313
2413
|
convertRecord(data, messages, pendingToolCalls, sessionId, currentAssistantIndex, latestAssistantTextIndex, pendingPlan) {
|
|
2314
2414
|
const recordType = String(data["type"] ?? "");
|
|
@@ -2320,7 +2420,7 @@ var CodexAgent = class extends BaseAgent {
|
|
|
2320
2420
|
}
|
|
2321
2421
|
const payload = data["payload"] ?? {};
|
|
2322
2422
|
const payloadType = String(payload["type"] ?? "");
|
|
2323
|
-
const timestampMs = parseTimestampMs2(payload);
|
|
2423
|
+
const timestampMs = parseTimestampMs2(data) || parseTimestampMs2(payload);
|
|
2324
2424
|
switch (payloadType) {
|
|
2325
2425
|
case "message": {
|
|
2326
2426
|
const role = String(payload["role"] ?? "");
|
|
@@ -2902,7 +3002,12 @@ var CursorAgent = class extends BaseAgent {
|
|
|
2902
3002
|
const title = this.extractTitle(composer);
|
|
2903
3003
|
const createdAt = composer.createdAt ?? 0;
|
|
2904
3004
|
const updatedAt = composer.updatedAt ?? createdAt;
|
|
2905
|
-
const
|
|
3005
|
+
const messages = this.loadMessagesFromBubbles(db, composerId, sessionId);
|
|
3006
|
+
const hasSubagents = Array.isArray(composer.subagentInfos) && composer.subagentInfos.length > 0;
|
|
3007
|
+
if (messages.length === 0 && !hasSubagents) {
|
|
3008
|
+
continue;
|
|
3009
|
+
}
|
|
3010
|
+
const messageCount = messages.length;
|
|
2906
3011
|
const directory = workspacePathMap.get(composerId) ?? "";
|
|
2907
3012
|
heads.push({
|
|
2908
3013
|
id: sessionId,
|
|
@@ -3571,4 +3676,4 @@ export {
|
|
|
3571
3676
|
scanSessions,
|
|
3572
3677
|
scanSessionsAsync
|
|
3573
3678
|
};
|
|
3574
|
-
//# sourceMappingURL=chunk-
|
|
3679
|
+
//# sourceMappingURL=chunk-BQ22Y6H4.js.map
|