claude-discover 1.9.2 → 1.9.5
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/bin/claude/statusline.mjs +3 -9
- package/bin/proxy.mjs +38 -51
- package/out/main/main.js +783 -529
- package/out/preload/preload.cjs +2 -2
- package/out/renderer/assets/{index-BugPzqD2.js → index-CX9ZlZGo.js} +162 -103
- package/out/renderer/assets/{index-03LlBvFr.css → index-DZ1Gj6hz.css} +35 -54
- package/out/renderer/assets/{vendors-S1fS5xz9.js → vendors-JM3FOKMR.js} +3173 -1199
- package/out/renderer/index.html +3 -3
- package/package.json +10 -10
- package/bin/claude/hooks.mjs +0 -102
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, j as jsxRuntimeExports, f as format, s as startOfWeek, a as startOfMonth, b as startOfDay, e as endOfWeek, c as endOfMonth, d as endOfDay, g as addWeeks, h as addMonths, i as addDays, k as isSameWeek, l as isSameMonth, m as isSameDay, n as intervalToDuration, o as getDaysInMonth, p as addHours, q as encode, H as Hourglass, G as Gauge, M as MessageSquare, C as Clock, Z as Zap, D as DollarSign, R as React, t as Markdown$1, u as rehypeHighlight, v as remarkGfm, T as Terminal, J as JsonView, w as vscodeTheme, x as tippy, y as reactDomExports, z as
|
|
1
|
+
import { r as reactExports, j as jsxRuntimeExports, f as format, s as startOfWeek, a as startOfMonth, b as startOfDay, e as endOfWeek, c as endOfMonth, d as endOfDay, g as addWeeks, h as addMonths, i as addDays, k as isSameWeek, l as isSameMonth, m as isSameDay, n as intervalToDuration, o as getDaysInMonth, p as addHours, q as encode, H as Hourglass, G as Gauge, M as MessageSquare, C as Clock, Z as Zap, D as DollarSign, R as React, t as Markdown$1, u as rehypeHighlight, v as remarkGfm, T as Terminal, J as JsonView, w as vscodeTheme, x as tippy, y as reactDomExports, z as an, A as qt, Q as Qt, B as nn, E as parse, F as delegate, I as clientExports } from "./vendors-JM3FOKMR.js";
|
|
2
2
|
const SOURCE_COLORS = {
|
|
3
3
|
scheduled: "#14b8a6",
|
|
4
4
|
cli: "#3b82f6",
|
|
@@ -9,7 +9,7 @@ const SOURCE_COLORS = {
|
|
|
9
9
|
other: "#94a3b8"
|
|
10
10
|
};
|
|
11
11
|
const SOURCE_ORDER = ["cli", "claude-desktop", "sdk-cli", "sdk-ts", "sdk-py", "scheduled", "other"];
|
|
12
|
-
const SOURCE_LABELS = {
|
|
12
|
+
const SOURCE_LABELS$1 = {
|
|
13
13
|
scheduled: "Scheduled",
|
|
14
14
|
cli: "CLI",
|
|
15
15
|
"claude-desktop": "Desktop",
|
|
@@ -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.5") {
|
|
38
|
+
const [MAJOR, MINOR, PATCH] = "1.9.5".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.5");
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
function useMouseFontScale(storageKey) {
|
|
@@ -104,12 +104,12 @@ function useMouse(ref, handlers) {
|
|
|
104
104
|
}
|
|
105
105
|
const isJournal = (s) => s.sessionId.endsWith("-journal");
|
|
106
106
|
function subagentsByParent(sessions) {
|
|
107
|
-
const
|
|
107
|
+
const parents = new Set(sessions.map((s) => s.filePath));
|
|
108
108
|
const byParent = /* @__PURE__ */ new Map();
|
|
109
109
|
for (const s of sessions) {
|
|
110
|
-
if (!
|
|
111
|
-
let arr = byParent.get(s.
|
|
112
|
-
if (!arr) byParent.set(s.
|
|
110
|
+
if (!parents.has(s.parentFilePath)) continue;
|
|
111
|
+
let arr = byParent.get(s.parentFilePath);
|
|
112
|
+
if (!arr) byParent.set(s.parentFilePath, arr = []);
|
|
113
113
|
arr.push(s);
|
|
114
114
|
}
|
|
115
115
|
return byParent;
|
|
@@ -365,7 +365,7 @@ function GanttChart({
|
|
|
365
365
|
}, []);
|
|
366
366
|
const { groups, totalHeight } = reactExports.useMemo(() => {
|
|
367
367
|
const clusters = subagentClusters(sessions, SUBAGENT_SPLIT_GAP).filter((c) => c.length >= 2);
|
|
368
|
-
const collapsed = new Set(clusters.flat().map((s) => s.
|
|
368
|
+
const collapsed = new Set(clusters.flat().map((s) => s.filePath));
|
|
369
369
|
const byKey = /* @__PURE__ */ new Map();
|
|
370
370
|
const addItem = (s, item, cost) => {
|
|
371
371
|
const key = s.project || "(no project)";
|
|
@@ -375,9 +375,9 @@ function GanttChart({
|
|
|
375
375
|
group.cost += cost || 0;
|
|
376
376
|
};
|
|
377
377
|
for (const s of sessions) {
|
|
378
|
-
if (collapsed.has(s.
|
|
378
|
+
if (collapsed.has(s.filePath)) continue;
|
|
379
379
|
addItem(s, {
|
|
380
|
-
id: s.
|
|
380
|
+
id: s.filePath,
|
|
381
381
|
label: s.summary || s.firstUserPrompt || s.firstUserCommand || s.sessionId,
|
|
382
382
|
start: s.startedAt,
|
|
383
383
|
end: endOf(s),
|
|
@@ -388,7 +388,7 @@ function GanttChart({
|
|
|
388
388
|
for (const subs of clusters) {
|
|
389
389
|
const periods = subs.map((c) => ({ start: c.startedAt, end: endOf(c) }));
|
|
390
390
|
addItem(subs[0], {
|
|
391
|
-
id: `${subs[0].
|
|
391
|
+
id: `${subs[0].filePath}::subagents`,
|
|
392
392
|
start: periods[0].start,
|
|
393
393
|
end: Math.max(...periods.map((p) => p.end)),
|
|
394
394
|
source: subs[0].source,
|
|
@@ -498,7 +498,7 @@ function GanttChart({
|
|
|
498
498
|
g.placed.map(({ item, lane }) => {
|
|
499
499
|
const y = g.yOffset + lane * (bar.height + bar.row_gap);
|
|
500
500
|
const color = SOURCE_COLORS[item.source] || SOURCE_COLORS.other;
|
|
501
|
-
const isSelected = item.subs ? item.subs.some((c) => c.
|
|
501
|
+
const isSelected = item.subs ? item.subs.some((c) => c.filePath === selectedId) : item.id === selectedId;
|
|
502
502
|
const periods = item.activityPeriods?.length ? item.activityPeriods : [{ start: item.start, end: item.end }];
|
|
503
503
|
const rawX1 = xFor(item.start);
|
|
504
504
|
const rawX2 = xFor(item.end);
|
|
@@ -509,7 +509,7 @@ function GanttChart({
|
|
|
509
509
|
"g",
|
|
510
510
|
{
|
|
511
511
|
className: `bar ${isSelected ? "selected" : ""}`,
|
|
512
|
-
onClick: () => onSelect(item.subs ? item.subs.at(-1).
|
|
512
|
+
onClick: () => onSelect(item.subs ? item.subs.at(-1).filePath : item.id),
|
|
513
513
|
children: [
|
|
514
514
|
/* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x, y, width: w, height: bar.height, rx: bar.radius, fill: color, className: "bar-fill" }),
|
|
515
515
|
periods.slice(0, -1).map((p, i) => {
|
|
@@ -521,7 +521,7 @@ function GanttChart({
|
|
|
521
521
|
item.subs && /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x, y, width: w, height: bar.height, rx: bar.radius, fill: "url(#gantt-subagent-hatch)", opacity: 0.5, pointerEvents: "none" }),
|
|
522
522
|
item.subs && /* @__PURE__ */ jsxRuntimeExports.jsx("text", { x: x + w / 2, y: y + bar.height / 2, textAnchor: "middle", dominantBaseline: "central", className: "gantt-bar-count", children: item.subCount }),
|
|
523
523
|
isSelected && /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x, y, width: w, height: bar.height, rx: bar.radius, className: "bar-outline" }),
|
|
524
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("title", { children: `${item.subs ? `${item.subCount} subagents` : `${SOURCE_LABELS[item.source] || item.source} · ${item.label}`}
|
|
524
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("title", { children: `${item.subs ? `${item.subCount} subagents` : `${SOURCE_LABELS$1[item.source] || item.source} · ${item.label}`}
|
|
525
525
|
${g.key}
|
|
526
526
|
${new Date(item.start).toLocaleString()} → ${new Date(item.end).toLocaleString()}` })
|
|
527
527
|
]
|
|
@@ -616,7 +616,7 @@ function Toolbar({
|
|
|
616
616
|
const dim = sourceFilter && !active2;
|
|
617
617
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: `legend-chip ${active2 ? "active" : ""} ${dim ? "dim" : ""}`, onClick: () => onToggleSourceFilter?.(k), children: [
|
|
618
618
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "swatch", style: { background: SOURCE_COLORS[k] || SOURCE_COLORS.other } }),
|
|
619
|
-
SOURCE_LABELS[k] || k
|
|
619
|
+
SOURCE_LABELS$1[k] || k
|
|
620
620
|
] }, k);
|
|
621
621
|
}) }),
|
|
622
622
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "gantt-toolbar-nav", children: [
|
|
@@ -677,14 +677,6 @@ function Toolbar({
|
|
|
677
677
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {})
|
|
678
678
|
] });
|
|
679
679
|
}
|
|
680
|
-
const HOUR = 60 * 60 * 1e3;
|
|
681
|
-
const THRESHOLDS = {
|
|
682
|
-
context: { warn: 1e5, danger: 2e5 },
|
|
683
|
-
messages: { warn: 250, danger: 500 },
|
|
684
|
-
workTime: { warn: 0.5 * HOUR, danger: 2 * HOUR },
|
|
685
|
-
cost: { warn: 3, danger: 8 },
|
|
686
|
-
tokens: { warn: 3e6, danger: 8e6 }
|
|
687
|
-
};
|
|
688
680
|
function fmtDuration(ms) {
|
|
689
681
|
if (!ms || ms < 0) return "—";
|
|
690
682
|
if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
|
|
@@ -709,6 +701,9 @@ function fmtNum(n) {
|
|
|
709
701
|
if (n == null) return "—";
|
|
710
702
|
return n.toLocaleString();
|
|
711
703
|
}
|
|
704
|
+
function fmtToolCalls({ toolCalls, skillCalls }) {
|
|
705
|
+
return skillCalls ? `${fmtNum(toolCalls)}, ${fmtNum(skillCalls)} skill${skillCalls === 1 ? "" : "s"}` : fmtNum(toolCalls);
|
|
706
|
+
}
|
|
712
707
|
function fmtUSD(n) {
|
|
713
708
|
if (n == null) return "—";
|
|
714
709
|
return `$${n.toFixed(2)}`;
|
|
@@ -872,6 +867,14 @@ function PeriodSummary({ sessions, dayAnchor, granularity = "day" }) {
|
|
|
872
867
|
] })
|
|
873
868
|
] });
|
|
874
869
|
}
|
|
870
|
+
const HOUR = 60 * 60 * 1e3;
|
|
871
|
+
const THRESHOLDS = {
|
|
872
|
+
context: { warn: 1e5, danger: 2e5 },
|
|
873
|
+
messages: { warn: 250, danger: 500 },
|
|
874
|
+
workTime: { warn: 0.5 * HOUR, danger: 2 * HOUR },
|
|
875
|
+
cost: { warn: 3, danger: 8 },
|
|
876
|
+
tokens: { warn: 3e6, danger: 8e6 }
|
|
877
|
+
};
|
|
875
878
|
const countTokens = (text, model = "") => {
|
|
876
879
|
if (!text) return 0;
|
|
877
880
|
const LEGACY_CLAUDE = /-(3|4)(-|$)/;
|
|
@@ -882,6 +885,7 @@ const queuedPrompt = (it) => it.type === "attachment" && it.attachment?.type ===
|
|
|
882
885
|
function flatten(items, instructions = []) {
|
|
883
886
|
const turns = [];
|
|
884
887
|
const results = {};
|
|
888
|
+
const companions = {};
|
|
885
889
|
for (const it of items) {
|
|
886
890
|
const queued = queuedPrompt(it);
|
|
887
891
|
if (queued) {
|
|
@@ -901,6 +905,7 @@ function flatten(items, instructions = []) {
|
|
|
901
905
|
continue;
|
|
902
906
|
}
|
|
903
907
|
if (it.type === "attachment" && it.attachment) {
|
|
908
|
+
if (it.attachment.type === "structured_output" && it.attachment.toolUseID) continue;
|
|
904
909
|
const block = { type: "attachment", attachment: it.attachment };
|
|
905
910
|
const last = turns[turns.length - 1];
|
|
906
911
|
if (last && last.isMeta && last.blocks.every((b) => b.type === "attachment")) {
|
|
@@ -939,9 +944,19 @@ ${text}` }]
|
|
|
939
944
|
});
|
|
940
945
|
continue;
|
|
941
946
|
}
|
|
947
|
+
if (it.turnCompanion && it.sourceToolUseID) {
|
|
948
|
+
companions[it.sourceToolUseID] = companionText(it);
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
const command = it.turnCompanion && turns.findLast((t) => t.uuid === it.parentUuid);
|
|
952
|
+
if (command) {
|
|
953
|
+
const name = command.blocks.map((b) => parseCommand(b.text)?.name).find(Boolean)?.replace(/^\//, "");
|
|
954
|
+
command.blocks.push({ type: "skill", name, text: companionText(it) });
|
|
955
|
+
continue;
|
|
956
|
+
}
|
|
942
957
|
if (it.type !== "user" && it.type !== "assistant") continue;
|
|
943
958
|
const msg = it.message || {};
|
|
944
|
-
const blocks = normalizeContent(msg.content)
|
|
959
|
+
const blocks = collapseRedactedThinking(normalizeContent(msg.content));
|
|
945
960
|
if (blocks.length === 0) continue;
|
|
946
961
|
for (const b of blocks) {
|
|
947
962
|
if (b.type === "tool_result" && b.tool_use_id) results[b.tool_use_id] = b;
|
|
@@ -961,21 +976,21 @@ ${text}` }]
|
|
|
961
976
|
});
|
|
962
977
|
}
|
|
963
978
|
for (const t of turns) {
|
|
964
|
-
t.blocks = t.blocks.map((b) => b.type === "tool_use" ? { ...b, result: results[b.id] } : b).filter((b) => !(b.type === "tool_result" && results[b.tool_use_id]));
|
|
979
|
+
t.blocks = t.blocks.map((b) => b.type === "tool_use" ? { ...b, result: withCompanion(results[b.id], companions[b.id]) } : b).filter((b) => !(b.type === "tool_result" && results[b.tool_use_id]));
|
|
965
980
|
}
|
|
966
981
|
const out = turns.filter((t) => t.blocks.length > 0);
|
|
967
|
-
|
|
982
|
+
if (instructions.length) {
|
|
983
|
+
const first = instructions.find((it) => it.timestamp);
|
|
968
984
|
const turn = {
|
|
969
|
-
uuid:
|
|
970
|
-
// system prompts share a file_path, their hash disambiguates
|
|
985
|
+
uuid: "instructions",
|
|
971
986
|
role: "instruction",
|
|
972
987
|
isMeta: true,
|
|
973
|
-
ts:
|
|
988
|
+
ts: first ? Date.parse(first.timestamp) - 500 : null,
|
|
974
989
|
model: null,
|
|
975
990
|
usage: null,
|
|
976
991
|
tokenDelta: null,
|
|
977
992
|
tokenTotal: null,
|
|
978
|
-
blocks:
|
|
993
|
+
blocks: instructions.map((it) => ({ type: "instruction", it }))
|
|
979
994
|
};
|
|
980
995
|
const i = out.findIndex((t) => t.ts != null && t.ts > turn.ts);
|
|
981
996
|
i === -1 ? out.push(turn) : out.splice(i, 0, turn);
|
|
@@ -1003,6 +1018,21 @@ function contextWindow(models = []) {
|
|
|
1003
1018
|
const is200k = (model) => SMALL_CONTEXT.has(model.replace(/[-@]\d{8}.*$/, ""));
|
|
1004
1019
|
return models.some((m) => m && !is200k(m)) ? 1e6 : 2e5;
|
|
1005
1020
|
}
|
|
1021
|
+
function collapseRedactedThinking(blocks) {
|
|
1022
|
+
const out = [];
|
|
1023
|
+
for (const b of blocks) {
|
|
1024
|
+
if (!(b.type === "thinking" && !b.thinking?.trim())) {
|
|
1025
|
+
out.push(b);
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
1028
|
+
const last = out[out.length - 1];
|
|
1029
|
+
if (last?.redacted) last.redacted++;
|
|
1030
|
+
else out.push({ type: "thinking", redacted: 1 });
|
|
1031
|
+
}
|
|
1032
|
+
return out;
|
|
1033
|
+
}
|
|
1034
|
+
const companionText = (it) => normalizeContent(it.message?.content).filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
1035
|
+
const withCompanion = (result, text) => text ? { ...result ?? { type: "tool_result" }, content: [...normalizeContent(result?.content), { type: "text", text }] } : result;
|
|
1006
1036
|
function normalizeContent(content) {
|
|
1007
1037
|
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
1008
1038
|
if (!Array.isArray(content)) return [];
|
|
@@ -1050,6 +1080,10 @@ function parseCommand(text) {
|
|
|
1050
1080
|
caveat: field("local-command-caveat")
|
|
1051
1081
|
};
|
|
1052
1082
|
}
|
|
1083
|
+
const SOURCE_LABELS = { system: "system prompt", tools: "tools", message: "user message" };
|
|
1084
|
+
function groupInstructions(strips) {
|
|
1085
|
+
return Object.entries(SOURCE_LABELS).map(([source, label]) => [label, strips.filter((it) => it.source === source)]).filter(([, list]) => list.length);
|
|
1086
|
+
}
|
|
1053
1087
|
function instructionTitle(it, model) {
|
|
1054
1088
|
const parts = [it.memory_type, it.model && it.model !== model && it.model].filter(Boolean).join(", ");
|
|
1055
1089
|
return parts ? `${it.name ?? it.file_path} (${parts})` : it.name ?? it.file_path;
|
|
@@ -1071,9 +1105,7 @@ function groupTurns(turns) {
|
|
|
1071
1105
|
else pending.push(t);
|
|
1072
1106
|
} else if (t.role === "instruction") {
|
|
1073
1107
|
flush();
|
|
1074
|
-
|
|
1075
|
-
if (prev?.kind === "instruction" && prev.turns.at(-1).ts === t.ts) prev.turns.push(t);
|
|
1076
|
-
else groups.push({ kind: "instruction", turns: [t] });
|
|
1108
|
+
groups.push({ kind: "instruction", turns: [t] });
|
|
1077
1109
|
} else if (t.role === "user") {
|
|
1078
1110
|
flush();
|
|
1079
1111
|
groups.push({ kind: "user", turns: [...pending, t] });
|
|
@@ -1148,11 +1180,11 @@ function SessionList({ sessions, selectedId, deepLink, onSelect }) {
|
|
|
1148
1180
|
const t = setInterval(() => tick((n) => n + 1), 6e4);
|
|
1149
1181
|
return () => clearInterval(t);
|
|
1150
1182
|
}, []);
|
|
1151
|
-
const
|
|
1152
|
-
|
|
1153
|
-
|
|
1183
|
+
const labelCommand = (s) => !(s.aiTitle || s.summary || s.firstUserPrompt) && parseCommand(s.firstUserCommand);
|
|
1184
|
+
const sessionLabel = (s) => {
|
|
1185
|
+
const c = labelCommand(s);
|
|
1186
|
+
return c ? `${c.name || c.message} ${c.args}` : s.aiTitle || s.summary || s.firstUserPrompt || s.sessionId || "";
|
|
1154
1187
|
};
|
|
1155
|
-
const sessionLabel = (s) => s.aiTitle || s.summary || s.firstUserPrompt || cmd(s.firstUserCommand) || s.sessionId || "";
|
|
1156
1188
|
const q = filter.trim().toLowerCase();
|
|
1157
1189
|
const filtered = q ? sessions.filter((s) => [
|
|
1158
1190
|
s.customTitle,
|
|
@@ -1170,9 +1202,9 @@ function SessionList({ sessions, selectedId, deepLink, onSelect }) {
|
|
|
1170
1202
|
const sorted = sortBy === "cost" ? [...filtered].sort((a, b) => (b.cost || 0) - (a.cost || 0)) : sortBy === "tokens" ? [...filtered].sort((a, b) => (b.totalTokens || 0) - (a.totalTokens || 0)) : sortBy === "name" ? [...filtered].sort((a, b) => sessionLabel(a).toLowerCase().localeCompare(sessionLabel(b).toLowerCase())) : filtered;
|
|
1171
1203
|
const grouped = reactExports.useMemo(() => {
|
|
1172
1204
|
const byParent = subagentsByParent(sorted);
|
|
1173
|
-
return sorted.flatMap((s) => byParent.has(s.
|
|
1205
|
+
return sorted.flatMap((s) => byParent.has(s.parentFilePath) ? [] : [
|
|
1174
1206
|
{ session: s, isChild: false },
|
|
1175
|
-
...(byParent.get(s.
|
|
1207
|
+
...(byParent.get(s.filePath) ?? []).map((c) => ({ session: c, isChild: true }))
|
|
1176
1208
|
]);
|
|
1177
1209
|
}, [sorted]);
|
|
1178
1210
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-list", children: [
|
|
@@ -1211,16 +1243,17 @@ function SessionList({ sessions, selectedId, deepLink, onSelect }) {
|
|
|
1211
1243
|
const isSubagent = s.sessionId.startsWith("agent-");
|
|
1212
1244
|
const journal = isJournal(s);
|
|
1213
1245
|
const isFork = !!s.forkedFrom;
|
|
1214
|
-
const linked = deepLink
|
|
1246
|
+
const linked = !!deepLink && s.filePath === selectedId;
|
|
1215
1247
|
const linkTip = linked && `Opened from deep link
|
|
1216
1248
|
claude-discover://session?id=${deepLink.id}${deepLink.date ? `&date=${deepLink.date}` : ""}`;
|
|
1249
|
+
const command = labelCommand(s);
|
|
1217
1250
|
const sessionName = s.customTitle && s.agentName && s.customTitle !== s.agentName ? `${s.customTitle} [${s.agentName}]` : s.customTitle || s.agentName || "";
|
|
1218
1251
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1219
1252
|
"div",
|
|
1220
1253
|
{
|
|
1221
|
-
ref: selectedId === s.
|
|
1222
|
-
className: `session-row ${selectedId === s.
|
|
1223
|
-
onClick: () => onSelect(selectedId === s.
|
|
1254
|
+
ref: selectedId === s.filePath ? selectedRef : null,
|
|
1255
|
+
className: `session-row ${selectedId === s.filePath ? "selected" : ""} ${isChild ? "is-subagent-child" : ""} ${linked ? "deep-linked" : ""}`,
|
|
1256
|
+
onClick: () => onSelect(selectedId === s.filePath ? null : s.filePath),
|
|
1224
1257
|
style: { borderLeftColor: SOURCE_COLORS[s.source] || SOURCE_COLORS.other },
|
|
1225
1258
|
children: [
|
|
1226
1259
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-row-main", children: [
|
|
@@ -1256,15 +1289,17 @@ ${TIPS.time}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { size: 11
|
|
|
1256
1289
|
] }),
|
|
1257
1290
|
isFork && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "fork-tag", title: `Forked from session ${s.forkedFrom.sessionId}`, children: "↳" }),
|
|
1258
1291
|
sessionName && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-name", children: sessionName }),
|
|
1259
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-label-text", children:
|
|
1292
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-label-text", children: command ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1293
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-command", children: command.name || command.message }),
|
|
1294
|
+
" ",
|
|
1295
|
+
command.args
|
|
1296
|
+
] }) : sessionLabel(s) })
|
|
1260
1297
|
] }),
|
|
1261
1298
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-time-bottom", children: [
|
|
1299
|
+
s.project && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-project", title: s.project, children: s.projectShort }),
|
|
1300
|
+
s.models?.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "session-model", children: s.models.map((m) => m.replace(/^claude-/, "")).join(", ") }),
|
|
1262
1301
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: format(s.lastActivityAt, "MMM d, HH:mm:ss"), children: fmtAgo(s.lastActivityAt) }),
|
|
1263
|
-
|
|
1264
|
-
", ",
|
|
1265
|
-
s.models.map((m) => m.replace(/^claude-/, "")).join(", ")
|
|
1266
|
-
] }),
|
|
1267
|
-
linked && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "deeplink-note", "data-tippy-content": linkTip, "data-tippy-maxWidth": 560, children: ", opened from deep link" })
|
|
1302
|
+
linked && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "deeplink-note", "data-tippy-content": linkTip, "data-tippy-maxWidth": 560, children: "opened from deep link" })
|
|
1268
1303
|
] })
|
|
1269
1304
|
] }),
|
|
1270
1305
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-row-stats", children: [
|
|
@@ -1273,7 +1308,7 @@ ${TIPS.time}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { size: 11
|
|
|
1273
1308
|
] })
|
|
1274
1309
|
]
|
|
1275
1310
|
},
|
|
1276
|
-
s.
|
|
1311
|
+
s.filePath
|
|
1277
1312
|
);
|
|
1278
1313
|
})
|
|
1279
1314
|
] })
|
|
@@ -1344,7 +1379,9 @@ function fenceTags(text) {
|
|
|
1344
1379
|
if (close < 0) continue;
|
|
1345
1380
|
const end = close + m[1].length + 3;
|
|
1346
1381
|
if (end !== text.length && text[end] !== "\n" && text[end] !== "\r") continue;
|
|
1347
|
-
|
|
1382
|
+
const gap = text.slice(cursor, m.index);
|
|
1383
|
+
if (out && !gap.trim()) out = out.slice(0, -4) + gap + text.slice(m.index, end) + "\n```";
|
|
1384
|
+
else out += gap + "```xml\n" + text.slice(m.index, end) + "\n```";
|
|
1348
1385
|
cursor = startRe.lastIndex = end;
|
|
1349
1386
|
}
|
|
1350
1387
|
out += text.slice(cursor);
|
|
@@ -1497,6 +1534,7 @@ function AssistantCard({ turns, point, ctxLimit, duration: duration2, showAuthor
|
|
|
1497
1534
|
const [open, setOpen] = useCollapsed(false);
|
|
1498
1535
|
const toolBlocks = turns.flatMap((t) => t.blocks.filter((b) => b.type === "tool_use"));
|
|
1499
1536
|
const errorCount = toolBlocks.filter((b) => b.result?.is_error).length;
|
|
1537
|
+
const skillCount = toolBlocks.filter((b) => b.name === "Skill").length;
|
|
1500
1538
|
const isAux = (t) => !t.blocks.some((b) => b.type === "text");
|
|
1501
1539
|
const foldable = toolBlocks.length > 0 && turns.some(isAux);
|
|
1502
1540
|
const end = turns.findLast((t) => t.ts != null)?.ts ?? null;
|
|
@@ -1508,6 +1546,7 @@ function AssistantCard({ turns, point, ctxLimit, duration: duration2, showAuthor
|
|
|
1508
1546
|
const anyVisible = turns.some((t) => !hidden(t));
|
|
1509
1547
|
const parts = [
|
|
1510
1548
|
toolBlocks.length > 0 && `${toolBlocks.length} tool call${toolBlocks.length === 1 ? "" : "s"}`,
|
|
1549
|
+
skillCount > 0 && `${skillCount} skill${skillCount === 1 ? "" : "s"}`,
|
|
1511
1550
|
errorCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "msg-errors", children: [
|
|
1512
1551
|
errorCount,
|
|
1513
1552
|
" error",
|
|
@@ -1552,21 +1591,25 @@ function Block({ block }) {
|
|
|
1552
1591
|
const cmd = parseCommand(block.text);
|
|
1553
1592
|
if (cmd) {
|
|
1554
1593
|
if (!cmd.name && !cmd.args && !cmd.stdout && !cmd.caveat) return null;
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
" ",
|
|
1559
|
-
cmd.args
|
|
1594
|
+
const promptArgs = cmd.args.trim().includes("\n");
|
|
1595
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1596
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "block-command", children: [
|
|
1597
|
+
cmd.name && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "cmd-name", children: cmd.name }),
|
|
1598
|
+
cmd.args && !promptArgs && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "cmd-args", children: [
|
|
1599
|
+
" ",
|
|
1600
|
+
cmd.args
|
|
1601
|
+
] }),
|
|
1602
|
+
cmd.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cmd-stdout", children: cmd.stdout }),
|
|
1603
|
+
cmd.caveat && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cmd-stdout", children: cmd.caveat })
|
|
1560
1604
|
] }),
|
|
1561
|
-
|
|
1562
|
-
cmd.caveat && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cmd-stdout", children: cmd.caveat })
|
|
1605
|
+
promptArgs && /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { className: "block-text", text: cmd.args, autoFence: true })
|
|
1563
1606
|
] });
|
|
1564
1607
|
}
|
|
1565
1608
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { className: "block-text", text: block.text, autoFence: true });
|
|
1566
1609
|
}
|
|
1567
1610
|
if (block.type === "thinking") {
|
|
1568
|
-
if (
|
|
1569
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { title: "
|
|
1611
|
+
if (block.redacted) return /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { title: `Thinking (encrypted${block.redacted > 1 ? ` · ${block.redacted}` : ""})` });
|
|
1612
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { title: "Thinking", defaultOpen: false, children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: block.thinking }) });
|
|
1570
1613
|
}
|
|
1571
1614
|
if (block.type === "tool_use") {
|
|
1572
1615
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Collapsible, { title: toolSummary(block.name, block.input), defaultOpen: false, children: [
|
|
@@ -1574,6 +1617,9 @@ function Block({ block }) {
|
|
|
1574
1617
|
block.result && /* @__PURE__ */ jsxRuntimeExports.jsx(Block, { block: block.result })
|
|
1575
1618
|
] });
|
|
1576
1619
|
}
|
|
1620
|
+
if (block.type === "skill") {
|
|
1621
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collapsible, { title: block.name ? `Skill: ${block.name}` : "Skill", defaultOpen: false, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { className: "block-text", text: block.text }) });
|
|
1622
|
+
}
|
|
1577
1623
|
if (block.type === "tool_result") {
|
|
1578
1624
|
const c = block.content;
|
|
1579
1625
|
const parts = Array.isArray(c) ? c : [typeof c === "string" ? { type: "text", text: c } : c];
|
|
@@ -1677,12 +1723,15 @@ function JsonBlock({ value }) {
|
|
|
1677
1723
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Markdown, { className: "block-text", text: "```json\n" + safeJson(value) + "\n```" });
|
|
1678
1724
|
}
|
|
1679
1725
|
function InstructionRun({ turns, model }) {
|
|
1680
|
-
const
|
|
1726
|
+
const strips = turns.flatMap((t) => t.blocks).map(({ it }) => ({ ...it, tokens: countTokens(it.content, it.model ?? model) }));
|
|
1681
1727
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1682
|
-
|
|
1683
|
-
|
|
1728
|
+
groupInstructions(strips).map(([label, list]) => /* @__PURE__ */ jsxRuntimeExports.jsxs(React.Fragment, { children: [
|
|
1729
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "aux instruction-source", children: label }),
|
|
1730
|
+
list.map((it) => /* @__PURE__ */ jsxRuntimeExports.jsx(InstructionFile, { it, model, tokens: it.tokens }, `${it.hash ?? it.file_path}-${it.timestamp}`))
|
|
1731
|
+
] }, label)),
|
|
1732
|
+
strips.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "aux instruction-total", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "instruction-tokens", children: [
|
|
1684
1733
|
"~ ",
|
|
1685
|
-
fmtCompact(
|
|
1734
|
+
fmtCompact(strips.reduce((a, it) => a + it.tokens, 0))
|
|
1686
1735
|
] }) })
|
|
1687
1736
|
] });
|
|
1688
1737
|
}
|
|
@@ -1885,7 +1934,7 @@ const Pane = React.memo(function Pane2({ value, headers, seen, expandAll }) {
|
|
|
1885
1934
|
] })
|
|
1886
1935
|
] });
|
|
1887
1936
|
});
|
|
1888
|
-
function RequestsView({
|
|
1937
|
+
function RequestsView({ filePath, date, granularity = "day", fileSize = 0, expandAll = null }) {
|
|
1889
1938
|
const [records, setRecords] = reactExports.useState(null);
|
|
1890
1939
|
const [selected, setSelected] = reactExports.useState(0);
|
|
1891
1940
|
const [tab, setTab] = reactExports.useState("request");
|
|
@@ -1896,16 +1945,16 @@ function RequestsView({ sessionId, date, granularity = "day", fileSize = 0, expa
|
|
|
1896
1945
|
reactExports.useEffect(() => {
|
|
1897
1946
|
setRecords(null);
|
|
1898
1947
|
setSelected(0);
|
|
1899
|
-
}, [
|
|
1948
|
+
}, [filePath, date, granularity]);
|
|
1900
1949
|
reactExports.useEffect(() => {
|
|
1901
1950
|
let cancelled = false;
|
|
1902
|
-
window.api.readRequests(
|
|
1951
|
+
window.api.readRequests(filePath, date || null, granularity).then((res) => {
|
|
1903
1952
|
if (!cancelled) setRecords(res);
|
|
1904
1953
|
});
|
|
1905
1954
|
return () => {
|
|
1906
1955
|
cancelled = true;
|
|
1907
1956
|
};
|
|
1908
|
-
}, [
|
|
1957
|
+
}, [filePath, date, granularity, fileSize]);
|
|
1909
1958
|
if (!records) return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "requests-view", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "requests-empty", children: "Loading…" }) });
|
|
1910
1959
|
if (!records.length) {
|
|
1911
1960
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "requests-view", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "requests-empty", children: "No captured requests for this session. Requests are recorded only while the capture proxy is running." }) });
|
|
@@ -1951,8 +2000,8 @@ function resultText(r) {
|
|
|
1951
2000
|
}
|
|
1952
2001
|
function renderBlock(b) {
|
|
1953
2002
|
if (b.type === "text") return truncate(b.text || "");
|
|
1954
|
-
if (b.type === "thinking") return `
|
|
1955
|
-
${fence(b.thinking
|
|
2003
|
+
if (b.type === "thinking") return b.redacted ? `_Thinking (encrypted${b.redacted > 1 ? ` · ${b.redacted}` : ""})_` : `Thinking:
|
|
2004
|
+
${fence(b.thinking)}`;
|
|
1956
2005
|
if (b.type === "tool_use") {
|
|
1957
2006
|
const tail = b.result ? `
|
|
1958
2007
|
${b.result.is_error ? "error" : "result"}:
|
|
@@ -1963,6 +2012,8 @@ ${fence(JSON.stringify(b.input, null, 2), "json")}${tail}`;
|
|
|
1963
2012
|
}
|
|
1964
2013
|
if (b.type === "tool_result") return `${b.is_error ? "error" : "result"}:
|
|
1965
2014
|
${fence(resultText(b))}`;
|
|
2015
|
+
if (b.type === "skill") return `Skill${b.name ? `: ${b.name}` : ""}:
|
|
2016
|
+
${fence(b.text)}`;
|
|
1966
2017
|
if (b.type === "image") return "[image]";
|
|
1967
2018
|
if (b.type === "instruction") {
|
|
1968
2019
|
const it = b.it;
|
|
@@ -1974,9 +2025,11 @@ ${fence(it.error ? `error: ${it.error}` : it.content || "")}`;
|
|
|
1974
2025
|
return fence(JSON.stringify(b, null, 2), "json");
|
|
1975
2026
|
}
|
|
1976
2027
|
function renderTurn(t) {
|
|
1977
|
-
if (t.role === "instruction")
|
|
2028
|
+
if (t.role === "instruction") {
|
|
2029
|
+
return groupInstructions(t.blocks.map((b) => b.it)).map(([label, list]) => `**Instructions loaded (${label}):**
|
|
1978
2030
|
|
|
1979
|
-
${
|
|
2031
|
+
${list.map((it) => renderBlock({ type: "instruction", it })).join("\n\n")}`).join("\n\n");
|
|
2032
|
+
}
|
|
1980
2033
|
const role = t.role === "user" ? t.queued ? "User (queued)" : "User" : `Assistant`;
|
|
1981
2034
|
const tokens2 = t.tokenTotal > 0 && t.tokenDelta != null ? ` (${t.tokenDelta >= 0 ? "+" : ""}${fmtCompact(t.tokenDelta)} / ${fmtCompact(t.tokenTotal)} tokens)` : "";
|
|
1982
2035
|
return `**${role}${tokens2}:**
|
|
@@ -2028,7 +2081,7 @@ ${transcript}`;
|
|
|
2028
2081
|
- Wall duration: ${fmtDuration(wallDuration)}
|
|
2029
2082
|
- Active periods: ${fmtNum(meta.activityPeriods.length)}
|
|
2030
2083
|
- Messages: ${fmtNum(meta.messageCount)}
|
|
2031
|
-
- Tool calls: ${
|
|
2084
|
+
- Tool calls: ${fmtToolCalls(meta)}
|
|
2032
2085
|
|
|
2033
2086
|
## Identity
|
|
2034
2087
|
- Model: ${meta.models.join(", ") || "—"}
|
|
@@ -2273,7 +2326,7 @@ ${body}`);
|
|
|
2273
2326
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Wall duration", value: fmtDuration(wallDuration) }),
|
|
2274
2327
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Active periods", value: fmtNum(meta.activityPeriods.length) }),
|
|
2275
2328
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Messages", value: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: tone(meta.messageCount, THRESHOLDS.messages), children: fmtNum(meta.messageCount) }) }),
|
|
2276
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Tool calls", value:
|
|
2329
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Tool calls", value: fmtToolCalls(meta) })
|
|
2277
2330
|
] }),
|
|
2278
2331
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Section, { title: "Identity", children: [
|
|
2279
2332
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Field, { label: "Model", value: modelLabel, mono: true }),
|
|
@@ -2365,17 +2418,17 @@ function Session({ meta, missing, date, granularity = "day" }) {
|
|
|
2365
2418
|
const [mode, setMode] = useLocalStorage("session.view-mode", "conversation");
|
|
2366
2419
|
const [agentOpen, setAgentOpen] = reactExports.useState(false);
|
|
2367
2420
|
const [expandAll, setExpandAll] = reactExports.useState(null);
|
|
2368
|
-
const
|
|
2421
|
+
const filePath = meta?.filePath;
|
|
2369
2422
|
const fileSize = meta?.fileSize;
|
|
2370
|
-
const agent = useAgent(`${
|
|
2423
|
+
const agent = useAgent(`${filePath}|${date}`);
|
|
2371
2424
|
reactExports.useEffect(() => {
|
|
2372
2425
|
setItems(null);
|
|
2373
2426
|
setInstructions([]);
|
|
2374
|
-
}, [
|
|
2427
|
+
}, [filePath, date, granularity]);
|
|
2375
2428
|
reactExports.useEffect(() => {
|
|
2376
|
-
if (!
|
|
2429
|
+
if (!filePath) return;
|
|
2377
2430
|
let cancelled = false;
|
|
2378
|
-
window.api.readSession(
|
|
2431
|
+
window.api.readSession(filePath, date || null, granularity).then((res) => {
|
|
2379
2432
|
if (cancelled || !res) return;
|
|
2380
2433
|
setItems(res.items);
|
|
2381
2434
|
setInstructions(res.instructions || []);
|
|
@@ -2383,7 +2436,7 @@ function Session({ meta, missing, date, granularity = "day" }) {
|
|
|
2383
2436
|
return () => {
|
|
2384
2437
|
cancelled = true;
|
|
2385
2438
|
};
|
|
2386
|
-
}, [
|
|
2439
|
+
}, [filePath, date, granularity, fileSize]);
|
|
2387
2440
|
if (!meta) {
|
|
2388
2441
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-view empty", children: missing?.warn ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "session-missing", children: [
|
|
2389
2442
|
"⚠ ",
|
|
@@ -2412,7 +2465,7 @@ function Session({ meta, missing, date, granularity = "day" }) {
|
|
|
2412
2465
|
}
|
|
2413
2466
|
)
|
|
2414
2467
|
] }),
|
|
2415
|
-
mode === "conversation" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "view-tab-pane-content", children: items ? /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationView, { items, instructions, expandAll }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "empty", children: "Loading conversation…" }) }) : mode === "jsonl" ? /* @__PURE__ */ jsxRuntimeExports.jsx(JsonlView, { items, expandAll }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RequestsView, {
|
|
2468
|
+
mode === "conversation" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "view-tab-pane-content", children: items ? /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationView, { items, instructions, expandAll }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "empty", children: "Loading conversation…" }) }) : mode === "jsonl" ? /* @__PURE__ */ jsxRuntimeExports.jsx(JsonlView, { items, expandAll }) : /* @__PURE__ */ jsxRuntimeExports.jsx(RequestsView, { filePath, date, granularity, fileSize, expandAll })
|
|
2416
2469
|
] }),
|
|
2417
2470
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SessionSummary, { meta, items, instructions, agent, onOpenAgent: () => setAgentOpen(true), granularity })
|
|
2418
2471
|
] }) }) }) }) });
|
|
@@ -2479,19 +2532,16 @@ function StatusSwitch({ service, on, warn, button, className = "", tooltip, chan
|
|
|
2479
2532
|
)
|
|
2480
2533
|
] });
|
|
2481
2534
|
}
|
|
2482
|
-
const proxyTooltip = /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2483
|
-
"Captures Claude Code's raw API traffic - system prompt, tool definitions, injected reminders, responses.",
|
|
2484
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", {})
|
|
2485
|
-
"Applies only to newly started Claude Code sessions."
|
|
2535
|
+
const proxyTooltip = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2536
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Captures Claude Code's raw API traffic - system prompt, tool definitions, injected reminders, responses." }),
|
|
2537
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Applies only to newly started Claude Code sessions." })
|
|
2486
2538
|
] });
|
|
2487
2539
|
const proxyChanges = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
2488
2540
|
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: `"env": {
|
|
2489
2541
|
"ANTHROPIC_BASE_URL": "http://127.0.0.1:41414",
|
|
2490
2542
|
"ENABLE_TOOL_SEARCH": "true"
|
|
2491
|
-
},
|
|
2492
|
-
"hooks": {
|
|
2493
|
-
"SessionStart": ["…/bin/claude/hooks.mjs"]
|
|
2494
2543
|
}` }),
|
|
2544
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Also registers the proxy as a login service so it survives restarts." }),
|
|
2495
2545
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
2496
2546
|
"Note: ",
|
|
2497
2547
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "/remote-control" }),
|
|
@@ -2575,13 +2625,22 @@ function App() {
|
|
|
2575
2625
|
const [deepLink, setDeepLink] = reactExports.useState(null);
|
|
2576
2626
|
const [sourceFilter, setSourceFilter] = reactExports.useState(null);
|
|
2577
2627
|
const [projectFilter, setProjectFilter] = reactExports.useState(null);
|
|
2578
|
-
const { defaultLayout, onLayoutChanged } =
|
|
2579
|
-
const { defaultLayout: rootLayout, onLayoutChanged: onRootLayoutChanged } =
|
|
2628
|
+
const { defaultLayout, onLayoutChanged } = an({ id: "app.body", panelIds: ["list", "detail"], storage: localStorage });
|
|
2629
|
+
const { defaultLayout: rootLayout, onLayoutChanged: onRootLayoutChanged } = an({ id: "app.root", panelIds: ["gantt", "body"], storage: localStorage });
|
|
2580
2630
|
const dayRange = reactExports.useMemo(() => {
|
|
2581
2631
|
const start = anchor;
|
|
2582
2632
|
const end = endOfPeriod(anchor, granularity);
|
|
2583
2633
|
return { start, end };
|
|
2584
2634
|
}, [anchor, granularity]);
|
|
2635
|
+
reactExports.useEffect(() => {
|
|
2636
|
+
const shown = startOfPeriod(Date.now(), granularity);
|
|
2637
|
+
if (anchor !== shown) return;
|
|
2638
|
+
const id = setInterval(() => {
|
|
2639
|
+
const current = startOfPeriod(Date.now(), granularity);
|
|
2640
|
+
if (current !== shown) setAnchor(current);
|
|
2641
|
+
}, 6e4);
|
|
2642
|
+
return () => clearInterval(id);
|
|
2643
|
+
}, [anchor, granularity]);
|
|
2585
2644
|
reactExports.useEffect(() => {
|
|
2586
2645
|
let cancelled = false;
|
|
2587
2646
|
setScanProgress(null);
|
|
@@ -2613,7 +2672,7 @@ function App() {
|
|
|
2613
2672
|
return { sourceFiltered, past, availableSources };
|
|
2614
2673
|
}, [sessions, sourceFilter, projectFilter]);
|
|
2615
2674
|
const selected = reactExports.useMemo(
|
|
2616
|
-
() => sessions.find((s) => s.sessionId === selectedId) || null,
|
|
2675
|
+
() => sessions.find((s) => s.filePath === selectedId || s.sessionId === selectedId) || null,
|
|
2617
2676
|
[sessions, selectedId]
|
|
2618
2677
|
);
|
|
2619
2678
|
let missing = null;
|
|
@@ -2655,14 +2714,14 @@ function App() {
|
|
|
2655
2714
|
}
|
|
2656
2715
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "app", children: [
|
|
2657
2716
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2658
|
-
|
|
2717
|
+
qt,
|
|
2659
2718
|
{
|
|
2660
2719
|
orientation: "vertical",
|
|
2661
2720
|
className: "app-main",
|
|
2662
2721
|
defaultLayout: rootLayout,
|
|
2663
2722
|
onLayoutChanged: onRootLayoutChanged,
|
|
2664
2723
|
children: [
|
|
2665
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2724
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Qt, { id: "gantt", defaultSize: 400, minSize: 180, className: "gantt-pane", children: [
|
|
2666
2725
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2667
2726
|
Toolbar,
|
|
2668
2727
|
{
|
|
@@ -2686,7 +2745,7 @@ function App() {
|
|
|
2686
2745
|
dayRange,
|
|
2687
2746
|
sessions: dayItems.sourceFiltered,
|
|
2688
2747
|
onSelect: selectSession,
|
|
2689
|
-
selectedId,
|
|
2748
|
+
selectedId: selected?.filePath ?? null,
|
|
2690
2749
|
dayAnchor: anchor,
|
|
2691
2750
|
granularity,
|
|
2692
2751
|
projectFilter,
|
|
@@ -2696,26 +2755,26 @@ function App() {
|
|
|
2696
2755
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PeriodSummary, { sessions: dayItems.past, dayAnchor: anchor, granularity })
|
|
2697
2756
|
] })
|
|
2698
2757
|
] }),
|
|
2699
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2700
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2701
|
-
|
|
2758
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(nn, { className: "resize-handle resize-handle-h" }),
|
|
2759
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Qt, { id: "body", minSize: 20, className: "body-outer", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2760
|
+
qt,
|
|
2702
2761
|
{
|
|
2703
2762
|
orientation: "horizontal",
|
|
2704
2763
|
className: "body",
|
|
2705
2764
|
defaultLayout,
|
|
2706
2765
|
onLayoutChanged,
|
|
2707
2766
|
children: [
|
|
2708
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2767
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Qt, { id: "list", defaultSize: 350, minSize: 200, maxSize: 700, className: "body-pane", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2709
2768
|
SessionList,
|
|
2710
2769
|
{
|
|
2711
2770
|
sessions: dayItems.past,
|
|
2712
|
-
selectedId,
|
|
2771
|
+
selectedId: selected?.filePath ?? null,
|
|
2713
2772
|
deepLink,
|
|
2714
2773
|
onSelect: selectSession
|
|
2715
2774
|
}
|
|
2716
2775
|
) }),
|
|
2717
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2718
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2776
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(nn, { className: "resize-handle resize-handle-v" }),
|
|
2777
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Qt, { id: "detail", minSize: 30, className: "body-pane", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Session, { meta: selected, missing, date: format(anchor, "yyyy-MM-dd"), granularity }) })
|
|
2719
2778
|
]
|
|
2720
2779
|
}
|
|
2721
2780
|
) })
|