@tonyclaw/agent-inspector 2.0.22 → 2.0.23
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/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-NEdpe1wl.js → CompareDrawer-DnYQtd8R.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-Dwhi4Q1c.js → ProxyViewerContainer-BTYGkg36.js} +4 -4
- package/.output/public/assets/{ReplayDialog-DijzJwaQ.js → ReplayDialog-B-3V95xT.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CYbosGYy.js → RequestAnatomy-CT8hLGLa.js} +1 -1
- package/.output/public/assets/{ResponseView-B3dPM63X.js → ResponseView-DK3CYom0.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-DYDx3xRY.js → StreamingChunkSequence-D3jJutjp.js} +1 -1
- package/.output/public/assets/_sessionId-DpdfAzbo.js +1 -0
- package/.output/public/assets/index-BpJNbm9G.js +1 -0
- package/.output/public/assets/{main-N-sjHJUM.js → main-hF_572U6.js} +2 -2
- package/.output/server/{_sessionId-BR46y_bO.mjs → _sessionId-BqhNE2M8.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-DDxpmdPs.mjs → CompareDrawer-C4LQW4S1.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-B1zAefzz.mjs → ProxyViewerContainer-BKInvawk.mjs} +7 -7
- package/.output/server/_ssr/{ReplayDialog-DleMFvMx.mjs → ReplayDialog-C3ZiRihL.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-B-P9tC3D.mjs → RequestAnatomy-DlVAPIQZ.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-DWfGn0i3.mjs → ResponseView-nMS0rkxu.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-C8kFF6xJ.mjs → StreamingChunkSequence-PDWqrNiO.mjs} +2 -2
- package/.output/server/_ssr/{index-DzENi2RO.mjs → index-Cd1zD-lo.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-Dy1VEjxy.mjs → router-R9gm7_sh.mjs} +150 -76
- package/.output/server/{_tanstack-start-manifest_v-CyzuAD8A.mjs → _tanstack-start-manifest_v-BnLVH_EX.mjs} +1 -1
- package/.output/server/index.mjs +57 -57
- package/package.json +1 -1
- package/src/proxy/store.ts +198 -135
- package/src/routes/api/logs.stream.ts +1 -1
- package/.output/public/assets/_sessionId-b1KDnByv.js +0 -1
- package/.output/public/assets/index-CUyRKgII.js +0 -1
package/src/proxy/store.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
createReadStream,
|
|
4
|
+
createWriteStream,
|
|
5
|
+
readdirSync,
|
|
6
|
+
statSync,
|
|
7
|
+
type WriteStream,
|
|
8
|
+
} from "node:fs";
|
|
9
|
+
import { open, unlink, rename } from "node:fs/promises";
|
|
3
10
|
import { readdir as readdirCallback } from "node:fs/promises";
|
|
4
11
|
import { createInterface } from "node:readline";
|
|
5
12
|
import { Buffer } from "node:buffer";
|
|
@@ -273,33 +280,7 @@ export async function getLogById(id: number): Promise<CapturedLog | null> {
|
|
|
273
280
|
return null;
|
|
274
281
|
}
|
|
275
282
|
|
|
276
|
-
|
|
277
|
-
const content = readFileSync(filePath, "utf-8");
|
|
278
|
-
const lines = content.split("\n");
|
|
279
|
-
|
|
280
|
-
let lastMatch: CapturedLog | null = null;
|
|
281
|
-
for (const line of lines) {
|
|
282
|
-
if (line.trim() === "") continue;
|
|
283
|
-
try {
|
|
284
|
-
const parsed: unknown = JSON.parse(line);
|
|
285
|
-
if (typeof parsed === "object" && parsed !== null) {
|
|
286
|
-
const desc = Object.getOwnPropertyDescriptor(parsed, "id");
|
|
287
|
-
if (desc !== undefined && typeof desc.value === "number" && desc.value === id) {
|
|
288
|
-
const result = CapturedLogSchema.safeParse(parsed);
|
|
289
|
-
if (result.success) {
|
|
290
|
-
lastMatch = normalizeLogSession(result.data);
|
|
291
|
-
if (result.data.responseStatus !== null) {
|
|
292
|
-
addToCache(lastMatch);
|
|
293
|
-
observeSessionLog(lastMatch);
|
|
294
|
-
return lastMatch;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
} catch {
|
|
300
|
-
// Skip malformed lines
|
|
301
|
-
}
|
|
302
|
-
}
|
|
283
|
+
const lastMatch = await scanLogFileForId(filePath, id);
|
|
303
284
|
if (lastMatch !== null) {
|
|
304
285
|
addToCache(lastMatch);
|
|
305
286
|
observeSessionLog(lastMatch);
|
|
@@ -312,6 +293,37 @@ export async function getLogById(id: number): Promise<CapturedLog | null> {
|
|
|
312
293
|
return null;
|
|
313
294
|
}
|
|
314
295
|
|
|
296
|
+
async function scanLogFileForId(filePath: string, id: number): Promise<CapturedLog | null> {
|
|
297
|
+
let lastMatch: CapturedLog | null = null;
|
|
298
|
+
const fileStream = createInterface({
|
|
299
|
+
input: createReadStream(filePath),
|
|
300
|
+
crlfDelay: Infinity,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
for await (const line of fileStream) {
|
|
304
|
+
if (line.trim() === "") continue;
|
|
305
|
+
try {
|
|
306
|
+
const parsed: unknown = JSON.parse(line);
|
|
307
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
308
|
+
const desc = Object.getOwnPropertyDescriptor(parsed, "id");
|
|
309
|
+
if (desc !== undefined && typeof desc.value === "number" && desc.value === id) {
|
|
310
|
+
const result = CapturedLogSchema.safeParse(parsed);
|
|
311
|
+
if (result.success) {
|
|
312
|
+
lastMatch = normalizeLogSession(result.data);
|
|
313
|
+
if (result.data.responseStatus !== null) {
|
|
314
|
+
return lastMatch;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
// Skip malformed lines
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return lastMatch;
|
|
325
|
+
}
|
|
326
|
+
|
|
315
327
|
export function getFilteredLogs(sessionId?: string, model?: string): CapturedLog[] {
|
|
316
328
|
// Cache maintains insertion order (sorted by ID since logs are added in ID order)
|
|
317
329
|
// Use spread instead of Array.from for slightly better performance
|
|
@@ -326,43 +338,26 @@ function matchesLogFilters(log: CapturedLog, sessionId?: string, model?: string)
|
|
|
326
338
|
return true;
|
|
327
339
|
}
|
|
328
340
|
|
|
329
|
-
|
|
330
|
-
filteredMemoryCount: number,
|
|
331
|
-
offset: number,
|
|
332
|
-
limit: number,
|
|
333
|
-
): boolean {
|
|
334
|
-
return offset + limit <= filteredMemoryCount;
|
|
335
|
-
}
|
|
341
|
+
type PersistedLogVisitor = (log: CapturedLog) => void;
|
|
336
342
|
|
|
337
|
-
function
|
|
338
|
-
return logs.slice(offset, offset + limit);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
async function readPersistedLogsById(): Promise<Map<number, CapturedLog>> {
|
|
342
|
-
const byId = new Map<number, CapturedLog>();
|
|
343
|
+
async function visitPersistedLogs(visitor: PersistedLogVisitor): Promise<void> {
|
|
343
344
|
const logDir = resolveLogDir();
|
|
344
|
-
if (!existsSync(logDir)) return
|
|
345
|
+
if (!existsSync(logDir)) return;
|
|
345
346
|
|
|
346
347
|
try {
|
|
347
348
|
const entries = await readdirCallback(logDir);
|
|
348
349
|
const files = entries.filter((file) => file.endsWith(".jsonl")).sort();
|
|
349
350
|
for (const file of files) {
|
|
350
|
-
await
|
|
351
|
+
await visitPersistedLogFile(join(logDir, file), visitor);
|
|
351
352
|
}
|
|
352
353
|
} catch (err) {
|
|
353
354
|
logger.error("[store] Failed to list persisted logs:", String(err));
|
|
354
355
|
}
|
|
355
|
-
|
|
356
|
-
for (const log of memoryCache.values()) {
|
|
357
|
-
byId.set(log.id, log);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return byId;
|
|
361
356
|
}
|
|
362
357
|
|
|
363
|
-
async function
|
|
358
|
+
async function visitPersistedLogFile(
|
|
364
359
|
filePath: string,
|
|
365
|
-
|
|
360
|
+
visitor: PersistedLogVisitor,
|
|
366
361
|
): Promise<void> {
|
|
367
362
|
if (!existsSync(filePath)) return;
|
|
368
363
|
|
|
@@ -379,8 +374,7 @@ async function readPersistedLogFile(
|
|
|
379
374
|
const result = CapturedLogSchema.safeParse(parsed);
|
|
380
375
|
if (result.success) {
|
|
381
376
|
const log = normalizeLogSession(result.data);
|
|
382
|
-
|
|
383
|
-
observeSessionLog(log);
|
|
377
|
+
visitor(log);
|
|
384
378
|
}
|
|
385
379
|
} catch {
|
|
386
380
|
// Skip malformed lines.
|
|
@@ -392,24 +386,44 @@ async function readPersistedLogFile(
|
|
|
392
386
|
}
|
|
393
387
|
|
|
394
388
|
export async function listLogsPage(options: ListLogsPageOptions): Promise<ListLogsPageResult> {
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
389
|
+
const seenIds = new Set<number>();
|
|
390
|
+
const pageById = new Map<number, CapturedLog>();
|
|
391
|
+
const pageStart = options.offset;
|
|
392
|
+
const pageEnd = options.offset + options.limit;
|
|
393
|
+
let total = 0;
|
|
394
|
+
|
|
395
|
+
const visitLog = (log: CapturedLog): void => {
|
|
396
|
+
if (!matchesLogFilters(log, options.sessionId, options.model)) return;
|
|
397
|
+
|
|
398
|
+
if (!seenIds.has(log.id)) {
|
|
399
|
+
seenIds.add(log.id);
|
|
400
|
+
const position = total;
|
|
401
|
+
total += 1;
|
|
402
|
+
if (position >= pageStart && position < pageEnd) {
|
|
403
|
+
pageById.set(log.id, log);
|
|
404
|
+
}
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (pageById.has(log.id)) {
|
|
409
|
+
pageById.set(log.id, log);
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
await visitPersistedLogs((log) => {
|
|
414
|
+
observeSessionLog(log);
|
|
415
|
+
visitLog(log);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
for (const log of memoryCache.values()) {
|
|
419
|
+
visitLog(log);
|
|
403
420
|
}
|
|
404
421
|
|
|
405
|
-
const
|
|
406
|
-
const persistedLogs = [...persistedById.values()]
|
|
407
|
-
.filter((log) => matchesLogFilters(log, options.sessionId, options.model))
|
|
408
|
-
.sort((left, right) => left.id - right.id);
|
|
422
|
+
const logs = [...pageById.values()].sort((left, right) => left.id - right.id);
|
|
409
423
|
|
|
410
424
|
return {
|
|
411
|
-
logs
|
|
412
|
-
total
|
|
425
|
+
logs,
|
|
426
|
+
total,
|
|
413
427
|
offset: options.offset,
|
|
414
428
|
limit: options.limit,
|
|
415
429
|
};
|
|
@@ -492,65 +506,41 @@ export async function loadLogsIntoMemory(): Promise<void> {
|
|
|
492
506
|
const logDir = resolveLogDir();
|
|
493
507
|
if (!existsSync(logDir)) return;
|
|
494
508
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const entries = await readdirCallback(logDir);
|
|
500
|
-
const filesWithExt = entries.filter((f: string) => f.endsWith(".jsonl")).sort();
|
|
501
|
-
for (const file of filesWithExt) {
|
|
502
|
-
const filePath = join(logDir, file);
|
|
503
|
-
await loadLogFile(filePath, lastCompletedById);
|
|
504
|
-
}
|
|
505
|
-
} catch (err) {
|
|
506
|
-
logger.error("[store] Failed to read log directory:", String(err));
|
|
507
|
-
}
|
|
509
|
+
const recentCompletedById = new Map<number, CapturedLog>();
|
|
510
|
+
await visitPersistedLogs((log) => {
|
|
511
|
+
rememberRecentCompletedLog(log, recentCompletedById);
|
|
512
|
+
});
|
|
508
513
|
|
|
509
514
|
// Sort by id descending, keep only MAX_MEMORY_CACHE newest completed entries
|
|
510
|
-
const sorted = [...
|
|
511
|
-
for (
|
|
512
|
-
|
|
513
|
-
if (entry !== undefined) addToCache(entry);
|
|
515
|
+
const sorted = [...recentCompletedById.values()].sort((a, b) => b.id - a.id);
|
|
516
|
+
for (const entry of sorted) {
|
|
517
|
+
addToCache(entry);
|
|
514
518
|
}
|
|
515
519
|
|
|
516
520
|
rebuildSessionRegistry(memoryCache.values());
|
|
517
521
|
}
|
|
518
522
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
):
|
|
523
|
-
if (
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
523
|
+
function rememberRecentCompletedLog(
|
|
524
|
+
log: CapturedLog,
|
|
525
|
+
recentCompletedById: Map<number, CapturedLog>,
|
|
526
|
+
): void {
|
|
527
|
+
if (log.responseStatus === null) return;
|
|
528
|
+
recentCompletedById.set(log.id, log);
|
|
529
|
+
while (recentCompletedById.size > MAX_MEMORY_CACHE) {
|
|
530
|
+
const oldestId = findSmallestLogId(recentCompletedById);
|
|
531
|
+
if (oldestId === null) return;
|
|
532
|
+
recentCompletedById.delete(oldestId);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
530
535
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
const desc = Object.getOwnPropertyDescriptor(parsed, "id");
|
|
537
|
-
if (desc !== undefined && typeof desc.value === "number") {
|
|
538
|
-
const statusDesc = Object.getOwnPropertyDescriptor(parsed, "responseStatus");
|
|
539
|
-
if (statusDesc !== undefined && statusDesc.value !== null) {
|
|
540
|
-
const result = CapturedLogSchema.safeParse(parsed);
|
|
541
|
-
if (result.success) {
|
|
542
|
-
lastCompletedById.set(desc.value, result.data);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
} catch {
|
|
548
|
-
// Skip malformed lines
|
|
549
|
-
}
|
|
536
|
+
function findSmallestLogId(logsById: ReadonlyMap<number, CapturedLog>): number | null {
|
|
537
|
+
let smallestId: number | null = null;
|
|
538
|
+
for (const id of logsById.keys()) {
|
|
539
|
+
if (smallestId === null || id < smallestId) {
|
|
540
|
+
smallestId = id;
|
|
550
541
|
}
|
|
551
|
-
} catch (err) {
|
|
552
|
-
logger.error("[store] Failed to load logs into memory:", String(err));
|
|
553
542
|
}
|
|
543
|
+
return smallestId;
|
|
554
544
|
}
|
|
555
545
|
|
|
556
546
|
export function clearAllLogs(): { cleared: number } {
|
|
@@ -632,40 +622,113 @@ type RewriteLogFileResult = {
|
|
|
632
622
|
removedIds: Set<number>;
|
|
633
623
|
};
|
|
634
624
|
|
|
625
|
+
function tempRewritePath(filePath: string): string {
|
|
626
|
+
return `${filePath}.rewrite-${String(process.pid)}-${String(Date.now())}.tmp`;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
async function removeTempFile(filePath: string): Promise<void> {
|
|
630
|
+
try {
|
|
631
|
+
await unlink(filePath);
|
|
632
|
+
} catch {
|
|
633
|
+
// Best-effort cleanup for temp rewrite files.
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function waitForWriterDrain(writer: WriteStream): Promise<boolean> {
|
|
638
|
+
return new Promise((resolve) => {
|
|
639
|
+
const cleanup = (): void => {
|
|
640
|
+
writer.off("drain", onDrain);
|
|
641
|
+
writer.off("error", onError);
|
|
642
|
+
};
|
|
643
|
+
const onDrain = (): void => {
|
|
644
|
+
cleanup();
|
|
645
|
+
resolve(true);
|
|
646
|
+
};
|
|
647
|
+
const onError = (): void => {
|
|
648
|
+
cleanup();
|
|
649
|
+
resolve(false);
|
|
650
|
+
};
|
|
651
|
+
writer.once("drain", onDrain);
|
|
652
|
+
writer.once("error", onError);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async function writeKeptLogLine(writer: WriteStream, line: string): Promise<boolean> {
|
|
657
|
+
if (writer.write(`${line}\n`, "utf-8")) return true;
|
|
658
|
+
return await waitForWriterDrain(writer);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function finishWriter(writer: WriteStream): Promise<boolean> {
|
|
662
|
+
return new Promise((resolve) => {
|
|
663
|
+
const cleanup = (): void => {
|
|
664
|
+
writer.off("finish", onFinish);
|
|
665
|
+
writer.off("error", onError);
|
|
666
|
+
};
|
|
667
|
+
const onFinish = (): void => {
|
|
668
|
+
cleanup();
|
|
669
|
+
resolve(true);
|
|
670
|
+
};
|
|
671
|
+
const onError = (): void => {
|
|
672
|
+
cleanup();
|
|
673
|
+
resolve(false);
|
|
674
|
+
};
|
|
675
|
+
writer.once("finish", onFinish);
|
|
676
|
+
writer.once("error", onError);
|
|
677
|
+
writer.end();
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
|
|
635
681
|
async function rewriteLogFileWithoutIds(
|
|
636
682
|
filePath: string,
|
|
637
683
|
ids: ReadonlySet<number>,
|
|
638
684
|
): Promise<RewriteLogFileResult> {
|
|
639
|
-
|
|
685
|
+
const tempPath = tempRewritePath(filePath);
|
|
686
|
+
const writer = createWriteStream(tempPath, { encoding: "utf-8" });
|
|
687
|
+
const removedIds = new Set<number>();
|
|
688
|
+
let keptLineCount = 0;
|
|
689
|
+
let writeOk = true;
|
|
690
|
+
|
|
640
691
|
try {
|
|
641
|
-
|
|
692
|
+
const fileStream = createInterface({
|
|
693
|
+
input: createReadStream(filePath),
|
|
694
|
+
crlfDelay: Infinity,
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
for await (const line of fileStream) {
|
|
698
|
+
if (line === "") continue;
|
|
699
|
+
const id = readLogIdFromLine(line);
|
|
700
|
+
if (id !== null && ids.has(id)) {
|
|
701
|
+
removedIds.add(id);
|
|
702
|
+
} else {
|
|
703
|
+
keptLineCount += 1;
|
|
704
|
+
writeOk = await writeKeptLogLine(writer, line);
|
|
705
|
+
if (!writeOk) break;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
642
708
|
} catch (err) {
|
|
643
|
-
logger.warn("[store] Failed to
|
|
644
|
-
|
|
709
|
+
logger.warn("[store] Failed to stream log file for deletion:", filePath, String(err));
|
|
710
|
+
writeOk = false;
|
|
645
711
|
}
|
|
646
712
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
for (const line of lines) {
|
|
651
|
-
if (line === "") continue;
|
|
652
|
-
const id = readLogIdFromLine(line);
|
|
653
|
-
if (id !== null && ids.has(id)) {
|
|
654
|
-
removedIds.add(id);
|
|
655
|
-
} else {
|
|
656
|
-
keptLines.push(line);
|
|
657
|
-
}
|
|
713
|
+
if (!(await finishWriter(writer)) || !writeOk) {
|
|
714
|
+
await removeTempFile(tempPath);
|
|
715
|
+
return { rewritten: false, removedIds: new Set() };
|
|
658
716
|
}
|
|
659
717
|
|
|
660
|
-
if (removedIds.size === 0)
|
|
718
|
+
if (removedIds.size === 0) {
|
|
719
|
+
await removeTempFile(tempPath);
|
|
720
|
+
return { rewritten: false, removedIds };
|
|
721
|
+
}
|
|
661
722
|
|
|
662
723
|
try {
|
|
663
|
-
if (
|
|
724
|
+
if (keptLineCount === 0) {
|
|
725
|
+
await removeTempFile(tempPath);
|
|
664
726
|
await unlink(filePath);
|
|
665
727
|
} else {
|
|
666
|
-
await
|
|
728
|
+
await rename(tempPath, filePath);
|
|
667
729
|
}
|
|
668
730
|
} catch (err) {
|
|
731
|
+
await removeTempFile(tempPath);
|
|
669
732
|
logger.warn("[store] Failed to rewrite log file after deletion:", filePath, String(err));
|
|
670
733
|
return { rewritten: false, removedIds: new Set() };
|
|
671
734
|
}
|
|
@@ -2,7 +2,7 @@ import { createFileRoute } from "@tanstack/react-router";
|
|
|
2
2
|
import { onLogUpdate, getLogSessionId, listLogsPage } from "../../proxy/store";
|
|
3
3
|
import { type CapturedLog } from "../../proxy/schemas";
|
|
4
4
|
|
|
5
|
-
const INITIAL_STREAM_LOG_LIMIT =
|
|
5
|
+
const INITIAL_STREAM_LOG_LIMIT = 100;
|
|
6
6
|
|
|
7
7
|
export const Route = createFileRoute("/api/logs/stream")({
|
|
8
8
|
server: {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{R as s,j as e}from"./main-N-sjHJUM.js";import{P as i}from"./ProxyViewerContainer-Dwhi4Q1c.js";function t(){const{sessionId:o}=s.useParams();return e.jsx(i,{initialSessionId:o},o)}export{t as component};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as o}from"./ProxyViewerContainer-Dwhi4Q1c.js";import"./main-N-sjHJUM.js";const r=o;export{r as component};
|