@tonyclaw/agent-inspector 2.0.15 → 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.
Files changed (36) hide show
  1. package/.output/cli.js +399 -28
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-B6WCFRJq.js → CompareDrawer-DDg7Cs4N.js} +1 -1
  4. package/.output/public/assets/{ProxyViewerContainer-CofGRJoO.js → ProxyViewerContainer-DbbK1y7N.js} +24 -24
  5. package/.output/public/assets/{ReplayDialog-O_53zkX8.js → ReplayDialog-C1zWNkoz.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-CqBSMZv5.js → RequestAnatomy-DR8OICOJ.js} +1 -1
  7. package/.output/public/assets/{ResponseView-BvbA6zot.js → ResponseView-Dh9iSj6h.js} +1 -1
  8. package/.output/public/assets/{StreamingChunkSequence-Bnf6djjc.js → StreamingChunkSequence-B_xElyH3.js} +1 -1
  9. package/.output/public/assets/_sessionId-gv1a_NNu.js +1 -0
  10. package/.output/public/assets/index-u-LwDaeH.js +1 -0
  11. package/.output/public/assets/{main-Biir9ZGe.js → main-bwZlEXw2.js} +2 -2
  12. package/.output/server/{_sessionId-B77Gh4IL.mjs → _sessionId-BEuJJhqT.mjs} +2 -2
  13. package/.output/server/_ssr/{CompareDrawer-D4-RHFqW.mjs → CompareDrawer-yTO93GMz.mjs} +2 -2
  14. package/.output/server/_ssr/{ProxyViewerContainer-YP28-_2H.mjs → ProxyViewerContainer-C8qCkHGB.mjs} +72 -22
  15. package/.output/server/_ssr/{ReplayDialog-D9rQlrcY.mjs → ReplayDialog-DRF9PG7Z.mjs} +3 -3
  16. package/.output/server/_ssr/{RequestAnatomy-BXCRWD9H.mjs → RequestAnatomy-DBcuV_jV.mjs} +2 -2
  17. package/.output/server/_ssr/{ResponseView-DEwWMqSS.mjs → ResponseView-JJm78HZT.mjs} +2 -2
  18. package/.output/server/_ssr/{StreamingChunkSequence-CdrTPf5v.mjs → StreamingChunkSequence-DyGKjBYx.mjs} +2 -2
  19. package/.output/server/_ssr/{index-Chf1DYqT.mjs → index-T7JG28t6.mjs} +2 -2
  20. package/.output/server/_ssr/index.mjs +2 -2
  21. package/.output/server/_ssr/{router-BHXU5jWm.mjs → router-BJob8RN3.mjs} +2 -2
  22. package/.output/server/{_tanstack-start-manifest_v-D1dtacWy.mjs → _tanstack-start-manifest_v-CuiFi3XC.mjs} +1 -1
  23. package/.output/server/index.mjs +57 -57
  24. package/README.md +22 -5
  25. package/package.json +3 -3
  26. package/scripts/setup-agent-skills.mjs +64 -0
  27. package/src/cli/onboard.ts +407 -13
  28. package/src/cli/templates/codex-skill-onboard.ts +13 -4
  29. package/src/cli/templates/command-onboard.ts +12 -4
  30. package/src/cli/templates/skill-onboard.ts +30 -8
  31. package/src/components/OnboardingBanner.tsx +35 -7
  32. package/src/components/providers/SettingsDialog.tsx +22 -4
  33. package/src/lib/useOnboarding.ts +9 -1
  34. package/.output/public/assets/_sessionId-9ICCw6YA.js +0 -1
  35. package/.output/public/assets/index-DVkMYH8H.js +0 -1
  36. package/scripts/setup-codex-skill.mjs +0 -38
