@tonyclaw/agent-inspector 2.0.17 → 2.0.19
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 +149 -40
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-DDg7Cs4N.js → CompareDrawer-D-90PIPw.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-CxRDWacg.js +114 -0
- package/.output/public/assets/ReplayDialog-DzlLYoTO.js +1 -0
- package/.output/public/assets/{RequestAnatomy-DR8OICOJ.js → RequestAnatomy-0hbyf6oa.js} +1 -1
- package/.output/public/assets/ResponseView-CKe0tNqr.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-enhfdeNh.js +1 -0
- package/.output/public/assets/_sessionId-CJ-SusES.js +1 -0
- package/.output/public/assets/index-BbFsmQRC.js +1 -0
- package/.output/public/assets/index-BfBgrkgU.css +1 -0
- package/.output/public/assets/{main-bwZlEXw2.js → main-o9-hg8g1.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +141 -118
- package/.output/server/_libs/tanstack__react-virtual.mjs +13 -2
- package/.output/server/_libs/tanstack__virtual-core.mjs +24 -1
- package/.output/server/{_sessionId-BEuJJhqT.mjs → _sessionId-F8lm6PIb.mjs} +3 -2
- package/.output/server/_ssr/{CompareDrawer-yTO93GMz.mjs → CompareDrawer-Cf1yfwfd.mjs} +4 -3
- package/.output/server/_ssr/{ProxyViewerContainer-C8qCkHGB.mjs → ProxyViewerContainer-Bmu9867L.mjs} +349 -74
- package/.output/server/_ssr/{ReplayDialog-DRF9PG7Z.mjs → ReplayDialog-DxZfLBOe.mjs} +199 -17
- package/.output/server/_ssr/{RequestAnatomy-DBcuV_jV.mjs → RequestAnatomy-CbdERGZd.mjs} +4 -3
- package/.output/server/_ssr/{ResponseView-JJm78HZT.mjs → ResponseView-CvLd6qxI.mjs} +4 -3
- package/.output/server/_ssr/{StreamingChunkSequence-DyGKjBYx.mjs → StreamingChunkSequence-B_lkRB6o.mjs} +4 -3
- package/.output/server/_ssr/{index-T7JG28t6.mjs → index-ejrSItfz.mjs} +3 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-BJob8RN3.mjs → router-SbCnbDc2.mjs} +896 -240
- package/.output/server/{_tanstack-start-manifest_v-CuiFi3XC.mjs → _tanstack-start-manifest_v-yx8ftqWz.mjs} +1 -1
- package/.output/server/index.mjs +60 -60
- package/README.md +26 -109
- package/package.json +2 -1
- package/src/cli/doctor.ts +160 -8
- package/src/cli/templates/skill-onboard.ts +2 -20
- package/src/components/OnboardingBanner.tsx +13 -13
- package/src/components/ProxyViewer.tsx +55 -38
- package/src/components/ProxyViewerContainer.tsx +5 -0
- package/src/components/providers/SettingsDialog.tsx +113 -2
- package/src/components/proxy-viewer/ConversationGroup.tsx +20 -3
- package/src/components/proxy-viewer/ConversationGroupList.tsx +144 -0
- package/src/components/proxy-viewer/ConversationHeader.tsx +0 -2
- package/src/components/proxy-viewer/ReplayDialog.tsx +200 -13
- package/src/components/proxy-viewer/index.ts +1 -1
- package/src/knowledge/openclawClient.ts +0 -8
- package/src/knowledge/types.ts +0 -2
- package/src/lib/export-logs.ts +72 -5
- package/src/lib/providerTestContract.ts +0 -1
- package/src/lib/useProviders.ts +1 -1
- package/src/mcp/server.ts +14 -6
- package/src/mcp/toolHandlers.ts +21 -4
- package/src/proxy/chunkStorage.ts +2 -4
- package/src/proxy/dataDir.ts +37 -15
- package/src/proxy/formats/anthropic/index.ts +0 -1
- package/src/proxy/formats/anthropic/schemas.ts +0 -2
- package/src/proxy/handler.ts +41 -29
- package/src/proxy/logFinalizer.ts +93 -11
- package/src/proxy/logger.ts +35 -10
- package/src/proxy/providers.ts +12 -5
- package/src/proxy/rawStreamCapture.ts +85 -0
- package/src/proxy/schemas.ts +1 -51
- package/src/proxy/sessionRuntime.ts +0 -9
- package/src/proxy/socketTracker.ts +15 -8
- package/src/proxy/store.ts +414 -13
- package/src/routes/api/logs.$id.replay.ts +66 -1
- package/src/routes/api/logs.stream.ts +11 -3
- package/src/routes/api/logs.ts +51 -17
- package/src/routes/api/providers.$providerId.ts +10 -3
- package/src/routes/api/providers.ts +6 -3
- package/.output/public/assets/ProxyViewerContainer-DbbK1y7N.js +0 -114
- package/.output/public/assets/ReplayDialog-C1zWNkoz.js +0 -1
- package/.output/public/assets/ResponseView-Dh9iSj6h.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-B_xElyH3.js +0 -1
- package/.output/public/assets/_sessionId-gv1a_NNu.js +0 -1
- package/.output/public/assets/index-D_nZj9Vt.css +0 -1
- package/.output/public/assets/index-u-LwDaeH.js +0 -1
- package/src/components/ui/json-expansion-button.tsx +0 -56
package/.output/cli.js
CHANGED
|
@@ -389,9 +389,6 @@ agent_inspector_data_dir() {
|
|
|
389
389
|
case "$AGENT_INSPECTOR_CONFIG_DIR" in /*) printf '%s
|
|
390
390
|
' "$AGENT_INSPECTOR_CONFIG_DIR" ;; *) printf '%s
|
|
391
391
|
' "$base/$AGENT_INSPECTOR_CONFIG_DIR" ;; esac
|
|
392
|
-
elif { [ ! -e "$base/.agent-inspector/providers.json" ] && [ ! -e "$base/.agent-inspector/config.json" ] && [ ! -e "$base/.agent-inspector/logs" ] && [ ! -e "$base/.agent-inspector/chunks" ]; } && { [ -e "$base/.llm-inspector/providers.json" ] || [ -e "$base/.llm-inspector/config.json" ] || [ -e "$base/.llm-inspector/logs" ] || [ -e "$base/.llm-inspector/chunks" ]; }; then
|
|
393
|
-
printf '%s
|
|
394
|
-
' "$base/.llm-inspector"
|
|
395
392
|
else
|
|
396
393
|
printf '%s
|
|
397
394
|
' "$base/.agent-inspector"
|
|
@@ -439,14 +436,7 @@ function Resolve-AgentInspectorDataDir {
|
|
|
439
436
|
if ([System.IO.Path]::IsPathRooted($env:AGENT_INSPECTOR_CONFIG_DIR)) { return $env:AGENT_INSPECTOR_CONFIG_DIR }
|
|
440
437
|
return (Join-Path $base $env:AGENT_INSPECTOR_CONFIG_DIR)
|
|
441
438
|
}
|
|
442
|
-
|
|
443
|
-
$legacy = Join-Path $base '.llm-inspector'
|
|
444
|
-
$currentHasState = (Test-Path (Join-Path $current 'providers.json')) -or (Test-Path (Join-Path $current 'config.json')) -or (Test-Path (Join-Path $current 'logs')) -or (Test-Path (Join-Path $current 'chunks'))
|
|
445
|
-
$legacyHasState = (Test-Path (Join-Path $legacy 'providers.json')) -or (Test-Path (Join-Path $legacy 'config.json')) -or (Test-Path (Join-Path $legacy 'logs')) -or (Test-Path (Join-Path $legacy 'chunks'))
|
|
446
|
-
if (-not $currentHasState -and $legacyHasState) {
|
|
447
|
-
return $legacy
|
|
448
|
-
}
|
|
449
|
-
return $current
|
|
439
|
+
return (Join-Path $base '.agent-inspector')
|
|
450
440
|
}
|
|
451
441
|
$dataDir = Resolve-AgentInspectorDataDir
|
|
452
442
|
$providers = Join-Path $dataDir 'providers.json'
|
|
@@ -566,9 +556,6 @@ agent_inspector_data_dir() {
|
|
|
566
556
|
case "$AGENT_INSPECTOR_CONFIG_DIR" in /*) printf '%s
|
|
567
557
|
' "$AGENT_INSPECTOR_CONFIG_DIR" ;; *) printf '%s
|
|
568
558
|
' "$base/$AGENT_INSPECTOR_CONFIG_DIR" ;; esac
|
|
569
|
-
elif { [ ! -e "$base/.agent-inspector/providers.json" ] && [ ! -e "$base/.agent-inspector/config.json" ] && [ ! -e "$base/.agent-inspector/logs" ] && [ ! -e "$base/.agent-inspector/chunks" ]; } && { [ -e "$base/.llm-inspector/providers.json" ] || [ -e "$base/.llm-inspector/config.json" ] || [ -e "$base/.llm-inspector/logs" ] || [ -e "$base/.llm-inspector/chunks" ]; }; then
|
|
570
|
-
printf '%s
|
|
571
|
-
' "$base/.llm-inspector"
|
|
572
559
|
else
|
|
573
560
|
printf '%s
|
|
574
561
|
' "$base/.agent-inspector"
|
|
@@ -613,14 +600,7 @@ function Resolve-AgentInspectorDataDir {
|
|
|
613
600
|
if ([System.IO.Path]::IsPathRooted($env:AGENT_INSPECTOR_CONFIG_DIR)) { return $env:AGENT_INSPECTOR_CONFIG_DIR }
|
|
614
601
|
return (Join-Path $base $env:AGENT_INSPECTOR_CONFIG_DIR)
|
|
615
602
|
}
|
|
616
|
-
|
|
617
|
-
$legacy = Join-Path $base '.llm-inspector'
|
|
618
|
-
$currentHasState = (Test-Path (Join-Path $current 'providers.json')) -or (Test-Path (Join-Path $current 'config.json')) -or (Test-Path (Join-Path $current 'logs')) -or (Test-Path (Join-Path $current 'chunks'))
|
|
619
|
-
$legacyHasState = (Test-Path (Join-Path $legacy 'providers.json')) -or (Test-Path (Join-Path $legacy 'config.json')) -or (Test-Path (Join-Path $legacy 'logs')) -or (Test-Path (Join-Path $legacy 'chunks'))
|
|
620
|
-
if (-not $currentHasState -and $legacyHasState) {
|
|
621
|
-
return $legacy
|
|
622
|
-
}
|
|
623
|
-
return $current
|
|
603
|
+
return (Join-Path $base '.agent-inspector')
|
|
624
604
|
}
|
|
625
605
|
$dir = Resolve-AgentInspectorDataDir
|
|
626
606
|
$file = Join-Path $dir 'providers.json'
|
|
@@ -1514,13 +1494,16 @@ var init_onboard = __esm({
|
|
|
1514
1494
|
});
|
|
1515
1495
|
|
|
1516
1496
|
// src/proxy/dataDir.ts
|
|
1497
|
+
import { cpSync, existsSync as existsSync3, rmSync } from "node:fs";
|
|
1517
1498
|
import { isAbsolute, join as join3 } from "node:path";
|
|
1518
1499
|
function hasDataDirState(pathExists, dir) {
|
|
1519
1500
|
return pathExists(join3(dir, "providers.json")) || pathExists(join3(dir, "config.json")) || pathExists(join3(dir, "logs")) || pathExists(join3(dir, "chunks"));
|
|
1520
1501
|
}
|
|
1521
|
-
function
|
|
1522
|
-
|
|
1523
|
-
|
|
1502
|
+
function defaultBaseDir(env = process.env, platform = process.platform) {
|
|
1503
|
+
return platform === "win32" ? env["USERPROFILE"] ?? env["APPDATA"] ?? "C:\\" : env["HOME"] ?? "/tmp";
|
|
1504
|
+
}
|
|
1505
|
+
function resolveDataDir(_pathExists, env = process.env, platform = process.platform) {
|
|
1506
|
+
const base = defaultBaseDir(env, platform);
|
|
1524
1507
|
const dirEnv = env["AGENT_INSPECTOR_DATA_DIR"];
|
|
1525
1508
|
if (dirEnv !== void 0 && dirEnv !== "") {
|
|
1526
1509
|
return isAbsolute(dirEnv) ? dirEnv : join3(base, dirEnv);
|
|
@@ -1529,16 +1512,32 @@ function resolveDataDir(pathExists, env = process.env, platform = process.platfo
|
|
|
1529
1512
|
if (legacyDirEnv !== void 0 && legacyDirEnv !== "") {
|
|
1530
1513
|
return isAbsolute(legacyDirEnv) ? legacyDirEnv : join3(base, legacyDirEnv);
|
|
1531
1514
|
}
|
|
1515
|
+
return join3(base, CURRENT_DATA_DIR_NAME);
|
|
1516
|
+
}
|
|
1517
|
+
function hasExplicitDataDir() {
|
|
1518
|
+
return process.env["AGENT_INSPECTOR_DATA_DIR"] !== void 0 && process.env["AGENT_INSPECTOR_DATA_DIR"] !== "" || process.env["AGENT_INSPECTOR_CONFIG_DIR"] !== void 0 && process.env["AGENT_INSPECTOR_CONFIG_DIR"] !== "";
|
|
1519
|
+
}
|
|
1520
|
+
function migrateLegacyDataDirs() {
|
|
1521
|
+
if (hasExplicitDataDir()) return;
|
|
1522
|
+
const base = defaultBaseDir();
|
|
1532
1523
|
const currentDir = join3(base, CURRENT_DATA_DIR_NAME);
|
|
1533
|
-
|
|
1534
|
-
|
|
1524
|
+
if (hasDataDirState(existsSync3, currentDir)) return;
|
|
1525
|
+
for (const legacyName of LEGACY_DATA_DIR_NAMES) {
|
|
1526
|
+
const legacyDir = join3(base, legacyName);
|
|
1527
|
+
if (!existsSync3(legacyDir)) continue;
|
|
1528
|
+
try {
|
|
1529
|
+
cpSync(legacyDir, currentDir, { recursive: true, force: true });
|
|
1530
|
+
rmSync(legacyDir, { recursive: true, force: true });
|
|
1531
|
+
} catch {
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1535
1534
|
}
|
|
1536
|
-
var CURRENT_DATA_DIR_NAME,
|
|
1535
|
+
var CURRENT_DATA_DIR_NAME, LEGACY_DATA_DIR_NAMES;
|
|
1537
1536
|
var init_dataDir = __esm({
|
|
1538
1537
|
"src/proxy/dataDir.ts"() {
|
|
1539
1538
|
"use strict";
|
|
1540
1539
|
CURRENT_DATA_DIR_NAME = ".agent-inspector";
|
|
1541
|
-
|
|
1540
|
+
LEGACY_DATA_DIR_NAMES = [".llm-inspector", ".llm-agent"];
|
|
1542
1541
|
}
|
|
1543
1542
|
});
|
|
1544
1543
|
|
|
@@ -1548,11 +1547,12 @@ __export(doctor_exports, {
|
|
|
1548
1547
|
buildDoctorReport: () => buildDoctorReport,
|
|
1549
1548
|
createDoctorDeps: () => createDoctorDeps,
|
|
1550
1549
|
doctorHelp: () => doctorHelp,
|
|
1550
|
+
formatDoctorJson: () => formatDoctorJson,
|
|
1551
1551
|
formatDoctorReport: () => formatDoctorReport,
|
|
1552
1552
|
parseDoctorArgs: () => parseDoctorArgs,
|
|
1553
1553
|
runDoctor: () => runDoctor
|
|
1554
1554
|
});
|
|
1555
|
-
import { existsSync as
|
|
1555
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync } from "node:fs";
|
|
1556
1556
|
import { isAbsolute as isAbsolute2, join as join4, resolve } from "node:path";
|
|
1557
1557
|
import { createConnection } from "node:net";
|
|
1558
1558
|
function check(name, severity, message, hint = "") {
|
|
@@ -1575,6 +1575,10 @@ function parseDoctorArgs(argv, env = process.env) {
|
|
|
1575
1575
|
port: envPort ?? DEFAULT_PORT2,
|
|
1576
1576
|
configDir: null,
|
|
1577
1577
|
providersJson: null,
|
|
1578
|
+
chromeExtension: false,
|
|
1579
|
+
fix: false,
|
|
1580
|
+
json: false,
|
|
1581
|
+
verbose: false,
|
|
1578
1582
|
help: false
|
|
1579
1583
|
};
|
|
1580
1584
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -1614,6 +1618,18 @@ function parseDoctorArgs(argv, env = process.env) {
|
|
|
1614
1618
|
i++;
|
|
1615
1619
|
break;
|
|
1616
1620
|
}
|
|
1621
|
+
case "--chrome-extension":
|
|
1622
|
+
options.chromeExtension = true;
|
|
1623
|
+
break;
|
|
1624
|
+
case "--fix":
|
|
1625
|
+
options.fix = true;
|
|
1626
|
+
break;
|
|
1627
|
+
case "--json":
|
|
1628
|
+
options.json = true;
|
|
1629
|
+
break;
|
|
1630
|
+
case "--verbose":
|
|
1631
|
+
options.verbose = true;
|
|
1632
|
+
break;
|
|
1617
1633
|
default:
|
|
1618
1634
|
return { kind: "error", message: `doctor: unknown option ${arg}` };
|
|
1619
1635
|
}
|
|
@@ -1769,6 +1785,79 @@ function checkPackage(rootDir, deps) {
|
|
|
1769
1785
|
return check("Package metadata", "warn", "package.json is not valid JSON.");
|
|
1770
1786
|
}
|
|
1771
1787
|
}
|
|
1788
|
+
function countFilesInDir(dir, deps) {
|
|
1789
|
+
const files = deps.listDir(dir);
|
|
1790
|
+
if (files === null) return null;
|
|
1791
|
+
let count = 0;
|
|
1792
|
+
for (const file of files) {
|
|
1793
|
+
const fileStat = deps.stat(join4(dir, file));
|
|
1794
|
+
if (fileStat !== null && !fileStat.isDirectory) count += 1;
|
|
1795
|
+
}
|
|
1796
|
+
return count;
|
|
1797
|
+
}
|
|
1798
|
+
function formatBytes(bytes) {
|
|
1799
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1800
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
1801
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MiB`;
|
|
1802
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GiB`;
|
|
1803
|
+
}
|
|
1804
|
+
function dirSize(dir, deps, depth = 0) {
|
|
1805
|
+
const dirStat = deps.stat(dir);
|
|
1806
|
+
if (dirStat === null) return null;
|
|
1807
|
+
if (!dirStat.isDirectory) return dirStat.size;
|
|
1808
|
+
if (depth > 4) return 0;
|
|
1809
|
+
const files = deps.listDir(dir);
|
|
1810
|
+
if (files === null) return null;
|
|
1811
|
+
let total = 0;
|
|
1812
|
+
for (const file of files) {
|
|
1813
|
+
const childSize = dirSize(join4(dir, file), deps, depth + 1);
|
|
1814
|
+
if (childSize !== null) total += childSize;
|
|
1815
|
+
}
|
|
1816
|
+
return total;
|
|
1817
|
+
}
|
|
1818
|
+
function verboseChecks(options, deps) {
|
|
1819
|
+
const dataDir = resolveDefaultDataDir(deps.env, deps.platform, deps.exists);
|
|
1820
|
+
const logsDir = join4(dataDir, "logs");
|
|
1821
|
+
const chunksDir = join4(dataDir, "chunks");
|
|
1822
|
+
const providerCandidates = providerConfigCandidates(options, deps);
|
|
1823
|
+
const captureMode = deps.env["AGENT_INSPECTOR_MODE"] ?? deps.env["AGENT_INSPECTOR_CAPTURE_MODE"] ?? "simple";
|
|
1824
|
+
const logCount = countFilesInDir(logsDir, deps);
|
|
1825
|
+
const logSize = dirSize(logsDir, deps);
|
|
1826
|
+
const chunkSize = dirSize(chunksDir, deps);
|
|
1827
|
+
const homeDir = deps.platform === "win32" ? deps.env["USERPROFILE"] ?? deps.env["APPDATA"] ?? null : deps.env["HOME"] ?? null;
|
|
1828
|
+
const claudeSkill = homeDir === null ? null : join4(homeDir, ".claude", "skills", "agent-inspector-onboard", "SKILL.md");
|
|
1829
|
+
const claudeCommand = homeDir === null ? null : join4(homeDir, ".claude", "commands", "agent-inspector-onboard.md");
|
|
1830
|
+
const codexSkill = homeDir === null ? null : join4(homeDir, ".codex", "skills", "agent-inspector-onboard", "SKILL.md");
|
|
1831
|
+
const hasClaudeOnboarding = claudeSkill !== null && claudeCommand !== null && deps.exists(claudeSkill) && deps.exists(claudeCommand);
|
|
1832
|
+
const hasCodexOnboarding = codexSkill !== null && deps.exists(codexSkill);
|
|
1833
|
+
return [
|
|
1834
|
+
check("Data directory", "pass", dataDir),
|
|
1835
|
+
check("Provider config search", "pass", providerCandidates.join(", ")),
|
|
1836
|
+
check("Capture mode env", "pass", captureMode),
|
|
1837
|
+
check(
|
|
1838
|
+
"Log storage",
|
|
1839
|
+
logCount === null ? "warn" : "pass",
|
|
1840
|
+
logCount === null ? `Log directory was not found or could not be read: ${logsDir}` : `${logCount} file(s), ${formatBytes(logSize ?? 0)} under ${logsDir}`
|
|
1841
|
+
),
|
|
1842
|
+
check(
|
|
1843
|
+
"Chunk storage",
|
|
1844
|
+
chunkSize === null ? "warn" : "pass",
|
|
1845
|
+
chunkSize === null ? `Chunk directory was not found or could not be read: ${chunksDir}` : `${formatBytes(chunkSize)} under ${chunksDir}`
|
|
1846
|
+
),
|
|
1847
|
+
check(
|
|
1848
|
+
"Claude onboarding",
|
|
1849
|
+
hasClaudeOnboarding ? "pass" : "warn",
|
|
1850
|
+
hasClaudeOnboarding ? "Claude Code skill and slash command are installed." : "Claude Code onboarding files were not found.",
|
|
1851
|
+
"Run `agent-inspector onboard --force` after installing or upgrading."
|
|
1852
|
+
),
|
|
1853
|
+
check(
|
|
1854
|
+
"Codex onboarding",
|
|
1855
|
+
hasCodexOnboarding ? "pass" : "warn",
|
|
1856
|
+
hasCodexOnboarding ? "Codex onboarding skill is installed." : "Codex onboarding skill was not found.",
|
|
1857
|
+
"Run `agent-inspector onboard --force` after installing or upgrading."
|
|
1858
|
+
)
|
|
1859
|
+
];
|
|
1860
|
+
}
|
|
1772
1861
|
function checkExtensionSource(rootDir, deps) {
|
|
1773
1862
|
const extensionDir = join4(rootDir, "extensions", "chrome");
|
|
1774
1863
|
const missing = EXTENSION_REQUIRED_FILES.filter((file) => !deps.exists(join4(extensionDir, file)));
|
|
@@ -1855,13 +1944,13 @@ function checkExtensionPackage(rootDir, deps) {
|
|
|
1855
1944
|
}
|
|
1856
1945
|
async function buildDoctorReport(options, deps = createDoctorDeps()) {
|
|
1857
1946
|
const rootDir = findProjectRoot(deps.cwd, deps);
|
|
1858
|
-
const
|
|
1947
|
+
const coreChecks = [
|
|
1859
1948
|
await checkProxyHealth(options.port, deps),
|
|
1860
1949
|
checkProviderConfig(options, deps),
|
|
1861
|
-
checkPackage(rootDir, deps)
|
|
1862
|
-
checkExtensionSource(rootDir, deps),
|
|
1863
|
-
checkExtensionPackage(rootDir, deps)
|
|
1950
|
+
checkPackage(rootDir, deps)
|
|
1864
1951
|
];
|
|
1952
|
+
const checksWithExtension = options.chromeExtension ? [...coreChecks, checkExtensionSource(rootDir, deps), checkExtensionPackage(rootDir, deps)] : coreChecks;
|
|
1953
|
+
const checks = options.verbose ? [...checksWithExtension, ...verboseChecks(options, deps)] : checksWithExtension;
|
|
1865
1954
|
const passCount = checks.filter((item) => item.severity === "pass").length;
|
|
1866
1955
|
const warnCount = checks.filter((item) => item.severity === "warn").length;
|
|
1867
1956
|
const failCount = checks.filter((item) => item.severity === "fail").length;
|
|
@@ -1888,14 +1977,22 @@ function formatDoctorReport(report) {
|
|
|
1888
1977
|
return `${lines.join("\n")}
|
|
1889
1978
|
`;
|
|
1890
1979
|
}
|
|
1980
|
+
function formatDoctorJson(report) {
|
|
1981
|
+
return `${JSON.stringify(report, null, 2)}
|
|
1982
|
+
`;
|
|
1983
|
+
}
|
|
1891
1984
|
function doctorHelp() {
|
|
1892
1985
|
return [
|
|
1893
1986
|
"agent-inspector doctor",
|
|
1894
1987
|
"",
|
|
1895
1988
|
"Usage:",
|
|
1896
|
-
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>]",
|
|
1989
|
+
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>] [--fix] [--json] [--verbose] [--chrome-extension]",
|
|
1897
1990
|
"",
|
|
1898
|
-
"Checks local proxy health, provider config presence, package metadata
|
|
1991
|
+
"Checks local proxy health, provider config presence, and package metadata.",
|
|
1992
|
+
"Pass --fix to run safe local repairs before checks, including legacy data-dir migration.",
|
|
1993
|
+
"Pass --json to emit a machine-readable report for CI, scripts, and Jenkins.",
|
|
1994
|
+
"Pass --verbose to include local paths, capture mode, and log storage checks.",
|
|
1995
|
+
"Pass --chrome-extension to also check Chrome companion source and packaged artifacts.",
|
|
1899
1996
|
""
|
|
1900
1997
|
].join("\n");
|
|
1901
1998
|
}
|
|
@@ -1942,14 +2039,23 @@ function listDir(path) {
|
|
|
1942
2039
|
return null;
|
|
1943
2040
|
}
|
|
1944
2041
|
}
|
|
2042
|
+
function stat(path) {
|
|
2043
|
+
try {
|
|
2044
|
+
const fileStat = statSync(path);
|
|
2045
|
+
return { isDirectory: fileStat.isDirectory(), size: fileStat.size };
|
|
2046
|
+
} catch {
|
|
2047
|
+
return null;
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
1945
2050
|
function createDoctorDeps() {
|
|
1946
2051
|
return {
|
|
1947
2052
|
env: process.env,
|
|
1948
2053
|
platform: process.platform,
|
|
1949
2054
|
cwd: process.cwd(),
|
|
1950
|
-
exists:
|
|
2055
|
+
exists: existsSync4,
|
|
1951
2056
|
readText,
|
|
1952
2057
|
listDir,
|
|
2058
|
+
stat,
|
|
1953
2059
|
fetchHealth,
|
|
1954
2060
|
isPortOpen
|
|
1955
2061
|
};
|
|
@@ -1965,8 +2071,11 @@ async function runDoctor(argv) {
|
|
|
1965
2071
|
process.stdout.write(doctorHelp());
|
|
1966
2072
|
return 0;
|
|
1967
2073
|
}
|
|
2074
|
+
if (parsed.options.fix) {
|
|
2075
|
+
migrateLegacyDataDirs();
|
|
2076
|
+
}
|
|
1968
2077
|
const report = await buildDoctorReport(parsed.options);
|
|
1969
|
-
process.stdout.write(formatDoctorReport(report));
|
|
2078
|
+
process.stdout.write(parsed.options.json ? formatDoctorJson(report) : formatDoctorReport(report));
|
|
1970
2079
|
return report.exitCode;
|
|
1971
2080
|
}
|
|
1972
2081
|
var DEFAULT_PORT2, PROBE_TIMEOUT_MS, EXTENSION_REQUIRED_FILES;
|
|
@@ -1996,7 +2105,7 @@ import { spawn, execSync } from "node:child_process";
|
|
|
1996
2105
|
import { createConnection as createConnection2 } from "node:net";
|
|
1997
2106
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
1998
2107
|
import { dirname as dirname2, join as join5, resolve as resolvePath } from "node:path";
|
|
1999
|
-
import { existsSync as
|
|
2108
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
2000
2109
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
2001
2110
|
var __dirname2 = dirname2(__filename2);
|
|
2002
2111
|
var DEFAULT_PORT3 = 25947;
|
|
@@ -2112,7 +2221,7 @@ function waitForProcessExit(child) {
|
|
|
2112
2221
|
}
|
|
2113
2222
|
function resolveServerCommand(outputDir, serverPath) {
|
|
2114
2223
|
const brandedRuntime = join5(outputDir, BRANDED_WINDOWS_RUNTIME_EXE);
|
|
2115
|
-
return process.platform === "win32" &&
|
|
2224
|
+
return process.platform === "win32" && existsSync5(brandedRuntime) ? { command: brandedRuntime, args: [serverPath] } : { command: process.execPath, args: [serverPath] };
|
|
2116
2225
|
}
|
|
2117
2226
|
function parseCaptureMode(value) {
|
|
2118
2227
|
switch (value) {
|
package/.output/nitro.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as h,j as t}from"./main-bwZlEXw2.js";import{c as X,g as O,r as P,a as q,X as Y,b as x,B as Z,f as $,R as ee,C as te,M as _,d as J,e as M,h as V,J as N,i as re,j as ne}from"./ProxyViewerContainer-DbbK1y7N.js";const se=[["line",{x1:"5",x2:"19",y1:"9",y2:"9",key:"1nwqeh"}],["line",{x1:"5",x2:"19",y1:"15",y2:"15",key:"g8yjpy"}]],ae=X("equal",se),oe="";function j(e){if(e.length===0)return oe;let r="";for(let n=0;n<e.length;n++){const s=e[n];s!==void 0&&(typeof s=="number"?r+=`[${s}]`:n===0?r+=s:r+=`.${s}`)}return r}function de(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function D(e){if(typeof e=="string")try{return C(JSON.parse(e))}catch{return{kind:"primitive",value:e}}return C(e)}function C(e){if(e===null)return{kind:"primitive",value:null};if(typeof e=="string")return{kind:"primitive",value:e};if(typeof e=="number")return{kind:"primitive",value:e};if(typeof e=="boolean")return{kind:"primitive",value:e};if(Array.isArray(e))return{kind:"array",value:e.map(r=>C(r))};if(de(e)){const r={};for(const n of Object.keys(e).sort())r[n]=C(e[n]);return{kind:"object",value:r}}return{kind:"primitive",value:null}}function ie(e,r){const n=[];return R([],e,r,n),n}function R(e,r,n,s){const d=j(e);if(E(r,n)){s.push({kind:"equal",path:d,value:r});return}if(r.kind!==n.kind){s.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="primitive"&&n.kind==="primitive"){s.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="object"&&n.kind==="object"){const o=Object.keys(r.value),a=Object.keys(n.value),m=new Set(a);for(const i of o){const f=r.value[i];if(f!==void 0)if(!m.has(i))s.push({kind:"removed",path:j([...e,i]),value:f});else{const p=n.value[i];if(p===void 0)continue;R([...e,i],f,p,s)}}for(const i of a){if(o.includes(i))continue;const f=n.value[i];f!==void 0&&s.push({kind:"added",path:j([...e,i]),value:f})}return}if(r.kind==="array"&&n.kind==="array"){const o=Math.min(r.value.length,n.value.length);for(let a=0;a<o;a++){const m=r.value[a],i=n.value[a];m===void 0||i===void 0||R([...e,a],m,i,s)}for(let a=o;a<n.value.length;a++){const m=n.value[a];m!==void 0&&s.push({kind:"added",path:j([...e,a]),value:m})}for(let a=o;a<r.value.length;a++){const m=r.value[a];m!==void 0&&s.push({kind:"removed",path:j([...e,a]),value:m})}}}function E(e,r){if(e.kind!==r.kind)return!1;if(e.kind==="primitive"&&r.kind==="primitive")return e.value===r.value;if(e.kind==="array"&&r.kind==="array"){if(e.value.length!==r.value.length)return!1;for(let n=0;n<e.value.length;n++){const s=e.value[n],d=r.value[n];if(s===void 0||d===void 0||!E(s,d))return!1}return!0}if(e.kind==="object"&&r.kind==="object"){const n=Object.keys(e.value),s=Object.keys(r.value);if(n.length!==s.length)return!1;for(const d of n){const o=e.value[d],a=r.value[d];if(o===void 0||a===void 0||!E(o,a))return!1}return!0}return!1}function v(e,r=80){let n;switch(e.kind){case"primitive":n=e.value===null?"null":JSON.stringify(e.value);break;case"array":n=`[… ${e.value.length} items]`;break;case"object":n=`{… ${Object.keys(e.value).length} keys}`;break}return n.length>r&&(n=`${n.slice(0,r-1)}…`),n}function w(e,r=2){return JSON.stringify(S(e),null,r)}function S(e){switch(e.kind){case"primitive":return e.value;case"array":return e.value.map(S);case"object":{const r={};for(const[n,s]of Object.entries(e.value))r[n]=S(s);return r}}}function K(e){if(e==="")return"";for(let r=e.length-1;r>=0;r--){const n=e[r];if(n==="."||n==="[")return e.substring(0,r)}return""}function L(e){return e.kind==="equal"&&(e.value.kind==="object"||e.value.kind==="array")}function le(e){const r=[];let n=0;for(;n<e.length;){const s=e[n];if(s!==void 0&&L(s)){const d=K(s.path);let o=n+1;for(;o<e.length;){const a=e[o];if(a===void 0||!L(a)||K(a.path)!==d)break;o++}if(o-n>1){const a=[];for(let m=n;m<o;m++){const i=e[m];i!==void 0&&i.kind==="equal"&&a.push(i)}r.push({kind:"equal-run",ops:a}),n=o;continue}}s!==void 0&&r.push({kind:"single",op:s}),n++}return r}const B={added:{icon:J,accent:"text-emerald-600 dark:text-emerald-400",bg:"bg-emerald-500/5 hover:bg-emerald-500/10",border:"border-l-emerald-500",label:"ADDED"},removed:{icon:_,accent:"text-rose-600 dark:text-rose-400",bg:"bg-rose-500/5 hover:bg-rose-500/10",border:"border-l-rose-500",label:"REMOVED"},changed:{icon:M,accent:"text-amber-600 dark:text-amber-400",bg:"bg-amber-500/5 hover:bg-amber-500/10",border:"border-l-amber-500",label:"CHANGED"},equal:{icon:ae,accent:"text-muted-foreground/70",bg:"bg-muted/20 hover:bg-muted/30",border:"border-l-muted-foreground/20",label:"EQUAL"}};function ce({ops:e,expanded:r,onToggle:n}){const s=e[0],d=e[e.length-1];if(s===void 0||d===void 0)return t.jsx("div",{className:"text-muted-foreground/40 text-xs",children:"—"});const o=s.path,a=d.path,m=e.length===1?o:`${o} … ${a}`,i=s.value.kind==="array"?`${e.length} equal arrays`:s.value.kind==="object"?`${e.length} equal objects`:"equal",f=B.equal;return t.jsxs("div",{className:x("border-l-4 rounded-sm",f.border,f.bg),children:[t.jsxs("button",{type:"button",onClick:n,className:"w-full text-left flex items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground cursor-pointer",children:[t.jsx(V,{className:x("size-3 transition-transform shrink-0",r&&"rotate-90")}),t.jsx(f.icon,{className:x("size-3 shrink-0",f.accent)}),t.jsx("span",{className:"font-mono truncate flex-1",title:`${o} … ${a}`,children:m}),t.jsx("span",{className:x("text-[10px] uppercase tracking-wider shrink-0",f.accent),children:f.label}),t.jsxs("span",{className:"text-muted-foreground/60 shrink-0",children:["(",i,")"]})]}),r&&t.jsx("div",{className:"ml-5 mt-1 mb-2 space-y-2 pr-2",children:e.map(p=>t.jsxs("div",{className:"border border-border/50 rounded p-2 bg-muted/20",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:p.path}),t.jsx(N,{text:w(p.value),defaultExpandDepth:0})]},p.path))})]})}function ue({op:e,idx:r,copiedPath:n,onCopyPath:s,expanded:d,onToggle:o}){const a=B[e.kind],m=a.icon,i=e.kind==="added"||e.kind==="removed"?e.value.kind==="object"||e.value.kind==="array":e.kind==="changed"?e.left.kind==="object"||e.left.kind==="array"||e.right.kind==="object"||e.right.kind==="array":!1,f=e.kind==="changed"?[{text:v(e.left,400),tone:"text-rose-700 dark:text-rose-300 line-through"},{text:v(e.right,400),tone:"text-emerald-700 dark:text-emerald-300"}]:e.kind==="removed"?[{text:v(e.value,400),tone:"text-rose-700 dark:text-rose-300 line-through"}]:e.kind==="added"?[{text:v(e.value,400),tone:"text-emerald-700 dark:text-emerald-300"}]:[{text:v(e.value,400),tone:"text-muted-foreground"}],p=n===e.path&&e.path!=="";return t.jsxs("div",{"data-diff-idx":r,"data-diff-kind":e.kind,className:x("border-l-4 rounded-sm px-3 py-2 my-0.5 transition-colors",a.border,a.bg),children:[t.jsxs("button",{type:"button",onClick:o,disabled:!i,className:x("w-full flex items-center gap-2 text-xs text-left rounded-sm",i?"cursor-pointer":"cursor-default"),"aria-expanded":i?d:void 0,"aria-label":i?d?`Collapse ${e.path||"root"}`:`Expand ${e.path||"root"}`:void 0,children:[i?t.jsx(V,{className:x("size-3 shrink-0 transition-transform",a.accent,d&&"rotate-90")}):t.jsx("span",{className:"size-3 shrink-0","aria-hidden":"true"}),t.jsx(m,{className:x("size-3.5 shrink-0",a.accent),strokeWidth:2.5}),t.jsx("span",{className:"font-mono truncate flex-1 min-w-0",title:e.path||"(root)",children:e.path===""?"(root)":e.path}),t.jsx("span",{className:x("text-[9px] font-bold uppercase tracking-wider shrink-0 px-1.5 py-0.5 rounded",a.accent,e.kind==="equal"?"bg-muted/40":"bg-background/60"),children:a.label}),e.path!==""&&t.jsx("span",{role:"button",tabIndex:0,onClick:b=>{b.stopPropagation(),s(e.path)},onKeyDown:b=>{(b.key==="Enter"||b.key===" ")&&(b.stopPropagation(),b.preventDefault(),s(e.path))},className:x("shrink-0 p-1 rounded transition-colors cursor-pointer inline-flex items-center justify-center",p?"text-emerald-500":"text-muted-foreground/50 hover:text-foreground hover:bg-muted"),"aria-label":p?"Copied":"Copy",title:p?"Copied!":"Copy",children:p?t.jsx(re,{className:"size-3"}):t.jsx(ne,{className:"size-3"})})]}),f.map((b,y)=>t.jsx("div",{className:x("font-mono text-xs mt-1 break-all pl-5",b.tone),children:b.text},y)),t.jsx("div",{className:"overflow-hidden transition-all duration-200",style:{maxHeight:d&&i?"2000px":"0"},"aria-hidden":!d,children:d&&i&&e.kind!=="equal"?t.jsx(me,{op:e}):null})]})}function me({op:e}){if(e.kind==="added"||e.kind==="removed")return t.jsx("div",{className:"pl-5 mt-2 border border-border/50 rounded p-2 bg-muted/20",children:t.jsx(N,{text:w(e.value),defaultExpandDepth:0})});const r=e.left.kind==="object"||e.left.kind==="array",n=e.right.kind==="object"||e.right.kind==="array";return!r&&!n?t.jsx("div",{className:"pl-5 mt-2 text-xs text-muted-foreground/70 italic",children:"Primitive values are shown inline above."}):t.jsxs("div",{className:"pl-5 mt-2 grid grid-cols-1 md:grid-cols-2 gap-2",children:[t.jsxs("div",{className:"border border-rose-500/30 rounded p-2 bg-rose-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-rose-500 mb-1",children:"Old"}),t.jsx(N,{text:w(e.left),defaultExpandDepth:0})]}),t.jsxs("div",{className:"border border-emerald-500/30 rounded p-2 bg-emerald-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-emerald-500 mb-1",children:"New"}),t.jsx(N,{text:w(e.right),defaultExpandDepth:0})]})]})}function xe({counts:e,onJumpTo:r}){const n=e.added+e.removed+e.changed;return t.jsxs("div",{className:"px-4 py-2 border-b border-border bg-muted/20 flex items-center gap-2 text-xs flex-wrap",children:[t.jsxs("span",{className:"text-muted-foreground font-medium",children:[n," ",n===1?"change":"changes"]}),t.jsxs("button",{type:"button",onClick:()=>r("removed"),disabled:e.removed===0,className:x("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.removed>0?"border-rose-500/40 text-rose-600 dark:text-rose-400 bg-rose-500/10 hover:bg-rose-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.removed>0?"Jump to first removed":"No removals",children:[t.jsx(_,{className:"size-3"}),e.removed," removed"]}),t.jsxs("button",{type:"button",onClick:()=>r("added"),disabled:e.added===0,className:x("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.added>0?"border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 hover:bg-emerald-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.added>0?"Jump to first added":"No additions",children:[t.jsx(J,{className:"size-3"}),e.added," added"]}),t.jsxs("button",{type:"button",onClick:()=>r("changed"),disabled:e.changed===0,className:x("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.changed>0?"border-amber-500/40 text-amber-600 dark:text-amber-400 bg-amber-500/10 hover:bg-amber-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.changed>0?"Jump to first changed":"No changes",children:[t.jsx(M,{className:"size-3"}),e.changed," changed"]})]})}function fe({mode:e,onChange:r}){return t.jsxs("div",{className:"inline-flex rounded-md border border-border overflow-hidden",children:[t.jsxs("button",{type:"button",onClick:()=>r("unified"),"aria-pressed":e==="unified",className:x("flex items-center gap-1 px-2 py-1 text-xs transition-colors cursor-pointer",e==="unified"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Unified view (single column, emphasized diffs)",children:[t.jsx(ee,{className:"size-3"}),"Unified"]}),t.jsxs("button",{type:"button",onClick:()=>r("split"),"aria-pressed":e==="split",className:x("flex items-center gap-1 px-2 py-1 text-xs transition-colors border-l border-border cursor-pointer",e==="split"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Split view (path | left | right)",children:[t.jsx(te,{className:"size-3"}),"Split"]})]})}function A({log:e,side:r}){const n=q(e);return t.jsxs("div",{className:"flex-1 min-w-0 space-y-1 text-xs",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Z,{variant:"outline",className:x("text-[10px] px-1.5 py-0 h-5 font-mono shrink-0",r==="left"?"border-rose-500/40 text-rose-400":"border-emerald-500/40 text-emerald-400"),children:r==="left"?"← Left":"Right →"}),t.jsxs("span",{className:"font-mono text-blue-400/80",children:["#",e.id]}),e.model!==null&&t.jsx("span",{className:"font-mono text-muted-foreground truncate",children:e.model})]}),t.jsxs("div",{className:"flex items-center gap-3 text-muted-foreground font-mono",children:[e.cacheCreationInputTokens!==null&&e.cacheCreationInputTokens>0&&t.jsxs("span",{className:"text-emerald-400",children:["KV Cache +",$(e.cacheCreationInputTokens)]}),e.cacheReadInputTokens!==null&&e.cacheReadInputTokens>0&&t.jsxs("span",{className:"text-purple-400",children:["KV Cache ~",$(e.cacheReadInputTokens)]}),t.jsx("span",{className:"truncate",title:e.timestamp,children:e.timestamp})]}),t.jsxs("div",{className:"text-muted-foreground/70 font-mono truncate",title:n,children:["session: ",n]})]})}function ve({left:e,right:r,onClose:n}){const s=h.useMemo(()=>{const l=O(P(e)).analyzeRequest(e.rawRequestBody),c=O(P(r)).analyzeRequest(r.rawRequestBody),u=D(l.comparisonValue),g=D(c.comparisonValue);return ie(u,g)},[e.apiFormat,e.path,e.rawRequestBody,r.apiFormat,r.path,r.rawRequestBody]),d=h.useMemo(()=>le(s),[s]),o=h.useMemo(()=>{let l=0,c=0,u=0;for(const g of d)if(g.kind==="single")switch(g.op.kind){case"added":l++;break;case"removed":c++;break;case"changed":u++;break}return{added:l,removed:c,changed:u}},[d]),[a,m]=h.useState(new Set),i=l=>{m(c=>{const u=new Set(c);return u.has(l)?u.delete(l):u.add(l),u})},[f,p]=h.useState(new Set),b=l=>{p(c=>{const u=new Set(c);return u.has(l)?u.delete(l):u.add(l),u})};h.useEffect(()=>{p(new Set)},[e.id,r.id]);const[y,F]=h.useState("unified"),T=h.useRef(null),[U,z]=h.useState(null),k=h.useRef(null),H=l=>{window.navigator.clipboard.writeText(l).then(()=>{z(l),k.current!==null&&clearTimeout(k.current),k.current=setTimeout(()=>z(null),1500)})};h.useEffect(()=>()=>{k.current!==null&&clearTimeout(k.current)},[]);const G=l=>{const c=d.findIndex(I=>I.kind==="single"&&I.op.kind===l);if(c===-1)return;const u=T.current;if(u===null)return;const g=u.querySelector(`[data-diff-idx="${c}"]`);g!==null&&g.scrollIntoView({behavior:"smooth",block:"center"})};h.useEffect(()=>{const l=u=>{u.key==="Escape"&&n()};document.addEventListener("keydown",l);const c=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",l),document.body.style.overflow=c}},[n]);const Q=q(e)===q(r),W=s.length===1&&s[0]?.kind==="equal";return t.jsxs("div",{className:"fixed inset-0 z-50 flex justify-end",role:"dialog","aria-modal":"true","aria-label":"Compare two log requests",children:[t.jsx("button",{type:"button",onClick:n,"aria-label":"Close compare drawer",className:"absolute inset-0 bg-black/40 cursor-default",tabIndex:-1}),t.jsxs("div",{className:x("relative bg-background border-l border-border shadow-xl","w-full md:w-[70vw] max-w-[1100px] flex flex-col h-full"),onClick:l=>l.stopPropagation(),onKeyDown:l=>l.stopPropagation(),children:[t.jsxs("div",{className:"flex items-start gap-4 px-4 py-3 border-b border-border",children:[t.jsxs("div",{className:"flex-1 flex gap-4 min-w-0",children:[t.jsx(A,{log:e,side:"left"}),t.jsx(A,{log:r,side:"right"})]}),t.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[t.jsx(fe,{mode:y,onChange:F}),t.jsx("button",{type:"button",onClick:n,"aria-label":"Close",className:"p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted cursor-pointer",children:t.jsx(Y,{className:"size-4"})})]})]}),!Q&&t.jsx("div",{className:"px-4 py-1.5 text-xs text-amber-400 bg-amber-500/10 border-b border-border",children:"Heads up: the two selected logs are from different sessions."}),W?t.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto flex items-center justify-center text-muted-foreground text-sm",children:"The two Request payloads are identical."}):t.jsxs(t.Fragment,{children:[t.jsx(xe,{counts:o,onJumpTo:G}),t.jsx("div",{ref:T,className:"flex-1 min-h-0 overflow-y-auto",children:y==="unified"?t.jsx("div",{className:"px-3 py-2 space-y-0.5",children:d.map((l,c)=>{if(l.kind==="equal-run")return t.jsx(ce,{ops:l.ops,expanded:a.has(c),onToggle:()=>i(c)},`r${c}`);const u=l.op;return t.jsx(ue,{op:u,idx:c,copiedPath:U,onCopyPath:H,expanded:f.has(c),onToggle:()=>b(c)},`o${c}`)})}):t.jsx(pe,{grouped:d,left:e,right:r})})]})]})]})}function pe({grouped:e,left:r,right:n}){return t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 gap-y-0.5 px-3 py-2 text-xs",children:[t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 col-span-3 pb-2 mb-2 border-b border-border text-[10px] uppercase tracking-wider text-muted-foreground",children:[t.jsx("span",{children:"Path"}),t.jsxs("span",{children:["Left (Log #",r.id,")"]}),t.jsxs("span",{children:["Right (Log #",n.id,")"]})]}),e.map((s,d)=>{if(s.kind==="equal-run")return t.jsxs("div",{className:"col-span-3 px-2 py-1 text-xs text-muted-foreground/60",children:[s.ops.length," equal siblings collapsed — switch to Unified to expand"]},d);const o=s.op;return o.kind==="equal"?t.jsxs("div",{className:"col-span-3 grid grid-cols-[200px_1fr_1fr] gap-x-2 px-2 py-0.5 text-muted-foreground",children:[t.jsx("span",{className:"font-mono text-xs truncate",title:o.path,children:o.path}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)})]},d):o.kind==="added"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-emerald-400/70 bg-emerald-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-emerald-300/90",children:["+ ",v(o.value,400)]})]},d):o.kind==="removed"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-rose-400/70 bg-rose-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-rose-300/90 line-through",children:["− ",v(o.value,400)]})]},d):t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-amber-400/70 bg-amber-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:o.path}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx("div",{className:"font-mono text-rose-300/90 break-all line-through",children:v(o.left,400)}),t.jsx("div",{className:"font-mono text-emerald-300/90 break-all",children:v(o.right,400)})]})]},d)})]})}export{ve as CompareDrawer};
|
|
1
|
+
import{r as h,j as t}from"./main-o9-hg8g1.js";import{c as X,g as O,r as P,a as q,X as Y,b as x,B as Z,f as $,R as ee,C as te,M as _,d as J,e as M,h as V,J as N,i as re,j as ne}from"./ProxyViewerContainer-CxRDWacg.js";const se=[["line",{x1:"5",x2:"19",y1:"9",y2:"9",key:"1nwqeh"}],["line",{x1:"5",x2:"19",y1:"15",y2:"15",key:"g8yjpy"}]],ae=X("equal",se),oe="";function j(e){if(e.length===0)return oe;let r="";for(let n=0;n<e.length;n++){const s=e[n];s!==void 0&&(typeof s=="number"?r+=`[${s}]`:n===0?r+=s:r+=`.${s}`)}return r}function de(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function D(e){if(typeof e=="string")try{return C(JSON.parse(e))}catch{return{kind:"primitive",value:e}}return C(e)}function C(e){if(e===null)return{kind:"primitive",value:null};if(typeof e=="string")return{kind:"primitive",value:e};if(typeof e=="number")return{kind:"primitive",value:e};if(typeof e=="boolean")return{kind:"primitive",value:e};if(Array.isArray(e))return{kind:"array",value:e.map(r=>C(r))};if(de(e)){const r={};for(const n of Object.keys(e).sort())r[n]=C(e[n]);return{kind:"object",value:r}}return{kind:"primitive",value:null}}function ie(e,r){const n=[];return R([],e,r,n),n}function R(e,r,n,s){const d=j(e);if(E(r,n)){s.push({kind:"equal",path:d,value:r});return}if(r.kind!==n.kind){s.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="primitive"&&n.kind==="primitive"){s.push({kind:"changed",path:d,left:r,right:n});return}if(r.kind==="object"&&n.kind==="object"){const o=Object.keys(r.value),a=Object.keys(n.value),m=new Set(a);for(const i of o){const f=r.value[i];if(f!==void 0)if(!m.has(i))s.push({kind:"removed",path:j([...e,i]),value:f});else{const p=n.value[i];if(p===void 0)continue;R([...e,i],f,p,s)}}for(const i of a){if(o.includes(i))continue;const f=n.value[i];f!==void 0&&s.push({kind:"added",path:j([...e,i]),value:f})}return}if(r.kind==="array"&&n.kind==="array"){const o=Math.min(r.value.length,n.value.length);for(let a=0;a<o;a++){const m=r.value[a],i=n.value[a];m===void 0||i===void 0||R([...e,a],m,i,s)}for(let a=o;a<n.value.length;a++){const m=n.value[a];m!==void 0&&s.push({kind:"added",path:j([...e,a]),value:m})}for(let a=o;a<r.value.length;a++){const m=r.value[a];m!==void 0&&s.push({kind:"removed",path:j([...e,a]),value:m})}}}function E(e,r){if(e.kind!==r.kind)return!1;if(e.kind==="primitive"&&r.kind==="primitive")return e.value===r.value;if(e.kind==="array"&&r.kind==="array"){if(e.value.length!==r.value.length)return!1;for(let n=0;n<e.value.length;n++){const s=e.value[n],d=r.value[n];if(s===void 0||d===void 0||!E(s,d))return!1}return!0}if(e.kind==="object"&&r.kind==="object"){const n=Object.keys(e.value),s=Object.keys(r.value);if(n.length!==s.length)return!1;for(const d of n){const o=e.value[d],a=r.value[d];if(o===void 0||a===void 0||!E(o,a))return!1}return!0}return!1}function v(e,r=80){let n;switch(e.kind){case"primitive":n=e.value===null?"null":JSON.stringify(e.value);break;case"array":n=`[… ${e.value.length} items]`;break;case"object":n=`{… ${Object.keys(e.value).length} keys}`;break}return n.length>r&&(n=`${n.slice(0,r-1)}…`),n}function w(e,r=2){return JSON.stringify(S(e),null,r)}function S(e){switch(e.kind){case"primitive":return e.value;case"array":return e.value.map(S);case"object":{const r={};for(const[n,s]of Object.entries(e.value))r[n]=S(s);return r}}}function K(e){if(e==="")return"";for(let r=e.length-1;r>=0;r--){const n=e[r];if(n==="."||n==="[")return e.substring(0,r)}return""}function L(e){return e.kind==="equal"&&(e.value.kind==="object"||e.value.kind==="array")}function le(e){const r=[];let n=0;for(;n<e.length;){const s=e[n];if(s!==void 0&&L(s)){const d=K(s.path);let o=n+1;for(;o<e.length;){const a=e[o];if(a===void 0||!L(a)||K(a.path)!==d)break;o++}if(o-n>1){const a=[];for(let m=n;m<o;m++){const i=e[m];i!==void 0&&i.kind==="equal"&&a.push(i)}r.push({kind:"equal-run",ops:a}),n=o;continue}}s!==void 0&&r.push({kind:"single",op:s}),n++}return r}const B={added:{icon:J,accent:"text-emerald-600 dark:text-emerald-400",bg:"bg-emerald-500/5 hover:bg-emerald-500/10",border:"border-l-emerald-500",label:"ADDED"},removed:{icon:_,accent:"text-rose-600 dark:text-rose-400",bg:"bg-rose-500/5 hover:bg-rose-500/10",border:"border-l-rose-500",label:"REMOVED"},changed:{icon:M,accent:"text-amber-600 dark:text-amber-400",bg:"bg-amber-500/5 hover:bg-amber-500/10",border:"border-l-amber-500",label:"CHANGED"},equal:{icon:ae,accent:"text-muted-foreground/70",bg:"bg-muted/20 hover:bg-muted/30",border:"border-l-muted-foreground/20",label:"EQUAL"}};function ce({ops:e,expanded:r,onToggle:n}){const s=e[0],d=e[e.length-1];if(s===void 0||d===void 0)return t.jsx("div",{className:"text-muted-foreground/40 text-xs",children:"—"});const o=s.path,a=d.path,m=e.length===1?o:`${o} … ${a}`,i=s.value.kind==="array"?`${e.length} equal arrays`:s.value.kind==="object"?`${e.length} equal objects`:"equal",f=B.equal;return t.jsxs("div",{className:x("border-l-4 rounded-sm",f.border,f.bg),children:[t.jsxs("button",{type:"button",onClick:n,className:"w-full text-left flex items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground cursor-pointer",children:[t.jsx(V,{className:x("size-3 transition-transform shrink-0",r&&"rotate-90")}),t.jsx(f.icon,{className:x("size-3 shrink-0",f.accent)}),t.jsx("span",{className:"font-mono truncate flex-1",title:`${o} … ${a}`,children:m}),t.jsx("span",{className:x("text-[10px] uppercase tracking-wider shrink-0",f.accent),children:f.label}),t.jsxs("span",{className:"text-muted-foreground/60 shrink-0",children:["(",i,")"]})]}),r&&t.jsx("div",{className:"ml-5 mt-1 mb-2 space-y-2 pr-2",children:e.map(p=>t.jsxs("div",{className:"border border-border/50 rounded p-2 bg-muted/20",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:p.path}),t.jsx(N,{text:w(p.value),defaultExpandDepth:0})]},p.path))})]})}function ue({op:e,idx:r,copiedPath:n,onCopyPath:s,expanded:d,onToggle:o}){const a=B[e.kind],m=a.icon,i=e.kind==="added"||e.kind==="removed"?e.value.kind==="object"||e.value.kind==="array":e.kind==="changed"?e.left.kind==="object"||e.left.kind==="array"||e.right.kind==="object"||e.right.kind==="array":!1,f=e.kind==="changed"?[{text:v(e.left,400),tone:"text-rose-700 dark:text-rose-300 line-through"},{text:v(e.right,400),tone:"text-emerald-700 dark:text-emerald-300"}]:e.kind==="removed"?[{text:v(e.value,400),tone:"text-rose-700 dark:text-rose-300 line-through"}]:e.kind==="added"?[{text:v(e.value,400),tone:"text-emerald-700 dark:text-emerald-300"}]:[{text:v(e.value,400),tone:"text-muted-foreground"}],p=n===e.path&&e.path!=="";return t.jsxs("div",{"data-diff-idx":r,"data-diff-kind":e.kind,className:x("border-l-4 rounded-sm px-3 py-2 my-0.5 transition-colors",a.border,a.bg),children:[t.jsxs("button",{type:"button",onClick:o,disabled:!i,className:x("w-full flex items-center gap-2 text-xs text-left rounded-sm",i?"cursor-pointer":"cursor-default"),"aria-expanded":i?d:void 0,"aria-label":i?d?`Collapse ${e.path||"root"}`:`Expand ${e.path||"root"}`:void 0,children:[i?t.jsx(V,{className:x("size-3 shrink-0 transition-transform",a.accent,d&&"rotate-90")}):t.jsx("span",{className:"size-3 shrink-0","aria-hidden":"true"}),t.jsx(m,{className:x("size-3.5 shrink-0",a.accent),strokeWidth:2.5}),t.jsx("span",{className:"font-mono truncate flex-1 min-w-0",title:e.path||"(root)",children:e.path===""?"(root)":e.path}),t.jsx("span",{className:x("text-[9px] font-bold uppercase tracking-wider shrink-0 px-1.5 py-0.5 rounded",a.accent,e.kind==="equal"?"bg-muted/40":"bg-background/60"),children:a.label}),e.path!==""&&t.jsx("span",{role:"button",tabIndex:0,onClick:b=>{b.stopPropagation(),s(e.path)},onKeyDown:b=>{(b.key==="Enter"||b.key===" ")&&(b.stopPropagation(),b.preventDefault(),s(e.path))},className:x("shrink-0 p-1 rounded transition-colors cursor-pointer inline-flex items-center justify-center",p?"text-emerald-500":"text-muted-foreground/50 hover:text-foreground hover:bg-muted"),"aria-label":p?"Copied":"Copy",title:p?"Copied!":"Copy",children:p?t.jsx(re,{className:"size-3"}):t.jsx(ne,{className:"size-3"})})]}),f.map((b,y)=>t.jsx("div",{className:x("font-mono text-xs mt-1 break-all pl-5",b.tone),children:b.text},y)),t.jsx("div",{className:"overflow-hidden transition-all duration-200",style:{maxHeight:d&&i?"2000px":"0"},"aria-hidden":!d,children:d&&i&&e.kind!=="equal"?t.jsx(me,{op:e}):null})]})}function me({op:e}){if(e.kind==="added"||e.kind==="removed")return t.jsx("div",{className:"pl-5 mt-2 border border-border/50 rounded p-2 bg-muted/20",children:t.jsx(N,{text:w(e.value),defaultExpandDepth:0})});const r=e.left.kind==="object"||e.left.kind==="array",n=e.right.kind==="object"||e.right.kind==="array";return!r&&!n?t.jsx("div",{className:"pl-5 mt-2 text-xs text-muted-foreground/70 italic",children:"Primitive values are shown inline above."}):t.jsxs("div",{className:"pl-5 mt-2 grid grid-cols-1 md:grid-cols-2 gap-2",children:[t.jsxs("div",{className:"border border-rose-500/30 rounded p-2 bg-rose-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-rose-500 mb-1",children:"Old"}),t.jsx(N,{text:w(e.left),defaultExpandDepth:0})]}),t.jsxs("div",{className:"border border-emerald-500/30 rounded p-2 bg-emerald-500/5",children:[t.jsx("div",{className:"text-[10px] uppercase tracking-wider text-emerald-500 mb-1",children:"New"}),t.jsx(N,{text:w(e.right),defaultExpandDepth:0})]})]})}function xe({counts:e,onJumpTo:r}){const n=e.added+e.removed+e.changed;return t.jsxs("div",{className:"px-4 py-2 border-b border-border bg-muted/20 flex items-center gap-2 text-xs flex-wrap",children:[t.jsxs("span",{className:"text-muted-foreground font-medium",children:[n," ",n===1?"change":"changes"]}),t.jsxs("button",{type:"button",onClick:()=>r("removed"),disabled:e.removed===0,className:x("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.removed>0?"border-rose-500/40 text-rose-600 dark:text-rose-400 bg-rose-500/10 hover:bg-rose-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.removed>0?"Jump to first removed":"No removals",children:[t.jsx(_,{className:"size-3"}),e.removed," removed"]}),t.jsxs("button",{type:"button",onClick:()=>r("added"),disabled:e.added===0,className:x("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.added>0?"border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 hover:bg-emerald-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.added>0?"Jump to first added":"No additions",children:[t.jsx(J,{className:"size-3"}),e.added," added"]}),t.jsxs("button",{type:"button",onClick:()=>r("changed"),disabled:e.changed===0,className:x("inline-flex items-center gap-1 px-2 py-0.5 rounded-full border cursor-pointer transition-colors",e.changed>0?"border-amber-500/40 text-amber-600 dark:text-amber-400 bg-amber-500/10 hover:bg-amber-500/20":"border-border text-muted-foreground/40 cursor-not-allowed"),title:e.changed>0?"Jump to first changed":"No changes",children:[t.jsx(M,{className:"size-3"}),e.changed," changed"]})]})}function fe({mode:e,onChange:r}){return t.jsxs("div",{className:"inline-flex rounded-md border border-border overflow-hidden",children:[t.jsxs("button",{type:"button",onClick:()=>r("unified"),"aria-pressed":e==="unified",className:x("flex items-center gap-1 px-2 py-1 text-xs transition-colors cursor-pointer",e==="unified"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Unified view (single column, emphasized diffs)",children:[t.jsx(ee,{className:"size-3"}),"Unified"]}),t.jsxs("button",{type:"button",onClick:()=>r("split"),"aria-pressed":e==="split",className:x("flex items-center gap-1 px-2 py-1 text-xs transition-colors border-l border-border cursor-pointer",e==="split"?"bg-muted text-foreground":"hover:bg-muted/50 text-muted-foreground"),title:"Split view (path | left | right)",children:[t.jsx(te,{className:"size-3"}),"Split"]})]})}function A({log:e,side:r}){const n=q(e);return t.jsxs("div",{className:"flex-1 min-w-0 space-y-1 text-xs",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Z,{variant:"outline",className:x("text-[10px] px-1.5 py-0 h-5 font-mono shrink-0",r==="left"?"border-rose-500/40 text-rose-400":"border-emerald-500/40 text-emerald-400"),children:r==="left"?"← Left":"Right →"}),t.jsxs("span",{className:"font-mono text-blue-400/80",children:["#",e.id]}),e.model!==null&&t.jsx("span",{className:"font-mono text-muted-foreground truncate",children:e.model})]}),t.jsxs("div",{className:"flex items-center gap-3 text-muted-foreground font-mono",children:[e.cacheCreationInputTokens!==null&&e.cacheCreationInputTokens>0&&t.jsxs("span",{className:"text-emerald-400",children:["KV Cache +",$(e.cacheCreationInputTokens)]}),e.cacheReadInputTokens!==null&&e.cacheReadInputTokens>0&&t.jsxs("span",{className:"text-purple-400",children:["KV Cache ~",$(e.cacheReadInputTokens)]}),t.jsx("span",{className:"truncate",title:e.timestamp,children:e.timestamp})]}),t.jsxs("div",{className:"text-muted-foreground/70 font-mono truncate",title:n,children:["session: ",n]})]})}function ve({left:e,right:r,onClose:n}){const s=h.useMemo(()=>{const l=O(P(e)).analyzeRequest(e.rawRequestBody),c=O(P(r)).analyzeRequest(r.rawRequestBody),u=D(l.comparisonValue),g=D(c.comparisonValue);return ie(u,g)},[e.apiFormat,e.path,e.rawRequestBody,r.apiFormat,r.path,r.rawRequestBody]),d=h.useMemo(()=>le(s),[s]),o=h.useMemo(()=>{let l=0,c=0,u=0;for(const g of d)if(g.kind==="single")switch(g.op.kind){case"added":l++;break;case"removed":c++;break;case"changed":u++;break}return{added:l,removed:c,changed:u}},[d]),[a,m]=h.useState(new Set),i=l=>{m(c=>{const u=new Set(c);return u.has(l)?u.delete(l):u.add(l),u})},[f,p]=h.useState(new Set),b=l=>{p(c=>{const u=new Set(c);return u.has(l)?u.delete(l):u.add(l),u})};h.useEffect(()=>{p(new Set)},[e.id,r.id]);const[y,F]=h.useState("unified"),T=h.useRef(null),[U,z]=h.useState(null),k=h.useRef(null),H=l=>{window.navigator.clipboard.writeText(l).then(()=>{z(l),k.current!==null&&clearTimeout(k.current),k.current=setTimeout(()=>z(null),1500)})};h.useEffect(()=>()=>{k.current!==null&&clearTimeout(k.current)},[]);const G=l=>{const c=d.findIndex(I=>I.kind==="single"&&I.op.kind===l);if(c===-1)return;const u=T.current;if(u===null)return;const g=u.querySelector(`[data-diff-idx="${c}"]`);g!==null&&g.scrollIntoView({behavior:"smooth",block:"center"})};h.useEffect(()=>{const l=u=>{u.key==="Escape"&&n()};document.addEventListener("keydown",l);const c=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",l),document.body.style.overflow=c}},[n]);const Q=q(e)===q(r),W=s.length===1&&s[0]?.kind==="equal";return t.jsxs("div",{className:"fixed inset-0 z-50 flex justify-end",role:"dialog","aria-modal":"true","aria-label":"Compare two log requests",children:[t.jsx("button",{type:"button",onClick:n,"aria-label":"Close compare drawer",className:"absolute inset-0 bg-black/40 cursor-default",tabIndex:-1}),t.jsxs("div",{className:x("relative bg-background border-l border-border shadow-xl","w-full md:w-[70vw] max-w-[1100px] flex flex-col h-full"),onClick:l=>l.stopPropagation(),onKeyDown:l=>l.stopPropagation(),children:[t.jsxs("div",{className:"flex items-start gap-4 px-4 py-3 border-b border-border",children:[t.jsxs("div",{className:"flex-1 flex gap-4 min-w-0",children:[t.jsx(A,{log:e,side:"left"}),t.jsx(A,{log:r,side:"right"})]}),t.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[t.jsx(fe,{mode:y,onChange:F}),t.jsx("button",{type:"button",onClick:n,"aria-label":"Close",className:"p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted cursor-pointer",children:t.jsx(Y,{className:"size-4"})})]})]}),!Q&&t.jsx("div",{className:"px-4 py-1.5 text-xs text-amber-400 bg-amber-500/10 border-b border-border",children:"Heads up: the two selected logs are from different sessions."}),W?t.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto flex items-center justify-center text-muted-foreground text-sm",children:"The two Request payloads are identical."}):t.jsxs(t.Fragment,{children:[t.jsx(xe,{counts:o,onJumpTo:G}),t.jsx("div",{ref:T,className:"flex-1 min-h-0 overflow-y-auto",children:y==="unified"?t.jsx("div",{className:"px-3 py-2 space-y-0.5",children:d.map((l,c)=>{if(l.kind==="equal-run")return t.jsx(ce,{ops:l.ops,expanded:a.has(c),onToggle:()=>i(c)},`r${c}`);const u=l.op;return t.jsx(ue,{op:u,idx:c,copiedPath:U,onCopyPath:H,expanded:f.has(c),onToggle:()=>b(c)},`o${c}`)})}):t.jsx(pe,{grouped:d,left:e,right:r})})]})]})]})}function pe({grouped:e,left:r,right:n}){return t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 gap-y-0.5 px-3 py-2 text-xs",children:[t.jsxs("div",{className:"grid grid-cols-[200px_1fr_1fr] gap-x-2 col-span-3 pb-2 mb-2 border-b border-border text-[10px] uppercase tracking-wider text-muted-foreground",children:[t.jsx("span",{children:"Path"}),t.jsxs("span",{children:["Left (Log #",r.id,")"]}),t.jsxs("span",{children:["Right (Log #",n.id,")"]})]}),e.map((s,d)=>{if(s.kind==="equal-run")return t.jsxs("div",{className:"col-span-3 px-2 py-1 text-xs text-muted-foreground/60",children:[s.ops.length," equal siblings collapsed — switch to Unified to expand"]},d);const o=s.op;return o.kind==="equal"?t.jsxs("div",{className:"col-span-3 grid grid-cols-[200px_1fr_1fr] gap-x-2 px-2 py-0.5 text-muted-foreground",children:[t.jsx("span",{className:"font-mono text-xs truncate",title:o.path,children:o.path}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)}),t.jsx("span",{className:"font-mono text-xs break-all opacity-60",children:v(o.value,200)})]},d):o.kind==="added"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-emerald-400/70 bg-emerald-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-emerald-300/90",children:["+ ",v(o.value,400)]})]},d):o.kind==="removed"?t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-rose-400/70 bg-rose-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-0.5",children:o.path}),t.jsxs("div",{className:"font-mono break-all text-rose-300/90 line-through",children:["− ",v(o.value,400)]})]},d):t.jsxs("div",{className:"col-span-3 px-2 py-1 rounded text-xs border-l-2 border-l-amber-400/70 bg-amber-500/5",children:[t.jsx("div",{className:"font-mono text-xs text-muted-foreground mb-1",children:o.path}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx("div",{className:"font-mono text-rose-300/90 break-all line-through",children:v(o.left,400)}),t.jsx("div",{className:"font-mono text-emerald-300/90 break-all",children:v(o.right,400)})]})]},d)})]})}export{ve as CompareDrawer};
|