@tonyclaw/agent-inspector 3.0.7 → 3.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.output/cli.js +245 -171
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-C0Kbsm-Q.js → CompareDrawer-CJKL4LMm.js} +1 -1
  4. package/.output/public/assets/ProxyViewerContainer-DBUy29O-.js +106 -0
  5. package/.output/public/assets/ReplayDialog-BYanl-a_.js +1 -0
  6. package/.output/public/assets/{RequestAnatomy-fa0JXy5p.js → RequestAnatomy-DvPz1jqE.js} +1 -1
  7. package/.output/public/assets/ResponseView-sZnxp9GN.js +3 -0
  8. package/.output/public/assets/StreamingChunkSequence-G-tiYiBd.js +1 -0
  9. package/.output/public/assets/{_sessionId-D5fYH2C0.js → _sessionId-_hDcsmXq.js} +1 -1
  10. package/.output/public/assets/agent-inspector-58K1_MsC.ico +0 -0
  11. package/.output/public/assets/index-DAPAWsAd.js +1 -0
  12. package/.output/public/assets/index-DspnLqUW.css +1 -0
  13. package/.output/public/assets/{index-BEsqvywM.js → index-SuOSQb2_.js} +1 -1
  14. package/.output/public/assets/{json-viewer-B0QRbMSf.js → json-viewer-yQdhgjaw.js} +1 -1
  15. package/.output/public/assets/{main-CuKZD7n0.js → main-CgjcDxjR.js} +2 -2
  16. package/.output/server/_libs/radix-ui__react-dialog.mjs +2 -2
  17. package/.output/server/{_sessionId-DdBTK3qm.mjs → _sessionId-BGISf2En.mjs} +3 -3
  18. package/.output/server/_ssr/{CompareDrawer-m82cVZ73.mjs → CompareDrawer-s-UF9gW3.mjs} +2 -2
  19. package/.output/server/_ssr/{ProxyViewerContainer-7geuf78f.mjs → ProxyViewerContainer-C0Sbz9ED.mjs} +1033 -530
  20. package/.output/server/_ssr/{ReplayDialog-B8RlWLLH.mjs → ReplayDialog-DvS8gvJr.mjs} +58 -23
  21. package/.output/server/_ssr/{RequestAnatomy-BE7pmwpv.mjs → RequestAnatomy-BwhWglJL.mjs} +2 -2
  22. package/.output/server/_ssr/{ResponseView-D-sDsdQr.mjs → ResponseView-wBVreqQf.mjs} +2 -2
  23. package/.output/server/_ssr/{StreamingChunkSequence-DU_hThJr.mjs → StreamingChunkSequence-Dr6eg-MJ.mjs} +30 -20
  24. package/.output/server/_ssr/{index-D0sV8UbE.mjs → index-B98Wia1X.mjs} +2 -2
  25. package/.output/server/_ssr/index.mjs +2 -2
  26. package/.output/server/_ssr/{json-viewer-CaDh1zrw.mjs → json-viewer-D7L8y0FH.mjs} +2 -2
  27. package/.output/server/_ssr/{router-Zh2iZ_u0.mjs → router-g9mo0nWT.mjs} +459 -196
  28. package/.output/server/_tanstack-start-manifest_v-CbGc-o50.mjs +4 -0
  29. package/.output/server/index.mjs +76 -69
  30. package/package.json +1 -1
  31. package/src/assets/IDE/opencode.svg +1 -1
  32. package/src/assets/IDE/xiaomimimo.svg +1 -1
  33. package/src/cli/detect-tools.ts +2 -27
  34. package/src/cli/templates/codex-skill-onboard.ts +1 -1
  35. package/src/cli/templates/skill-onboard.ts +2 -3
  36. package/src/cli.ts +9 -86
  37. package/src/components/ProxyViewer.tsx +249 -37
  38. package/src/components/ProxyViewerContainer.tsx +167 -22
  39. package/src/components/clients/ClientLogo.tsx +38 -3
  40. package/src/components/ecosystem/AgentLabDialog.tsx +204 -3
  41. package/src/components/groups/GroupsDialog.tsx +28 -40
  42. package/src/components/providers/ImportWizardDialog.tsx +51 -101
  43. package/src/components/providers/ProvidersPanel.tsx +82 -68
  44. package/src/components/providers/SettingsDialog.tsx +11 -12
  45. package/src/components/proxy-viewer/AgentTraceSummary.tsx +15 -23
  46. package/src/components/proxy-viewer/ReplayDialog.tsx +65 -22
  47. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +33 -20
  48. package/src/components/proxy-viewer/TurnGroup.tsx +0 -16
  49. package/src/components/proxy-viewer/log-formats/anthropic.ts +5 -5
  50. package/src/components/proxy-viewer/log-formats/openai.ts +7 -10
  51. package/src/components/proxy-viewer/requestTools.ts +5 -2
  52. package/src/lib/apiClient.ts +43 -10
  53. package/src/lib/ecosystemContract.ts +32 -0
  54. package/src/lib/export-logs.ts +37 -3
  55. package/src/proxy/ecosystemRegistry.ts +244 -0
  56. package/src/proxy/ecosystemTasks.ts +153 -0
  57. package/src/proxy/platformCommands.ts +212 -0
  58. package/src/proxy/socketTracker.ts +84 -143
  59. package/src/routes/api/ecosystem.packages.$packageId.help.ts +16 -0
  60. package/src/routes/api/ecosystem.packages.$packageId.install.ts +16 -0
  61. package/src/routes/api/ecosystem.packages.$packageId.runner-presets.ts +19 -0
  62. package/src/routes/api/ecosystem.packages.$packageId.upgrade.ts +16 -0
  63. package/src/routes/api/ecosystem.packages.ts +1 -248
  64. package/src/routes/api/ecosystem.tasks.$taskId.ts +16 -0
  65. package/src/routes/api/ecosystem.tasks.ts +12 -0
  66. package/src/routes/api/providers.$providerId.test.log.ts +28 -24
  67. package/.output/public/assets/ProxyViewerContainer-p-rpYyiF.js +0 -106
  68. package/.output/public/assets/ReplayDialog-CM3dhP8v.js +0 -1
  69. package/.output/public/assets/ResponseView-Bq6sC7Ay.js +0 -3
  70. package/.output/public/assets/StreamingChunkSequence-CGOun3Df.js +0 -1
  71. package/.output/public/assets/index-C29Olfzt.js +0 -1
  72. package/.output/public/assets/index-DgANE0r3.css +0 -1
  73. package/.output/server/_tanstack-start-manifest_v-LCE-2AaF.mjs +0 -4