@@ -76,7 +76,19 @@ Default proxy port: \`${port}\` (override with \`PORT=<n> agent-inspector\` or \
76
76
 
77
77
  **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."
78
78
 
79
- **DO:** Probe the three pieces of state this skill touches. Use targeted checks do **not** read large JSON files into the conversation.
79
+ **DO:** First check whether the generated onboarding files match the installed npm package. If any
80
+ entry is \`outdated\` or \`missing\`, tell the user to run \`agent-inspector onboard --force\` before
81
+ continuing so they are not guided by stale instructions.
82
+
83
+ \`\`\`bash
84
+ agent-inspector onboard --status
85
+ \`\`\`
86
+
87
+ \`\`\`powershell
88
+ agent-inspector onboard --status
89
+ \`\`\`
90
+
91
+ **DO:** Then probe the three pieces of state this skill touches. Use targeted checks — do **not** read large JSON files into the conversation.
80
92
 
81
93
  \`\`\`bash
82
94
  # 1. Is the proxy already up?
@@ -226,11 +238,13 @@ if ($null) { Write-Host 'claude-code: present' } else { Write-Host 'claude-code:
226
238
  \`\`\`
227
239
  ## Welcome to Agent Inspector!
228
240
 
229
- Agent Inspector is an agent observability and knowledge-capture platform for AI coding tools. The \`agent-inspector\` CLI runs a transparent local proxy + Web UI, so you can see every model request and response: system prompts, tool definitions, message history, SSE streaming chunks, and token counts captured live in a browser tab.
241
+ Agent Inspector is an agent observability and knowledge-capture platform for AI coding tools. The \`agent-inspector\` CLI runs a transparent local proxy + Web UI, so you can see model requests and responses, system prompts, tool definitions, message history, timing, and token counts captured live in a browser tab.
242
+
243
+ Agent Inspector starts in **Simple mode** by default. Simple mode is the right habit for everyday use: it keeps requests, responses, tools, timing, and token usage while avoiding heavier raw headers, raw response, and detailed SSE chunk artifacts. Use **Full mode** only when the user is debugging provider headers, raw response payloads, or SSE stream details.
230
244
 
231
245
  **What we'll do in the next ~10 minutes:**
232
246
  1. Add your first LLM provider (Anthropic or OpenAI key)
233
- 2. Start the proxy
247
+ 2. Start the proxy in Simple mode
234
248
  3. Wire your AI tool to use it
235
249
  4. Capture a first request end-to-end
236
250
  5. Tour the key UI affordances
@@ -346,7 +360,7 @@ $json | Set-Content -Path $file -Encoding UTF8
346
360
 
347
361
  ## Phase 3: Start proxy
348
362
 
349
- **EXPLAIN:** "Time to start the proxy. It binds to port ${port} by default, reuses an already-running healthy agent-inspector, and prints the URL. Use \`--force-restart\` only when you intentionally want to replace the existing process."
363
+ **EXPLAIN:** "Time to start the proxy. It binds to port ${port} by default, starts in Simple mode for lower overhead, reuses an already-running healthy agent-inspector, and prints the URL. Use \`--force-restart\` only when you intentionally want to replace the existing process. If the user is diagnosing raw headers, raw response, or SSE chunks, restart with \`agent-inspector --mode full\`."
350
364
 
351
365
  **DO:** Skip this phase entirely if the Phase 0 health check already reported \`PROXY: up\` and the user opted to skip done phases.
352
366
 
@@ -354,7 +368,7 @@ $json | Set-Content -Path $file -Encoding UTF8
354
368
 
355
369
  \`\`\`bash
356
370
  # Unix / macOS / WSL
357
- agent-inspector --background --no-open > /tmp/agent-inspector.log 2>&1
371
+ agent-inspector --mode simple --background --no-open > /tmp/agent-inspector.log 2>&1
358
372
  \`\`\`
359
373
 
360
374
  \`\`\`powershell
@@ -367,14 +381,14 @@ $err = Join-Path $env:TEMP 'agent-inspector.err.log'
367
381
  $found = Get-Command agent-inspector -ErrorAction SilentlyContinue
368
382
  if ($found) {
369
383
  $shim = $found.Source
370
- $args = '--background','--no-open'
384
+ $args = '--mode','simple','--background','--no-open'
371
385
  } elseif (Test-Path (Join-Path $env:APPDATA 'npm/agent-inspector.cmd')) {
372
386
  $shim = Join-Path $env:APPDATA 'npm/agent-inspector.cmd'
373
- $args = '--background','--no-open'
387
+ $args = '--mode','simple','--background','--no-open'
374
388
  } else {
375
389
  # bin not on PATH and not at the default npm prefix — let cmd resolve it
376
390
  $shim = 'cmd.exe'
377
- $args = '/c','agent-inspector','--background','--no-open'
391
+ $args = '/c','agent-inspector','--mode','simple','--background','--no-open'
378
392
  }
379
393
  Start-Process -FilePath $shim -ArgumentList $args -RedirectStandardOutput $log -RedirectStandardError $err -WindowStyle Hidden
380
394
  \`\`\`
@@ -394,6 +408,12 @@ done
394
408
  curl -sS "http://localhost:${port}/api/health"
395
409
  \`\`\`
396
410
 
411
+ **DO:** Read \`/api/config\` and tell the user which capture mode is active. If it is not \`simple\` during onboarding, explain that an existing process is already running and offer to restart with \`agent-inspector --mode simple --force-restart\`.
412
+
413
+ \`\`\`bash
414
+ curl -sS "http://localhost:${port}/api/config" | grep -o '"captureMode":"[^"]*"'
415
+ \`\`\`
416
+
397
417
  > **PAUSE** — if the health check fails, show the user the log file (\`/tmp/agent-inspector.log\` or \`%TEMP%\\agent-inspector.log\`) and diagnose. Common issues: another process on the port, firewall, missing providers. Use \`AskUserQuestion\` with header \`Proxy up?\` and options \`["Yes, proxy is up", "No, I see an error in the log"]\`. Wait for the answer.
398
418
 
399
419
  ---
@@ -538,6 +558,8 @@ done
538
558
  \`\`\`
539
559
 
540
560
  - **Re-run onboard**: \`agent-inspector onboard --force\` refreshes this skill.
561
+ - **Check onboard files**: \`agent-inspector onboard --status\` shows whether generated skills are
562
+ current, outdated, missing, newer, or custom.
541
563
  - **Full docs**: see the project README (linked from the Web UI footer).
542
564
 
543
565
  > **PAUSE** — use \`AskUserQuestion\` with header \`All set?\` and options \`["All set, I'm done", "Wait, I want to revisit a phase"]\`. Wait for the answer.
@@ -7,10 +7,12 @@ import { useOnboarding } from "../lib/useOnboarding";
7
7
  * dismissal through the server runtime config.
8
8
  */
9
9
  export function OnboardingBanner(): JSX.Element | null {
10
- const { hasSeenOnboarding, isLoading, markSeen } = useOnboarding();
10
+ const { hasSeenOnboarding, captureMode, isLoading, markSeen } = useOnboarding();
11
11
 
12
12
  if (isLoading || hasSeenOnboarding) return null;
13
13
 
14
+ const isFullMode = captureMode === "full";
15
+
14
16
  return (
15
17
  <div
16
18
  role="note"
@@ -19,17 +21,43 @@ export function OnboardingBanner(): JSX.Element | null {
19
21
  >
20
22
  <div className="min-w-0 flex-1">
21
23
  <div className="mb-1 font-medium text-amber-600 dark:text-amber-400">
22
- Agent Inspector is ready
24
+ {isFullMode
25
+ ? "Agent Inspector is ready in Full mode"
26
+ : "Agent Inspector is ready in Simple mode"}
23
27
  </div>
24
28
  <ul className="space-y-0.5 text-xs leading-relaxed text-muted-foreground">
29
+ {isFullMode ? (
30
+ <>
31
+ <li>
32
+ <strong>Full mode</strong>: raw headers, raw response, and SSE chunks are captured
33
+ for diagnostics.
34
+ </li>
35
+ <li>
36
+ <strong>Daily work</strong>: restart with <code>agent-inspector --mode simple</code>{" "}
37
+ to reduce capture overhead.
38
+ </li>
39
+ </>
40
+ ) : (
41
+ <>
42
+ <li>
43
+ <strong>Simple mode</strong>: lightweight capture for requests, responses, tools,
44
+ timing, and token usage.
45
+ </li>
46
+ <li>
47
+ <strong>Need diagnostics?</strong> Restart with{" "}
48
+ <code>agent-inspector --mode full</code> for raw headers, raw response, and SSE
49
+ chunks.
50
+ </li>
51
+ </>
52
+ )}
25
53
  <li>
26
- <strong>Trace</strong>: requests, responses, streaming chunks, tools, and timing.
27
- </li>
28
- <li>
29
- <strong>Replay</strong>: resend captured requests and compare provider behavior.
54
+ <strong>Replay and Memory</strong>: available in both modes for provider checks and
55
+ reviewable knowledge candidates.
30
56
  </li>
31
57
  <li>
32
- <strong>Memory</strong>: create reviewable candidates before promotion to OpenClaw.
58
+ <strong>Agent setup</strong>: run <code>agent-inspector onboard --status</code>, then
59
+ use <code>/agent-inspector:onboard</code> in Claude Code or ask Codex to use{" "}
60
+ <code>agent-inspector-onboard</code>.
33
61
  </li>
34
62
  </ul>
35
63
  </div>
@@ -75,7 +75,7 @@ export function SettingsDialog(): JSX.Element {
75
75
  <TabsTrigger value="onboarding">Onboarding</TabsTrigger>
76
76
  </TabsList>
77
77
 
78
- <div className="mt-4 overflow-y-auto flex-1 pr-3">
78
+ <div className="mt-4 flex-1 overflow-x-hidden overflow-y-auto pr-3">
79
79
  <TabsContent value="providers">
80
80
  <ProvidersPanel
81
81
  externalProviders={providers}
@@ -119,7 +119,7 @@ function CopyableSetupValue({
119
119
  }): JSX.Element {
120
120
  const copied = copiedId === id;
121
121
  return (
122
- <div className="rounded-md border border-border bg-muted/20 px-3 py-2">
122
+ <div className="min-w-0 rounded-md border border-border bg-muted/20 px-3 py-2">
123
123
  <div className="mb-1 text-xs font-medium text-muted-foreground">{label}</div>
124
124
  <div className="flex min-w-0 items-center gap-2">
125
125
  <code className="min-w-0 flex-1 truncate font-mono text-xs text-foreground">{value}</code>
@@ -146,10 +146,28 @@ function OnboardingSettingsTab(): JSX.Element {
146
146
  }, []);
147
147
  const values = useMemo(
148
148
  () => [
149
- { id: "skill", label: "Codex skill", value: "agent-inspector onboard --force" },
149
+ { id: "status", label: "Check onboarding", value: "agent-inspector onboard --status" },
150
+ {
151
+ id: "status-json",
152
+ label: "Check onboarding JSON",
153
+ value: "agent-inspector onboard --status --json",
154
+ },
155
+ { id: "refresh", label: "Refresh generated files", value: "agent-inspector onboard --force" },
156
+ {
157
+ id: "uninstall",
158
+ label: "Remove matching generated files",
159
+ value: "agent-inspector onboard --uninstall",
160
+ },
161
+ { id: "claude", label: "Claude Code command", value: "/agent-inspector:onboard" },
162
+ {
163
+ id: "codex",
164
+ label: "Codex prompt",
165
+ value: "Use the agent-inspector-onboard skill",
166
+ },
150
167
  { id: "mcp", label: "MCP URL", value: `${origin}/api/mcp` },
151
168
  { id: "proxy", label: "Proxy URL", value: `${origin}/proxy` },
152
169
  { id: "anthropic", label: "Anthropic base", value: `ANTHROPIC_BASE_URL=${origin}/proxy` },
170
+ { id: "openai", label: "OpenAI base", value: `OPENAI_BASE_URL=${origin}/proxy` },
153
171
  ],
154
172
  [origin],
155
173
  );
@@ -162,7 +180,7 @@ function OnboardingSettingsTab(): JSX.Element {
162
180
  }, []);
163
181
 
164
182
  return (
165
- <div className="space-y-4">
183
+ <div className="min-w-0 space-y-4">
166
184
  <div className="flex items-center gap-2">
167
185
  <Terminal className="size-4 text-muted-foreground" />
168
186
  <h3 className="text-sm font-semibold">Agent onboarding</h3>
@@ -1,14 +1,18 @@
1
1
  import useSWR, { type SWRResponse, useSWRConfig } from "swr";
2
2
  import { fetchJson } from "./apiClient";
3
3
  import {
4
+ DEFAULT_CAPTURE_MODE,
4
5
  DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
5
6
  DEFAULT_TIME_DISPLAY_FORMAT,
6
7
  RuntimeConfigSchema,
8
+ type CaptureMode,
7
9
  type RuntimeConfig,
8
10
  } from "./runtimeConfig";
9
11
 
10
12
  export const ONBOARDING_SWR_KEY = "/api/config";
11
13
 
14
+ type RuntimeConfigPatch = Partial<Omit<RuntimeConfig, "captureMode">>;
15
+
12
16
  async function fetcher(url: string): Promise<RuntimeConfig> {
13
17
  return fetchJson(
14
18
  url,
@@ -18,7 +22,7 @@ async function fetcher(url: string): Promise<RuntimeConfig> {
18
22
  );
19
23
  }
20
24
 
21
- async function patchRuntimeConfig(patch: Partial<RuntimeConfig>): Promise<RuntimeConfig> {
25
+ async function patchRuntimeConfig(patch: RuntimeConfigPatch): Promise<RuntimeConfig> {
22
26
  return fetchJson(
23
27
  ONBOARDING_SWR_KEY,
24
28
  RuntimeConfigSchema,
@@ -33,6 +37,7 @@ async function patchRuntimeConfig(patch: Partial<RuntimeConfig>): Promise<Runtim
33
37
 
34
38
  export type UseOnboarding = {
35
39
  hasSeenOnboarding: boolean;
40
+ captureMode: CaptureMode;
36
41
  isLoading: boolean;
37
42
  markSeen: () => Promise<void>;
38
43
  };
@@ -59,6 +64,7 @@ export function useOnboarding(): UseOnboarding {
59
64
  const { mutate: globalMutate } = useSWRConfig();
60
65
 
61
66
  const hasSeenOnboarding = response.data?.hasSeenOnboarding ?? false;
67
+ const captureMode = response.data?.captureMode ?? DEFAULT_CAPTURE_MODE;
62
68
 
63
69
  const markSeen = async (): Promise<void> => {
64
70
  await globalMutate(ONBOARDING_SWR_KEY, patchRuntimeConfig({ hasSeenOnboarding: true }), {
@@ -68,6 +74,7 @@ export function useOnboarding(): UseOnboarding {
68
74
  slowResponseThresholdSeconds:
69
75
  response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
70
76
  timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
77
+ captureMode,
71
78
  },
72
79
  rollbackOnError: true,
73
80
  revalidate: false,
@@ -76,6 +83,7 @@ export function useOnboarding(): UseOnboarding {
76
83
 
77
84
  return {
78
85
  hasSeenOnboarding,
86
+ captureMode,
79
87
  isLoading: response.isLoading,
80
88
  markSeen,
81
89
  };
@@ -1 +0,0 @@
1
- import{R as s,j as e}from"./main-Biir9ZGe.js";import{P as i}from"./ProxyViewerContainer-CofGRJoO.js";function t(){const{sessionId:o}=s.useParams();return e.jsx(i,{initialSessionId:o},o)}export{t as component};
@@ -1 +0,0 @@
1
- import{P as o}from"./ProxyViewerContainer-CofGRJoO.js";import"./main-Biir9ZGe.js";const r=o;export{r as component};
@@ -1,38 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { dirname, join } from "node:path";
4
- import { spawnSync } from "node:child_process";
5
- import { fileURLToPath } from "node:url";
6
-
7
- const scriptDir = dirname(fileURLToPath(import.meta.url));
8
- const packageRoot = dirname(scriptDir);
9
- const cliEntry = join(packageRoot, ".output", "cli.js");
10
- const codexHome = process.env["CODEX_HOME"] ?? join(homedir(), ".codex");
11
-
12
- function shouldSkip() {
13
- return (
14
- process.env["AGENT_INSPECTOR_SKIP_CODEX_SKILL"] === "1" ||
15
- !existsSync(cliEntry) ||
16
- (!existsSync(codexHome) && process.env["AGENT_INSPECTOR_INSTALL_CODEX_SKILL"] !== "1")
17
- );
18
- }
19
-
20
- function main() {
21
- if (shouldSkip()) return;
22
-
23
- const result = spawnSync(process.execPath, [cliEntry, "onboard", "--codex-only"], {
24
- stdio: "ignore",
25
- windowsHide: true,
26
- });
27
-
28
- if (result.status !== 0) {
29
- console.warn("Skipping Codex onboard skill installation.");
30
- }
31
- }
32
-
33
- try {
34
- main();
35
- } catch (error) {
36
- const message = error instanceof Error ? error.message : String(error);
37
- console.warn(`Skipping Codex onboard skill installation: ${message}`);
38
- }