@tonyclaw/agent-inspector 3.0.7 → 3.0.9
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/.output/cli.js +245 -171
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-C0Kbsm-Q.js → CompareDrawer-CJKL4LMm.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-DBUy29O-.js +106 -0
- package/.output/public/assets/ReplayDialog-BYanl-a_.js +1 -0
- package/.output/public/assets/{RequestAnatomy-fa0JXy5p.js → RequestAnatomy-DvPz1jqE.js} +1 -1
- package/.output/public/assets/ResponseView-sZnxp9GN.js +3 -0
- package/.output/public/assets/StreamingChunkSequence-G-tiYiBd.js +1 -0
- package/.output/public/assets/{_sessionId-D5fYH2C0.js → _sessionId-_hDcsmXq.js} +1 -1
- package/.output/public/assets/agent-inspector-58K1_MsC.ico +0 -0
- package/.output/public/assets/index-DAPAWsAd.js +1 -0
- package/.output/public/assets/index-DspnLqUW.css +1 -0
- package/.output/public/assets/{index-BEsqvywM.js → index-SuOSQb2_.js} +1 -1
- package/.output/public/assets/{json-viewer-B0QRbMSf.js → json-viewer-yQdhgjaw.js} +1 -1
- package/.output/public/assets/{main-CuKZD7n0.js → main-CgjcDxjR.js} +2 -2
- package/.output/server/_libs/radix-ui__react-dialog.mjs +2 -2
- package/.output/server/{_sessionId-DdBTK3qm.mjs → _sessionId-BGISf2En.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-m82cVZ73.mjs → CompareDrawer-s-UF9gW3.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-7geuf78f.mjs → ProxyViewerContainer-C0Sbz9ED.mjs} +1033 -530
- package/.output/server/_ssr/{ReplayDialog-B8RlWLLH.mjs → ReplayDialog-DvS8gvJr.mjs} +58 -23
- package/.output/server/_ssr/{RequestAnatomy-BE7pmwpv.mjs → RequestAnatomy-BwhWglJL.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-D-sDsdQr.mjs → ResponseView-wBVreqQf.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-DU_hThJr.mjs → StreamingChunkSequence-Dr6eg-MJ.mjs} +30 -20
- package/.output/server/_ssr/{index-D0sV8UbE.mjs → index-B98Wia1X.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-CaDh1zrw.mjs → json-viewer-D7L8y0FH.mjs} +2 -2
- package/.output/server/_ssr/{router-Zh2iZ_u0.mjs → router-g9mo0nWT.mjs} +459 -196
- package/.output/server/_tanstack-start-manifest_v-CbGc-o50.mjs +4 -0
- package/.output/server/index.mjs +76 -69
- package/package.json +1 -1
- package/src/assets/IDE/opencode.svg +1 -1
- package/src/assets/IDE/xiaomimimo.svg +1 -1
- package/src/cli/detect-tools.ts +2 -27
- package/src/cli/templates/codex-skill-onboard.ts +1 -1
- package/src/cli/templates/skill-onboard.ts +2 -3
- package/src/cli.ts +9 -86
- package/src/components/ProxyViewer.tsx +249 -37
- package/src/components/ProxyViewerContainer.tsx +167 -22
- package/src/components/clients/ClientLogo.tsx +38 -3
- package/src/components/ecosystem/AgentLabDialog.tsx +204 -3
- package/src/components/groups/GroupsDialog.tsx +28 -40
- package/src/components/providers/ImportWizardDialog.tsx +51 -101
- package/src/components/providers/ProvidersPanel.tsx +82 -68
- package/src/components/providers/SettingsDialog.tsx +11 -12
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +15 -23
- package/src/components/proxy-viewer/ReplayDialog.tsx +65 -22
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +33 -20
- package/src/components/proxy-viewer/TurnGroup.tsx +0 -16
- package/src/components/proxy-viewer/log-formats/anthropic.ts +5 -5
- package/src/components/proxy-viewer/log-formats/openai.ts +7 -10
- package/src/components/proxy-viewer/requestTools.ts +5 -2
- package/src/lib/apiClient.ts +43 -10
- package/src/lib/ecosystemContract.ts +32 -0
- package/src/lib/export-logs.ts +37 -3
- package/src/proxy/ecosystemRegistry.ts +244 -0
- package/src/proxy/ecosystemTasks.ts +153 -0
- package/src/proxy/platformCommands.ts +212 -0
- package/src/proxy/socketTracker.ts +84 -143
- package/src/routes/api/ecosystem.packages.$packageId.help.ts +16 -0
- package/src/routes/api/ecosystem.packages.$packageId.install.ts +16 -0
- package/src/routes/api/ecosystem.packages.$packageId.runner-presets.ts +19 -0
- package/src/routes/api/ecosystem.packages.$packageId.upgrade.ts +16 -0
- package/src/routes/api/ecosystem.packages.ts +1 -248
- package/src/routes/api/ecosystem.tasks.$taskId.ts +16 -0
- package/src/routes/api/ecosystem.tasks.ts +12 -0
- package/src/routes/api/providers.$providerId.test.log.ts +28 -24
- package/.output/public/assets/ProxyViewerContainer-p-rpYyiF.js +0 -106
- package/.output/public/assets/ReplayDialog-CM3dhP8v.js +0 -1
- package/.output/public/assets/ResponseView-Bq6sC7Ay.js +0 -3
- package/.output/public/assets/StreamingChunkSequence-CGOun3Df.js +0 -1
- package/.output/public/assets/index-C29Olfzt.js +0 -1
- package/.output/public/assets/index-DgANE0r3.css +0 -1
- package/.output/server/_tanstack-start-manifest_v-LCE-2AaF.mjs +0 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback, useRef, useMemo, useTransition, type JSX } from "react";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { CapturedLogSchema, type CapturedLog } from "../contracts";
|
|
4
|
-
import { fetchJson } from "../lib/apiClient";
|
|
4
|
+
import { fetchJson, fetchJsonWithTimeout } from "../lib/apiClient";
|
|
5
5
|
import { InspectorGroupsListResponseSchema, type InspectorGroup } from "../lib/groupContract";
|
|
6
6
|
import { ImportLogsResponseSchema, type ImportLogsResponse } from "../lib/logImportContract";
|
|
7
7
|
import { useStripConfig } from "../lib/useStripConfig";
|
|
@@ -9,6 +9,7 @@ import { OnboardingBanner } from "./OnboardingBanner";
|
|
|
9
9
|
import {
|
|
10
10
|
ProxyViewer,
|
|
11
11
|
type LogPaginationControls,
|
|
12
|
+
type SessionLoadProgress,
|
|
12
13
|
type SessionMembershipEvidence,
|
|
13
14
|
} from "./ProxyViewer";
|
|
14
15
|
import { dispatchLogFocusRequest } from "./proxy-viewer/logFocus";
|
|
@@ -49,6 +50,14 @@ type LogCursorPage = z.infer<typeof LogCursorPageSchema>;
|
|
|
49
50
|
|
|
50
51
|
const SessionsResponseSchema = z.array(z.string());
|
|
51
52
|
|
|
53
|
+
const DeleteLogsResponseSchema = z.object({
|
|
54
|
+
success: z.boolean(),
|
|
55
|
+
cleared: z.number().int().nonnegative(),
|
|
56
|
+
logFilesRewritten: z.number().int().nonnegative().optional(),
|
|
57
|
+
chunkFilesDeleted: z.number().int().nonnegative(),
|
|
58
|
+
sessionArchiveLogsDeleted: z.number().int().nonnegative().optional(),
|
|
59
|
+
});
|
|
60
|
+
|
|
52
61
|
type SessionPageRequest =
|
|
53
62
|
| { kind: "newest" }
|
|
54
63
|
| { kind: "oldest" }
|
|
@@ -118,6 +127,8 @@ const HASH_HIGHLIGHT_MS = 1800;
|
|
|
118
127
|
const SESSION_PAGE_LIMIT = 100;
|
|
119
128
|
const SESSION_RELOAD_PAGE_LIMIT = 500;
|
|
120
129
|
const MAX_SESSION_RELOAD_PAGES = 200;
|
|
130
|
+
const SESSION_LOGS_FETCH_TIMEOUT_MS = 20_000;
|
|
131
|
+
const SESSION_MEMBERSHIP_FETCH_TIMEOUT_MS = 10_000;
|
|
121
132
|
|
|
122
133
|
function buildLogsStreamUrl(sessionId: string | undefined): string {
|
|
123
134
|
const params = new URLSearchParams();
|
|
@@ -167,6 +178,18 @@ function buildLogIndex(logs: readonly CapturedLog[]): Map<number, number> {
|
|
|
167
178
|
return idx;
|
|
168
179
|
}
|
|
169
180
|
|
|
181
|
+
function fetchSessionLogsPage(
|
|
182
|
+
sessionId: string,
|
|
183
|
+
request: SessionPageRequest,
|
|
184
|
+
limit = SESSION_PAGE_LIMIT,
|
|
185
|
+
): Promise<LogCursorPage> {
|
|
186
|
+
return fetchJsonWithTimeout(
|
|
187
|
+
buildSessionLogsPageUrl(sessionId, request, limit),
|
|
188
|
+
LogCursorPageSchema,
|
|
189
|
+
SESSION_LOGS_FETCH_TIMEOUT_MS,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
170
193
|
export function mergeLogsById(
|
|
171
194
|
previousLogs: readonly CapturedLog[],
|
|
172
195
|
incomingLogs: readonly CapturedLog[],
|
|
@@ -222,12 +245,17 @@ export function ProxyViewerContainer({
|
|
|
222
245
|
const [streamInitialized, setStreamInitialized] = useState(initialSessionId === undefined);
|
|
223
246
|
const [logPage, setLogPage] = useState<LogCursorPage | null>(null);
|
|
224
247
|
const [sessionPageLoading, setSessionPageLoading] = useState(initialSessionId !== undefined);
|
|
248
|
+
const [sessionLoadProgress, setSessionLoadProgress] = useState<SessionLoadProgress | undefined>(
|
|
249
|
+
undefined,
|
|
250
|
+
);
|
|
225
251
|
const [sessionMemberships, setSessionMemberships] = useState<SessionMembershipEvidence[]>([]);
|
|
226
252
|
const [, startLogTransition] = useTransition();
|
|
227
253
|
const eventSourceRef = useRef<EventSource | null>(null);
|
|
228
254
|
const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
229
255
|
const handledHashRef = useRef<string | null>(null);
|
|
230
256
|
const sessionPageRequestIdRef = useRef(0);
|
|
257
|
+
const sessionLoadStartedAtRef = useRef<number | null>(null);
|
|
258
|
+
const sessionLoadTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
231
259
|
|
|
232
260
|
// O(1) log lookup by id
|
|
233
261
|
const logIndexRef = useRef<Map<number, number>>(new Map());
|
|
@@ -242,6 +270,53 @@ export function ProxyViewerContainer({
|
|
|
242
270
|
[showToast],
|
|
243
271
|
);
|
|
244
272
|
|
|
273
|
+
const stopSessionLoadProgress = useCallback(() => {
|
|
274
|
+
if (sessionLoadTimerRef.current !== null) {
|
|
275
|
+
clearInterval(sessionLoadTimerRef.current);
|
|
276
|
+
sessionLoadTimerRef.current = null;
|
|
277
|
+
}
|
|
278
|
+
sessionLoadStartedAtRef.current = null;
|
|
279
|
+
setSessionLoadProgress(undefined);
|
|
280
|
+
}, []);
|
|
281
|
+
|
|
282
|
+
const startSessionLoadProgress = useCallback(
|
|
283
|
+
(label: string, requestId: number, loadedLogs = 0, loadedPages = 0) => {
|
|
284
|
+
if (sessionLoadTimerRef.current !== null) {
|
|
285
|
+
clearInterval(sessionLoadTimerRef.current);
|
|
286
|
+
}
|
|
287
|
+
const startedAt = Date.now();
|
|
288
|
+
sessionLoadStartedAtRef.current = startedAt;
|
|
289
|
+
const update = (): void => {
|
|
290
|
+
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
291
|
+
setSessionLoadProgress({
|
|
292
|
+
label,
|
|
293
|
+
elapsedMs: Date.now() - startedAt,
|
|
294
|
+
timeoutMs: SESSION_LOGS_FETCH_TIMEOUT_MS,
|
|
295
|
+
loadedLogs,
|
|
296
|
+
loadedPages,
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
update();
|
|
300
|
+
sessionLoadTimerRef.current = setInterval(update, 250);
|
|
301
|
+
},
|
|
302
|
+
[],
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
const updateSessionLoadProgress = useCallback(
|
|
306
|
+
(label: string, requestId: number, loadedLogs: number, loadedPages: number) => {
|
|
307
|
+
const startedAt = sessionLoadStartedAtRef.current;
|
|
308
|
+
if (startedAt === null || sessionPageRequestIdRef.current !== requestId) return;
|
|
309
|
+
setSessionLoadProgress({
|
|
310
|
+
label,
|
|
311
|
+
elapsedMs: Date.now() - startedAt,
|
|
312
|
+
timeoutMs: SESSION_LOGS_FETCH_TIMEOUT_MS,
|
|
313
|
+
loadedLogs,
|
|
314
|
+
loadedPages,
|
|
315
|
+
});
|
|
316
|
+
},
|
|
317
|
+
[],
|
|
318
|
+
);
|
|
319
|
+
|
|
245
320
|
// Derived view: the logs the user actually sees. Recomputed only when the
|
|
246
321
|
// underlying set or filter changes — never on every SSE message.
|
|
247
322
|
const logs = useMemo(
|
|
@@ -355,9 +430,10 @@ export function ProxyViewerContainer({
|
|
|
355
430
|
const requestId = sessionPageRequestIdRef.current + 1;
|
|
356
431
|
sessionPageRequestIdRef.current = requestId;
|
|
357
432
|
setSessionPageLoading(true);
|
|
433
|
+
startSessionLoadProgress("Loading session logs", requestId);
|
|
358
434
|
dismissToast();
|
|
359
435
|
|
|
360
|
-
void
|
|
436
|
+
void fetchSessionLogsPage(initialSessionId, request)
|
|
361
437
|
.then((page) => {
|
|
362
438
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
363
439
|
const nextLogs = page.logs;
|
|
@@ -366,6 +442,7 @@ export function ProxyViewerContainer({
|
|
|
366
442
|
setLogPage(page);
|
|
367
443
|
setSelectedSession(initialSessionId);
|
|
368
444
|
setSessionPageLoading(false);
|
|
445
|
+
stopSessionLoadProgress();
|
|
369
446
|
dismissToast();
|
|
370
447
|
})
|
|
371
448
|
.catch((err: unknown) => {
|
|
@@ -373,10 +450,17 @@ export function ProxyViewerContainer({
|
|
|
373
450
|
setAllLogs([]);
|
|
374
451
|
setLogPage(null);
|
|
375
452
|
setSessionPageLoading(false);
|
|
453
|
+
stopSessionLoadProgress();
|
|
376
454
|
showErrorToast(err instanceof Error ? err.message : "Failed to load session logs");
|
|
377
455
|
});
|
|
378
456
|
},
|
|
379
|
-
[
|
|
457
|
+
[
|
|
458
|
+
dismissToast,
|
|
459
|
+
initialSessionId,
|
|
460
|
+
showErrorToast,
|
|
461
|
+
startSessionLoadProgress,
|
|
462
|
+
stopSessionLoadProgress,
|
|
463
|
+
],
|
|
380
464
|
);
|
|
381
465
|
|
|
382
466
|
const reloadSessionLogs = useCallback(
|
|
@@ -384,15 +468,18 @@ export function ProxyViewerContainer({
|
|
|
384
468
|
const requestId = sessionPageRequestIdRef.current + 1;
|
|
385
469
|
sessionPageRequestIdRef.current = requestId;
|
|
386
470
|
setSessionPageLoading(true);
|
|
471
|
+
startSessionLoadProgress("Reloading full session", requestId);
|
|
387
472
|
dismissToast();
|
|
388
473
|
|
|
389
474
|
void (async () => {
|
|
390
475
|
const collected: CapturedLog[] = [];
|
|
391
|
-
let page = await
|
|
392
|
-
|
|
393
|
-
|
|
476
|
+
let page = await fetchSessionLogsPage(
|
|
477
|
+
sessionId,
|
|
478
|
+
{ kind: "oldest" },
|
|
479
|
+
SESSION_RELOAD_PAGE_LIMIT,
|
|
394
480
|
);
|
|
395
481
|
collected.push(...page.logs);
|
|
482
|
+
updateSessionLoadProgress("Reloading full session", requestId, collected.length, 1);
|
|
396
483
|
|
|
397
484
|
let loadedPages = 1;
|
|
398
485
|
while (
|
|
@@ -400,16 +487,19 @@ export function ProxyViewerContainer({
|
|
|
400
487
|
page.newestLogId !== null &&
|
|
401
488
|
loadedPages < MAX_SESSION_RELOAD_PAGES
|
|
402
489
|
) {
|
|
403
|
-
page = await
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
SESSION_RELOAD_PAGE_LIMIT,
|
|
408
|
-
),
|
|
409
|
-
LogCursorPageSchema,
|
|
490
|
+
page = await fetchSessionLogsPage(
|
|
491
|
+
sessionId,
|
|
492
|
+
{ kind: "newer", afterLogId: page.newestLogId },
|
|
493
|
+
SESSION_RELOAD_PAGE_LIMIT,
|
|
410
494
|
);
|
|
411
495
|
collected.push(...page.logs);
|
|
412
496
|
loadedPages += 1;
|
|
497
|
+
updateSessionLoadProgress(
|
|
498
|
+
"Reloading full session",
|
|
499
|
+
requestId,
|
|
500
|
+
collected.length,
|
|
501
|
+
loadedPages,
|
|
502
|
+
);
|
|
413
503
|
}
|
|
414
504
|
|
|
415
505
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
@@ -420,6 +510,7 @@ export function ProxyViewerContainer({
|
|
|
420
510
|
});
|
|
421
511
|
setKnownSessions((prev) => mergeSessionIds(prev, [sessionId]));
|
|
422
512
|
setSessionPageLoading(false);
|
|
513
|
+
stopSessionLoadProgress();
|
|
423
514
|
if (page.hasNewer) {
|
|
424
515
|
showToast({
|
|
425
516
|
message: `Loaded ${String(collected.length)} logs for this session. More history is available.`,
|
|
@@ -431,10 +522,18 @@ export function ProxyViewerContainer({
|
|
|
431
522
|
})().catch((err: unknown) => {
|
|
432
523
|
if (sessionPageRequestIdRef.current !== requestId) return;
|
|
433
524
|
setSessionPageLoading(false);
|
|
525
|
+
stopSessionLoadProgress();
|
|
434
526
|
showErrorToast(err instanceof Error ? err.message : "Failed to reload session logs");
|
|
435
527
|
});
|
|
436
528
|
},
|
|
437
|
-
[
|
|
529
|
+
[
|
|
530
|
+
dismissToast,
|
|
531
|
+
showErrorToast,
|
|
532
|
+
showToast,
|
|
533
|
+
startSessionLoadProgress,
|
|
534
|
+
stopSessionLoadProgress,
|
|
535
|
+
updateSessionLoadProgress,
|
|
536
|
+
],
|
|
438
537
|
);
|
|
439
538
|
|
|
440
539
|
useEffect(() => {
|
|
@@ -444,13 +543,12 @@ export function ProxyViewerContainer({
|
|
|
444
543
|
}
|
|
445
544
|
|
|
446
545
|
let cancelled = false;
|
|
447
|
-
void
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
})
|
|
546
|
+
void fetchJsonWithTimeout(
|
|
547
|
+
"/api/groups",
|
|
548
|
+
InspectorGroupsListResponseSchema,
|
|
549
|
+
SESSION_MEMBERSHIP_FETCH_TIMEOUT_MS,
|
|
550
|
+
)
|
|
551
|
+
.then((response) => response.groups)
|
|
454
552
|
.then((groups) => {
|
|
455
553
|
if (cancelled || groups === null) return;
|
|
456
554
|
setSessionMemberships(buildSessionMembershipEvidence(groups, initialSessionId));
|
|
@@ -468,6 +566,12 @@ export function ProxyViewerContainer({
|
|
|
468
566
|
refreshSessions();
|
|
469
567
|
}, [refreshSessions]);
|
|
470
568
|
|
|
569
|
+
useEffect(() => {
|
|
570
|
+
return () => {
|
|
571
|
+
stopSessionLoadProgress();
|
|
572
|
+
};
|
|
573
|
+
}, [stopSessionLoadProgress]);
|
|
574
|
+
|
|
471
575
|
useEffect(() => {
|
|
472
576
|
if (initialSessionId === undefined) return;
|
|
473
577
|
loadSessionPage({ kind: "newest" });
|
|
@@ -553,6 +657,8 @@ export function ProxyViewerContainer({
|
|
|
553
657
|
|
|
554
658
|
const handleClearAll = useCallback(() => {
|
|
555
659
|
const clearedSessions = extractSessions(allLogs);
|
|
660
|
+
stopSessionLoadProgress();
|
|
661
|
+
setSessionPageLoading(false);
|
|
556
662
|
logIndexRef.current.clear();
|
|
557
663
|
setAllLogs([]);
|
|
558
664
|
setLogPage(null);
|
|
@@ -561,7 +667,7 @@ export function ProxyViewerContainer({
|
|
|
561
667
|
message: "Cleared the current view. Stored logs are still reloadable.",
|
|
562
668
|
tone: "success",
|
|
563
669
|
});
|
|
564
|
-
}, [allLogs, showToast]);
|
|
670
|
+
}, [allLogs, showToast, stopSessionLoadProgress]);
|
|
565
671
|
|
|
566
672
|
const handleClearGroup = useCallback(
|
|
567
673
|
(ids: number[]) => {
|
|
@@ -579,6 +685,41 @@ export function ProxyViewerContainer({
|
|
|
579
685
|
[showToast],
|
|
580
686
|
);
|
|
581
687
|
|
|
688
|
+
const handleDeleteCurrentView = useCallback(
|
|
689
|
+
async (ids: number[]): Promise<void> => {
|
|
690
|
+
if (ids.length === 0) return;
|
|
691
|
+
const idSet = new Set(ids);
|
|
692
|
+
const removed = allLogs.filter((log) => idSet.has(log.id));
|
|
693
|
+
const result = await fetchJson("/api/logs", DeleteLogsResponseSchema, {
|
|
694
|
+
method: "DELETE",
|
|
695
|
+
headers: { "content-type": "application/json" },
|
|
696
|
+
body: JSON.stringify({ ids }),
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
setAllLogs((prev) => {
|
|
700
|
+
const remaining = prev.filter((log) => !idSet.has(log.id));
|
|
701
|
+
logIndexRef.current = buildLogIndex(remaining);
|
|
702
|
+
return remaining;
|
|
703
|
+
});
|
|
704
|
+
setLogPage((prev) =>
|
|
705
|
+
prev === null
|
|
706
|
+
? null
|
|
707
|
+
: {
|
|
708
|
+
...prev,
|
|
709
|
+
logs: prev.logs.filter((log) => !idSet.has(log.id)),
|
|
710
|
+
},
|
|
711
|
+
);
|
|
712
|
+
setKnownSessions((prev) => mergeSessionIds(prev, extractSessions(removed)));
|
|
713
|
+
showToast({
|
|
714
|
+
message: `Deleted ${result.cleared.toString()} stored log${
|
|
715
|
+
result.cleared === 1 ? "" : "s"
|
|
716
|
+
} from the current view.`,
|
|
717
|
+
tone: "success",
|
|
718
|
+
});
|
|
719
|
+
},
|
|
720
|
+
[allLogs, showToast],
|
|
721
|
+
);
|
|
722
|
+
|
|
582
723
|
const handleReloadSession = useCallback(() => {
|
|
583
724
|
if (initialSessionId !== undefined) {
|
|
584
725
|
loadSessionPage({ kind: "newest" });
|
|
@@ -644,6 +785,7 @@ export function ProxyViewerContainer({
|
|
|
644
785
|
if (initialSessionId === undefined) return undefined;
|
|
645
786
|
return {
|
|
646
787
|
isLoading: sessionPageLoading,
|
|
788
|
+
loadProgress: sessionLoadProgress,
|
|
647
789
|
total: logPage?.total ?? null,
|
|
648
790
|
pageSize: logPage?.limit ?? SESSION_PAGE_LIMIT,
|
|
649
791
|
hasOlder: logPage?.hasOlder ?? false,
|
|
@@ -662,6 +804,7 @@ export function ProxyViewerContainer({
|
|
|
662
804
|
loadOlderPage,
|
|
663
805
|
loadOldestPage,
|
|
664
806
|
logPage,
|
|
807
|
+
sessionLoadProgress,
|
|
665
808
|
sessionPageLoading,
|
|
666
809
|
]);
|
|
667
810
|
|
|
@@ -678,6 +821,7 @@ export function ProxyViewerContainer({
|
|
|
678
821
|
onSessionChange={setSelectedSession}
|
|
679
822
|
onModelChange={setSelectedModel}
|
|
680
823
|
onClearAll={handleClearAll}
|
|
824
|
+
onDeleteCurrentView={handleDeleteCurrentView}
|
|
681
825
|
onReloadSession={
|
|
682
826
|
initialSessionId !== undefined || selectedSession !== "__all__"
|
|
683
827
|
? handleReloadSession
|
|
@@ -692,6 +836,7 @@ export function ProxyViewerContainer({
|
|
|
692
836
|
: sessionPageLoading
|
|
693
837
|
}
|
|
694
838
|
pagination={pagination}
|
|
839
|
+
sessionLoadProgress={sessionLoadProgress}
|
|
695
840
|
sessionMemberships={sessionMemberships}
|
|
696
841
|
viewMode={viewMode}
|
|
697
842
|
captureMode={captureMode}
|
|
@@ -4,8 +4,15 @@ import ClaudeCodeLogoSvg from "../../assets/IDE/claudecode-color.svg";
|
|
|
4
4
|
import CodexLogoSvg from "../../assets/IDE/codex-color.svg";
|
|
5
5
|
import OpenCodeLogoSvg from "../../assets/IDE/opencode.svg";
|
|
6
6
|
import MiMoCodeLogoSvg from "../../assets/IDE/xiaomimimo.svg";
|
|
7
|
+
import AgentInspectorLogo from "../../assets/agent-inspector.ico";
|
|
7
8
|
|
|
8
|
-
export type ClientApp =
|
|
9
|
+
export type ClientApp =
|
|
10
|
+
| "agent-inspector"
|
|
11
|
+
| "codex"
|
|
12
|
+
| "opencode"
|
|
13
|
+
| "mimo-code"
|
|
14
|
+
| "claude-code"
|
|
15
|
+
| "unknown";
|
|
9
16
|
|
|
10
17
|
export type ClientAppDetectionInput = {
|
|
11
18
|
userAgent?: string | null;
|
|
@@ -14,6 +21,7 @@ export type ClientAppDetectionInput = {
|
|
|
14
21
|
};
|
|
15
22
|
|
|
16
23
|
const CLIENT_LABELS: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
24
|
+
"agent-inspector": "Inspector",
|
|
17
25
|
codex: "Codex",
|
|
18
26
|
opencode: "OpenCode",
|
|
19
27
|
"mimo-code": "MiMo Code",
|
|
@@ -38,6 +46,9 @@ export function detectClientApp(input: ClientAppDetectionInput): ClientApp {
|
|
|
38
46
|
normalize(input.clientProjectFolder),
|
|
39
47
|
].join(" ");
|
|
40
48
|
|
|
49
|
+
if (matchesAny(haystack, ["agent-inspector", "agent inspector", "provider-test"])) {
|
|
50
|
+
return "agent-inspector";
|
|
51
|
+
}
|
|
41
52
|
if (matchesAny(haystack, ["mimocode", "mimo-code", "mimo code"])) return "mimo-code";
|
|
42
53
|
if (matchesAny(haystack, ["opencode", "open-code", "open code"])) return "opencode";
|
|
43
54
|
if (matchesAny(haystack, ["claude-code", "claude code", "claudecode"])) return "claude-code";
|
|
@@ -50,6 +61,7 @@ export function detectClientApp(input: ClientAppDetectionInput): ClientApp {
|
|
|
50
61
|
|
|
51
62
|
export function clientAppLabel(client: ClientApp): string | null {
|
|
52
63
|
switch (client) {
|
|
64
|
+
case "agent-inspector":
|
|
53
65
|
case "codex":
|
|
54
66
|
case "opencode":
|
|
55
67
|
case "mimo-code":
|
|
@@ -61,12 +73,29 @@ export function clientAppLabel(client: ClientApp): string | null {
|
|
|
61
73
|
}
|
|
62
74
|
|
|
63
75
|
const CLIENT_LOGOS: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
76
|
+
"agent-inspector": AgentInspectorLogo,
|
|
64
77
|
codex: CodexLogoSvg,
|
|
65
78
|
opencode: OpenCodeLogoSvg,
|
|
66
79
|
"mimo-code": MiMoCodeLogoSvg,
|
|
67
80
|
"claude-code": ClaudeCodeLogoSvg,
|
|
68
81
|
};
|
|
69
82
|
|
|
83
|
+
const CLIENT_LOGO_FRAMES: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
84
|
+
"agent-inspector": "border-orange-200/25 bg-orange-300/[0.12]",
|
|
85
|
+
codex: "border-cyan-200/20 bg-cyan-300/[0.08]",
|
|
86
|
+
opencode: "border-sky-200/25 bg-sky-300/[0.12]",
|
|
87
|
+
"mimo-code": "border-orange-200/25 bg-orange-400/[0.12]",
|
|
88
|
+
"claude-code": "border-amber-100/20 bg-amber-300/[0.09]",
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const CLIENT_LOGO_IMAGES: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
92
|
+
"agent-inspector": "p-0.5 drop-shadow-[0_0_8px_rgba(251,146,60,0.35)]",
|
|
93
|
+
codex: "p-0.5",
|
|
94
|
+
opencode: "p-1 drop-shadow-[0_0_8px_rgba(125,211,252,0.35)]",
|
|
95
|
+
"mimo-code": "p-0.5 drop-shadow-[0_0_8px_rgba(255,105,0,0.35)]",
|
|
96
|
+
"claude-code": "p-0.5",
|
|
97
|
+
};
|
|
98
|
+
|
|
70
99
|
export function ClientLogo({
|
|
71
100
|
client,
|
|
72
101
|
className,
|
|
@@ -82,13 +111,19 @@ export function ClientLogo({
|
|
|
82
111
|
return (
|
|
83
112
|
<span
|
|
84
113
|
className={cn(
|
|
85
|
-
"
|
|
114
|
+
"inline-flex size-6 shrink-0 items-center justify-center rounded-md border p-0 shadow-sm",
|
|
115
|
+
CLIENT_LOGO_FRAMES[client],
|
|
86
116
|
className,
|
|
87
117
|
)}
|
|
88
118
|
aria-label={label}
|
|
89
119
|
title={label}
|
|
90
120
|
>
|
|
91
|
-
<img
|
|
121
|
+
<img
|
|
122
|
+
src={logoSrc}
|
|
123
|
+
alt=""
|
|
124
|
+
className={cn("size-full object-contain", CLIENT_LOGO_IMAGES[client])}
|
|
125
|
+
aria-hidden="true"
|
|
126
|
+
/>
|
|
92
127
|
</span>
|
|
93
128
|
);
|
|
94
129
|
}
|