@@ -1,252 +1,5 @@
1
- import { execFile } from "node:child_process";
2
- import { readFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
1
  import { createFileRoute } from "@tanstack/react-router";
5
- import packageJson from "../../../package.json";
6
- import type {
7
- EcosystemPackage,
8
- EcosystemPackageState,
9
- EcosystemRunnerPreset,
10
- } from "../../lib/ecosystemContract";
11
-
12
- type PackageDefinition = {
13
- id: string;
14
- name: string;
15
- npmName: string;
16
- capability: string;
17
- description: string;
18
- workflow: string;
19
- primary: boolean;
20
- };
21
-
22
- type NpmResult = {
23
- ok: boolean;
24
- stdout: string;
25
- };
26
-
27
- type PackageVersionResult = {
28
- installedVersion: string | null;
29
- latestVersion: string | null;
30
- state: EcosystemPackageState;
31
- };
32
-
33
- const ECOSYSTEM_PACKAGES: PackageDefinition[] = [
34
- {
35
- id: "inspector",
36
- name: "Agent Inspector",
37
- npmName: "@tonyclaw/agent-inspector",
38
- capability: "Observe",
39
- description: "Captures proxy traffic, sessions, turns, tools, providers, and raw bodies.",
40
- workflow: "Keep every agent run visible and reloadable.",
41
- primary: true,
42
- },
43
- {
44
- id: "mcp",
45
- name: "Inspector MCP",
46
- npmName: "@tonyclaw/agent-inspector-mcp",
47
- capability: "Connect",
48
- description: "Exposes sessions, logs, providers, runs, and evidence to MCP clients.",
49
- workflow: "Let Codex, OpenCode, MiMo Code, and other tools query Inspector as memory.",
50
- primary: true,
51
- },
52
- {
53
- id: "eval-harness",
54
- name: "Eval Harness",
55
- npmName: "@tonyclaw/eval-harness",
56
- capability: "Evaluate",
57
- description:
58
- "Runs MCP-aware agent evaluations, runner presets, regressions, and model bakeoffs.",
59
- workflow: "Promote Inspector evidence into repeatable evaluation batches.",
60
- primary: false,
61
- },
62
- ];
63
-
64
- const RUNNER_PRESETS: EcosystemRunnerPreset[] = [
65
- {
66
- id: "opencode",
67
- name: "OpenCode",
68
- validatedVersion: "1.17.11",
69
- binary: "opencode",
70
- modelFlag: "--model",
71
- variantFlag: "--variant",
72
- tools: ["opencode", "node"],
73
- logDir: "opencode",
74
- skillsDir: ".opencode/skills",
75
- agentsDir: ".opencode/agents",
76
- },
77
- {
78
- id: "mimo",
79
- name: "MiMo Code",
80
- validatedVersion: "0.1.4",
81
- binary: "mimo",
82
- modelFlag: "--model",
83
- variantFlag: "--agent",
84
- tools: ["mimo", "node"],
85
- logDir: "mimocode",
86
- skillsDir: ".mimocode/skills",
87
- agentsDir: ".mimocode/agents",
88
- },
89
- {
90
- id: "codex",
91
- name: "Codex CLI",
92
- validatedVersion: "0.142.5",
93
- binary: "codex",
94
- modelFlag: "--model",
95
- variantFlag: null,
96
- tools: ["codex"],
97
- logDir: "codex",
98
- skillsDir: ".codex/skills",
99
- agentsDir: ".codex/agents",
100
- },
101
- {
102
- id: "claude",
103
- name: "Claude Code",
104
- validatedVersion: "2.1.195",
105
- binary: "claude",
106
- modelFlag: "--model",
107
- variantFlag: null,
108
- tools: ["claude"],
109
- logDir: "claude",
110
- skillsDir: ".claude/skills",
111
- agentsDir: ".claude/agents",
112
- },
113
- ];
114
-
115
- const NPM_TIMEOUT_MS = 4000;
116
-
117
- function npmCommand(): string {
118
- return process.platform === "win32" ? "npm.cmd" : "npm";
119
- }
120
-
121
- function runNpm(args: readonly string[]): Promise<NpmResult> {
122
- return new Promise((resolve) => {
123
- try {
124
- execFile(
125
- npmCommand(),
126
- [...args],
127
- { timeout: NPM_TIMEOUT_MS, windowsHide: true },
128
- (error, stdout) => {
129
- resolve({
130
- ok: error === null,
131
- stdout: String(stdout).trim(),
132
- });
133
- },
134
- );
135
- } catch {
136
- resolve({ ok: false, stdout: "" });
137
- }
138
- });
139
- }
140
-
141
- async function readGlobalNpmRoot(): Promise<string | null> {
142
- const result = await runNpm(["root", "-g"]);
143
- if (!result.ok || result.stdout.length === 0) return null;
144
- return result.stdout;
145
- }
146
-
147
- function readGlobalNpmRootFallback(): string | null {
148
- switch (process.platform) {
149
- case "win32": {
150
- const appData = process.env["APPDATA"];
151
- if (appData === undefined || appData.length === 0) return null;
152
- return join(appData, "npm", "node_modules");
153
- }
154
- case "darwin":
155
- case "linux":
156
- case "aix":
157
- case "freebsd":
158
- case "openbsd":
159
- case "sunos": {
160
- const prefix = process.env["PREFIX"];
161
- if (prefix !== undefined && prefix.length > 0) return join(prefix, "lib", "node_modules");
162
- return "/usr/local/lib/node_modules";
163
- }
164
- case "android":
165
- case "cygwin":
166
- case "haiku":
167
- case "netbsd":
168
- return null;
169
- }
170
-
171
- return null;
172
- }
173
-
174
- function packageJsonPath(globalRoot: string, npmName: string): string {
175
- const parts = npmName.split("/");
176
- return join(globalRoot, ...parts, "package.json");
177
- }
178
-
179
- function readJsonStringField(raw: unknown, field: string): string | null {
180
- if (typeof raw !== "object" || raw === null) return null;
181
- const descriptor = Object.getOwnPropertyDescriptor(raw, field);
182
- if (descriptor === undefined) return null;
183
- return typeof descriptor.value === "string" ? descriptor.value : null;
184
- }
185
-
186
- async function readInstalledVersion(
187
- globalRoot: string | null,
188
- npmName: string,
189
- ): Promise<string | null> {
190
- if (npmName === packageJson.name) return packageJson.version;
191
- if (globalRoot === null) return null;
192
-
193
- try {
194
- const raw = await readFile(packageJsonPath(globalRoot, npmName), "utf8");
195
- return readJsonStringField(JSON.parse(raw), "version");
196
- } catch {
197
- return null;
198
- }
199
- }
200
-
201
- async function readLatestVersion(npmName: string): Promise<string | null> {
202
- const result = await runNpm(["view", npmName, "version", "--json"]);
203
- if (!result.ok || result.stdout.length === 0) return null;
204
-
205
- try {
206
- const parsed: unknown = JSON.parse(result.stdout);
207
- return typeof parsed === "string" && parsed.length > 0 ? parsed : null;
208
- } catch {
209
- return result.stdout.length > 0 ? result.stdout : null;
210
- }
211
- }
212
-
213
- function packageState(
214
- installedVersion: string | null,
215
- latestVersion: string | null,
216
- ): EcosystemPackageState {
217
- if (installedVersion !== null && latestVersion !== null && installedVersion !== latestVersion) {
218
- return "update-available";
219
- }
220
- if (installedVersion !== null) return "installed";
221
- if (latestVersion !== null) return "available";
222
- return "planned";
223
- }
224
-
225
- async function describePackage(
226
- definition: PackageDefinition,
227
- globalRoot: string | null,
228
- ): Promise<EcosystemPackage> {
229
- const [installedVersion, latestVersion] = await Promise.all([
230
- readInstalledVersion(globalRoot, definition.npmName),
231
- readLatestVersion(definition.npmName),
232
- ]);
233
- const state = packageState(installedVersion, latestVersion);
234
-
235
- return {
236
- ...definition,
237
- installCommand: `npm install -g ${definition.npmName}`,
238
- installedVersion,
239
- latestVersion,
240
- state,
241
- };
242
- }
243
-
244
- async function listEcosystemPackages(): Promise<EcosystemPackage[]> {
245
- const globalRoot = (await readGlobalNpmRoot()) ?? readGlobalNpmRootFallback();
246
- return Promise.all(
247
- ECOSYSTEM_PACKAGES.map((definition) => describePackage(definition, globalRoot)),
248
- );
249
- }
2
+ import { listEcosystemPackages, RUNNER_PRESETS } from "../../proxy/ecosystemRegistry";
250
3
 
251
4
  export const Route = createFileRoute("/api/ecosystem/packages")({
252
5
  server: {
@@ -0,0 +1,16 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+ import { getEcosystemTask } from "../../proxy/ecosystemTasks";
3
+
4
+ export const Route = createFileRoute("/api/ecosystem/tasks/$taskId")({
5
+ server: {
6
+ handlers: {
7
+ GET: ({ params }: { params: { taskId: string } }) => {
8
+ const task = getEcosystemTask(params.taskId);
9
+ if (task === null) {
10
+ return Response.json({ error: "Unknown ecosystem task" }, { status: 404 });
11
+ }
12
+ return Response.json({ task });
13
+ },
14
+ },
15
+ },
16
+ });
@@ -0,0 +1,12 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+ import { listEcosystemTasks } from "../../proxy/ecosystemTasks";
3
+
4
+ export const Route = createFileRoute("/api/ecosystem/tasks")({
5
+ server: {
6
+ handlers: {
7
+ GET: () => {
8
+ return Response.json({ tasks: listEcosystemTasks() });
9
+ },
10
+ },
11
+ },
12
+ });
@@ -1,4 +1,5 @@
1
1
  import { createFileRoute } from "@tanstack/react-router";
2
+ import { basename } from "node:path";
2
3
  import { getProvider, getModelUsageName } from "../../proxy/providers";
3
4
  import { addTestLogEntry } from "../../proxy/store";
4
5
  import { getConfig } from "../../proxy/config";
@@ -51,6 +52,27 @@ function getResultTokensPerSecond(result: TestResult): number | null {
51
52
  );
52
53
  }
53
54
 
55
+ function providerTestClientFields(providerName: string): {
56
+ userAgent: string;
57
+ origin: null;
58
+ isTest: true;
59
+ providerName: string;
60
+ clientPid: number;
61
+ clientCwd: string;
62
+ clientProjectFolder: string;
63
+ } {
64
+ const cwd = process.cwd();
65
+ return {
66
+ userAgent: "Agent Inspector Provider Test",
67
+ origin: null,
68
+ isTest: true,
69
+ providerName,
70
+ clientPid: process.pid,
71
+ clientCwd: cwd,
72
+ clientProjectFolder: basename(cwd),
73
+ };
74
+ }
75
+
54
76
  async function logModelResults(
55
77
  displayName: string,
56
78
  providerName: string,
@@ -90,11 +112,8 @@ async function logModelResults(
90
112
  totalStreamMs: null,
91
113
  tokensPerSecond: null,
92
114
  streaming: false,
93
- userAgent: "provider-test",
94
- origin: null,
95
115
  apiFormat: "anthropic",
96
- isTest: true,
97
- providerName,
116
+ ...providerTestClientFields(providerName),
98
117
  headers: captureFullDetails ? getResultHeaders(nonStreamingResult) : undefined,
99
118
  });
100
119
 
@@ -121,11 +140,8 @@ async function logModelResults(
121
140
  tokensPerSecond: getResultTokensPerSecond(streamingResult),
122
141
  streaming: true,
123
142
  streamingChunks: captureFullDetails ? streamingResult.streamingChunks : undefined,
124
- userAgent: "provider-test",
125
- origin: null,
126
143
  apiFormat: "anthropic",
127
- isTest: true,
128
- providerName,
144
+ ...providerTestClientFields(providerName),
129
145
  headers: captureFullDetails ? getResultHeaders(streamingResult) : undefined,
130
146
  });
131
147
  }
@@ -158,11 +174,8 @@ async function logModelResults(
158
174
  totalStreamMs: null,
159
175
  tokensPerSecond: null,
160
176
  streaming: false,
161
- userAgent: "provider-test",
162
- origin: null,
163
177
  apiFormat: "openai",
164
- isTest: true,
165
- providerName,
178
+ ...providerTestClientFields(providerName),
166
179
  headers: captureFullDetails ? getResultHeaders(nonStreamingResult) : undefined,
167
180
  });
