claude-discover 1.9.1 → 1.9.2
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/out/main/main.js
CHANGED
|
@@ -432,13 +432,14 @@ class RequestParser {
|
|
|
432
432
|
return files;
|
|
433
433
|
}
|
|
434
434
|
}
|
|
435
|
+
const agentKey = (id) => id?.includes("@") ? id.slice(0, id.indexOf("@")) : id?.replace(/^a/, "").replace(/-[0-9a-f]{16}$/, "") ?? null;
|
|
435
436
|
class RequestFile {
|
|
436
437
|
constructor(sessionId, { dir = REQUESTS_DIR, agentId = null } = {}) {
|
|
437
438
|
this.filePath = join(dir, `${sessionId}.requests.jsonl`);
|
|
438
|
-
this.
|
|
439
|
+
this.agentKey = agentKey(agentId);
|
|
439
440
|
}
|
|
440
441
|
#mine(rec) {
|
|
441
|
-
return (rec.requestHeaders?.["x-claude-code-agent-id"] ?? null) === this.
|
|
442
|
+
return agentKey(rec.requestHeaders?.["x-claude-code-agent-id"] ?? null) === this.agentKey;
|
|
442
443
|
}
|
|
443
444
|
async lines() {
|
|
444
445
|
const raw = await fsp.readFile(this.filePath, "utf8").catch(() => "");
|
|
@@ -1126,7 +1127,7 @@ class SessionsService extends EventEmitter {
|
|
|
1126
1127
|
}
|
|
1127
1128
|
// Subagents send the parent's session id, so the proxy logs their requests into the parent's
|
|
1128
1129
|
// file, tagged x-claude-code-agent-id — route their reads there. The transcript filename is
|
|
1129
|
-
// `agent-<id
|
|
1130
|
+
// `agent-<id>`; RequestFile normalizes that id against the header's own spelling.
|
|
1130
1131
|
#requestFile(sessionId, parentSessionId) {
|
|
1131
1132
|
const agentId = parentSessionId && sessionId.startsWith("agent-") ? sessionId.slice("agent-".length) : null;
|
|
1132
1133
|
return agentId ? new RequestFile(parentSessionId, { agentId }) : new RequestFile(sessionId);
|
|
@@ -34,13 +34,13 @@ function useLocalStorage(key, initial) {
|
|
|
34
34
|
}
|
|
35
35
|
function clearOutdatedLocalStorage() {
|
|
36
36
|
const version = localStorage.getItem(VERSION_KEY);
|
|
37
|
-
if (version !== "1.9.
|
|
38
|
-
const [MAJOR, MINOR, PATCH] = "1.9.
|
|
37
|
+
if (version !== "1.9.2") {
|
|
38
|
+
const [MAJOR, MINOR, PATCH] = "1.9.2".split(".");
|
|
39
39
|
const [major, minor, patch] = (version ?? "").split(".");
|
|
40
40
|
if (MAJOR !== major || MINOR !== minor) {
|
|
41
41
|
localStorage.clear();
|
|
42
42
|
}
|
|
43
|
-
localStorage.setItem(VERSION_KEY, "1.9.
|
|
43
|
+
localStorage.setItem(VERSION_KEY, "1.9.2");
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
function useMouseFontScale(storageKey) {
|
|
@@ -983,6 +983,26 @@ ${text}` }]
|
|
|
983
983
|
return out;
|
|
984
984
|
}
|
|
985
985
|
const currentModel = (turns) => turns.findLast((t) => t.model && t.model !== "<synthetic>")?.model;
|
|
986
|
+
const SMALL_CONTEXT = /* @__PURE__ */ new Set([
|
|
987
|
+
"claude-3-opus",
|
|
988
|
+
"claude-3-sonnet",
|
|
989
|
+
"claude-3-haiku",
|
|
990
|
+
"claude-3-5-sonnet",
|
|
991
|
+
"claude-3-5-haiku",
|
|
992
|
+
"claude-3-7-sonnet",
|
|
993
|
+
"claude-haiku-4-5",
|
|
994
|
+
"claude-opus-4",
|
|
995
|
+
"claude-opus-4-1",
|
|
996
|
+
"claude-opus-4-5",
|
|
997
|
+
"claude-opus-4-6",
|
|
998
|
+
"claude-sonnet-4",
|
|
999
|
+
"claude-sonnet-4-5",
|
|
1000
|
+
"claude-sonnet-4-6"
|
|
1001
|
+
]);
|
|
1002
|
+
function contextWindow(models = []) {
|
|
1003
|
+
const is200k = (model) => SMALL_CONTEXT.has(model.replace(/[-@]\d{8}.*$/, ""));
|
|
1004
|
+
return models.some((m) => m && !is200k(m)) ? 1e6 : 2e5;
|
|
1005
|
+
}
|
|
986
1006
|
function normalizeContent(content) {
|
|
987
1007
|
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
988
1008
|
if (!Array.isArray(content)) return [];
|
|
@@ -1411,22 +1431,23 @@ function ConversationView({ items, instructions = [], expandAll = null }) {
|
|
|
1411
1431
|
const durations = reactExports.useMemo(() => cycleDurations(groups), [groups]);
|
|
1412
1432
|
const findOpen = useFindActive();
|
|
1413
1433
|
const [scale, zoomRef] = useMouseFontScale("font-scale.conversation");
|
|
1434
|
+
const model = currentModel(turns);
|
|
1435
|
+
const ctxLimit = contextWindow([model]);
|
|
1414
1436
|
const hasTimeline = points.some(Boolean);
|
|
1415
1437
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandAllContext.Provider, { value: expandAll, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: zoomRef, className: `conversation${hasTimeline ? " has-token-timeline" : ""}`, style: { "--font-scale": scale }, children: groups.map((g, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `conv-row conv-row-${g.kind}`, children: [
|
|
1416
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(LazyMount, { eager: i < 8, forceMount: findOpen, placeholderMinHeight: 80, children: g.kind === "user" ? /* @__PURE__ */ jsxRuntimeExports.jsx(UserRow, { turns: g.turns, point: points[i] }) : g.kind === "assistant" ? /* @__PURE__ */ jsxRuntimeExports.jsx(AssistantCard, { turns: g.turns, point: points[i], duration: durations[i], showAuthor: groups[i - 1]?.kind !== "assistant" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(InstructionRun, { turns: g.turns, model
|
|
1438
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LazyMount, { eager: i < 8, forceMount: findOpen, placeholderMinHeight: 80, children: g.kind === "user" ? /* @__PURE__ */ jsxRuntimeExports.jsx(UserRow, { turns: g.turns, point: points[i], ctxLimit }) : g.kind === "assistant" ? /* @__PURE__ */ jsxRuntimeExports.jsx(AssistantCard, { turns: g.turns, point: points[i], ctxLimit, duration: durations[i], showAuthor: groups[i - 1]?.kind !== "assistant" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(InstructionRun, { turns: g.turns, model }) }),
|
|
1417
1439
|
points[i] ? /* @__PURE__ */ jsxRuntimeExports.jsx(TokenPoint, { point: points[i] }) : hasTimeline && g.kind === "user" && g.turns.some(isCommandTurn) && /* @__PURE__ */ jsxRuntimeExports.jsx(TokenPoint, { point: { role: "command", delta: 0 } })
|
|
1418
1440
|
] }, g.turns[0].uuid)) }) });
|
|
1419
1441
|
}
|
|
1420
1442
|
const ClaudeIcon = () => /* @__PURE__ */ jsxRuntimeExports.jsx("img", { className: "msg-icon claude-icon", src: claudeIcon, alt: "" });
|
|
1421
|
-
const CTX_LIMIT = THRESHOLDS.context.danger;
|
|
1422
1443
|
function TokenPoint({ point: p }) {
|
|
1423
1444
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `token-point token-point-${p.role}${p.delta < 0 ? " negative" : ""}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "token-point-dot" }) });
|
|
1424
1445
|
}
|
|
1425
|
-
function TokenStats({ point }) {
|
|
1446
|
+
function TokenStats({ point, ctxLimit }) {
|
|
1426
1447
|
if (!point) return null;
|
|
1427
1448
|
const rows = [];
|
|
1428
1449
|
if (point.ctx != null) {
|
|
1429
|
-
const width = Math.min(point.ctx /
|
|
1450
|
+
const width = Math.min(point.ctx / ctxLimit, 1) * 100;
|
|
1430
1451
|
rows.push(`<div class="token-tooltip-ctx">Context <span class="token-point-ctx-bar"><span style="width:${width}%"></span></span> <span class="token-tooltip-ctx-val">${fmtCompact(point.ctx)}</span></div>`);
|
|
1431
1452
|
}
|
|
1432
1453
|
const u = point.usage;
|
|
@@ -1444,7 +1465,7 @@ function TokenStats({ point }) {
|
|
|
1444
1465
|
rows.push(`<div class="token-tooltip-total"><span>Accumulated tokens</span><span>${fmtCompact(point.total)}</span></div>`);
|
|
1445
1466
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "msg-tokens", "data-tippy-html": `<div class="token-tooltip">${rows.join("")}</div>`, children: fmtCompact(point.total) });
|
|
1446
1467
|
}
|
|
1447
|
-
function UserRow({ turns, point }) {
|
|
1468
|
+
function UserRow({ turns, point, ctxLimit }) {
|
|
1448
1469
|
const [open, setOpen] = useCollapsed(false);
|
|
1449
1470
|
const msg = turns.find((t) => !isContextTurn(t));
|
|
1450
1471
|
const ctxItems = turns.filter(isContextTurn).flatMap((t) => t.blocks);
|
|
@@ -1464,7 +1485,7 @@ function UserRow({ turns, point }) {
|
|
|
1464
1485
|
] })
|
|
1465
1486
|
] }),
|
|
1466
1487
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "msg-header-right", children: [
|
|
1467
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TokenStats, { point }),
|
|
1488
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TokenStats, { point, ctxLimit }),
|
|
1468
1489
|
msg.ts != null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "msg-time", children: format(msg.ts, "HH:mm:ss") })
|
|
1469
1490
|
] })
|
|
1470
1491
|
] }),
|
|
@@ -1472,7 +1493,7 @@ function UserRow({ turns, point }) {
|
|
|
1472
1493
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TurnRow, { turn: msg })
|
|
1473
1494
|
] });
|
|
1474
1495
|
}
|
|
1475
|
-
function AssistantCard({ turns, point, duration: duration2, showAuthor = true }) {
|
|
1496
|
+
function AssistantCard({ turns, point, ctxLimit, duration: duration2, showAuthor = true }) {
|
|
1476
1497
|
const [open, setOpen] = useCollapsed(false);
|
|
1477
1498
|
const toolBlocks = turns.flatMap((t) => t.blocks.filter((b) => b.type === "tool_use"));
|
|
1478
1499
|
const errorCount = toolBlocks.filter((b) => b.result?.is_error).length;
|
|
@@ -1506,7 +1527,7 @@ function AssistantCard({ turns, point, duration: duration2, showAuthor = true })
|
|
|
1506
1527
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: summary })
|
|
1507
1528
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "msg-summary", children: summary })),
|
|
1508
1529
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "msg-header-right", children: [
|
|
1509
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TokenStats, { point }),
|
|
1530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TokenStats, { point, ctxLimit }),
|
|
1510
1531
|
end != null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "msg-time", title: duration2 > 0 ? `Response time: ${fmtDuration(duration2)}` : null, children: format(end, "HH:mm:ss") })
|
|
1511
1532
|
] })
|
|
1512
1533
|
] }),
|
|
@@ -1908,7 +1929,6 @@ function RequestsView({ sessionId, date, granularity = "day", fileSize = 0, expa
|
|
|
1908
1929
|
] })
|
|
1909
1930
|
] });
|
|
1910
1931
|
}
|
|
1911
|
-
const CONTEXT_WINDOW$1 = THRESHOLDS.context.danger;
|
|
1912
1932
|
let MAX_LINES = 10;
|
|
1913
1933
|
let MAX_LINE_CHARS = 200;
|
|
1914
1934
|
let MODEL = null;
|
|
@@ -1971,7 +1991,8 @@ function markdownSession(meta, items, truncated, instructions = []) {
|
|
|
1971
1991
|
const t = meta.tokens;
|
|
1972
1992
|
const stu = meta.serverToolUse;
|
|
1973
1993
|
const wallDuration = meta.lastActivityAt - meta.startedAt;
|
|
1974
|
-
const
|
|
1994
|
+
const ctxLimit = contextWindow(meta.models);
|
|
1995
|
+
const contextPct = Math.round(meta.lastContextTokens / ctxLimit * 100);
|
|
1975
1996
|
const cacheHitPct = (meta.cacheHitRatio * 100).toFixed(0);
|
|
1976
1997
|
const turns = items ? flatten(items, instructions) : null;
|
|
1977
1998
|
MODEL = turns ? currentModel(turns) : null;
|
|
@@ -1987,7 +2008,7 @@ ${transcript}`;
|
|
|
1987
2008
|
- Estimated cost: ${fmtUSD(meta.cost)}
|
|
1988
2009
|
- Total tokens: ${fmtCompact(meta.totalTokens)}
|
|
1989
2010
|
- Working time: ${fmtDuration(meta.activeMs)}
|
|
1990
|
-
- Context size: ${fmtCompact(meta.lastContextTokens)} / ${fmtCompact(
|
|
2011
|
+
- Context size: ${fmtCompact(meta.lastContextTokens)} / ${fmtCompact(ctxLimit)} (${contextPct}%)${meta.savings.using5mCache > 0 ? `
|
|
1991
2012
|
|
|
1992
2013
|
## Potential savings
|
|
1993
2014
|
- with 5m cache: ${meta.cost > 0 ? `(${(meta.savings.using5mCache / meta.cost * 100).toFixed(0)}%) ` : ""}−${fmtUSD(meta.savings.using5mCache)}` : ""}
|
|
@@ -2155,7 +2176,6 @@ ${body}`;
|
|
|
2155
2176
|
] })
|
|
2156
2177
|
] });
|
|
2157
2178
|
}
|
|
2158
|
-
const CONTEXT_WINDOW = THRESHOLDS.context.danger;
|
|
2159
2179
|
function SessionSummary({ meta, items, instructions, agent, onOpenAgent, granularity = "day" }) {
|
|
2160
2180
|
const timeFormat = granularity === "day" ? "pp" : "MMM d, pp";
|
|
2161
2181
|
const onAnalyze = () => {
|
|
@@ -2174,7 +2194,8 @@ ${body}`);
|
|
|
2174
2194
|
const stu = meta.serverToolUse;
|
|
2175
2195
|
const hasServerTools = stu.webSearch > 0 || stu.webFetch > 0;
|
|
2176
2196
|
const modelLabel = meta.models.join(", ") || "—";
|
|
2177
|
-
const
|
|
2197
|
+
const ctxLimit = contextWindow(meta.models);
|
|
2198
|
+
const ctxTone = tone(meta.lastContextTokens, THRESHOLDS.context);
|
|
2178
2199
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-summary", children: [
|
|
2179
2200
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "summary-ai", children: [
|
|
2180
2201
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "summary-ai-row", children: [
|
|
@@ -2209,7 +2230,7 @@ ${body}`);
|
|
|
2209
2230
|
] }) }),
|
|
2210
2231
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Total tokens", value: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: tone(totalTokens2, THRESHOLDS.tokens), children: fmtCompact(totalTokens2) }) }),
|
|
2211
2232
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Working time", value: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: tone(activeDuration, THRESHOLDS.workTime), children: fmtDuration(activeDuration) }) }),
|
|
2212
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Context size", value: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className:
|
|
2233
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Context size", value: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: ctxTone, children: `${fmtCompact(meta.lastContextTokens)} / ${fmtCompact(ctxLimit)}` }), below: /* @__PURE__ */ jsxRuntimeExports.jsx(Bar, { ratio: meta.lastContextTokens / ctxLimit, tone: ctxTone }) })
|
|
2213
2234
|
] }),
|
|
2214
2235
|
meta.savings.using5mCache > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Section, { title: "Potential savings", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2215
2236
|
Field,
|
|
@@ -2364,10 +2385,10 @@ function Session({ meta, missing, date, granularity = "day" }) {
|
|
|
2364
2385
|
};
|
|
2365
2386
|
}, [sessionId, date, granularity, fileSize]);
|
|
2366
2387
|
if (!meta) {
|
|
2367
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-view empty", children: missing ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-missing", children: [
|
|
2388
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-view empty", children: missing?.warn ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-missing", children: [
|
|
2368
2389
|
"⚠ ",
|
|
2369
|
-
missing
|
|
2370
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Select a session to inspect." }) });
|
|
2390
|
+
missing.text
|
|
2391
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: missing?.text || "Select a session to inspect." }) });
|
|
2371
2392
|
}
|
|
2372
2393
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-view", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "view-body", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "view-conversation", children: agentOpen ? /* @__PURE__ */ jsxRuntimeExports.jsx(AgentView, { meta, items, instructions, agent, onClose: () => setAgentOpen(false) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "view-tab-pane", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "view-tab-pane-row", children: [
|
|
2373
2394
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "view-tab-pane-main", children: [
|
|
@@ -2598,8 +2619,8 @@ function App() {
|
|
|
2598
2619
|
let missing = null;
|
|
2599
2620
|
if (!selected && scanProgress?.scanning === false) {
|
|
2600
2621
|
const when = granularity === "day" ? `on ${format(anchor, "MMM d, yyyy")}` : `in this ${granularity}`;
|
|
2601
|
-
if (!sessions.length) missing = `No sessions recorded ${when}
|
|
2602
|
-
else if (deepLink?.date === format(anchor, "yyyy-MM-dd")) missing = `Session ${selectedId} has no records ${when}
|
|
2622
|
+
if (!sessions.length) missing = { text: `No sessions recorded ${when}.` };
|
|
2623
|
+
else if (deepLink?.date === format(anchor, "yyyy-MM-dd")) missing = { text: `Session ${selectedId} has no records ${when}.`, warn: true };
|
|
2603
2624
|
}
|
|
2604
2625
|
const selectSession = reactExports.useCallback((id, link = null) => {
|
|
2605
2626
|
closeFind();
|
package/out/renderer/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta charset="UTF-8" />
|
|
7
7
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
8
|
<title>Discover</title>
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-BugPzqD2.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="./assets/vendors-S1fS5xz9.js">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="./assets/vendors-B4XMnGdr.css">
|
|
12
12
|
<link rel="stylesheet" crossorigin href="./assets/index-03LlBvFr.css">
|
package/package.json
CHANGED