claude-session-dashboard 0.3.1 → 0.4.1
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/dist/client/assets/{_dashboard-C-1YOzkf.js → _dashboard-t702m22X.js} +1 -1
- package/dist/client/assets/_sessionId-D4Tpmmb5.js +12 -0
- package/dist/client/assets/app-DREGBD44.css +1 -0
- package/dist/client/assets/{createServerFn-B5mibSc4.js → createServerFn-BYTDoNe-.js} +1 -1
- package/dist/client/assets/{index-C83jHUdL.js → index-DnK_zh3s.js} +1 -1
- package/dist/client/assets/main-CV28H4XG.js +56 -0
- package/dist/client/assets/{sessions.queries-C-HTNzuR.js → sessions.queries-tzrs5GhP.js} +1 -1
- package/dist/client/assets/{settings-D56cUmNH.js → settings-D8yv1q93.js} +1 -1
- package/dist/client/assets/{settings.types-l5MKKuAK.js → settings.types-CMYAW0cQ.js} +1 -1
- package/dist/client/assets/stats-C_6E4jyb.js +4 -0
- package/dist/client/assets/useSessionCost-BBu3AmcX.js +37 -0
- package/dist/server/assets/{_sessionId-BvDwvNyA.js → _sessionId-DyFxvcBN.js} +2 -2
- package/dist/server/assets/{_tanstack-start-manifest_v-CVdzOaof.js → _tanstack-start-manifest_v-JNF_5-F_.js} +1 -1
- package/dist/server/assets/{claude-path-B2oho3NT.js → claude-path-BdwflgZ1.js} +2 -2
- package/dist/server/assets/{index-Biupny11.js → index-Bx7vBs4O.js} +1 -1
- package/dist/server/assets/{project-analytics.server-t1bM6wAa.js → project-analytics.server-aftsdOgf.js} +3 -3
- package/dist/server/assets/{router-kB-tCwY9.js → router-Cd4jLk4T.js} +5 -5
- package/dist/server/assets/{session-detail.server-IUw67jz-.js → session-detail.server-4Cp5Zyo1.js} +2 -2
- package/dist/server/assets/{session-parser-CIucKYBT.js → session-parser-Bq8g2LOP.js} +89 -15
- package/dist/server/assets/{session-scanner-1h9TTTAV.js → session-scanner-BzGf0Bqs.js} +2 -2
- package/dist/server/assets/{sessions.server-Cpffr3MU.js → sessions.server-XaGOdz4f.js} +3 -3
- package/dist/server/assets/{settings-jxAA3KAS.js → settings-KKaz1ty7.js} +1 -1
- package/dist/server/assets/{stats-CzGBAoxT.js → stats-Bsrkajci.js} +1 -1
- package/dist/server/assets/{stats.server-DXJiLqey.js → stats.server-qTOvID9-.js} +1 -1
- package/dist/server/server.js +23 -18
- package/package.json +5 -5
- package/dist/client/assets/_sessionId-C4jQeEqE.js +0 -12
- package/dist/client/assets/app-DNBe9Acr.css +0 -1
- package/dist/client/assets/main-CkUc_xJ0.js +0 -18
- package/dist/client/assets/stats-BunIdzj_.js +0 -4
- package/dist/client/assets/useSessionCost-BDldLkTA.js +0 -65
|
@@ -10,7 +10,7 @@ import { ResponsiveContainer, AreaChart, YAxis, Tooltip, ReferenceLine, Area } f
|
|
|
10
10
|
import { s as settingsQuery } from "./settings.queries-DSQd324O.js";
|
|
11
11
|
import { g as getMergedPricing, c as calculateSessionCost, u as useSessionCost, E as ExportDropdown, d as downloadFile, e as sessionToJSON } from "./useSessionCost-CYs5UOX-.js";
|
|
12
12
|
import { a as activeSessionsQuery } from "./sessions.queries-B5ZBiVJy.js";
|
|
13
|
-
import { b as Route, u as usePrivacy } from "./router-
|
|
13
|
+
import { b as Route, u as usePrivacy } from "./router-Cd4jLk4T.js";
|
|
14
14
|
import "@tanstack/history";
|
|
15
15
|
import "@tanstack/router-core/ssr/client";
|
|
16
16
|
import "@tanstack/router-core";
|
|
@@ -1226,7 +1226,7 @@ function ErrorPanel({ errors }) {
|
|
|
1226
1226
|
}
|
|
1227
1227
|
function computeAgentTokens(agent) {
|
|
1228
1228
|
if (!agent.tokens) return void 0;
|
|
1229
|
-
return agent.tokens.inputTokens + agent.tokens.outputTokens;
|
|
1229
|
+
return agent.tokens.inputTokens + agent.tokens.outputTokens + agent.tokens.cacheReadInputTokens + agent.tokens.cacheCreationInputTokens;
|
|
1230
1230
|
}
|
|
1231
1231
|
function AgentDispatchesPanel({
|
|
1232
1232
|
agents
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/__root.tsx", "children": ["/", "/_dashboard"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/__root.tsx", "children": ["/", "/_dashboard"], "preloads": ["/assets/main-CV28H4XG.js"], "assets": [] }, "/": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/index.tsx" }, "/_dashboard": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/_dashboard.tsx", "children": ["/_dashboard/settings", "/_dashboard/stats", "/_dashboard/sessions/$sessionId", "/_dashboard/sessions/"], "assets": [], "preloads": ["/assets/_dashboard-t702m22X.js", "/assets/createServerFn-BYTDoNe-.js", "/assets/sessions.queries-tzrs5GhP.js"] }, "/_dashboard/settings": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/_dashboard/settings.tsx", "assets": [], "preloads": ["/assets/settings-D8yv1q93.js", "/assets/settings.types-CMYAW0cQ.js"] }, "/_dashboard/stats": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/_dashboard/stats.tsx", "assets": [], "preloads": ["/assets/stats-C_6E4jyb.js", "/assets/format-Bsprb3az.js", "/assets/useSessionCost-BBu3AmcX.js", "/assets/settings.types-CMYAW0cQ.js"] }, "/_dashboard/sessions/$sessionId": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/_dashboard/sessions/$sessionId.tsx", "assets": [], "preloads": ["/assets/_sessionId-D4Tpmmb5.js", "/assets/format-Bsprb3az.js", "/assets/useSessionCost-BBu3AmcX.js", "/assets/settings.types-CMYAW0cQ.js"] }, "/_dashboard/sessions/": { "filePath": "/home/runner/work/claude-session-dashboard/claude-session-dashboard/apps/web/src/routes/_dashboard/sessions/index.tsx", "assets": [], "preloads": ["/assets/index-DnK_zh3s.js", "/assets/format-Bsprb3az.js"] } }, "clientEntry": "/assets/main-CV28H4XG.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
|
@@ -23,9 +23,9 @@ function extractSessionId(filename) {
|
|
|
23
23
|
return filename.replace(/\.jsonl$/, "");
|
|
24
24
|
}
|
|
25
25
|
export {
|
|
26
|
-
|
|
26
|
+
getProjectsDir as a,
|
|
27
27
|
extractSessionId as b,
|
|
28
28
|
decodeProjectDirName as d,
|
|
29
29
|
extractProjectName as e,
|
|
30
|
-
|
|
30
|
+
getStatsPath as g
|
|
31
31
|
};
|
|
@@ -4,7 +4,7 @@ import { useQuery } from "@tanstack/react-query";
|
|
|
4
4
|
import { Link, useNavigate } from "@tanstack/react-router";
|
|
5
5
|
import { p as paginatedSessionListQuery, a as activeSessionsQuery } from "./sessions.queries-B5ZBiVJy.js";
|
|
6
6
|
import { a as formatDuration, b as formatRelativeTime, d as formatBytes } from "./format-DIZHV7IJ.js";
|
|
7
|
-
import { u as usePrivacy, a as Route } from "./router-
|
|
7
|
+
import { u as usePrivacy, a as Route } from "./router-Cd4jLk4T.js";
|
|
8
8
|
import "./createSsrRpc-CVg2UDl0.js";
|
|
9
9
|
import "../server.js";
|
|
10
10
|
import "@tanstack/history";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { c as createServerRpc } from "./createServerRpc-Bd3B-Ah9.js";
|
|
2
|
-
import { s as scanAllSessions } from "./session-scanner-
|
|
2
|
+
import { s as scanAllSessions } from "./session-scanner-BzGf0Bqs.js";
|
|
3
3
|
import { c as createServerFn } from "../server.js";
|
|
4
4
|
import "node:fs";
|
|
5
5
|
import "node:path";
|
|
6
|
-
import "./claude-path-
|
|
6
|
+
import "./claude-path-BdwflgZ1.js";
|
|
7
7
|
import "node:os";
|
|
8
|
-
import "./session-parser-
|
|
8
|
+
import "./session-parser-Bq8g2LOP.js";
|
|
9
9
|
import "node:readline";
|
|
10
10
|
import "@tanstack/history";
|
|
11
11
|
import "@tanstack/router-core/ssr/client";
|
|
@@ -96,7 +96,7 @@ function usePrivacy() {
|
|
|
96
96
|
}
|
|
97
97
|
return ctx;
|
|
98
98
|
}
|
|
99
|
-
const appCss = "/assets/app-
|
|
99
|
+
const appCss = "/assets/app-DREGBD44.css";
|
|
100
100
|
const queryClient = new QueryClient({
|
|
101
101
|
defaultOptions: {
|
|
102
102
|
queries: {
|
|
@@ -145,7 +145,7 @@ const Route$4 = createFileRoute("/")({
|
|
|
145
145
|
throw redirect({ to: "/sessions" });
|
|
146
146
|
}
|
|
147
147
|
});
|
|
148
|
-
const $$splitComponentImporter$3 = () => import("./stats-
|
|
148
|
+
const $$splitComponentImporter$3 = () => import("./stats-Bsrkajci.js");
|
|
149
149
|
const statsSearchSchema = z.object({
|
|
150
150
|
tab: z.enum(["overview", "projects"]).default("overview").catch("overview")
|
|
151
151
|
});
|
|
@@ -153,11 +153,11 @@ const Route$3 = createFileRoute("/_dashboard/stats")({
|
|
|
153
153
|
validateSearch: statsSearchSchema,
|
|
154
154
|
component: lazyRouteComponent($$splitComponentImporter$3, "component")
|
|
155
155
|
});
|
|
156
|
-
const $$splitComponentImporter$2 = () => import("./settings-
|
|
156
|
+
const $$splitComponentImporter$2 = () => import("./settings-KKaz1ty7.js");
|
|
157
157
|
const Route$2 = createFileRoute("/_dashboard/settings")({
|
|
158
158
|
component: lazyRouteComponent($$splitComponentImporter$2, "component")
|
|
159
159
|
});
|
|
160
|
-
const $$splitComponentImporter$1 = () => import("./index-
|
|
160
|
+
const $$splitComponentImporter$1 = () => import("./index-Bx7vBs4O.js");
|
|
161
161
|
const sessionsSearchSchema = z.object({
|
|
162
162
|
page: z.number().int().min(1).default(1).catch(1),
|
|
163
163
|
pageSize: z.number().int().min(5).max(100).default(5).catch(5),
|
|
@@ -169,7 +169,7 @@ const Route$1 = createFileRoute("/_dashboard/sessions/")({
|
|
|
169
169
|
validateSearch: sessionsSearchSchema,
|
|
170
170
|
component: lazyRouteComponent($$splitComponentImporter$1, "component")
|
|
171
171
|
});
|
|
172
|
-
const $$splitComponentImporter = () => import("./_sessionId-
|
|
172
|
+
const $$splitComponentImporter = () => import("./_sessionId-DyFxvcBN.js");
|
|
173
173
|
const searchSchema = z.object({
|
|
174
174
|
project: z.string().optional()
|
|
175
175
|
});
|
package/dist/server/assets/{session-detail.server-IUw67jz-.js → session-detail.server-4Cp5Zyo1.js}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { c as createServerRpc } from "./createServerRpc-Bd3B-Ah9.js";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
|
-
import { e as extractProjectName,
|
|
5
|
-
import { p as parseDetail } from "./session-parser-
|
|
4
|
+
import { e as extractProjectName, a as getProjectsDir, d as decodeProjectDirName } from "./claude-path-BdwflgZ1.js";
|
|
5
|
+
import { p as parseDetail } from "./session-parser-Bq8g2LOP.js";
|
|
6
6
|
import { c as createServerFn } from "../server.js";
|
|
7
7
|
import "node:os";
|
|
8
8
|
import "node:readline";
|
|
@@ -274,6 +274,12 @@ async function parseDetail(filePath, sessionId, projectPath, projectName) {
|
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
|
+
if (resultText && toolUseId) {
|
|
278
|
+
const agentIdMatch = resultText.match(/agentId:\s*(\w+)/);
|
|
279
|
+
if (agentIdMatch) {
|
|
280
|
+
agentIdByToolUseId.set(String(toolUseId), agentIdMatch[1]);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
277
283
|
if (msg.toolUseResult && toolUseId) {
|
|
278
284
|
const agent = agentByToolUseId.get(String(toolUseId));
|
|
279
285
|
if (agent) {
|
|
@@ -281,6 +287,12 @@ async function parseDetail(filePath, sessionId, projectPath, projectName) {
|
|
|
281
287
|
if (result.totalTokens) agent.totalTokens = result.totalTokens;
|
|
282
288
|
if (result.totalToolUseCount) agent.totalToolUseCount = result.totalToolUseCount;
|
|
283
289
|
if (result.totalDurationMs) agent.durationMs = result.totalDurationMs;
|
|
290
|
+
if (result.isAsync === true && result.agentId) {
|
|
291
|
+
agentIdByToolUseId.set(String(toolUseId), result.agentId);
|
|
292
|
+
}
|
|
293
|
+
if (result.retrieval_status && result.task?.task_id) {
|
|
294
|
+
agentIdByToolUseId.set(String(toolUseId), result.task.task_id);
|
|
295
|
+
}
|
|
284
296
|
}
|
|
285
297
|
}
|
|
286
298
|
}
|
|
@@ -326,7 +338,38 @@ async function parseDetail(filePath, sessionId, projectPath, projectName) {
|
|
|
326
338
|
agent.agentId = agentId;
|
|
327
339
|
const subagentFilePath = `${subagentDir}/subagents/agent-${agentId}.jsonl`;
|
|
328
340
|
try {
|
|
329
|
-
|
|
341
|
+
const detail = await parseSubagentDetail(subagentFilePath);
|
|
342
|
+
agent.skills = detail.skills;
|
|
343
|
+
if (!agent.tokens) {
|
|
344
|
+
agent.tokens = detail.tokens;
|
|
345
|
+
totalTokens.inputTokens += detail.tokens.inputTokens;
|
|
346
|
+
totalTokens.outputTokens += detail.tokens.outputTokens;
|
|
347
|
+
totalTokens.cacheReadInputTokens += detail.tokens.cacheReadInputTokens;
|
|
348
|
+
totalTokens.cacheCreationInputTokens += detail.tokens.cacheCreationInputTokens;
|
|
349
|
+
if (detail.model) {
|
|
350
|
+
const modelId = detail.model;
|
|
351
|
+
const existing = tokensByModel[modelId] ?? {
|
|
352
|
+
inputTokens: 0,
|
|
353
|
+
outputTokens: 0,
|
|
354
|
+
cacheReadInputTokens: 0,
|
|
355
|
+
cacheCreationInputTokens: 0
|
|
356
|
+
};
|
|
357
|
+
existing.inputTokens += detail.tokens.inputTokens;
|
|
358
|
+
existing.outputTokens += detail.tokens.outputTokens;
|
|
359
|
+
existing.cacheReadInputTokens += detail.tokens.cacheReadInputTokens;
|
|
360
|
+
existing.cacheCreationInputTokens += detail.tokens.cacheCreationInputTokens;
|
|
361
|
+
tokensByModel[modelId] = existing;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (!agent.toolCalls) {
|
|
365
|
+
agent.toolCalls = detail.toolCalls;
|
|
366
|
+
}
|
|
367
|
+
if (!agent.model && detail.model) {
|
|
368
|
+
agent.model = detail.model;
|
|
369
|
+
}
|
|
370
|
+
if (!agent.totalToolUseCount && detail.totalToolUseCount > 0) {
|
|
371
|
+
agent.totalToolUseCount = detail.totalToolUseCount;
|
|
372
|
+
}
|
|
330
373
|
} catch {
|
|
331
374
|
}
|
|
332
375
|
})
|
|
@@ -354,8 +397,18 @@ async function parseDetail(filePath, sessionId, projectPath, projectName) {
|
|
|
354
397
|
};
|
|
355
398
|
}
|
|
356
399
|
const COMMAND_NAME_RE = /<command-name>([^<]+)<\/command-name>/;
|
|
357
|
-
async function
|
|
400
|
+
async function parseSubagentDetail(subagentFilePath) {
|
|
358
401
|
const skills = [];
|
|
402
|
+
const tokens = {
|
|
403
|
+
inputTokens: 0,
|
|
404
|
+
outputTokens: 0,
|
|
405
|
+
cacheReadInputTokens: 0,
|
|
406
|
+
cacheCreationInputTokens: 0
|
|
407
|
+
};
|
|
408
|
+
const toolCalls = {};
|
|
409
|
+
let model;
|
|
410
|
+
let totalToolUseCount = 0;
|
|
411
|
+
const seenRequestIds = /* @__PURE__ */ new Set();
|
|
359
412
|
const stream = fs.createReadStream(subagentFilePath, { encoding: "utf-8" });
|
|
360
413
|
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
361
414
|
let lineCount = 0;
|
|
@@ -385,22 +438,43 @@ async function parseSubagentSkills(subagentFilePath) {
|
|
|
385
438
|
}
|
|
386
439
|
}
|
|
387
440
|
}
|
|
388
|
-
if (msg.type === "assistant" && msg.message
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
441
|
+
if (msg.type === "assistant" && msg.message) {
|
|
442
|
+
const requestId = msg.requestId;
|
|
443
|
+
const isNewRequest = !requestId || !seenRequestIds.has(requestId);
|
|
444
|
+
if (requestId) seenRequestIds.add(requestId);
|
|
445
|
+
if (msg.message.model && !model) {
|
|
446
|
+
model = msg.message.model;
|
|
447
|
+
}
|
|
448
|
+
if (isNewRequest && msg.message.usage) {
|
|
449
|
+
const u = msg.message.usage;
|
|
450
|
+
tokens.inputTokens += u.input_tokens ?? 0;
|
|
451
|
+
tokens.outputTokens += u.output_tokens ?? 0;
|
|
452
|
+
tokens.cacheReadInputTokens += u.cache_read_input_tokens ?? 0;
|
|
453
|
+
tokens.cacheCreationInputTokens += u.cache_creation_input_tokens ?? 0;
|
|
454
|
+
}
|
|
455
|
+
if (msg.message.content) {
|
|
456
|
+
for (const block of msg.message.content) {
|
|
457
|
+
if (block.type === "tool_use" && block.name) {
|
|
458
|
+
toolCalls[block.name] = (toolCalls[block.name] ?? 0) + 1;
|
|
459
|
+
totalToolUseCount++;
|
|
460
|
+
if (block.name === "Skill") {
|
|
461
|
+
const inp = block.input;
|
|
462
|
+
if (inp?.skill) {
|
|
463
|
+
skills.push({
|
|
464
|
+
skill: String(inp.skill),
|
|
465
|
+
args: inp.args ? String(inp.args) : null,
|
|
466
|
+
timestamp: msg.timestamp ?? "",
|
|
467
|
+
toolUseId: block.id ?? "",
|
|
468
|
+
source: "invoked"
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
400
474
|
}
|
|
401
475
|
}
|
|
402
476
|
}
|
|
403
|
-
return skills;
|
|
477
|
+
return { skills, tokens, toolCalls, model, totalToolUseCount };
|
|
404
478
|
}
|
|
405
479
|
function getContextLimit(_modelName) {
|
|
406
480
|
return 2e5;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
import { a as parseSummary } from "./session-parser-
|
|
3
|
+
import { a as getProjectsDir, d as decodeProjectDirName, e as extractProjectName, b as extractSessionId } from "./claude-path-BdwflgZ1.js";
|
|
4
|
+
import { a as parseSummary } from "./session-parser-Bq8g2LOP.js";
|
|
5
5
|
async function scanProjects() {
|
|
6
6
|
const projectsDir = getProjectsDir();
|
|
7
7
|
let entries;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { c as createServerRpc } from "./createServerRpc-Bd3B-Ah9.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { s as scanAllSessions, g as getActiveSessions } from "./session-scanner-
|
|
3
|
+
import { s as scanAllSessions, g as getActiveSessions } from "./session-scanner-BzGf0Bqs.js";
|
|
4
4
|
import { c as createServerFn } from "../server.js";
|
|
5
5
|
import "node:fs";
|
|
6
6
|
import "node:path";
|
|
7
|
-
import "./claude-path-
|
|
7
|
+
import "./claude-path-BdwflgZ1.js";
|
|
8
8
|
import "node:os";
|
|
9
|
-
import "./session-parser-
|
|
9
|
+
import "./session-parser-Bq8g2LOP.js";
|
|
10
10
|
import "node:readline";
|
|
11
11
|
import "@tanstack/history";
|
|
12
12
|
import "@tanstack/router-core/ssr/client";
|
|
@@ -3,7 +3,7 @@ import { useState } from "react";
|
|
|
3
3
|
import { useQuery } from "@tanstack/react-query";
|
|
4
4
|
import { s as settingsQuery, u as useSettingsMutation } from "./settings.queries-DSQd324O.js";
|
|
5
5
|
import { a as SUBSCRIPTION_TIERS, b as DEFAULT_PRICING, D as DEFAULT_SETTINGS } from "./settings.types-DntadCHo.js";
|
|
6
|
-
import { u as usePrivacy } from "./router-
|
|
6
|
+
import { u as usePrivacy } from "./router-Cd4jLk4T.js";
|
|
7
7
|
import "./createSsrRpc-CVg2UDl0.js";
|
|
8
8
|
import "../server.js";
|
|
9
9
|
import "@tanstack/history";
|
|
@@ -8,7 +8,7 @@ import { format, addDays, getDay, parseISO, startOfISOWeek } from "date-fns";
|
|
|
8
8
|
import { createPortal } from "react-dom";
|
|
9
9
|
import { f as formatTokenCount, a as formatDuration, b as formatRelativeTime, c as formatUSD } from "./format-DIZHV7IJ.js";
|
|
10
10
|
import { Link } from "@tanstack/react-router";
|
|
11
|
-
import { u as usePrivacy, R as Route } from "./router-
|
|
11
|
+
import { u as usePrivacy, R as Route } from "./router-Cd4jLk4T.js";
|
|
12
12
|
import { u as useSessionCost, E as ExportDropdown, d as downloadFile, a as dailyActivityToCSV, b as dailyTokensToCSV, m as modelUsageToCSV, s as statsToJSON } from "./useSessionCost-CYs5UOX-.js";
|
|
13
13
|
import "@tanstack/history";
|
|
14
14
|
import "@tanstack/router-core/ssr/client";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { c as createServerRpc } from "./createServerRpc-Bd3B-Ah9.js";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { g as getStatsPath } from "./claude-path-BdwflgZ1.js";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import * as os from "node:os";
|
|
6
6
|
import { z } from "zod";
|
package/dist/server/server.js
CHANGED
|
@@ -423,7 +423,7 @@ function getResponse() {
|
|
|
423
423
|
return event.res;
|
|
424
424
|
}
|
|
425
425
|
async function getStartManifest(matchedRoutes) {
|
|
426
|
-
const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-
|
|
426
|
+
const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-JNF_5-F_.js");
|
|
427
427
|
const startManifest = tsrStartManifest();
|
|
428
428
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
429
429
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -577,30 +577,30 @@ function createMultiplexedStream(jsonStream, rawStreams) {
|
|
|
577
577
|
}
|
|
578
578
|
});
|
|
579
579
|
}
|
|
580
|
-
const manifest = { "
|
|
581
|
-
functionName: "getSessionDetail_createServerFn_handler",
|
|
582
|
-
importer: () => import("./assets/session-detail.server-IUw67jz-.js")
|
|
583
|
-
}, "4b9a58c176f487b49800a372100037cdf33cf048f3592a449f115c7e3f5ea799": {
|
|
580
|
+
const manifest = { "4b9a58c176f487b49800a372100037cdf33cf048f3592a449f115c7e3f5ea799": {
|
|
584
581
|
functionName: "getStats_createServerFn_handler",
|
|
585
|
-
importer: () => import("./assets/stats.server-
|
|
586
|
-
}, "
|
|
587
|
-
functionName: "
|
|
588
|
-
importer: () => import("./assets/
|
|
589
|
-
}, "3050115d92ca91ab1fd8fd698e33076328aae80dc64ca27c088eee16cebccc1a": {
|
|
590
|
-
functionName: "saveSettings_createServerFn_handler",
|
|
591
|
-
importer: () => import("./assets/settings.server-6B2PvLgf.js")
|
|
582
|
+
importer: () => import("./assets/stats.server-qTOvID9-.js")
|
|
583
|
+
}, "ff8a3161afdfa175e9c519e4146a56ab5bce6e80745e99cfc2191ebbb7a859bb": {
|
|
584
|
+
functionName: "getSessionDetail_createServerFn_handler",
|
|
585
|
+
importer: () => import("./assets/session-detail.server-4Cp5Zyo1.js")
|
|
592
586
|
}, "bf8e4a7901f1843bdc9c46be1ad5ad59c615b8bbe611b73eb3ff28f20e43ee0d": {
|
|
593
587
|
functionName: "getSessionList_createServerFn_handler",
|
|
594
|
-
importer: () => import("./assets/sessions.server-
|
|
588
|
+
importer: () => import("./assets/sessions.server-XaGOdz4f.js")
|
|
595
589
|
}, "839d29fe93dfa2a6d506af7b48ca25197190a5ff4c796e970ddfdc6e8c98827f": {
|
|
596
590
|
functionName: "getActiveSessionList_createServerFn_handler",
|
|
597
|
-
importer: () => import("./assets/sessions.server-
|
|
591
|
+
importer: () => import("./assets/sessions.server-XaGOdz4f.js")
|
|
598
592
|
}, "a3f42f9012fd83586787da8f7cb90649da739dd947d867eb67572f68735ff495": {
|
|
599
593
|
functionName: "getPaginatedSessions_createServerFn_handler",
|
|
600
|
-
importer: () => import("./assets/sessions.server-
|
|
594
|
+
importer: () => import("./assets/sessions.server-XaGOdz4f.js")
|
|
595
|
+
}, "810657681a273df5b4e58f0d8fcc6a5451598b489431b9bcaa98eea0ad815da8": {
|
|
596
|
+
functionName: "getSettings_createServerFn_handler",
|
|
597
|
+
importer: () => import("./assets/settings.server-6B2PvLgf.js")
|
|
598
|
+
}, "3050115d92ca91ab1fd8fd698e33076328aae80dc64ca27c088eee16cebccc1a": {
|
|
599
|
+
functionName: "saveSettings_createServerFn_handler",
|
|
600
|
+
importer: () => import("./assets/settings.server-6B2PvLgf.js")
|
|
601
601
|
}, "64052f224a1d6696436e5d3deeee2b798f0742e1292ffabd038c3a7bf75e6fcb": {
|
|
602
602
|
functionName: "getProjectAnalytics_createServerFn_handler",
|
|
603
|
-
importer: () => import("./assets/project-analytics.server-
|
|
603
|
+
importer: () => import("./assets/project-analytics.server-aftsdOgf.js")
|
|
604
604
|
} };
|
|
605
605
|
async function getServerFnById(id) {
|
|
606
606
|
const serverFnInfo = manifest[id];
|
|
@@ -1016,7 +1016,7 @@ let entriesPromise;
|
|
|
1016
1016
|
let baseManifestPromise;
|
|
1017
1017
|
let cachedFinalManifestPromise;
|
|
1018
1018
|
async function loadEntries() {
|
|
1019
|
-
const routerEntry = await import("./assets/router-
|
|
1019
|
+
const routerEntry = await import("./assets/router-Cd4jLk4T.js").then((n) => n.r);
|
|
1020
1020
|
const startEntry = await import("./assets/start-HYkvq4Ni.js");
|
|
1021
1021
|
return { startEntry, routerEntry };
|
|
1022
1022
|
}
|
|
@@ -1229,6 +1229,7 @@ function createStartHandler(cbOrOptions) {
|
|
|
1229
1229
|
);
|
|
1230
1230
|
const ctx2 = await executeMiddleware([...middlewares2, serverFnHandler], {
|
|
1231
1231
|
request,
|
|
1232
|
+
pathname: url.pathname,
|
|
1232
1233
|
context: createNullProtoObject(requestOpts?.context)
|
|
1233
1234
|
});
|
|
1234
1235
|
return handleRedirectResponse(ctx2.response, request, getRouter);
|
|
@@ -1305,7 +1306,11 @@ function createStartHandler(cbOrOptions) {
|
|
|
1305
1306
|
);
|
|
1306
1307
|
const ctx = await executeMiddleware(
|
|
1307
1308
|
[...middlewares, requestHandlerMiddleware],
|
|
1308
|
-
{
|
|
1309
|
+
{
|
|
1310
|
+
request,
|
|
1311
|
+
pathname: url.pathname,
|
|
1312
|
+
context: createNullProtoObject(requestOpts?.context)
|
|
1313
|
+
}
|
|
1309
1314
|
);
|
|
1310
1315
|
return handleRedirectResponse(ctx.response, request, getRouter);
|
|
1311
1316
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-session-dashboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Local observability dashboard for Claude Code sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,15 +52,15 @@
|
|
|
52
52
|
"date-fns": "^4.1.0",
|
|
53
53
|
"react": "^19.1.0",
|
|
54
54
|
"react-dom": "^19.1.0",
|
|
55
|
-
"recharts": "^
|
|
56
|
-
"zod": "^3.
|
|
55
|
+
"recharts": "^3.7.0",
|
|
56
|
+
"zod": "^4.3.6"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@eslint/js": "^9.39.2",
|
|
60
60
|
"@playwright/test": "^1.58.2",
|
|
61
61
|
"@tailwindcss/vite": "^4.1.0",
|
|
62
62
|
"@testing-library/react": "^16.3.2",
|
|
63
|
-
"@types/node": "^
|
|
63
|
+
"@types/node": "^25.2.3",
|
|
64
64
|
"@types/react": "^19.1.0",
|
|
65
65
|
"@types/react-dom": "^19.1.0",
|
|
66
66
|
"@vitejs/plugin-react": "^5.1.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"typescript": "^5.8.0",
|
|
75
75
|
"typescript-eslint": "^8.55.0",
|
|
76
76
|
"vite": "^7.3.0",
|
|
77
|
-
"vite-tsconfig-paths": "^
|
|
77
|
+
"vite-tsconfig-paths": "^6.1.1",
|
|
78
78
|
"vitest": "^4.0.18"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import{c as K,r as M,j as e,L as A,h as _,b as Z}from"./main-CkUc_xJ0.js";import{c as J,q as V,u as O}from"./createServerFn-B5mibSc4.js";import{f as C,d as P,b as T,i as H,g as U}from"./format-Bsprb3az.js";import{R as ee,V as se,Y as te,U as ae,a5 as B,W as ne,a6 as le,a7 as re,_ as z,$ as oe,a0 as ie,a8 as ce}from"./useSessionCost-BDldLkTA.js";import{s as de}from"./settings.types-l5MKKuAK.js";import{a as xe}from"./sessions.queries-C-HTNzuR.js";const me=J({method:"GET"}).handler(K("ff8a3161afdfa175e9c519e4146a56ab5bce6e80745e99cfc2191ebbb7a859bb"));function pe(s,a,t){return V({queryKey:["session","detail",s],queryFn:()=>me({data:{sessionId:s,projectPath:a}}),staleTime:t?2e3:3e4,refetchInterval:t?5e3:void 0})}function ue(s,a,t,r){const l=[];for(const o of s)if(o.timestamp){const p=new Date(o.timestamp).getTime();isNaN(p)||l.push(p)}for(const o of a)if(o.timestamp){const p=new Date(o.timestamp).getTime();isNaN(p)||l.push(p)}for(const o of t)if(o.timestamp){const p=new Date(o.timestamp).getTime();isNaN(p)||l.push(p)}if(l.length===0)return{startMs:0,endMs:0,durationMs:0,mainLane:[],agentLanes:[],skillMarkers:[],errorMarkers:[]};const c=Math.min(...l),n=Math.max(...l),m=Math.max(n-c,1);function d(o){return(o-c)/m}const f=new Set(a.map(o=>o.toolUseId)),u=new Set(t.map(o=>o.toolUseId)),y=[];for(const o of s){if(o.type!=="assistant"||o.toolCalls.length===0)continue;const p=new Date(o.timestamp).getTime();if(!isNaN(p))for(const i of o.toolCalls)f.has(i.toolUseId)||u.has(i.toolUseId)||y.push({timestampMs:p,toolName:i.toolName,toolUseId:i.toolUseId,relativeX:d(p)})}const h=a.map(o=>{const p=new Date(o.timestamp).getTime(),i=o.durationMs?p+o.durationMs:p+m*.02,j=[];if(o.toolCalls){const x=Object.entries(o.toolCalls).sort(([,w],[,R])=>R-w),b=x.reduce((w,[,R])=>w+R,0);let g=0;for(const[w,R]of x)for(let F=0;F<R;F++){const q=b>1?g/(b-1):.5,Q=p+(i-p)*q;j.push({toolName:w,count:1,relativeX:d(Q)}),g++}}return{subagentType:o.subagentType,description:o.description,startMs:p,endMs:i,startX:d(p),endX:d(i),durationMs:o.durationMs??null,totalTokens:o.totalTokens??null,totalToolUseCount:o.totalToolUseCount??null,toolDots:j,skills:o.skills?.map(x=>({skill:x.skill,args:x.args}))??[]}}),k=t.map(o=>{const p=new Date(o.timestamp).getTime();return isNaN(p)?null:{skill:o.skill,args:o.args,timestampMs:p,relativeX:d(p)}}).filter(o=>o!==null),v=r.map(o=>{const p=new Date(o.timestamp).getTime();return isNaN(p)?null:{message:o.message,type:o.type,timestampMs:p,relativeX:d(p)}}).filter(o=>o!==null);return{startMs:c,endMs:n,durationMs:m,mainLane:y,agentLanes:h,skillMarkers:k,errorMarkers:v}}function W(s){const a=s.match(/^mcp__[^_]+_[^_]+_[^_]+__(.+)$/);return a?a[1]:s}const he={Read:"#e09070",Grep:"#e09070",Glob:"#e09070",Write:"#34d399",Edit:"#34d399",NotebookEdit:"#34d399",Bash:"#fbbf24",Task:"#818cf8",TaskCreate:"#c084fc",TaskUpdate:"#c084fc",TaskList:"#c084fc",TaskGet:"#c084fc",Skill:"#fcd34d",WebSearch:"#22d3ee",WebFetch:"#22d3ee",EnterPlanMode:"#f472b6",ExitPlanMode:"#f472b6",AskUserQuestion:"#a78bfa"},ge="#9ca3af";function X(s){return he[s]??ge}const S=90,$=16,D=24,N=32,E=8,Y=4;function ye(s,a,t){const r=a-s;if(r<=0)return[];const l=Math.max(3,Math.round(t/120)),c=r/l,n=[5e3,1e4,15e3,3e4,6e4,2*6e4,5*6e4,10*6e4,15*6e4,30*6e4,60*6e4,120*6e4],m=n.find(h=>h>=c)??n[n.length-1],f=r<5*6e4?"HH:mm:ss":"HH:mm",u=Math.ceil(s/m)*m,y=[];for(let h=u;h<=a;h+=m){const k=(h-s)/r;y.push({ms:h,label:C(new Date(h),f),x:S+k*(t-S-$)})}return y}function fe({data:s,width:a,onHover:t}){const r=M.useRef(null),l=a,c=l-S-$,n=s.skillMarkers.length>0,m=s.errorMarkers.length>0;let d=D;const f=d;d+=N;const u=[];for(let i=0;i<s.agentLanes.length;i++)d+=E,u.push(d),d+=N;let y=0;n&&(d+=E,y=d,d+=N);let h=0;m&&(d+=E,h=d,d+=N);const k=Math.max(d+8,80);function v(i){return S+i*c}const o=M.useCallback(i=>{if(!r.current)return{x:0,y:0};const j=r.current.getBoundingClientRect();return{x:i.clientX-j.left,y:i.clientY-j.top}},[]),p=ye(s.startMs,s.endMs,l);return e.jsxs("svg",{ref:r,width:l,height:k,className:"select-none",role:"img","aria-label":"Session timeline showing tool calls, agent runs, and skill invocations",onMouseLeave:()=>t(null,{x:0,y:0}),children:[e.jsx("line",{x1:S,y1:D-4,x2:l-$,y2:D-4,stroke:"#374151",strokeWidth:1}),p.map(i=>e.jsxs("g",{children:[e.jsx("line",{x1:i.x,y1:D-8,x2:i.x,y2:D-4,stroke:"#4b5563",strokeWidth:1}),e.jsx("text",{x:i.x,y:D-12,textAnchor:"middle",className:"fill-gray-500 text-[10px]",children:i.label})]},i.ms)),e.jsx("text",{x:4,y:f+N/2+4,className:"fill-gray-500 text-[11px] font-medium",children:"Main"}),e.jsx("line",{x1:S,y1:f+N/2,x2:l-$,y2:f+N/2,stroke:"#1f2937",strokeWidth:1,strokeDasharray:"2,4"}),s.mainLane.map(i=>e.jsx("circle",{cx:v(i.relativeX),cy:f+N/2,r:Y,fill:X(i.toolName),opacity:.85,className:"cursor-pointer transition-transform hover:opacity-100",onMouseEnter:j=>t({kind:"tool",toolName:i.toolName,timestamp:new Date(i.timestampMs).toISOString(),toolUseId:i.toolUseId},o(j)),onMouseLeave:()=>t(null,{x:0,y:0}),children:e.jsx("title",{children:i.toolName})},i.toolUseId)),s.agentLanes.map((i,j)=>e.jsx(be,{lane:i,y:u[j],toX:v,laneHeight:N,onHover:t,getPosition:o},`${i.subagentType}-${j}`)),n&&e.jsxs(e.Fragment,{children:[e.jsx("text",{x:4,y:y+N/2+4,className:"fill-amber-400/70 text-[11px] font-medium",children:"Skills"}),e.jsx("line",{x1:S,y1:y+N/2,x2:l-$,y2:y+N/2,stroke:"#1f2937",strokeWidth:1,strokeDasharray:"2,4"}),s.skillMarkers.map((i,j)=>{const x=v(i.relativeX),b=y+N/2,g=5;return e.jsx("polygon",{points:`${x},${b-g} ${x+g},${b} ${x},${b+g} ${x-g},${b}`,fill:"#fbbf24",opacity:.85,className:"cursor-pointer hover:opacity-100",onMouseEnter:w=>t({kind:"skill",skill:i.skill,args:i.args,timestamp:new Date(i.timestampMs).toISOString()},o(w)),onMouseLeave:()=>t(null,{x:0,y:0}),children:e.jsxs("title",{children:["/",i.skill]})},`${i.skill}-${j}`)})]}),m&&e.jsxs(e.Fragment,{children:[e.jsx("text",{x:4,y:h+N/2+4,className:"fill-red-400/70 text-[11px] font-medium",children:"Errors"}),e.jsx("line",{x1:S,y1:h+N/2,x2:l-$,y2:h+N/2,stroke:"#1f2937",strokeWidth:1,strokeDasharray:"2,4"}),s.errorMarkers.map((i,j)=>{const x=v(i.relativeX),b=h+N/2,g=5;return e.jsxs("g",{className:"cursor-pointer hover:opacity-100",opacity:.85,onMouseEnter:w=>t({kind:"error",message:i.message,type:i.type,timestamp:new Date(i.timestampMs).toISOString()},o(w)),onMouseLeave:()=>t(null,{x:0,y:0}),children:[e.jsx("line",{x1:x-g,y1:b-g,x2:x+g,y2:b+g,stroke:"#f87171",strokeWidth:2,strokeLinecap:"round"}),e.jsx("line",{x1:x+g,y1:b-g,x2:x-g,y2:b+g,stroke:"#f87171",strokeWidth:2,strokeLinecap:"round"}),e.jsxs("title",{children:[i.type,": ",i.message]})]},`err-${j}`)})]})]})}function be({lane:s,y:a,toX:t,laneHeight:r,onHover:l,getPosition:c}){const n=t(s.startX),m=Math.max(t(s.endX)-n,8),d=a+r/2,f=s.subagentType.length>10?s.subagentType.slice(0,10)+"...":s.subagentType;return e.jsxs("g",{children:[e.jsx("text",{x:4,y:d+4,className:"fill-indigo-400/70 text-[11px] font-medium",children:f}),e.jsx("rect",{x:n,y:a+2,width:m,height:r-4,rx:6,fill:"rgba(99, 102, 241, 0.08)",stroke:"rgba(99, 102, 241, 0.2)",strokeWidth:1,className:"cursor-pointer hover:fill-indigo-500/15",onMouseEnter:u=>l({kind:"agent",agent:s},c(u)),onMouseLeave:()=>l(null,{x:0,y:0}),children:e.jsxs("title",{children:[s.subagentType,": ",s.description]})}),e.jsx("line",{x1:n+4,y1:d,x2:n+m-4,y2:d,stroke:"rgba(99, 102, 241, 0.15)",strokeWidth:1}),s.toolDots.map((u,y)=>e.jsx("circle",{cx:t(u.relativeX),cy:d,r:Y-.5,fill:X(u.toolName),opacity:.75,className:"cursor-pointer hover:opacity-100",onMouseEnter:h=>l({kind:"tool",toolName:u.toolName,timestamp:new Date(s.startMs+(u.relativeX-s.startX)/(s.endX-s.startX)*(s.endMs-s.startMs)).toISOString(),toolUseId:`${s.subagentType}-${u.toolName}-${y}`},c(h)),onMouseLeave:()=>l(null,{x:0,y:0}),children:e.jsxs("title",{children:[u.toolName," (",s.subagentType,")"]})},`${u.toolName}-${y}`)),s.skills&&s.skills.length>0&&s.skills.map((u,y)=>{const h=s.startX+(s.endX-s.startX)/(s.skills.length+1)*(y+1),k=t(h),v=a+6,o=3;return e.jsx("polygon",{points:`${k},${v-o} ${k+o},${v} ${k},${v+o} ${k-o},${v}`,fill:"#fbbf24",opacity:.85,className:"cursor-pointer hover:opacity-100",onMouseEnter:p=>l({kind:"skill",skill:u.skill,args:u.args,timestamp:new Date(s.startMs).toISOString()},c(p)),onMouseLeave:()=>l(null,{x:0,y:0}),children:e.jsxs("title",{children:["/",u.skill," (",s.subagentType,")"]})},`skill-${u.skill}-${y}`)})]})}function je({item:s,position:a}){return e.jsxs("div",{className:"pointer-events-none absolute z-50 rounded-lg border border-gray-700 bg-gray-900 px-3 py-2 text-xs shadow-xl",style:{left:a.x,top:a.y,transform:"translate(-50%, -100%) translateY(-8px)"},children:[s.kind==="tool"&&e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold text-gray-100",children:W(s.toolName)}),e.jsx("div",{className:"text-gray-400",children:C(new Date(s.timestamp),"HH:mm:ss")}),e.jsxs("div",{className:"font-mono text-[10px] text-gray-600",children:[s.toolUseId.slice(0,16),"..."]})]}),s.kind==="agent"&&e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold text-indigo-300",children:s.agent.subagentType}),e.jsx("div",{className:"max-w-48 truncate text-gray-400",children:s.agent.description}),e.jsx("div",{className:"mt-1 flex items-center gap-2 text-gray-500",children:s.agent.durationMs!=null&&e.jsxs("span",{children:[C(new Date(s.agent.startMs),"HH:mm")," -"," ",C(new Date(s.agent.endMs),"HH:mm")," (",P(s.agent.durationMs),")"]})}),e.jsxs("div",{className:"flex items-center gap-2 text-gray-500",children:[s.agent.totalTokens!=null&&e.jsxs("span",{children:[T(s.agent.totalTokens)," tokens"]}),s.agent.totalToolUseCount!=null&&e.jsxs("span",{children:[s.agent.totalToolUseCount," tools"]})]})]}),s.kind==="skill"&&e.jsxs("div",{children:[e.jsxs("div",{className:"font-semibold text-amber-300",children:["/",s.skill]}),s.args&&e.jsx("div",{className:"text-gray-400",children:s.args}),e.jsx("div",{className:"text-gray-500",children:C(new Date(s.timestamp),"HH:mm:ss")})]}),s.kind==="error"&&e.jsxs("div",{children:[e.jsx("div",{className:"font-semibold text-red-400",children:s.type}),e.jsx("div",{className:"max-w-48 truncate text-gray-400",children:s.message}),e.jsx("div",{className:"text-gray-500",children:C(new Date(s.timestamp),"HH:mm:ss")})]})]})}function Ne({toolNames:s}){const a=[...new Set(s)].slice(0,12);return a.length===0?null:e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 px-1 text-[10px] text-gray-500",children:[a.map(t=>e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block h-2 w-2 rounded-full",style:{backgroundColor:X(t)}}),e.jsx("span",{children:W(t)})]},t)),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block h-2 w-2 rotate-45 bg-amber-400"}),e.jsx("span",{children:"Skill"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"text-red-400 font-bold leading-none",children:"×"}),e.jsx("span",{children:"Error"})]})]})}function ve({turns:s,agents:a,skills:t,errors:r}){const l=M.useRef(null),[c,n]=M.useState(0),[m,d]=M.useState(1),[f,u]=M.useState(null);M.useEffect(()=>{if(!l.current)return;const x=new ResizeObserver(b=>{const g=b[0];g&&n(g.contentRect.width)});return x.observe(l.current),()=>x.disconnect()},[]);const y=M.useMemo(()=>ue(s,a,t,r),[s,a,t,r]),h=M.useMemo(()=>{const x=y.mainLane.map(g=>g.toolName);for(const g of y.agentLanes)for(const w of g.toolDots)x.push(w.toolName);const b={};for(const g of x)b[g]=(b[g]??0)+1;return Object.entries(b).sort(([,g],[,w])=>w-g).map(([g])=>g)},[y]),k=(x,b)=>{u(x?{item:x,position:b}:null)};if(s.length===0)return e.jsx("div",{className:"py-8 text-center text-sm text-gray-500",children:"No timeline data available"});const v=new Set(a.map(x=>x.toolUseId)),o=new Set(t.map(x=>x.toolUseId));let p=0,i=0,j=0;for(const x of s)if(x.type==="user"&&x.message?.trim()&&p++,x.type==="assistant"){i++;for(const b of x.toolCalls)!v.has(b.toolUseId)&&!o.has(b.toolUseId)&&j++}return e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-4",children:[e.jsx(I,{label:"User commands",value:p,color:"blue"}),e.jsx(I,{label:"AI responses",value:i,color:"purple"}),j>0&&e.jsx(I,{label:"Tool calls",value:j,color:"gray"}),a.length>0&&e.jsx(I,{label:"Agents",value:a.length,color:"indigo"}),t.length>0&&e.jsx(I,{label:"Skills",value:t.length,color:"amber"}),r.length>0&&e.jsx(I,{label:"Errors",value:r.length,color:"red"})]}),e.jsxs("div",{className:"mb-3 flex items-start justify-between gap-2",children:[e.jsx("div",{className:"flex-1",children:h.length>0&&e.jsx(Ne,{toolNames:h})}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx("button",{type:"button",onClick:()=>d(x=>Math.max(1,x-.5)),disabled:m<=1,className:"rounded bg-gray-800 px-2 py-0.5 text-xs text-gray-300 transition-colors hover:bg-gray-700 disabled:opacity-30",title:"Zoom out",children:"−"}),e.jsx("span",{className:"min-w-[3rem] text-center text-[10px] tabular-nums text-gray-500",children:m===1?"Fit":`${m.toFixed(1)}x`}),e.jsx("button",{type:"button",onClick:()=>d(x=>Math.min(8,x+.5)),disabled:m>=8,className:"rounded bg-gray-800 px-2 py-0.5 text-xs text-gray-300 transition-colors hover:bg-gray-700 disabled:opacity-30",title:"Zoom in",children:"+"}),m>1&&e.jsx("button",{type:"button",onClick:()=>d(1),className:"ml-1 rounded bg-gray-800 px-2 py-0.5 text-[10px] text-gray-400 transition-colors hover:bg-gray-700",title:"Reset zoom",children:"Reset"})]})]}),e.jsx("div",{ref:l,className:"relative overflow-x-auto",children:c>0&&e.jsxs(e.Fragment,{children:[e.jsx(fe,{data:y,width:Math.max(c*m,400),onHover:k}),f&&e.jsx(je,{item:f.item,position:f.position})]})})]})}function I({label:s,value:a,color:t}){const r={blue:"bg-brand-500/15 text-brand-400",purple:"bg-purple-500/15 text-purple-400",gray:"bg-gray-800 text-gray-300",indigo:"bg-indigo-500/15 text-indigo-400",amber:"bg-amber-500/15 text-amber-400",red:"bg-red-500/15 text-red-400"};return e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`rounded-md px-2 py-1 text-sm font-bold tabular-nums ${r[t]}`,children:a}),e.jsx("span",{className:"text-[11px] text-gray-500",children:s})]})}function ke({contextWindow:s,tokens:a}){const[t,r]=M.useState(!1);if(!s)return e.jsx(we,{tokens:a});const{contextLimit:l,modelName:c,systemOverhead:n,currentContextSize:m,messagesEstimate:d,freeSpace:f,autocompactBuffer:u,usagePercent:y,snapshots:h}=s,k=n/l*100,v=d/l*100,o=u/l*100,p=Math.max(0,100-k-v),i=c.replace(/^claude-/,"").split("-202")[0],j=h.map(x=>({turn:x.turnIndex,context:x.contextSize}));return e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Context Window"}),e.jsx("span",{className:"rounded bg-gray-800 px-1.5 py-0.5 text-[10px] font-mono text-gray-400",children:i})]}),e.jsxs("div",{className:"mt-1 flex items-baseline gap-1",children:[e.jsx("span",{className:"text-2xl font-bold text-white",children:T(m)}),e.jsxs("span",{className:"text-sm text-gray-500",children:["/ ",T(l)]}),e.jsxs("span",{className:"text-sm text-gray-400",children:["(",y,"%)"]})]}),e.jsx("p",{className:"text-[10px] text-gray-500",children:"~estimated from token usage"}),e.jsxs("div",{className:"mt-3 flex h-3 overflow-hidden rounded-full bg-gray-800",children:[e.jsx("div",{className:"bg-purple-500",style:{width:`${k}%`},title:`System: ~${T(n)}`}),e.jsx("div",{className:"bg-brand-500",style:{width:`${v}%`},title:`Messages: ~${T(d)}`}),p>0&&e.jsx(e.Fragment,{children:p>o?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"bg-gray-700",style:{width:`${p-o}%`}}),e.jsx("div",{className:"autocompact-stripe",style:{width:`${Math.min(o,p)}%`}})]}):e.jsx("div",{className:"autocompact-stripe",style:{width:`${p}%`}})})]}),e.jsxs("div",{className:"mt-1 flex gap-3 text-[10px] text-gray-500",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block h-2 w-2 rounded-sm bg-purple-500"}),"system"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block h-2 w-2 rounded-sm bg-brand-500"}),"messages"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block h-2 w-2 rounded-sm bg-gray-700"}),"free"]})]}),e.jsxs("div",{className:"mt-3 space-y-1.5",children:[e.jsx(L,{label:"System overhead",value:n,total:l,color:"bg-purple-500",prefix:"~"}),e.jsx(L,{label:"Messages",value:d,total:l,color:"bg-brand-500",prefix:"~"}),e.jsx(L,{label:"Autocompact buffer",value:u,total:l,color:"bg-amber-500"}),e.jsx(L,{label:"Free space",value:f,total:l,color:"bg-gray-600"})]}),j.length>1&&e.jsxs("div",{className:"mt-3",children:[e.jsx("p",{className:"mb-1 text-[10px] text-gray-500",children:"Context growth"}),e.jsx(ee,{width:"100%",height:96,children:e.jsxs(se,{data:j,children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"contextGrad",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#d97757",stopOpacity:.3}),e.jsx("stop",{offset:"100%",stopColor:"#d97757",stopOpacity:.05})]})}),e.jsx(te,{domain:[0,l],hide:!0}),e.jsx(ae,{contentStyle:{background:"#1c1c1a",border:"1px solid #3d3b36",borderRadius:"8px",fontSize:"11px"},labelFormatter:x=>`Turn ${x}`,formatter:x=>[T(x),"Context"]}),e.jsx(B,{y:l,stroke:"#ef4444",strokeDasharray:"4 4",strokeOpacity:.5}),e.jsx(B,{y:l-u,stroke:"#f59e0b",strokeDasharray:"2 4",strokeOpacity:.3}),e.jsx(ne,{type:"stepAfter",dataKey:"context",stroke:"#d97757",fill:"url(#contextGrad)",strokeWidth:1.5,dot:!1})]})})]}),e.jsxs("button",{onClick:()=>r(!t),className:"mt-3 flex w-full items-center gap-1 text-xs text-gray-400 hover:text-gray-300 transition-colors",children:[e.jsx("span",{className:"text-[10px]",children:t?"▾":"▸"}),"Token Details"]}),t&&e.jsx(Te,{tokens:a}),e.jsx("style",{children:`
|
|
2
|
-
.autocompact-stripe {
|
|
3
|
-
background: repeating-linear-gradient(
|
|
4
|
-
-45deg,
|
|
5
|
-
#78716c,
|
|
6
|
-
#78716c 2px,
|
|
7
|
-
#f59e0b 2px,
|
|
8
|
-
#f59e0b 4px
|
|
9
|
-
);
|
|
10
|
-
opacity: 0.4;
|
|
11
|
-
}
|
|
12
|
-
`})]})}function L({label:s,value:a,total:t,color:r,prefix:l=""}){const c=Math.max(0,Math.min(100,a/t*100));return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-32 text-xs text-gray-400 shrink-0",children:s}),e.jsxs("span",{className:"w-16 text-right text-xs font-mono text-gray-300 shrink-0",children:[l,T(a)]}),e.jsx("div",{className:"flex-1 h-1.5 rounded-full bg-gray-800 overflow-hidden",children:e.jsx("div",{className:`h-full rounded-full ${r}`,style:{width:`${c}%`,opacity:.7}})})]})}function Te({tokens:s}){const a=s.inputTokens+s.outputTokens+s.cacheReadInputTokens+s.cacheCreationInputTokens,t=[{label:"Input",value:s.inputTokens,color:"bg-brand-400"},{label:"Output",value:s.outputTokens,color:"bg-emerald-400"},{label:"Cache Read",value:s.cacheReadInputTokens,color:"bg-amber-400"},{label:"Cache Create",value:s.cacheCreationInputTokens,color:"bg-purple-400"}];return e.jsxs("div",{className:"mt-2 space-y-1.5",children:[t.map(r=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-gray-400",children:r.label}),e.jsx("span",{className:"text-xs font-mono text-gray-300",children:T(r.value)})]},r.label)),a>0&&e.jsx("div",{className:"flex h-2 overflow-hidden rounded-full bg-gray-800",children:t.filter(r=>r.value>0).map(r=>e.jsx("div",{className:`${r.color} opacity-60`,style:{width:`${r.value/a*100}%`}},r.label))})]})}function we({tokens:s}){const a=s.inputTokens+s.outputTokens,t=a+s.cacheReadInputTokens+s.cacheCreationInputTokens,r=[{label:"Input",value:s.inputTokens,color:"text-brand-400"},{label:"Output",value:s.outputTokens,color:"text-emerald-400"},{label:"Cache Read",value:s.cacheReadInputTokens,color:"text-amber-400"},{label:"Cache Create",value:s.cacheCreationInputTokens,color:"text-purple-400"}];return e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Token Usage"}),e.jsx("p",{className:"mt-1 text-2xl font-bold text-white",children:T(a)}),e.jsxs("p",{className:"text-[10px] text-gray-500",children:["input + output (",T(t)," incl. cache)"]}),e.jsx("div",{className:"mt-3 space-y-2",children:r.map(l=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-gray-400",children:l.label}),e.jsx("span",{className:`text-xs font-mono ${l.color}`,children:T(l.value)})]},l.label))}),t>0&&e.jsx("div",{className:"mt-3 flex h-2 overflow-hidden rounded-full bg-gray-800",children:r.filter(l=>l.value>0).map(l=>e.jsx("div",{className:`${l.color.replace("text-","bg-")} opacity-60`,style:{width:`${l.value/t*100}%`}},l.label))})]})}function Me({toolFrequency:s}){const a=Object.entries(s).sort(([,r],[,l])=>l-r),t=a[0]?.[1]??1;return a.length===0?e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Tool Usage"}),e.jsx("p",{className:"mt-2 text-xs text-gray-500",children:"No tools used"})]}):e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Tool Usage"}),e.jsxs("p",{className:"mt-1 text-xs text-gray-500",children:[a.length," tools, ",a.reduce((r,[,l])=>r+l,0)," calls"]}),e.jsx("div",{className:"mt-3 space-y-1.5",children:a.slice(0,15).map(([r,l])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-32 shrink-0 truncate text-xs font-mono text-gray-400",title:r,children:W(r)}),e.jsx("div",{className:"flex-1",children:e.jsx("div",{className:"h-4 rounded bg-brand-500/20",style:{width:`${l/t*100}%`},children:e.jsx("span",{className:"px-1.5 text-xs text-brand-300",children:l})})})]},r))})]})}function Ce({errors:s}){return s.length===0?null:e.jsxs("div",{className:"rounded-xl border border-red-900/50 bg-red-950/20 p-4",children:[e.jsxs("h3",{className:"text-sm font-semibold text-red-400",children:["Errors (",s.length,")"]}),e.jsx("div",{className:"mt-3 max-h-64 space-y-2 overflow-y-auto",children:s.map((a,t)=>e.jsxs("div",{className:"rounded-lg bg-red-950/30 p-2.5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs font-mono text-red-300",children:a.type}),a.timestamp&&e.jsx("span",{className:"text-xs text-gray-500",children:H(a.timestamp)})]}),e.jsx("p",{className:"mt-1 text-xs text-red-200/80",children:a.message})]},t))})]})}function G(s){if(s.tokens)return s.tokens.inputTokens+s.tokens.outputTokens}function Se({agents:s}){const{data:a}=O(de),{agentCosts:t,totalAgentCost:r}=M.useMemo(()=>{if(!a)return{agentCosts:new Map,totalAgentCost:0};const c=le(a),n=new Map;let m=0;for(let d=0;d<s.length;d++){const f=s[d];if(!f.tokens)continue;const y={[f.model??"claude-sonnet-4"]:f.tokens},h=re(y,c);n.set(d,h.totalUSD),m+=h.totalUSD}return{agentCosts:n,totalAgentCost:m}},[a,s]);if(s.length===0)return null;const l=s.reduce((c,n)=>c+(n.totalTokens??G(n)??0),0);return e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Agent Dispatches"}),e.jsxs("p",{className:"mt-1 text-xs text-gray-500",children:[s.length," agent dispatch",s.length!==1?"es":"",l>0&&e.jsxs("span",{className:"ml-1 text-indigo-400",children:["(",T(l)," tokens",r>0&&` · ~${U(r)}`,")"]})]}),e.jsx("div",{className:"mt-3 space-y-1",children:s.map((c,n)=>{const m=c.totalTokens??G(c),d=t.get(n);return e.jsxs("div",{className:"flex items-start gap-2 rounded bg-gray-950/40 px-2 py-1.5",children:[e.jsx("span",{className:"shrink-0 rounded bg-indigo-500/20 px-1.5 py-0.5 text-[10px] font-semibold text-indigo-300",children:c.subagentType}),c.model&&e.jsx("span",{className:"shrink-0 rounded bg-gray-800 px-1.5 py-0.5 text-[10px] font-mono text-gray-400",children:c.model.replace(/^claude-/,"").replace(/-\d{8}$/,"")}),e.jsx("span",{className:"min-w-0 flex-1 truncate text-xs text-gray-400",children:c.description}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[m!=null&&m>0&&e.jsx("span",{className:"text-[10px] font-mono text-indigo-400/80",children:T(m)}),d!=null&&d>0&&e.jsxs("span",{className:"text-[10px] font-mono text-emerald-400/80",children:["~",U(d)]}),c.totalToolUseCount!=null&&e.jsxs("span",{className:"text-[10px] text-gray-500",children:[c.totalToolUseCount," tools"]}),c.durationMs!=null&&e.jsx("span",{className:"text-[10px] text-gray-600",children:P(c.durationMs)}),c.timestamp&&e.jsx("span",{className:"text-[10px] text-gray-600",children:C(new Date(c.timestamp),"HH:mm:ss")})]})]},`a-${n}`)})})]})}function De({agents:s,skills:a}){const{groups:t,totalCount:r}=M.useMemo(()=>{const l=[...a.map(n=>({...n,agentSource:null})),...s.flatMap(n=>(n.skills??[]).map(m=>({...m,agentSource:n.subagentType})))].sort((n,m)=>n.timestamp.localeCompare(m.timestamp)),c=new Map;for(const n of l){let m=c.get(n.skill);m||(m={skill:n.skill,count:0,hasInjected:!1,invocations:[]},c.set(n.skill,m)),m.count++,n.source==="injected"&&(m.hasInjected=!0),m.invocations.push({agentSource:n.agentSource,timestamp:n.timestamp,source:n.source})}return{groups:Array.from(c.values()),totalCount:l.length}},[a,s]);return r===0?null:e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Skill Invocations"}),e.jsxs("p",{className:"mt-1 text-xs text-gray-500",children:[t.length," unique skill",t.length!==1?"s":"",","," ",r," invocation",r!==1?"s":""]}),e.jsx("div",{className:"mt-3 space-y-1",children:t.map(l=>e.jsxs("div",{className:"rounded bg-gray-950/40 px-2 py-1.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"shrink-0 rounded bg-amber-500/20 px-1.5 py-0.5 text-[10px] font-semibold text-amber-300",children:["/",l.skill]}),e.jsxs("span",{className:"text-[10px] text-gray-500",children:["×",l.count]}),l.hasInjected&&e.jsx("span",{className:"shrink-0 rounded bg-gray-800/40 px-1 py-0.5 text-[9px] text-gray-500",children:"context"})]}),e.jsx("div",{className:"mt-1 ml-2 flex flex-wrap gap-x-1 text-[10px] text-gray-500",children:l.invocations.map((c,n)=>e.jsxs("span",{children:[e.jsx("span",{className:"text-gray-400",children:c.agentSource??"session"}),", ",e.jsx("span",{className:"text-gray-600",children:C(new Date(c.timestamp),"HH:mm:ss")}),n<l.invocations.length-1&&e.jsx("span",{className:"text-gray-700",children:"; "})]},n))})]},l.skill))})]})}const Ie={pending:{label:"Pending",bg:"bg-gray-500/20",text:"text-gray-400"},in_progress:{label:"In Progress",bg:"bg-brand-500/20",text:"text-brand-400"},completed:{label:"Done",bg:"bg-emerald-500/20",text:"text-emerald-400"},deleted:{label:"Deleted",bg:"bg-red-500/20",text:"text-red-400"}};function $e({tasks:s}){if(s.length===0)return null;const a=s.filter(r=>r.status==="completed").length,t=s.filter(r=>r.status!=="deleted").length;return e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Tasks"}),e.jsxs("p",{className:"mt-1 text-xs text-gray-500",children:[a,"/",t," completed"]}),e.jsx("div",{className:"mt-3 space-y-1",children:s.map((r,l)=>{const c=Ie[r.status];return e.jsxs("div",{className:"flex items-start gap-2 rounded bg-gray-950/40 px-2 py-1.5",children:[e.jsx("span",{className:`shrink-0 rounded px-1.5 py-0.5 text-[10px] font-semibold ${c.bg} ${c.text}`,children:c.label}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"text-xs text-gray-300",children:r.subject}),r.description&&e.jsx("p",{className:"mt-0.5 truncate text-[10px] text-gray-500",children:r.description})]}),r.taskId&&e.jsxs("span",{className:"shrink-0 text-[10px] font-mono text-gray-600",children:["#",r.taskId]}),r.timestamp&&e.jsx("span",{className:"shrink-0 text-[10px] text-gray-600",children:C(new Date(r.timestamp),"HH:mm:ss")})]},r.taskId||l)})})]})}function Ue({tokensByModel:s}){const{cost:a,isLoading:t}=z(s);return t?e.jsx("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:e.jsx("div",{className:"h-6 w-32 animate-pulse rounded bg-gray-800"})}):!a||a.totalUSD===0?e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Cost Estimation"}),e.jsx("p",{className:"mt-2 text-xs text-gray-500",children:"No token data available"})]}):e.jsxs("div",{className:"rounded-xl border border-gray-800 bg-gray-900/50 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h3",{className:"text-sm font-semibold text-gray-300",children:"Cost Estimation"}),e.jsxs("span",{className:"font-mono text-lg font-bold text-white",children:["~",U(a.totalUSD)]})]}),e.jsxs("div",{className:"mt-4",children:[e.jsx("p",{className:"text-xs font-medium text-gray-400",children:"By Category"}),e.jsx(Re,{cost:a}),e.jsx(Le,{cost:a})]}),e.jsxs("div",{className:"mt-4",children:[e.jsx("p",{className:"text-xs font-medium text-gray-400",children:"By Model"}),e.jsx(Ee,{cost:a})]}),e.jsxs("div",{className:"mt-3 flex items-center justify-between border-t border-gray-800 pt-3",children:[e.jsx("p",{className:"text-[10px] text-gray-600",children:"Estimated based on API pricing. Actual costs may vary."}),e.jsx(A,{to:"/settings",className:"text-[10px] text-gray-500 hover:text-gray-300",children:"Configure pricing"})]})]})}function Re({cost:s}){const a=[{label:"Input tokens",value:s.byCategory.input,color:"text-brand-400"},{label:"Output tokens",value:s.byCategory.output,color:"text-emerald-400"},{label:"Cache read",value:s.byCategory.cacheRead,color:"text-amber-400"},{label:"Cache write",value:s.byCategory.cacheWrite,color:"text-purple-400"}];return e.jsx("div",{className:"mt-2 space-y-1",children:a.map(t=>e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-gray-400",children:t.label}),e.jsx("span",{className:`font-mono text-xs ${t.color}`,children:U(t.value)})]},t.label))})}function Le({cost:s}){if(s.totalUSD===0)return null;const a=[{key:"input",value:s.byCategory.input,color:"bg-brand-400"},{key:"output",value:s.byCategory.output,color:"bg-emerald-400"},{key:"cacheRead",value:s.byCategory.cacheRead,color:"bg-amber-400"},{key:"cacheWrite",value:s.byCategory.cacheWrite,color:"bg-purple-400"}];return e.jsx("div",{className:"mt-2 flex h-2 overflow-hidden rounded-full bg-gray-800",children:a.map(t=>{const r=t.value/s.totalUSD*100;return r<.5?null:e.jsx("div",{className:`${t.color} opacity-60`,style:{width:`${r}%`}},t.key)})})}function Ee({cost:s}){const a=Object.values(s.byModel).sort((t,r)=>r.totalCost-t.totalCost);return a.length===0?null:e.jsx("div",{className:"mt-2 space-y-1",children:a.map(t=>{const r=s.totalUSD>0?Math.round(t.totalCost/s.totalUSD*100):0;return e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"font-mono text-xs text-gray-300",children:t.displayName}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs text-gray-300",children:U(t.totalCost)}),e.jsxs("span",{className:"text-[10px] text-gray-500",children:["(",r,"%)"]}),e.jsxs("span",{className:"text-[10px] text-gray-600",children:[T(t.tokens.inputTokens+t.tokens.outputTokens+t.tokens.cacheReadInputTokens+t.tokens.cacheCreationInputTokens)," ","tok"]})]})]},t.modelId)})})}function Ae({tokensByModel:s}){const{cost:a,isLoading:t}=z(s);return t||!a||a.totalUSD===0?null:e.jsxs("span",{className:"font-mono text-xs text-emerald-400",title:"Estimated cost based on API pricing",children:["~",U(a.totalUSD)]})}function Oe(){return e.jsxs("div",{className:"mb-4 flex items-center gap-2 rounded-lg border border-emerald-800 bg-emerald-900/30 px-4 py-2 text-sm text-emerald-300",children:[e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-75"}),e.jsx("span",{className:"relative inline-flex h-2 w-2 rounded-full bg-emerald-500"})]}),"This session is currently active. Data refreshes automatically."]})}function Pe(s){const{data:a}=O(xe);return a?.some(t=>t.sessionId===s)??!1}function He(){const{sessionId:s}=_.useParams(),{project:a=""}=_.useSearch(),{privacyMode:t,anonymizeProjectName:r,anonymizeBranch:l}=Z(),c=Pe(s),{data:n,isLoading:m,error:d}=O(pe(s,a,c));if(m)return e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"h-8 w-48 animate-pulse rounded bg-gray-800"}),e.jsx("div",{className:"h-64 animate-pulse rounded-xl bg-gray-900/50"})]});if(d||!n)return e.jsxs("div",{className:"py-12 text-center",children:[e.jsxs("p",{className:"text-sm text-red-400",children:["Failed to load session: ",d?.message??"Not found"]}),e.jsx(A,{to:"/sessions",className:"mt-2 inline-block text-sm text-brand-300 hover:underline",children:"Back to sessions"})]});const f=n.turns[0]?.timestamp,u=n.turns[n.turns.length-1]?.timestamp,y=f&&u?new Date(u).getTime()-new Date(f).getTime():0;return e.jsxs("div",{children:[c&&e.jsx(Oe,{}),e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{children:[e.jsx(A,{to:"/sessions",className:"text-xs text-gray-500 hover:text-gray-300",children:"← Sessions"}),e.jsx("h1",{className:"mt-1 text-xl font-bold text-white",children:t?r(n.projectName):n.projectName}),e.jsxs("div",{className:"mt-1 flex items-center gap-3 text-xs text-gray-400",children:[n.branch&&e.jsx("span",{className:"font-mono",children:l(n.branch)}),f&&e.jsx("span",{children:H(f)}),e.jsx("span",{children:P(y)}),e.jsxs("span",{children:[n.turns.length," turns"]}),e.jsx(Ae,{tokensByModel:n.tokensByModel})]}),n.models.length>0&&e.jsx("div",{className:"mt-1 flex gap-1",children:n.models.map(h=>e.jsx("span",{className:"rounded bg-gray-800 px-1.5 py-0.5 text-[10px] font-mono text-gray-400",children:h.replace(/^claude-/,"").split("-202")[0]},h))})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(oe,{options:[{label:"Export Session (JSON)",onClick:()=>ie(ce(n),`session-${s.slice(0,8)}.json`,"application/json")}]}),e.jsx("span",{className:"font-mono text-xs text-gray-600",children:s.slice(0,8)})]})]}),e.jsxs("div",{className:"mt-6 grid grid-cols-1 gap-4 md:grid-cols-2",children:[e.jsx(ke,{contextWindow:n.contextWindow,tokens:n.totalTokens}),e.jsx(Me,{toolFrequency:n.toolFrequency})]}),e.jsx("div",{className:"mt-4",children:e.jsx(Ue,{tokensByModel:n.tokensByModel})}),n.agents.length>0&&e.jsx("div",{className:"mt-4",children:e.jsx(Se,{agents:n.agents})}),n.tasks.length>0&&e.jsx("div",{className:"mt-4",children:e.jsx($e,{tasks:n.tasks})}),e.jsx("div",{className:"mt-4",children:e.jsx(Ce,{errors:n.errors})}),e.jsxs("div",{className:"mt-6",children:[e.jsx("h2",{className:"mb-3 text-sm font-semibold text-gray-300",children:"Timeline"}),e.jsx(ve,{turns:n.turns,agents:n.agents,skills:n.skills,errors:n.errors})]}),(n.skills.length>0||n.agents.some(h=>(h.skills?.length??0)>0))&&e.jsx("div",{className:"mt-6",children:e.jsx(De,{agents:n.agents,skills:n.skills})})]})}export{He as component};
|