168
181
 
@@ -189,11 +202,8 @@ async function logModelResults(
189
202
  tokensPerSecond: getResultTokensPerSecond(streamingResult),
190
203
  streaming: true,
191
204
  streamingChunks: captureFullDetails ? streamingResult.streamingChunks : undefined,
192
- userAgent: "provider-test",
193
- origin: null,
194
205
  apiFormat: "openai",
195
- isTest: true,
196
- providerName,
206
+ ...providerTestClientFields(providerName),
197
207
  headers: captureFullDetails ? getResultHeaders(streamingResult) : undefined,
198
208
  });
199
209
  }
@@ -228,11 +238,8 @@ async function logModelResults(
228
238
  totalStreamMs: null,
229
239
  tokensPerSecond: null,
230
240
  streaming: false,
231
- userAgent: "provider-test",
232
- origin: null,
233
241
  apiFormat: "openai",
234
- isTest: true,
235
- providerName,
242
+ ...providerTestClientFields(providerName),
236
243
  headers: captureFullDetails ? getResultHeaders(nonStreamingResult) : undefined,
237
244
  });
238
245
 
@@ -259,11 +266,8 @@ async function logModelResults(
259
266
  tokensPerSecond: getResultTokensPerSecond(streamingResult),
260
267
  streaming: true,
261
268
  streamingChunks: captureFullDetails ? streamingResult.streamingChunks : undefined,
262
- userAgent: "provider-test",
263
- origin: null,
264
269
  apiFormat: "openai",
265
- isTest: true,
266
- providerName,
270
+ ...providerTestClientFields(providerName),
267
271
  headers: captureFullDetails ? getResultHeaders(streamingResult) : undefined,
268
272
  });
269
273
  }