@tonyclaw/agent-inspector 2.0.16 → 2.0.17
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 +376 -17
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-DPs4UHwd.js → CompareDrawer-DDg7Cs4N.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-B1KylMPs.js → ProxyViewerContainer-DbbK1y7N.js} +16 -16
- package/.output/public/assets/{ReplayDialog-8ISC28XF.js → ReplayDialog-C1zWNkoz.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-BhbsgfBO.js → RequestAnatomy-DR8OICOJ.js} +1 -1
- package/.output/public/assets/{ResponseView-CyM7JXeA.js → ResponseView-Dh9iSj6h.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-BaX0x38n.js → StreamingChunkSequence-B_xElyH3.js} +1 -1
- package/.output/public/assets/_sessionId-gv1a_NNu.js +1 -0
- package/.output/public/assets/index-u-LwDaeH.js +1 -0
- package/.output/public/assets/{main-B2t-3SYj.js → main-bwZlEXw2.js} +2 -2
- package/.output/server/{_sessionId-CEbZTs68.mjs → _sessionId-BEuJJhqT.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-CEo48Wsu.mjs → CompareDrawer-yTO93GMz.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-5ekIK_jx.mjs → ProxyViewerContainer-C8qCkHGB.mjs} +41 -12
- package/.output/server/_ssr/{ReplayDialog-C0nEvbYo.mjs → ReplayDialog-DRF9PG7Z.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-CT55prmM.mjs → RequestAnatomy-DBcuV_jV.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-DBZSBCOD.mjs → ResponseView-JJm78HZT.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-BuVT7Oke.mjs → StreamingChunkSequence-DyGKjBYx.mjs} +2 -2
- package/.output/server/_ssr/{index-Cw_zJVQv.mjs → index-T7JG28t6.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-DxjqHipT.mjs → router-BJob8RN3.mjs} +2 -2
- package/.output/server/{_tanstack-start-manifest_v-xeOo5gW5.mjs → _tanstack-start-manifest_v-CuiFi3XC.mjs} +1 -1
- package/.output/server/index.mjs +59 -59
- package/README.md +22 -5
- package/package.json +3 -3
- package/scripts/setup-agent-skills.mjs +64 -0
- package/src/cli/onboard.ts +407 -13
- package/src/cli/templates/codex-skill-onboard.ts +5 -0
- package/src/cli/templates/command-onboard.ts +12 -4
- package/src/cli/templates/skill-onboard.ts +15 -1
- package/src/components/OnboardingBanner.tsx +5 -0
- package/src/components/providers/SettingsDialog.tsx +22 -4
- package/.output/public/assets/_sessionId-CShO0OrR.js +0 -1
- package/.output/public/assets/index-BkdYiTpV.js +0 -1
- package/scripts/setup-codex-skill.mjs +0 -38
package/.output/cli.js
CHANGED
|
@@ -98,14 +98,17 @@ var init_detect_tools = __esm({
|
|
|
98
98
|
});
|
|
99
99
|
|
|
100
100
|
// src/cli/templates/command-onboard.ts
|
|
101
|
-
function renderCommandOnboard() {
|
|
101
|
+
function renderCommandOnboard(ctx) {
|
|
102
102
|
return `---
|
|
103
|
-
description: Walk through agent-inspector setup
|
|
103
|
+
description: Walk through agent-inspector setup - start the proxy, wire your AI tool, capture your first request.
|
|
104
|
+
metadata:
|
|
105
|
+
author: agent-inspector
|
|
106
|
+
version: ${ctx.version}
|
|
104
107
|
---
|
|
105
108
|
|
|
106
109
|
Invoke the \`agent-inspector-onboard\` skill and follow its phases.
|
|
107
110
|
|
|
108
|
-
The user wants to set up agent-inspector. If they have specific context (e.g. "I'm on Windows", "I already added my API key"), honor it
|
|
111
|
+
The user wants to set up agent-inspector. If they have specific context (e.g. "I'm on Windows", "I already added my API key"), honor it - but otherwise just run the skill end-to-end and let the \`EXPLAIN / DO / PAUSE\` markers drive the conversation.
|
|
109
112
|
`;
|
|
110
113
|
}
|
|
111
114
|
var init_command_onboard = __esm({
|
|
@@ -150,12 +153,14 @@ Check that the package and Codex home exist without printing secrets.
|
|
|
150
153
|
|
|
151
154
|
\`\`\`powershell
|
|
152
155
|
Get-Command agent-inspector -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source
|
|
156
|
+
agent-inspector onboard --status
|
|
153
157
|
Test-Path (Join-Path $env:USERPROFILE ".codex")
|
|
154
158
|
Test-Path (Join-Path $env:USERPROFILE ".codex\\config.toml")
|
|
155
159
|
\`\`\`
|
|
156
160
|
|
|
157
161
|
\`\`\`bash
|
|
158
162
|
command -v agent-inspector || true
|
|
163
|
+
agent-inspector onboard --status
|
|
159
164
|
test -d "$HOME/.codex" && echo "codex home: present" || echo "codex home: missing"
|
|
160
165
|
test -f "$HOME/.codex/config.toml" && echo "config: present" || echo "config: missing"
|
|
161
166
|
\`\`\`
|
|
@@ -166,6 +171,9 @@ If \`agent-inspector\` is missing, ask the user to install it first:
|
|
|
166
171
|
npm install -g @tonyclaw/agent-inspector
|
|
167
172
|
\`\`\`
|
|
168
173
|
|
|
174
|
+
If \`agent-inspector onboard --status\` reports \`outdated\` or \`missing\`, ask the user to run
|
|
175
|
+
\`agent-inspector onboard --force\` and restart this skill before continuing.
|
|
176
|
+
|
|
169
177
|
Do not read \`~/.codex/auth.json\`, token files, or unrelated Codex state files.
|
|
170
178
|
|
|
171
179
|
---
|
|
@@ -352,7 +360,19 @@ Default proxy port: \`${port}\` (override with \`PORT=<n> agent-inspector\` or \
|
|
|
352
360
|
|
|
353
361
|
**EXPLAIN:** "Before we do anything, let me see what's already set up. If some of the steps are already done, we can skip them."
|
|
354
362
|
|
|
355
|
-
**DO:**
|
|
363
|
+
**DO:** First check whether the generated onboarding files match the installed npm package. If any
|
|
364
|
+
entry is \`outdated\` or \`missing\`, tell the user to run \`agent-inspector onboard --force\` before
|
|
365
|
+
continuing so they are not guided by stale instructions.
|
|
366
|
+
|
|
367
|
+
\`\`\`bash
|
|
368
|
+
agent-inspector onboard --status
|
|
369
|
+
\`\`\`
|
|
370
|
+
|
|
371
|
+
\`\`\`powershell
|
|
372
|
+
agent-inspector onboard --status
|
|
373
|
+
\`\`\`
|
|
374
|
+
|
|
375
|
+
**DO:** Then probe the three pieces of state this skill touches. Use targeted checks \u2014 do **not** read large JSON files into the conversation.
|
|
356
376
|
|
|
357
377
|
\`\`\`bash
|
|
358
378
|
# 1. Is the proxy already up?
|
|
@@ -834,6 +854,8 @@ done
|
|
|
834
854
|
\`\`\`
|
|
835
855
|
|
|
836
856
|
- **Re-run onboard**: \`agent-inspector onboard --force\` refreshes this skill.
|
|
857
|
+
- **Check onboard files**: \`agent-inspector onboard --status\` shows whether generated skills are
|
|
858
|
+
current, outdated, missing, newer, or custom.
|
|
837
859
|
- **Full docs**: see the project README (linked from the Web UI footer).
|
|
838
860
|
|
|
839
861
|
> **PAUSE** \u2014 use \`AskUserQuestion\` with header \`All set?\` and options \`["All set, I'm done", "Wait, I want to revisit a phase"]\`. Wait for the answer.
|
|
@@ -864,10 +886,42 @@ var onboard_exports = {};
|
|
|
864
886
|
__export(onboard_exports, {
|
|
865
887
|
runOnboard: () => runOnboard
|
|
866
888
|
});
|
|
867
|
-
import {
|
|
889
|
+
import {
|
|
890
|
+
mkdirSync,
|
|
891
|
+
writeFileSync,
|
|
892
|
+
existsSync as existsSync2,
|
|
893
|
+
readFileSync,
|
|
894
|
+
unlinkSync,
|
|
895
|
+
readdirSync,
|
|
896
|
+
rmdirSync
|
|
897
|
+
} from "node:fs";
|
|
868
898
|
import { homedir as homedir2 } from "node:os";
|
|
869
899
|
import { dirname, join as join2 } from "node:path";
|
|
870
900
|
import { fileURLToPath } from "node:url";
|
|
901
|
+
function actionForStatus(label, state) {
|
|
902
|
+
switch (state) {
|
|
903
|
+
case "missing":
|
|
904
|
+
switch (label) {
|
|
905
|
+
case "Codex skill":
|
|
906
|
+
return "agent-inspector onboard --codex-only";
|
|
907
|
+
case "Claude skill":
|
|
908
|
+
case "Claude command":
|
|
909
|
+
return "agent-inspector onboard --skip-codex-skill";
|
|
910
|
+
default:
|
|
911
|
+
return "agent-inspector onboard";
|
|
912
|
+
}
|
|
913
|
+
case "outdated":
|
|
914
|
+
return "agent-inspector onboard --force";
|
|
915
|
+
case "custom":
|
|
916
|
+
return "preserved; use agent-inspector onboard --force to replace";
|
|
917
|
+
case "newer":
|
|
918
|
+
return "no action; installed file is newer than this package";
|
|
919
|
+
case "current":
|
|
920
|
+
return "no action";
|
|
921
|
+
default:
|
|
922
|
+
return "agent-inspector onboard";
|
|
923
|
+
}
|
|
924
|
+
}
|
|
871
925
|
function parseFlags(argv) {
|
|
872
926
|
const flags = {
|
|
873
927
|
force: false,
|
|
@@ -876,6 +930,9 @@ function parseFlags(argv) {
|
|
|
876
930
|
skipToolWire: false,
|
|
877
931
|
codexOnly: false,
|
|
878
932
|
skipCodexSkill: false,
|
|
933
|
+
uninstall: false,
|
|
934
|
+
status: false,
|
|
935
|
+
json: false,
|
|
879
936
|
skillDir: null,
|
|
880
937
|
codexSkillDir: null
|
|
881
938
|
};
|
|
@@ -902,6 +959,15 @@ function parseFlags(argv) {
|
|
|
902
959
|
case "--skip-codex-skill":
|
|
903
960
|
flags.skipCodexSkill = true;
|
|
904
961
|
break;
|
|
962
|
+
case "--uninstall":
|
|
963
|
+
flags.uninstall = true;
|
|
964
|
+
break;
|
|
965
|
+
case "--status":
|
|
966
|
+
flags.status = true;
|
|
967
|
+
break;
|
|
968
|
+
case "--json":
|
|
969
|
+
flags.json = true;
|
|
970
|
+
break;
|
|
905
971
|
case "--skill-dir": {
|
|
906
972
|
const next = argv[i + 1];
|
|
907
973
|
if (next === void 0) {
|
|
@@ -950,6 +1016,9 @@ Options:
|
|
|
950
1016
|
--skip-tool-wire Skip the wire-tool phase in the Claude skill body
|
|
951
1017
|
--skip-codex-skill Install only the Claude Code skill and slash command
|
|
952
1018
|
--codex-only Install only the Codex skill
|
|
1019
|
+
--uninstall Remove generated files whose version matches this package
|
|
1020
|
+
--status Show installed onboarding file versions and suggested action
|
|
1021
|
+
--json Emit machine-readable JSON with --status
|
|
953
1022
|
--skill-dir <path> Override the target Claude root directory (default: ~/.claude)
|
|
954
1023
|
--codex-skill-dir <path> Override the target Codex skills directory (default: ~/.codex/skills)
|
|
955
1024
|
-h, --help Show this help
|
|
@@ -985,15 +1054,173 @@ function buildDetectedSummary() {
|
|
|
985
1054
|
- Not detected: ${absentList}`;
|
|
986
1055
|
}
|
|
987
1056
|
function readPackageVersion() {
|
|
1057
|
+
const packageJsonPaths = [
|
|
1058
|
+
join2(__dirname, "..", "package.json"),
|
|
1059
|
+
join2(__dirname, "..", "..", "package.json")
|
|
1060
|
+
];
|
|
988
1061
|
try {
|
|
989
|
-
const
|
|
990
|
-
|
|
991
|
-
|
|
1062
|
+
for (const packageJsonPath of packageJsonPaths) {
|
|
1063
|
+
if (existsSync2(packageJsonPath)) {
|
|
1064
|
+
const raw = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
1065
|
+
if (isObject(raw) && typeof raw["version"] === "string") {
|
|
1066
|
+
return raw["version"];
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
992
1069
|
}
|
|
993
1070
|
} catch {
|
|
994
1071
|
}
|
|
995
1072
|
return "0.0.0";
|
|
996
1073
|
}
|
|
1074
|
+
function parseVersion(version) {
|
|
1075
|
+
const match = SEMVER_PATTERN.exec(version);
|
|
1076
|
+
if (match === null) {
|
|
1077
|
+
return null;
|
|
1078
|
+
}
|
|
1079
|
+
const majorText = match[1];
|
|
1080
|
+
const minorText = match[2];
|
|
1081
|
+
const patchText = match[3];
|
|
1082
|
+
if (majorText === void 0 || minorText === void 0 || patchText === void 0) {
|
|
1083
|
+
return null;
|
|
1084
|
+
}
|
|
1085
|
+
const major = Number(majorText);
|
|
1086
|
+
const minor = Number(minorText);
|
|
1087
|
+
const patch = Number(patchText);
|
|
1088
|
+
if (!Number.isInteger(major) || !Number.isInteger(minor) || !Number.isInteger(patch)) {
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
return { major, minor, patch };
|
|
1092
|
+
}
|
|
1093
|
+
function compareVersions(left, right) {
|
|
1094
|
+
const leftVersion = parseVersion(left);
|
|
1095
|
+
const rightVersion = parseVersion(right);
|
|
1096
|
+
if (leftVersion === null || rightVersion === null) {
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
const leftParts = [leftVersion.major, leftVersion.minor, leftVersion.patch];
|
|
1100
|
+
const rightParts = [rightVersion.major, rightVersion.minor, rightVersion.patch];
|
|
1101
|
+
for (let index = 0; index < leftParts.length; index++) {
|
|
1102
|
+
const leftPart = leftParts[index];
|
|
1103
|
+
const rightPart = rightParts[index];
|
|
1104
|
+
if (leftPart === void 0 || rightPart === void 0) {
|
|
1105
|
+
return null;
|
|
1106
|
+
}
|
|
1107
|
+
if (leftPart > rightPart) {
|
|
1108
|
+
return 1;
|
|
1109
|
+
}
|
|
1110
|
+
if (leftPart < rightPart) {
|
|
1111
|
+
return -1;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return 0;
|
|
1115
|
+
}
|
|
1116
|
+
function extractGeneratedVersion(body) {
|
|
1117
|
+
const frontmatterMatch = FRONTMATTER_PATTERN.exec(body);
|
|
1118
|
+
if (frontmatterMatch === null) {
|
|
1119
|
+
return null;
|
|
1120
|
+
}
|
|
1121
|
+
const frontmatter = frontmatterMatch[1];
|
|
1122
|
+
if (frontmatter === void 0) {
|
|
1123
|
+
return null;
|
|
1124
|
+
}
|
|
1125
|
+
const versionMatch = GENERATED_VERSION_PATTERN.exec(frontmatter);
|
|
1126
|
+
if (versionMatch === null) {
|
|
1127
|
+
return null;
|
|
1128
|
+
}
|
|
1129
|
+
return versionMatch[1] ?? null;
|
|
1130
|
+
}
|
|
1131
|
+
function hasAgentInspectorAuthor(body) {
|
|
1132
|
+
const frontmatterMatch = FRONTMATTER_PATTERN.exec(body);
|
|
1133
|
+
if (frontmatterMatch === null) {
|
|
1134
|
+
return false;
|
|
1135
|
+
}
|
|
1136
|
+
const frontmatter = frontmatterMatch[1];
|
|
1137
|
+
if (frontmatter === void 0) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
return /^\s*author:\s*agent-inspector\s*$/m.test(frontmatter);
|
|
1141
|
+
}
|
|
1142
|
+
function readGeneratedVersion(path) {
|
|
1143
|
+
try {
|
|
1144
|
+
return extractGeneratedVersion(readFileSync(path, "utf8"));
|
|
1145
|
+
} catch {
|
|
1146
|
+
return null;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
function isMatchingGeneratedFile(path, currentVersion) {
|
|
1150
|
+
try {
|
|
1151
|
+
const body = readFileSync(path, "utf8");
|
|
1152
|
+
return hasAgentInspectorAuthor(body) && extractGeneratedVersion(body) === currentVersion;
|
|
1153
|
+
} catch {
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
function readGeneratedFileStatus(file, currentVersion) {
|
|
1158
|
+
if (!existsSync2(file.path)) {
|
|
1159
|
+
return {
|
|
1160
|
+
label: file.label,
|
|
1161
|
+
path: file.path,
|
|
1162
|
+
state: "missing",
|
|
1163
|
+
version: null,
|
|
1164
|
+
action: actionForStatus(file.label, "missing")
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
try {
|
|
1168
|
+
const body = readFileSync(file.path, "utf8");
|
|
1169
|
+
const version = extractGeneratedVersion(body);
|
|
1170
|
+
if (!hasAgentInspectorAuthor(body) || version === null) {
|
|
1171
|
+
return {
|
|
1172
|
+
label: file.label,
|
|
1173
|
+
path: file.path,
|
|
1174
|
+
state: "custom",
|
|
1175
|
+
version,
|
|
1176
|
+
action: actionForStatus(file.label, "custom")
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
const comparison = compareVersions(version, currentVersion);
|
|
1180
|
+
if (comparison === null) {
|
|
1181
|
+
return {
|
|
1182
|
+
label: file.label,
|
|
1183
|
+
path: file.path,
|
|
1184
|
+
state: "custom",
|
|
1185
|
+
version,
|
|
1186
|
+
action: actionForStatus(file.label, "custom")
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
if (comparison < 0) {
|
|
1190
|
+
return {
|
|
1191
|
+
label: file.label,
|
|
1192
|
+
path: file.path,
|
|
1193
|
+
state: "outdated",
|
|
1194
|
+
version,
|
|
1195
|
+
action: actionForStatus(file.label, "outdated")
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
if (comparison > 0) {
|
|
1199
|
+
return {
|
|
1200
|
+
label: file.label,
|
|
1201
|
+
path: file.path,
|
|
1202
|
+
state: "newer",
|
|
1203
|
+
version,
|
|
1204
|
+
action: actionForStatus(file.label, "newer")
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
return {
|
|
1208
|
+
label: file.label,
|
|
1209
|
+
path: file.path,
|
|
1210
|
+
state: "current",
|
|
1211
|
+
version,
|
|
1212
|
+
action: actionForStatus(file.label, "current")
|
|
1213
|
+
};
|
|
1214
|
+
} catch {
|
|
1215
|
+
return {
|
|
1216
|
+
label: file.label,
|
|
1217
|
+
path: file.path,
|
|
1218
|
+
state: "custom",
|
|
1219
|
+
version: null,
|
|
1220
|
+
action: actionForStatus(file.label, "custom")
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
997
1224
|
function buildPlannedFiles(flags, targets, version) {
|
|
998
1225
|
const installClaude = !flags.codexOnly;
|
|
999
1226
|
const installCodex = !flags.skipCodexSkill;
|
|
@@ -1003,7 +1230,7 @@ function buildPlannedFiles(flags, targets, version) {
|
|
|
1003
1230
|
port: DEFAULT_PORT,
|
|
1004
1231
|
detectedSummary
|
|
1005
1232
|
}) : "";
|
|
1006
|
-
const commandBody = installClaude ? renderCommandOnboard() : "";
|
|
1233
|
+
const commandBody = installClaude ? renderCommandOnboard({ version }) : "";
|
|
1007
1234
|
const codexSkillBody = installCodex ? renderCodexSkillOnboard({
|
|
1008
1235
|
version,
|
|
1009
1236
|
port: DEFAULT_PORT
|
|
@@ -1029,8 +1256,125 @@ function buildPlannedFiles(flags, targets, version) {
|
|
|
1029
1256
|
}
|
|
1030
1257
|
];
|
|
1031
1258
|
}
|
|
1032
|
-
function shouldWrite(file, force) {
|
|
1033
|
-
|
|
1259
|
+
function shouldWrite(file, force, currentVersion) {
|
|
1260
|
+
if (!file.enabled) {
|
|
1261
|
+
return false;
|
|
1262
|
+
}
|
|
1263
|
+
if (force || !existsSync2(file.path)) {
|
|
1264
|
+
return true;
|
|
1265
|
+
}
|
|
1266
|
+
const existingVersion = readGeneratedVersion(file.path);
|
|
1267
|
+
if (existingVersion === null) {
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
const comparison = compareVersions(existingVersion, currentVersion);
|
|
1271
|
+
return comparison !== null && comparison < 0;
|
|
1272
|
+
}
|
|
1273
|
+
function shouldUninstall(file, currentVersion) {
|
|
1274
|
+
return file.enabled && existsSync2(file.path) && isMatchingGeneratedFile(file.path, currentVersion);
|
|
1275
|
+
}
|
|
1276
|
+
function removeEmptyDirectory(path) {
|
|
1277
|
+
try {
|
|
1278
|
+
if (readdirSync(path).length === 0) {
|
|
1279
|
+
rmdirSync(path);
|
|
1280
|
+
}
|
|
1281
|
+
} catch {
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
function runUninstall(plannedFiles, currentVersion, dryRun) {
|
|
1285
|
+
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1286
|
+
const filesToRemove = enabledFiles.filter((file) => shouldUninstall(file, currentVersion));
|
|
1287
|
+
if (dryRun) {
|
|
1288
|
+
process.stdout.write(`agent-inspector onboard --uninstall --dry-run
|
|
1289
|
+
|
|
1290
|
+
`);
|
|
1291
|
+
for (const file of enabledFiles) {
|
|
1292
|
+
const status = shouldUninstall(file, currentVersion) ? "matching" : "skipped";
|
|
1293
|
+
process.stdout.write(`${file.label}: ${file.path} (${status})
|
|
1294
|
+
`);
|
|
1295
|
+
}
|
|
1296
|
+
process.stdout.write(`
|
|
1297
|
+
No files were removed.
|
|
1298
|
+
`);
|
|
1299
|
+
return 0;
|
|
1300
|
+
}
|
|
1301
|
+
if (filesToRemove.length === 0) {
|
|
1302
|
+
process.stdout.write(
|
|
1303
|
+
"agent-inspector onboard: no generated onboarding files match this package version\n"
|
|
1304
|
+
);
|
|
1305
|
+
return 0;
|
|
1306
|
+
}
|
|
1307
|
+
try {
|
|
1308
|
+
for (const file of filesToRemove) {
|
|
1309
|
+
unlinkSync(file.path);
|
|
1310
|
+
removeEmptyDirectory(dirname(file.path));
|
|
1311
|
+
process.stdout.write(`Removed ${file.label}: ${file.path}
|
|
1312
|
+
`);
|
|
1313
|
+
}
|
|
1314
|
+
} catch (err) {
|
|
1315
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1316
|
+
process.stderr.write(`agent-inspector onboard: failed to remove files: ${msg}
|
|
1317
|
+
`);
|
|
1318
|
+
return 1;
|
|
1319
|
+
}
|
|
1320
|
+
return 0;
|
|
1321
|
+
}
|
|
1322
|
+
function formatStatusVersion(status) {
|
|
1323
|
+
return status.version ?? "-";
|
|
1324
|
+
}
|
|
1325
|
+
function summarizeStatusAction(statuses) {
|
|
1326
|
+
const actionable = statuses.filter(
|
|
1327
|
+
(status) => status.state === "missing" || status.state === "outdated"
|
|
1328
|
+
);
|
|
1329
|
+
if (actionable.length > 0) {
|
|
1330
|
+
const actions = Array.from(new Set(actionable.map((status) => status.action)));
|
|
1331
|
+
return `Run: ${actions.join(" && ")}`;
|
|
1332
|
+
}
|
|
1333
|
+
if (statuses.some((status) => status.state === "custom")) {
|
|
1334
|
+
return "Custom files are preserved. Use --force only if you want to replace them.";
|
|
1335
|
+
}
|
|
1336
|
+
if (statuses.some((status) => status.state === "newer")) {
|
|
1337
|
+
return "Installed files are newer than this package. No action needed.";
|
|
1338
|
+
}
|
|
1339
|
+
return "All selected onboarding files are current.";
|
|
1340
|
+
}
|
|
1341
|
+
function runStatus(plannedFiles, currentVersion, json) {
|
|
1342
|
+
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1343
|
+
const statuses = enabledFiles.map((file) => readGeneratedFileStatus(file, currentVersion));
|
|
1344
|
+
const summary = summarizeStatusAction(statuses);
|
|
1345
|
+
if (json) {
|
|
1346
|
+
process.stdout.write(
|
|
1347
|
+
`${JSON.stringify(
|
|
1348
|
+
{
|
|
1349
|
+
packageVersion: currentVersion,
|
|
1350
|
+
files: statuses,
|
|
1351
|
+
suggestedAction: summary
|
|
1352
|
+
},
|
|
1353
|
+
null,
|
|
1354
|
+
2
|
|
1355
|
+
)}
|
|
1356
|
+
`
|
|
1357
|
+
);
|
|
1358
|
+
return 0;
|
|
1359
|
+
}
|
|
1360
|
+
process.stdout.write(`agent-inspector onboard status
|
|
1361
|
+
`);
|
|
1362
|
+
process.stdout.write(`Package version: ${currentVersion}
|
|
1363
|
+
|
|
1364
|
+
`);
|
|
1365
|
+
for (const status of statuses) {
|
|
1366
|
+
process.stdout.write(`${status.label}: ${status.state}`);
|
|
1367
|
+
process.stdout.write(`, version ${formatStatusVersion(status)}
|
|
1368
|
+
`);
|
|
1369
|
+
process.stdout.write(` ${status.path}
|
|
1370
|
+
`);
|
|
1371
|
+
process.stdout.write(` Action: ${status.action}
|
|
1372
|
+
`);
|
|
1373
|
+
}
|
|
1374
|
+
process.stdout.write(`
|
|
1375
|
+
Suggested action: ${summary}
|
|
1376
|
+
`);
|
|
1377
|
+
return 0;
|
|
1034
1378
|
}
|
|
1035
1379
|
function runOnboard(argv) {
|
|
1036
1380
|
try {
|
|
@@ -1049,10 +1393,20 @@ function runOnboardSync(argv) {
|
|
|
1049
1393
|
const version = readPackageVersion();
|
|
1050
1394
|
const plannedFiles = buildPlannedFiles(flags, targets, version);
|
|
1051
1395
|
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1396
|
+
if (flags.json && !flags.status) {
|
|
1397
|
+
process.stderr.write("agent-inspector onboard: --json is only supported with --status\n");
|
|
1398
|
+
return 2;
|
|
1399
|
+
}
|
|
1052
1400
|
if (enabledFiles.length === 0) {
|
|
1053
1401
|
process.stderr.write("agent-inspector onboard: no onboarding target selected\n");
|
|
1054
1402
|
return 2;
|
|
1055
1403
|
}
|
|
1404
|
+
if (flags.status) {
|
|
1405
|
+
return runStatus(plannedFiles, version, flags.json);
|
|
1406
|
+
}
|
|
1407
|
+
if (flags.uninstall) {
|
|
1408
|
+
return runUninstall(plannedFiles, version, flags.dryRun);
|
|
1409
|
+
}
|
|
1056
1410
|
if (flags.dryRun) {
|
|
1057
1411
|
process.stdout.write(`agent-inspector onboard --dry-run
|
|
1058
1412
|
|
|
@@ -1097,9 +1451,11 @@ No files were written.
|
|
|
1097
1451
|
`);
|
|
1098
1452
|
return 0;
|
|
1099
1453
|
}
|
|
1100
|
-
const filesToWrite = plannedFiles.filter((file) => shouldWrite(file, flags.force));
|
|
1454
|
+
const filesToWrite = plannedFiles.filter((file) => shouldWrite(file, flags.force, version));
|
|
1101
1455
|
if (filesToWrite.length === 0) {
|
|
1102
|
-
process.stdout.write(
|
|
1456
|
+
process.stdout.write(
|
|
1457
|
+
"agent-inspector onboard: all selected onboarding files are already up to date\n"
|
|
1458
|
+
);
|
|
1103
1459
|
process.stdout.write("Re-run with --force to refresh.\n");
|
|
1104
1460
|
return 0;
|
|
1105
1461
|
}
|
|
@@ -1117,7 +1473,7 @@ No files were written.
|
|
|
1117
1473
|
const firstTool = detectFirst();
|
|
1118
1474
|
const toolHint = firstTool !== null ? firstTool.displayName : "no known tool detected";
|
|
1119
1475
|
for (const file of filesToWrite) {
|
|
1120
|
-
process.stdout.write(`Installed ${file.label} to: ${file.path}
|
|
1476
|
+
process.stdout.write(`Installed/updated ${file.label} to: ${file.path}
|
|
1121
1477
|
`);
|
|
1122
1478
|
}
|
|
1123
1479
|
process.stdout.write(`
|
|
@@ -1137,7 +1493,7 @@ Next steps:
|
|
|
1137
1493
|
`);
|
|
1138
1494
|
return 0;
|
|
1139
1495
|
}
|
|
1140
|
-
var __filename, __dirname, DEFAULT_PORT, SKILL_DIR_NAME, SKILL_FILE_NAME, COMMAND_FILE_NAME;
|
|
1496
|
+
var __filename, __dirname, DEFAULT_PORT, SKILL_DIR_NAME, SKILL_FILE_NAME, COMMAND_FILE_NAME, GENERATED_VERSION_PATTERN, FRONTMATTER_PATTERN, SEMVER_PATTERN;
|
|
1141
1497
|
var init_onboard = __esm({
|
|
1142
1498
|
"src/cli/onboard.ts"() {
|
|
1143
1499
|
"use strict";
|
|
@@ -1151,6 +1507,9 @@ var init_onboard = __esm({
|
|
|
1151
1507
|
SKILL_DIR_NAME = "agent-inspector-onboard";
|
|
1152
1508
|
SKILL_FILE_NAME = "SKILL.md";
|
|
1153
1509
|
COMMAND_FILE_NAME = process.platform === "win32" ? "agent-inspector-onboard.md" : "agent-inspector:onboard.md";
|
|
1510
|
+
GENERATED_VERSION_PATTERN = /^\s*version:\s*([0-9]+\.[0-9]+\.[0-9]+(?:[-+][^\s]+)?)\s*$/m;
|
|
1511
|
+
FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
1512
|
+
SEMVER_PATTERN = /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;
|
|
1154
1513
|
}
|
|
1155
1514
|
});
|
|
1156
1515
|
|
|
@@ -1193,7 +1552,7 @@ __export(doctor_exports, {
|
|
|
1193
1552
|
parseDoctorArgs: () => parseDoctorArgs,
|
|
1194
1553
|
runDoctor: () => runDoctor
|
|
1195
1554
|
});
|
|
1196
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2, readdirSync } from "node:fs";
|
|
1555
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, readdirSync as readdirSync2 } from "node:fs";
|
|
1197
1556
|
import { isAbsolute as isAbsolute2, join as join4, resolve } from "node:path";
|
|
1198
1557
|
import { createConnection } from "node:net";
|
|
1199
1558
|
function check(name, severity, message, hint = "") {
|
|
@@ -1578,7 +1937,7 @@ function readText(path) {
|
|
|
1578
1937
|
}
|
|
1579
1938
|
function listDir(path) {
|
|
1580
1939
|
try {
|
|
1581
|
-
return
|
|
1940
|
+
return readdirSync2(path);
|
|
1582
1941
|
} catch {
|
|
1583
1942
|
return null;
|
|
1584
1943
|
}
|
package/.output/nitro.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as h,j as t}from"./main-B2t-3SYj.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-B1KylMPs.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-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};
|