@tonyclaw/agent-inspector 2.0.1 → 2.0.2
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 +344 -53
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-sVLGhCO3.js → CompareDrawer-Bp7_x-5N.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-p9QvzZ6U.js → ProxyViewerContainer-USuxPy-K.js} +13 -13
- package/.output/public/assets/{ReplayDialog-DxbFUqNW.js → ReplayDialog-DFHCd0yx.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CSmGQa_g.js → RequestAnatomy-ehyrskxt.js} +1 -1
- package/.output/public/assets/{ResponseView-B5f89c8Z.js → ResponseView-BNGyc8e_.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-BzqpY0TN.js → StreamingChunkSequence-Bjs4Lqwn.js} +1 -1
- package/.output/public/assets/_sessionId-D_SeK_qp.js +1 -0
- package/.output/public/assets/index-BGGOWR7A.js +1 -0
- package/.output/public/assets/index-CIL46Z2y.css +1 -0
- package/.output/public/assets/{json-viewer-CKNMihlh.js → json-viewer-6uV_YXws.js} +1 -1
- package/.output/public/assets/{main-yWf8dv9w.js → main-FSGUGtEL.js} +2 -2
- package/.output/server/{_sessionId-DfHd0gd8.mjs → _sessionId-_bf9vUww.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-DGYAUWgF.mjs → CompareDrawer-DIth2DQM.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-fawglkTo.mjs → ProxyViewerContainer-249bTH-T.mjs} +24 -30
- package/.output/server/_ssr/{ReplayDialog-B4vlKa2W.mjs → ReplayDialog-C1aGx0y1.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-BNQvEIZK.mjs → RequestAnatomy-D2bCiEJn.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-X6X6G16_.mjs → ResponseView-DP6k4Xs_.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BPVN3MnF.mjs → StreamingChunkSequence-HyXZV-b5.mjs} +3 -3
- package/.output/server/_ssr/{index-CXmpc2X5.mjs → index-Bt47f9pn.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-3XC3eq4R.mjs → json-viewer-Co-YRwUP.mjs} +2 -2
- package/.output/server/_ssr/{router-C0B2qvIM.mjs → router-to_OJirX.mjs} +383 -43
- package/.output/server/{_tanstack-start-manifest_v-7tfsmd2I.mjs → _tanstack-start-manifest_v-Bd-2YRWo.mjs} +1 -1
- package/.output/server/index.mjs +63 -63
- package/README.md +47 -7
- package/package.json +3 -2
- package/scripts/setup-codex-skill.mjs +38 -0
- package/scripts/setup-windows-runtime.mjs +4 -3
- package/src/cli/onboard.ts +175 -68
- package/src/cli/templates/codex-skill-onboard.ts +210 -0
- package/src/components/providers/ProviderCard.tsx +2 -27
- package/src/components/providers/ProvidersPanel.tsx +16 -0
- package/src/knowledge/openclawClient.ts +34 -5
- package/src/knowledge/openclawGatewayClient.ts +237 -0
- package/src/knowledge/openclawMarkdown.ts +146 -0
- package/src/lib/providerTestPrompt.ts +78 -0
- package/src/routes/api/providers.$providerId.test.log.ts +9 -22
- package/.output/public/assets/_sessionId-BF7ftHV3.js +0 -1
- package/.output/public/assets/index-BU0PpLby.js +0 -1
- package/.output/public/assets/index-CpWG2hFn.css +0 -1
package/.output/cli.js
CHANGED
|
@@ -114,6 +114,208 @@ var init_command_onboard = __esm({
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
+
// src/cli/templates/codex-skill-onboard.ts
|
|
118
|
+
function renderCodexSkillOnboard(ctx) {
|
|
119
|
+
const { version, port } = ctx;
|
|
120
|
+
return `---
|
|
121
|
+
name: agent-inspector-onboard
|
|
122
|
+
description: Guide Codex users through connecting Agent Inspector v${version} as a local MCP server.
|
|
123
|
+
metadata:
|
|
124
|
+
author: agent-inspector
|
|
125
|
+
version: ${version}
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
# Agent Inspector onboard for Codex
|
|
129
|
+
|
|
130
|
+
Use this skill when the user wants to set up Agent Inspector inside Codex, connect the Agent Inspector MCP server, inspect captured model traffic from Codex, or turn Inspector sessions into reviewable knowledge candidates.
|
|
131
|
+
|
|
132
|
+
Agent Inspector runs a local web UI, proxy, REST API, and MCP endpoint on the same port. The default MCP endpoint is:
|
|
133
|
+
|
|
134
|
+
\`\`\`text
|
|
135
|
+
http://localhost:${port}/api/mcp
|
|
136
|
+
\`\`\`
|
|
137
|
+
|
|
138
|
+
This skill is installed at \`~/.codex/skills/agent-inspector-onboard/SKILL.md\`.
|
|
139
|
+
Codex user-level configuration lives in \`~/.codex/config.toml\`. Codex supports streamable HTTP MCP servers with \`mcp_servers.<id>.url\`, so no extra stdio bridge package is needed.
|
|
140
|
+
|
|
141
|
+
Keep this setup local and explicit. Agent Inspector MCP tools can read captured requests and provider configuration, so only wire it into trusted local Codex environments.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Phase 0: Preflight
|
|
146
|
+
|
|
147
|
+
Check that the package and Codex home exist without printing secrets.
|
|
148
|
+
|
|
149
|
+
\`\`\`powershell
|
|
150
|
+
Get-Command agent-inspector -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source
|
|
151
|
+
Test-Path (Join-Path $env:USERPROFILE ".codex")
|
|
152
|
+
Test-Path (Join-Path $env:USERPROFILE ".codex\\config.toml")
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
\`\`\`bash
|
|
156
|
+
command -v agent-inspector || true
|
|
157
|
+
test -d "$HOME/.codex" && echo "codex home: present" || echo "codex home: missing"
|
|
158
|
+
test -f "$HOME/.codex/config.toml" && echo "config: present" || echo "config: missing"
|
|
159
|
+
\`\`\`
|
|
160
|
+
|
|
161
|
+
If \`agent-inspector\` is missing, ask the user to install it first:
|
|
162
|
+
|
|
163
|
+
\`\`\`bash
|
|
164
|
+
npm install -g @tonyclaw/agent-inspector
|
|
165
|
+
\`\`\`
|
|
166
|
+
|
|
167
|
+
Do not read \`~/.codex/auth.json\`, token files, or unrelated Codex state files.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Phase 1: Start Agent Inspector
|
|
172
|
+
|
|
173
|
+
Start or reuse Agent Inspector before wiring MCP. Prefer the installed binary so Windows users get the branded runtime in Task Manager.
|
|
174
|
+
|
|
175
|
+
\`\`\`powershell
|
|
176
|
+
agent-inspector --background --no-open
|
|
177
|
+
Invoke-RestMethod -Uri "http://localhost:${port}/api/health" -TimeoutSec 3
|
|
178
|
+
\`\`\`
|
|
179
|
+
|
|
180
|
+
\`\`\`bash
|
|
181
|
+
agent-inspector --background --no-open
|
|
182
|
+
curl -fsS "http://localhost:${port}/api/health"
|
|
183
|
+
\`\`\`
|
|
184
|
+
|
|
185
|
+
If the health check fails, show only the relevant error and ask whether to diagnose startup before editing Codex config.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Phase 2: Wire Codex MCP
|
|
190
|
+
|
|
191
|
+
Add an \`agent-inspector\` MCP server to \`~/.codex/config.toml\`. Preserve the user's existing config and merge the table instead of replacing the file.
|
|
192
|
+
|
|
193
|
+
Recommended user-level config:
|
|
194
|
+
|
|
195
|
+
\`\`\`toml
|
|
196
|
+
[mcp_servers.agent-inspector]
|
|
197
|
+
url = "http://localhost:${port}/api/mcp"
|
|
198
|
+
startup_timeout_sec = 30
|
|
199
|
+
tool_timeout_sec = 60
|
|
200
|
+
\`\`\`
|
|
201
|
+
|
|
202
|
+
If the user's Codex environment is managed by an admin allowlist, they may also need a matching identity rule in the managed requirements layer:
|
|
203
|
+
|
|
204
|
+
\`\`\`toml
|
|
205
|
+
[mcp_servers.agent-inspector.identity]
|
|
206
|
+
url = "http://localhost:${port}/api/mcp"
|
|
207
|
+
\`\`\`
|
|
208
|
+
|
|
209
|
+
When editing:
|
|
210
|
+
|
|
211
|
+
- Ask before changing \`~/.codex/config.toml\`.
|
|
212
|
+
- Keep existing \`mcp_servers.*\`, \`projects.*\`, profiles, sandbox, approval, and model settings intact.
|
|
213
|
+
- Do not write provider API keys into Codex config.
|
|
214
|
+
- Do not expose Agent Inspector MCP beyond localhost.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Phase 3: Restart and verify Codex
|
|
219
|
+
|
|
220
|
+
Tell the user that Codex loads MCP servers at session startup. After saving \`config.toml\`, they should start a new Codex session or restart the Codex app.
|
|
221
|
+
|
|
222
|
+
Before restart, verify the HTTP endpoint itself:
|
|
223
|
+
|
|
224
|
+
\`\`\`bash
|
|
225
|
+
curl -sS -X POST "http://localhost:${port}/api/mcp" \\
|
|
226
|
+
-H "Content-Type: application/json" \\
|
|
227
|
+
-H "Accept: application/json, text/event-stream" \\
|
|
228
|
+
-d '{
|
|
229
|
+
"jsonrpc": "2.0",
|
|
230
|
+
"id": 1,
|
|
231
|
+
"method": "initialize",
|
|
232
|
+
"params": {
|
|
233
|
+
"protocolVersion": "2025-03-26",
|
|
234
|
+
"capabilities": {},
|
|
235
|
+
"clientInfo": { "name": "codex-onboard-check", "version": "0" }
|
|
236
|
+
}
|
|
237
|
+
}'
|
|
238
|
+
\`\`\`
|
|
239
|
+
|
|
240
|
+
Expected signal: a 200 response containing \`serverInfo\` with \`agent-inspector\`.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Phase 4: First Inspector query
|
|
245
|
+
|
|
246
|
+
After Codex restarts with the MCP server configured, ask Codex to use Agent Inspector:
|
|
247
|
+
|
|
248
|
+
\`\`\`text
|
|
249
|
+
Use Agent Inspector to list the latest captured logs.
|
|
250
|
+
\`\`\`
|
|
251
|
+
|
|
252
|
+
The expected tool is \`inspector_list_logs\`. If no logs exist yet, that is still a successful MCP connection.
|
|
253
|
+
|
|
254
|
+
Useful follow-up tools:
|
|
255
|
+
|
|
256
|
+
- \`inspector_list_logs\`
|
|
257
|
+
- \`inspector_get_log\`
|
|
258
|
+
- \`inspector_get_log_chunks\`
|
|
259
|
+
- \`inspector_list_sessions\`
|
|
260
|
+
- \`inspector_test_provider\`
|
|
261
|
+
- \`inspector_create_session_knowledge\`
|
|
262
|
+
- \`inspector_list_knowledge_candidates\`
|
|
263
|
+
- \`inspector_search_knowledge\`
|
|
264
|
+
- \`inspector_get_project_context\`
|
|
265
|
+
|
|
266
|
+
Provider mutation tools expose and modify local provider configuration. Ask for explicit user confirmation before using \`inspector_add_provider\`, \`inspector_update_provider\`, or \`inspector_replay_log\`.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Phase 5: Capture and memory review
|
|
271
|
+
|
|
272
|
+
To capture Codex traffic through Agent Inspector, route a model client through:
|
|
273
|
+
|
|
274
|
+
\`\`\`text
|
|
275
|
+
http://localhost:${port}/proxy
|
|
276
|
+
\`\`\`
|
|
277
|
+
|
|
278
|
+
For Anthropic-compatible tools, set \`ANTHROPIC_BASE_URL=http://localhost:${port}/proxy\`. For OpenAI-compatible tools, set \`OPENAI_BASE_URL=http://localhost:${port}/proxy\`.
|
|
279
|
+
|
|
280
|
+
For a Provider Test memory probe, run a provider test in the Agent Inspector UI:
|
|
281
|
+
|
|
282
|
+
1. Open \`http://localhost:${port}\`.
|
|
283
|
+
2. Go to Settings -> Providers.
|
|
284
|
+
3. Add or edit a Provider.
|
|
285
|
+
4. Run Test.
|
|
286
|
+
5. Check the \`provider-test\` session.
|
|
287
|
+
|
|
288
|
+
Then ask Codex:
|
|
289
|
+
|
|
290
|
+
\`\`\`text
|
|
291
|
+
Use Agent Inspector to create knowledge candidates for the provider-test session, then list the candidates.
|
|
292
|
+
\`\`\`
|
|
293
|
+
|
|
294
|
+
Expected flow:
|
|
295
|
+
|
|
296
|
+
- Raw Trace stays in Agent Inspector logs.
|
|
297
|
+
- Session Episode is reconstructed from the session.
|
|
298
|
+
- Memory Candidate is generated for review.
|
|
299
|
+
- Promotion to OpenClaw happens only after review through Agent Inspector.
|
|
300
|
+
|
|
301
|
+
Stop after showing candidates unless the user explicitly approves promotion.
|
|
302
|
+
`;
|
|
303
|
+
}
|
|
304
|
+
var REQUIRED_CODEX_PHASE_HEADINGS;
|
|
305
|
+
var init_codex_skill_onboard = __esm({
|
|
306
|
+
"src/cli/templates/codex-skill-onboard.ts"() {
|
|
307
|
+
"use strict";
|
|
308
|
+
REQUIRED_CODEX_PHASE_HEADINGS = [
|
|
309
|
+
"Phase 0: Preflight",
|
|
310
|
+
"Phase 1: Start Agent Inspector",
|
|
311
|
+
"Phase 2: Wire Codex MCP",
|
|
312
|
+
"Phase 3: Restart and verify Codex",
|
|
313
|
+
"Phase 4: First Inspector query",
|
|
314
|
+
"Phase 5: Capture and memory review"
|
|
315
|
+
];
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
117
319
|
// src/cli/templates/skill-onboard.ts
|
|
118
320
|
function renderSkillOnboard(ctx) {
|
|
119
321
|
const { version, port, detectedSummary } = ctx;
|
|
@@ -660,7 +862,10 @@ function parseFlags(argv) {
|
|
|
660
862
|
dryRun: false,
|
|
661
863
|
skipProvider: false,
|
|
662
864
|
skipToolWire: false,
|
|
663
|
-
|
|
865
|
+
codexOnly: false,
|
|
866
|
+
skipCodexSkill: false,
|
|
867
|
+
skillDir: null,
|
|
868
|
+
codexSkillDir: null
|
|
664
869
|
};
|
|
665
870
|
for (let i = 0; i < argv.length; i++) {
|
|
666
871
|
const arg = argv[i];
|
|
@@ -679,6 +884,12 @@ function parseFlags(argv) {
|
|
|
679
884
|
case "--skip-tool-wire":
|
|
680
885
|
flags.skipToolWire = true;
|
|
681
886
|
break;
|
|
887
|
+
case "--codex-only":
|
|
888
|
+
flags.codexOnly = true;
|
|
889
|
+
break;
|
|
890
|
+
case "--skip-codex-skill":
|
|
891
|
+
flags.skipCodexSkill = true;
|
|
892
|
+
break;
|
|
682
893
|
case "--skill-dir": {
|
|
683
894
|
const next = argv[i + 1];
|
|
684
895
|
if (next === void 0) {
|
|
@@ -689,6 +900,18 @@ function parseFlags(argv) {
|
|
|
689
900
|
i++;
|
|
690
901
|
break;
|
|
691
902
|
}
|
|
903
|
+
case "--codex-skill-dir": {
|
|
904
|
+
const next = argv[i + 1];
|
|
905
|
+
if (next === void 0) {
|
|
906
|
+
process.stderr.write(
|
|
907
|
+
"agent-inspector onboard: --codex-skill-dir requires a path argument\n"
|
|
908
|
+
);
|
|
909
|
+
process.exit(2);
|
|
910
|
+
}
|
|
911
|
+
flags.codexSkillDir = next;
|
|
912
|
+
i++;
|
|
913
|
+
break;
|
|
914
|
+
}
|
|
692
915
|
case "--help":
|
|
693
916
|
case "-h":
|
|
694
917
|
printHelp();
|
|
@@ -703,18 +926,21 @@ function parseFlags(argv) {
|
|
|
703
926
|
return flags;
|
|
704
927
|
}
|
|
705
928
|
function printHelp() {
|
|
706
|
-
process.stdout.write(`agent-inspector onboard
|
|
929
|
+
process.stdout.write(`agent-inspector onboard - install Agent Inspector onboarding skills
|
|
707
930
|
|
|
708
931
|
Usage:
|
|
709
932
|
agent-inspector onboard [options]
|
|
710
933
|
|
|
711
934
|
Options:
|
|
712
|
-
--force
|
|
713
|
-
--dry-run
|
|
714
|
-
--skip-provider
|
|
715
|
-
--skip-tool-wire
|
|
716
|
-
--skill
|
|
717
|
-
-
|
|
935
|
+
--force Overwrite existing generated skills and slash command
|
|
936
|
+
--dry-run Print target paths and template previews, write nothing
|
|
937
|
+
--skip-provider Skip the provider-setup phase in the Claude skill body
|
|
938
|
+
--skip-tool-wire Skip the wire-tool phase in the Claude skill body
|
|
939
|
+
--skip-codex-skill Install only the Claude Code skill and slash command
|
|
940
|
+
--codex-only Install only the Codex skill
|
|
941
|
+
--skill-dir <path> Override the target Claude root directory (default: ~/.claude)
|
|
942
|
+
--codex-skill-dir <path> Override the target Codex skills directory (default: ~/.codex/skills)
|
|
943
|
+
-h, --help Show this help
|
|
718
944
|
|
|
719
945
|
Exit codes:
|
|
720
946
|
0 success (or already installed)
|
|
@@ -724,11 +950,14 @@ Exit codes:
|
|
|
724
950
|
}
|
|
725
951
|
function resolveTargets(flags) {
|
|
726
952
|
const claudeRoot = flags.skillDir ?? join2(homedir2(), ".claude");
|
|
727
|
-
const
|
|
728
|
-
const
|
|
953
|
+
const claudeSkillDir = join2(claudeRoot, "skills", SKILL_DIR_NAME);
|
|
954
|
+
const claudeCommandsDir = join2(claudeRoot, "commands");
|
|
955
|
+
const codexRoot = process.env["CODEX_HOME"] ?? join2(homedir2(), ".codex");
|
|
956
|
+
const codexSkillsDir = flags.codexSkillDir ?? join2(codexRoot, "skills");
|
|
729
957
|
return {
|
|
730
|
-
|
|
731
|
-
|
|
958
|
+
claudeSkillFile: join2(claudeSkillDir, SKILL_FILE_NAME),
|
|
959
|
+
claudeCommandFile: join2(claudeCommandsDir, COMMAND_FILE_NAME),
|
|
960
|
+
codexSkillFile: join2(codexSkillsDir, SKILL_DIR_NAME, SKILL_FILE_NAME)
|
|
732
961
|
};
|
|
733
962
|
}
|
|
734
963
|
function isObject(value) {
|
|
@@ -743,6 +972,54 @@ function buildDetectedSummary() {
|
|
|
743
972
|
return ` - Detected: ${presentList}
|
|
744
973
|
- Not detected: ${absentList}`;
|
|
745
974
|
}
|
|
975
|
+
function readPackageVersion() {
|
|
976
|
+
try {
|
|
977
|
+
const raw = JSON.parse(readFileSync(join2(__dirname, "..", "package.json"), "utf8"));
|
|
978
|
+
if (isObject(raw) && typeof raw["version"] === "string") {
|
|
979
|
+
return raw["version"];
|
|
980
|
+
}
|
|
981
|
+
} catch {
|
|
982
|
+
}
|
|
983
|
+
return "0.0.0";
|
|
984
|
+
}
|
|
985
|
+
function buildPlannedFiles(flags, targets, version) {
|
|
986
|
+
const installClaude = !flags.codexOnly;
|
|
987
|
+
const installCodex = !flags.skipCodexSkill;
|
|
988
|
+
const detectedSummary = installClaude ? buildDetectedSummary() : "";
|
|
989
|
+
const claudeSkillBody = installClaude ? renderSkillOnboard({
|
|
990
|
+
version,
|
|
991
|
+
port: DEFAULT_PORT,
|
|
992
|
+
detectedSummary
|
|
993
|
+
}) : "";
|
|
994
|
+
const commandBody = installClaude ? renderCommandOnboard() : "";
|
|
995
|
+
const codexSkillBody = installCodex ? renderCodexSkillOnboard({
|
|
996
|
+
version,
|
|
997
|
+
port: DEFAULT_PORT
|
|
998
|
+
}) : "";
|
|
999
|
+
return [
|
|
1000
|
+
{
|
|
1001
|
+
label: "Claude skill",
|
|
1002
|
+
path: targets.claudeSkillFile,
|
|
1003
|
+
body: claudeSkillBody,
|
|
1004
|
+
enabled: installClaude
|
|
1005
|
+
},
|
|
1006
|
+
{
|
|
1007
|
+
label: "Claude command",
|
|
1008
|
+
path: targets.claudeCommandFile,
|
|
1009
|
+
body: commandBody,
|
|
1010
|
+
enabled: installClaude
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
label: "Codex skill",
|
|
1014
|
+
path: targets.codexSkillFile,
|
|
1015
|
+
body: codexSkillBody,
|
|
1016
|
+
enabled: installCodex
|
|
1017
|
+
}
|
|
1018
|
+
];
|
|
1019
|
+
}
|
|
1020
|
+
function shouldWrite(file, force) {
|
|
1021
|
+
return file.enabled && (force || !existsSync2(file.path));
|
|
1022
|
+
}
|
|
746
1023
|
function runOnboard(argv) {
|
|
747
1024
|
try {
|
|
748
1025
|
return Promise.resolve(runOnboardSync(argv));
|
|
@@ -756,62 +1033,69 @@ function runOnboard(argv) {
|
|
|
756
1033
|
}
|
|
757
1034
|
function runOnboardSync(argv) {
|
|
758
1035
|
const flags = parseFlags(argv);
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
let version = "0.0.0";
|
|
767
|
-
try {
|
|
768
|
-
const raw = JSON.parse(readFileSync(join2(__dirname, "..", "package.json"), "utf8"));
|
|
769
|
-
if (isObject(raw) && typeof raw["version"] === "string") {
|
|
770
|
-
version = raw["version"];
|
|
771
|
-
}
|
|
772
|
-
} catch {
|
|
1036
|
+
const targets = resolveTargets(flags);
|
|
1037
|
+
const version = readPackageVersion();
|
|
1038
|
+
const plannedFiles = buildPlannedFiles(flags, targets, version);
|
|
1039
|
+
const enabledFiles = plannedFiles.filter((file) => file.enabled);
|
|
1040
|
+
if (enabledFiles.length === 0) {
|
|
1041
|
+
process.stderr.write("agent-inspector onboard: no onboarding target selected\n");
|
|
1042
|
+
return 2;
|
|
773
1043
|
}
|
|
774
|
-
const detectedSummary = buildDetectedSummary();
|
|
775
|
-
const skillBody = renderSkillOnboard({
|
|
776
|
-
version,
|
|
777
|
-
port: DEFAULT_PORT,
|
|
778
|
-
detectedSummary
|
|
779
|
-
});
|
|
780
|
-
const commandBody = renderCommandOnboard();
|
|
781
1044
|
if (flags.dryRun) {
|
|
782
1045
|
process.stdout.write(`agent-inspector onboard --dry-run
|
|
783
1046
|
|
|
784
1047
|
`);
|
|
785
|
-
|
|
1048
|
+
for (const file of enabledFiles) {
|
|
1049
|
+
const status = existsSync2(file.path) ? "exists" : "missing";
|
|
1050
|
+
process.stdout.write(`${file.label}: ${file.path} (${status})
|
|
786
1051
|
`);
|
|
787
|
-
|
|
788
|
-
|
|
1052
|
+
}
|
|
1053
|
+
process.stdout.write(`
|
|
1054
|
+
Claude skill headings:
|
|
1055
|
+
`);
|
|
1056
|
+
if (!flags.codexOnly) {
|
|
1057
|
+
for (const heading of REQUIRED_PHASE_HEADINGS) {
|
|
1058
|
+
process.stdout.write(` - ${heading}
|
|
789
1059
|
`);
|
|
790
|
-
|
|
1060
|
+
}
|
|
1061
|
+
} else {
|
|
1062
|
+
process.stdout.write(` (disabled by --codex-only)
|
|
791
1063
|
`);
|
|
792
|
-
|
|
793
|
-
process.stdout.write(
|
|
1064
|
+
}
|
|
1065
|
+
process.stdout.write(`
|
|
1066
|
+
Codex skill headings:
|
|
794
1067
|
`);
|
|
795
|
-
|
|
1068
|
+
if (!flags.skipCodexSkill) {
|
|
1069
|
+
for (const heading of REQUIRED_CODEX_PHASE_HEADINGS) {
|
|
1070
|
+
process.stdout.write(` - ${heading}
|
|
796
1071
|
`);
|
|
797
|
-
|
|
798
|
-
|
|
1072
|
+
}
|
|
1073
|
+
} else {
|
|
1074
|
+
process.stdout.write(` (disabled by --skip-codex-skill)
|
|
799
1075
|
`);
|
|
800
1076
|
}
|
|
801
|
-
|
|
1077
|
+
if (!flags.codexOnly) {
|
|
1078
|
+
process.stdout.write(`
|
|
802
1079
|
Detected tools:
|
|
803
|
-
${
|
|
1080
|
+
${buildDetectedSummary()}
|
|
804
1081
|
`);
|
|
1082
|
+
}
|
|
805
1083
|
process.stdout.write(`
|
|
806
1084
|
No files were written.
|
|
807
1085
|
`);
|
|
808
1086
|
return 0;
|
|
809
1087
|
}
|
|
810
|
-
|
|
811
|
-
|
|
1088
|
+
const filesToWrite = plannedFiles.filter((file) => shouldWrite(file, flags.force));
|
|
1089
|
+
if (filesToWrite.length === 0) {
|
|
1090
|
+
process.stdout.write("agent-inspector onboard: all selected onboarding files already exist\n");
|
|
1091
|
+
process.stdout.write("Re-run with --force to refresh.\n");
|
|
1092
|
+
return 0;
|
|
1093
|
+
}
|
|
812
1094
|
try {
|
|
813
|
-
|
|
814
|
-
|
|
1095
|
+
for (const file of filesToWrite) {
|
|
1096
|
+
mkdirSync(dirname(file.path), { recursive: true });
|
|
1097
|
+
writeFileSync(file.path, file.body, "utf8");
|
|
1098
|
+
}
|
|
815
1099
|
} catch (err) {
|
|
816
1100
|
const msg = err instanceof Error ? err.message : String(err);
|
|
817
1101
|
process.stderr.write(`agent-inspector onboard: failed to write files: ${msg}
|
|
@@ -820,16 +1104,22 @@ No files were written.
|
|
|
820
1104
|
}
|
|
821
1105
|
const firstTool = detectFirst();
|
|
822
1106
|
const toolHint = firstTool !== null ? firstTool.displayName : "no known tool detected";
|
|
823
|
-
|
|
824
|
-
`
|
|
825
|
-
process.stdout.write(`Installed command to: ${commandFile}
|
|
1107
|
+
for (const file of filesToWrite) {
|
|
1108
|
+
process.stdout.write(`Installed ${file.label} to: ${file.path}
|
|
826
1109
|
`);
|
|
1110
|
+
}
|
|
827
1111
|
process.stdout.write(`
|
|
828
1112
|
Next steps:
|
|
829
1113
|
`);
|
|
830
|
-
|
|
1114
|
+
if (!flags.codexOnly) {
|
|
1115
|
+
process.stdout.write(` - Open Claude Code and run: /agent-inspector:onboard
|
|
831
1116
|
`);
|
|
832
|
-
|
|
1117
|
+
}
|
|
1118
|
+
if (!flags.skipCodexSkill) {
|
|
1119
|
+
process.stdout.write(` - Open Codex and ask to use the agent-inspector-onboard skill
|
|
1120
|
+
`);
|
|
1121
|
+
}
|
|
1122
|
+
process.stdout.write(` - Refresh later: agent-inspector onboard --force
|
|
833
1123
|
`);
|
|
834
1124
|
process.stdout.write(` - Detected primary tool: ${toolHint}
|
|
835
1125
|
`);
|
|
@@ -841,6 +1131,7 @@ var init_onboard = __esm({
|
|
|
841
1131
|
"use strict";
|
|
842
1132
|
init_detect_tools();
|
|
843
1133
|
init_command_onboard();
|
|
1134
|
+
init_codex_skill_onboard();
|
|
844
1135
|
init_skill_onboard();
|
|
845
1136
|
__filename = fileURLToPath(import.meta.url);
|
|
846
1137
|
__dirname = dirname(__filename);
|
package/.output/nitro.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as h,j as t}from"./main-yWf8dv9w.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 B,i as re,j as ne}from"./ProxyViewerContainer-p9QvzZ6U.js";import{J as N}from"./json-viewer-CKNMihlh.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 L(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 A(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&&A(s)){const d=L(s.path);let o=n+1;for(;o<e.length;){const a=e[o];if(a===void 0||!A(a)||L(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 V={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=V.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(B,{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=V[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(B,{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 K({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:["Cache +",$(e.cacheCreationInputTokens)]}),e.cacheReadInputTokens!==null&&e.cacheReadInputTokens>0&&t.jsxs("span",{className:"text-purple-400",children:["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 ge({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(K,{log:e,side:"left"}),t.jsx(K,{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{ge as CompareDrawer};
|
|
1
|
+
import{r as h,j as t}from"./main-FSGUGtEL.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 B,i as re,j as ne}from"./ProxyViewerContainer-USuxPy-K.js";import{J as N}from"./json-viewer-6uV_YXws.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 L(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 A(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&&A(s)){const d=L(s.path);let o=n+1;for(;o<e.length;){const a=e[o];if(a===void 0||!A(a)||L(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 V={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=V.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(B,{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=V[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(B,{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 K({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:["Cache +",$(e.cacheCreationInputTokens)]}),e.cacheReadInputTokens!==null&&e.cacheReadInputTokens>0&&t.jsxs("span",{className:"text-purple-400",children:["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 ge({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(K,{log:e,side:"left"}),t.jsx(K,{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{ge as CompareDrawer};
|