@tonyclaw/llm-inspector 1.18.2 → 1.19.1
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 +903 -139
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-C-4ypEWs.js → CompareDrawer-DtERUdIt.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-DfxRK7Nt.js +101 -0
- package/.output/public/assets/{ReplayDialog-CyBKOgba.js → ReplayDialog-VMsGnJSI.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-C0IrVQ3q.js → RequestAnatomy-Cx_vluvK.js} +1 -1
- package/.output/public/assets/{ResponseView-MogToC4i.js → ResponseView-5F8Ms5z4.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-ClhUhT-s.js → StreamingChunkSequence-CKDCWfu9.js} +1 -1
- package/.output/public/assets/_sessionId-C-aKd1Ky.js +1 -0
- package/.output/public/assets/index-B8ttyigz.js +1 -0
- package/.output/public/assets/index-DeJyypsp.css +1 -0
- package/.output/public/assets/{json-viewer-BicGakI5.js → json-viewer-CztuZ9cT.js} +2 -2
- package/.output/public/assets/{main-Be2qqUUW.js → main-CR9IJlz1.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +93 -72
- package/.output/server/{_sessionId-DhKJIdQC.mjs → _sessionId-DvWQaDEm.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-BGUgukJ8.mjs → CompareDrawer-C5FsxSDS.mjs} +4 -4
- package/.output/server/_ssr/{ProxyViewerContainer--3K3o3Sm.mjs → ProxyViewerContainer-v0cvR8f5.mjs} +354 -343
- package/.output/server/_ssr/{ReplayDialog-Bo86xZI4.mjs → ReplayDialog-C3KOv9OW.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-jRU5qgwB.mjs → RequestAnatomy-BYRe33eG.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-DdO_-79a.mjs → ResponseView-va7yQDeL.mjs} +4 -4
- package/.output/server/_ssr/{StreamingChunkSequence-BigLwhh4.mjs → StreamingChunkSequence-BJlI-gWl.mjs} +3 -3
- package/.output/server/_ssr/{index-BHG6vOnr.mjs → index-CS0fA2GT.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-B4c_WjXD.mjs → json-viewer-Dg8rqrxL.mjs} +9 -5
- package/.output/server/_ssr/{router-DVixpJO-.mjs → router-D_Boe9Bu.mjs} +3 -3
- package/.output/server/{_tanstack-start-manifest_v-BbvWUF4v.mjs → _tanstack-start-manifest_v-KFXyNRGC.mjs} +1 -1
- package/.output/server/index.mjs +65 -65
- package/package.json +2 -1
- package/src/cli/detect-tools.ts +146 -0
- package/src/cli/onboard.ts +229 -0
- package/src/cli/templates/command-onboard.ts +17 -0
- package/src/cli/templates/skill-onboard.ts +458 -0
- package/src/cli.ts +193 -163
- package/src/components/ProxyViewer.tsx +153 -142
- package/src/components/proxy-viewer/LogEntry.tsx +136 -157
- package/src/components/proxy-viewer/LogEntryHeader.tsx +147 -66
- package/src/components/proxy-viewer/useCopyFeedback.ts +36 -0
- package/src/components/ui/json-viewer.tsx +12 -0
- package/.output/public/assets/ProxyViewerContainer-WRenRpeh.js +0 -101
- package/.output/public/assets/_sessionId-BO47oA3Z.js +0 -1
- package/.output/public/assets/index-BRvz6-L6.css +0 -1
- package/.output/public/assets/index-Btw8ec7-.js +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { D as Dialog, b as DialogContent, d as DialogHeader, e as DialogTitle, T as Tabs, h as TabsList, i as TabsTrigger, j as TabsContent, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent, o as Button } from "./ProxyViewerContainer
|
|
3
|
-
import { ResponseView } from "./ResponseView-
|
|
4
|
-
import "./router-
|
|
2
|
+
import { D as Dialog, b as DialogContent, d as DialogHeader, e as DialogTitle, T as Tabs, h as TabsList, i as TabsTrigger, j as TabsContent, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent, o as Button } from "./ProxyViewerContainer-v0cvR8f5.mjs";
|
|
3
|
+
import { ResponseView } from "./ResponseView-va7yQDeL.mjs";
|
|
4
|
+
import "./router-D_Boe9Bu.mjs";
|
|
5
5
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
6
6
|
import "../_libs/jszip.mjs";
|
|
7
|
-
import "./json-viewer-
|
|
7
|
+
import "./json-viewer-Dg8rqrxL.mjs";
|
|
8
8
|
import { s as RotateCcw } from "../_libs/lucide-react.mjs";
|
|
9
9
|
import { d as object, c as boolean, n as number, b as string } from "../_libs/zod.mjs";
|
|
10
10
|
import "../_libs/swr.mjs";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { k as TooltipProvider, f as formatTokens, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer
|
|
3
|
-
import "./router-
|
|
2
|
+
import { k as TooltipProvider, f as formatTokens, c as cn, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-v0cvR8f5.mjs";
|
|
3
|
+
import "./router-D_Boe9Bu.mjs";
|
|
4
4
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
5
5
|
import "../_libs/jszip.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { Q as Info } from "../_libs/lucide-react.mjs";
|
|
7
7
|
import "../_libs/swr.mjs";
|
|
8
8
|
import "../_libs/use-sync-external-store.mjs";
|
|
9
9
|
import "../_libs/dequal.mjs";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { g as getLogFormatAdapter, f as formatTokens, c as cn, p as getStatusCategory, B as Badge, s as safeJsonValue } from "./ProxyViewerContainer
|
|
3
|
-
import { JsonViewer } from "./json-viewer-
|
|
4
|
-
import "./router-
|
|
2
|
+
import { g as getLogFormatAdapter, f as formatTokens, c as cn, p as getStatusCategory, B as Badge, s as safeJsonValue } from "./ProxyViewerContainer-v0cvR8f5.mjs";
|
|
3
|
+
import { JsonViewer } from "./json-viewer-Dg8rqrxL.mjs";
|
|
4
|
+
import "./router-D_Boe9Bu.mjs";
|
|
5
5
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
6
6
|
import "../_libs/jszip.mjs";
|
|
7
|
-
import { Z as Zap, i as TriangleAlert,
|
|
7
|
+
import { Z as Zap, i as TriangleAlert, V as CircleStop, Y as Brain, b as ChevronDown, f as ChevronRight, _ as Terminal } from "../_libs/lucide-react.mjs";
|
|
8
8
|
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
9
9
|
import { R as Root } from "../_libs/radix-ui__react-separator.mjs";
|
|
10
10
|
import { R as Root$1, C as CollapsibleTrigger$1, a as CollapsibleContent$1 } from "../_libs/radix-ui__react-collapsible.mjs";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { k as TooltipProvider, l as Tooltip, m as TooltipTrigger, B as Badge, n as TooltipContent } from "./ProxyViewerContainer
|
|
3
|
-
import { JsonViewer } from "./json-viewer-
|
|
4
|
-
import "./router-
|
|
2
|
+
import { k as TooltipProvider, l as Tooltip, m as TooltipTrigger, B as Badge, n as TooltipContent } from "./ProxyViewerContainer-v0cvR8f5.mjs";
|
|
3
|
+
import { JsonViewer } from "./json-viewer-Dg8rqrxL.mjs";
|
|
4
|
+
import "./router-D_Boe9Bu.mjs";
|
|
5
5
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
6
6
|
import "../_libs/jszip.mjs";
|
|
7
7
|
import { b as ChevronDown, f as ChevronRight, L as LoaderCircle } from "../_libs/lucide-react.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as ProxyViewerContainer } from "./ProxyViewerContainer
|
|
1
|
+
import { P as ProxyViewerContainer } from "./ProxyViewerContainer-v0cvR8f5.mjs";
|
|
2
2
|
import "../_libs/react.mjs";
|
|
3
|
-
import "./router-
|
|
3
|
+
import "./router-D_Boe9Bu.mjs";
|
|
4
4
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
5
5
|
import "../_libs/jszip.mjs";
|
|
6
6
|
import "../_libs/swr.mjs";
|
|
@@ -198,7 +198,7 @@ function getResponse() {
|
|
|
198
198
|
return event.res;
|
|
199
199
|
}
|
|
200
200
|
async function getStartManifest(matchedRoutes) {
|
|
201
|
-
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-
|
|
201
|
+
const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-KFXyNRGC.mjs");
|
|
202
202
|
const startManifest = tsrStartManifest();
|
|
203
203
|
const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
|
|
204
204
|
rootRoute.assets = rootRoute.assets || [];
|
|
@@ -767,7 +767,7 @@ let entriesPromise;
|
|
|
767
767
|
let baseManifestPromise;
|
|
768
768
|
let cachedFinalManifestPromise;
|
|
769
769
|
async function loadEntries() {
|
|
770
|
-
const routerEntry = await import("./router-
|
|
770
|
+
const routerEntry = await import("./router-D_Boe9Bu.mjs").then((n) => n.f);
|
|
771
771
|
const startEntry = await import("./start-HYkvq4Ni.mjs");
|
|
772
772
|
return { startEntry, routerEntry };
|
|
773
773
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
2
|
-
import { q as parseJsonText, c as cn, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer
|
|
3
|
-
import "./router-
|
|
2
|
+
import { q as parseJsonText, c as cn, k as TooltipProvider, l as Tooltip, m as TooltipTrigger, n as TooltipContent } from "./ProxyViewerContainer-v0cvR8f5.mjs";
|
|
3
|
+
import "./router-D_Boe9Bu.mjs";
|
|
4
4
|
import "../_libs/modelcontextprotocol__server.mjs";
|
|
5
5
|
import "../_libs/jszip.mjs";
|
|
6
|
-
import { C as Check, a as Copy, b as ChevronDown, f as ChevronRight,
|
|
6
|
+
import { C as Check, a as Copy, b as ChevronDown, f as ChevronRight, q as ChevronsDown } from "../_libs/lucide-react.mjs";
|
|
7
7
|
import { M as Markdown } from "../_libs/react-markdown.mjs";
|
|
8
8
|
import "../_libs/swr.mjs";
|
|
9
9
|
import "../_libs/use-sync-external-store.mjs";
|
|
@@ -490,7 +490,9 @@ function JsonViewer({
|
|
|
490
490
|
const JsonViewerFromString = reactExports.memo(function JsonViewerFromString2({
|
|
491
491
|
text,
|
|
492
492
|
defaultExpandDepth = 0,
|
|
493
|
-
className
|
|
493
|
+
className,
|
|
494
|
+
bulkDepth,
|
|
495
|
+
bulkRevision
|
|
494
496
|
}) {
|
|
495
497
|
const parsed = reactExports.useMemo(() => parseJsonText(text), [text]);
|
|
496
498
|
if (parsed.kind === "json") {
|
|
@@ -499,7 +501,9 @@ const JsonViewerFromString = reactExports.memo(function JsonViewerFromString2({
|
|
|
499
501
|
{
|
|
500
502
|
data: parsed.data,
|
|
501
503
|
defaultExpandDepth,
|
|
502
|
-
className
|
|
504
|
+
className,
|
|
505
|
+
bulkDepth,
|
|
506
|
+
bulkRevision
|
|
503
507
|
}
|
|
504
508
|
);
|
|
505
509
|
}
|
|
@@ -47,7 +47,7 @@ import "../_libs/debounce-fn.mjs";
|
|
|
47
47
|
import "../_libs/mimic-function.mjs";
|
|
48
48
|
import "../_libs/semver.mjs";
|
|
49
49
|
import "../_libs/uint8array-extras.mjs";
|
|
50
|
-
const appCss = "/assets/index-
|
|
50
|
+
const appCss = "/assets/index-DeJyypsp.css";
|
|
51
51
|
const Route$l = createRootRoute({
|
|
52
52
|
head: () => ({
|
|
53
53
|
meta: [
|
|
@@ -71,7 +71,7 @@ function RootDocument({ children }) {
|
|
|
71
71
|
] })
|
|
72
72
|
] });
|
|
73
73
|
}
|
|
74
|
-
const $$splitComponentImporter$1 = () => import("./index-
|
|
74
|
+
const $$splitComponentImporter$1 = () => import("./index-CS0fA2GT.mjs");
|
|
75
75
|
const Route$k = createFileRoute("/")({
|
|
76
76
|
component: lazyRouteComponent($$splitComponentImporter$1, "component")
|
|
77
77
|
});
|
|
@@ -114,7 +114,7 @@ function decodeSessionIdFromPath(encoded) {
|
|
|
114
114
|
function getSessionPath(sessionId) {
|
|
115
115
|
return `/session/${encodeSessionIdForPath(sessionId)}`;
|
|
116
116
|
}
|
|
117
|
-
const $$splitComponentImporter = () => import("../_sessionId-
|
|
117
|
+
const $$splitComponentImporter = () => import("../_sessionId-DvWQaDEm.mjs");
|
|
118
118
|
const Route$j = createFileRoute("/session/$sessionId")({
|
|
119
119
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
120
120
|
parseParams: (params) => ({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/session/$sessionId"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/session/$sessionId"], "preloads": ["/assets/main-CR9IJlz1.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-B8ttyigz.js", "/assets/ProxyViewerContainer-DfxRK7Nt.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/mcp": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/mcp.ts" }, "/api/models": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId", "/api/providers/export", "/api/providers/import", "/api/providers/scan"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/proxy/$.ts" }, "/session/$sessionId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/session/$sessionId.tsx", "assets": [], "preloads": ["/assets/_sessionId-C-aKd1Ky.js", "/assets/ProxyViewerContainer-DfxRK7Nt.js"] }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/config.paths.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.import.ts" }, "/api/providers/scan": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.scan.ts" }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.ts", "children": ["/api/providers/$providerId/test/log"] }, "/api/providers/$providerId/test/log": { "filePath": "C:/Users/claw/workspace/llm-inspector/src/routes/api/providers.$providerId.test.log.ts" } }, "clientEntry": "/assets/main-CR9IJlz1.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -35,110 +35,110 @@ const headers = ((m) => function headersRouteRule(event) {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
const assets = {
|
|
38
|
-
"/assets/
|
|
39
|
-
"type": "image/svg+xml",
|
|
40
|
-
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
41
|
-
"mtime": "2026-06-17T09:08:04.357Z",
|
|
42
|
-
"size": 5915,
|
|
43
|
-
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
44
|
-
},
|
|
45
|
-
"/assets/index-Btw8ec7-.js": {
|
|
46
|
-
"type": "text/javascript; charset=utf-8",
|
|
47
|
-
"etag": '"74-Si+LSldyx0r6eyhCKLBrfEnEPe8"',
|
|
48
|
-
"mtime": "2026-06-17T09:08:04.357Z",
|
|
49
|
-
"size": 116,
|
|
50
|
-
"path": "../public/assets/index-Btw8ec7-.js"
|
|
51
|
-
},
|
|
52
|
-
"/assets/index-BRvz6-L6.css": {
|
|
53
|
-
"type": "text/css; charset=utf-8",
|
|
54
|
-
"etag": '"17492-JL6LQ7LktE+Z13FtWdf220LM1h4"',
|
|
55
|
-
"mtime": "2026-06-17T09:08:04.357Z",
|
|
56
|
-
"size": 95378,
|
|
57
|
-
"path": "../public/assets/index-BRvz6-L6.css"
|
|
58
|
-
},
|
|
59
|
-
"/assets/CompareDrawer-C-4ypEWs.js": {
|
|
38
|
+
"/assets/CompareDrawer-DtERUdIt.js": {
|
|
60
39
|
"type": "text/javascript; charset=utf-8",
|
|
61
|
-
"etag": '"4a1f-
|
|
62
|
-
"mtime": "2026-06-
|
|
40
|
+
"etag": '"4a1f-iUikoccqSI5dxDV/DitC+V4SyF4"',
|
|
41
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
63
42
|
"size": 18975,
|
|
64
|
-
"path": "../public/assets/CompareDrawer-
|
|
43
|
+
"path": "../public/assets/CompareDrawer-DtERUdIt.js"
|
|
65
44
|
},
|
|
66
45
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
67
46
|
"type": "image/jpeg",
|
|
68
47
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
69
|
-
"mtime": "2026-06-
|
|
48
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
70
49
|
"size": 6918,
|
|
71
50
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
72
51
|
},
|
|
73
|
-
"/assets/
|
|
52
|
+
"/assets/index-B8ttyigz.js": {
|
|
74
53
|
"type": "text/javascript; charset=utf-8",
|
|
75
|
-
"etag": '"
|
|
76
|
-
"mtime": "2026-06-
|
|
77
|
-
"size":
|
|
78
|
-
"path": "../public/assets/
|
|
54
|
+
"etag": '"74-b0SfzNSVRwMMxI9rB/BBMzOdSls"',
|
|
55
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
56
|
+
"size": 116,
|
|
57
|
+
"path": "../public/assets/index-B8ttyigz.js"
|
|
79
58
|
},
|
|
80
|
-
"/assets/
|
|
59
|
+
"/assets/json-viewer-CztuZ9cT.js": {
|
|
81
60
|
"type": "text/javascript; charset=utf-8",
|
|
82
|
-
"etag": '"
|
|
83
|
-
"mtime": "2026-06-
|
|
84
|
-
"size":
|
|
85
|
-
"path": "../public/assets/
|
|
61
|
+
"etag": '"1e651-ZXyBYCz6WZX+FFKagLcAEHfl5xM"',
|
|
62
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
63
|
+
"size": 124497,
|
|
64
|
+
"path": "../public/assets/json-viewer-CztuZ9cT.js"
|
|
86
65
|
},
|
|
87
|
-
"/assets/
|
|
88
|
-
"type": "text/
|
|
89
|
-
"etag": '"
|
|
90
|
-
"mtime": "2026-06-
|
|
91
|
-
"size":
|
|
92
|
-
"path": "../public/assets/
|
|
66
|
+
"/assets/index-DeJyypsp.css": {
|
|
67
|
+
"type": "text/css; charset=utf-8",
|
|
68
|
+
"etag": '"17504-zMXz49VysEK/ru01MvYLc8/SiPI"',
|
|
69
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
70
|
+
"size": 95492,
|
|
71
|
+
"path": "../public/assets/index-DeJyypsp.css"
|
|
93
72
|
},
|
|
94
|
-
"/assets/RequestAnatomy-
|
|
73
|
+
"/assets/RequestAnatomy-Cx_vluvK.js": {
|
|
95
74
|
"type": "text/javascript; charset=utf-8",
|
|
96
|
-
"etag": '"142a-
|
|
97
|
-
"mtime": "2026-06-
|
|
75
|
+
"etag": '"142a-Yhymkf38kgBJoPDw4VNi/Dr6f+k"',
|
|
76
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
98
77
|
"size": 5162,
|
|
99
|
-
"path": "../public/assets/RequestAnatomy-
|
|
78
|
+
"path": "../public/assets/RequestAnatomy-Cx_vluvK.js"
|
|
100
79
|
},
|
|
101
|
-
"/assets/
|
|
80
|
+
"/assets/ResponseView-5F8Ms5z4.js": {
|
|
102
81
|
"type": "text/javascript; charset=utf-8",
|
|
103
|
-
"etag": '"
|
|
104
|
-
"mtime": "2026-06-
|
|
82
|
+
"etag": '"6e91-th7Dsd8aj+055p7AR8JrAwuhP30"',
|
|
83
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
84
|
+
"size": 28305,
|
|
85
|
+
"path": "../public/assets/ResponseView-5F8Ms5z4.js"
|
|
86
|
+
},
|
|
87
|
+
"/assets/StreamingChunkSequence-CKDCWfu9.js": {
|
|
88
|
+
"type": "text/javascript; charset=utf-8",
|
|
89
|
+
"etag": '"d81-j+RBgIkb3QoxK8obtxQiGw8pId4"',
|
|
90
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
105
91
|
"size": 3457,
|
|
106
|
-
"path": "../public/assets/StreamingChunkSequence-
|
|
92
|
+
"path": "../public/assets/StreamingChunkSequence-CKDCWfu9.js"
|
|
107
93
|
},
|
|
108
94
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
109
95
|
"type": "image/svg+xml",
|
|
110
96
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
111
|
-
"mtime": "2026-06-
|
|
97
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
112
98
|
"size": 11256,
|
|
113
99
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
114
100
|
},
|
|
115
|
-
"/assets/_sessionId-
|
|
101
|
+
"/assets/_sessionId-C-aKd1Ky.js": {
|
|
116
102
|
"type": "text/javascript; charset=utf-8",
|
|
117
|
-
"etag": '"d2-
|
|
118
|
-
"mtime": "2026-06-
|
|
103
|
+
"etag": '"d2-gL7mjPIXj+6BHz4XUVVdKjuvNDk"',
|
|
104
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
119
105
|
"size": 210,
|
|
120
|
-
"path": "../public/assets/_sessionId-
|
|
106
|
+
"path": "../public/assets/_sessionId-C-aKd1Ky.js"
|
|
121
107
|
},
|
|
122
|
-
"/assets/main-
|
|
108
|
+
"/assets/main-CR9IJlz1.js": {
|
|
123
109
|
"type": "text/javascript; charset=utf-8",
|
|
124
|
-
"etag": '"50a37-
|
|
125
|
-
"mtime": "2026-06-
|
|
110
|
+
"etag": '"50a37-XeRUA7+G6lgGxJXRg+juq8ZZbMM"',
|
|
111
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
126
112
|
"size": 330295,
|
|
127
|
-
"path": "../public/assets/main-
|
|
113
|
+
"path": "../public/assets/main-CR9IJlz1.js"
|
|
114
|
+
},
|
|
115
|
+
"/assets/alibaba-TTwafVwX.svg": {
|
|
116
|
+
"type": "image/svg+xml",
|
|
117
|
+
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
118
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
119
|
+
"size": 5915,
|
|
120
|
+
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
121
|
+
},
|
|
122
|
+
"/assets/ProxyViewerContainer-DfxRK7Nt.js": {
|
|
123
|
+
"type": "text/javascript; charset=utf-8",
|
|
124
|
+
"etag": '"76d0d-d2XlfO92n/Dltmn6NOHQY/Ui+fw"',
|
|
125
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
126
|
+
"size": 486669,
|
|
127
|
+
"path": "../public/assets/ProxyViewerContainer-DfxRK7Nt.js"
|
|
128
128
|
},
|
|
129
129
|
"/assets/qwen-CONDcHqt.png": {
|
|
130
130
|
"type": "image/png",
|
|
131
131
|
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
132
|
-
"mtime": "2026-06-
|
|
132
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
133
133
|
"size": 357059,
|
|
134
134
|
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
135
135
|
},
|
|
136
|
-
"/assets/
|
|
136
|
+
"/assets/ReplayDialog-VMsGnJSI.js": {
|
|
137
137
|
"type": "text/javascript; charset=utf-8",
|
|
138
|
-
"etag": '"
|
|
139
|
-
"mtime": "2026-06-
|
|
140
|
-
"size":
|
|
141
|
-
"path": "../public/assets/
|
|
138
|
+
"etag": '"11c0-t7Uuk+IRrGGdj7fX41f/Jt6J41I"',
|
|
139
|
+
"mtime": "2026-06-18T01:14:51.128Z",
|
|
140
|
+
"size": 4544,
|
|
141
|
+
"path": "../public/assets/ReplayDialog-VMsGnJSI.js"
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
144
|
function readAsset(id) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonyclaw/llm-inspector",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "LLM API proxy inspector — captures and displays requests/responses from AI coding tools in a web UI",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"build": "vite build && bun build:cli",
|
|
36
36
|
"build:cli": "npx esbuild src/cli.ts --bundle --platform=node --target=node18 --format=esm --outfile=.output/cli.js",
|
|
37
37
|
"prepublishOnly": "npm run build",
|
|
38
|
+
"postinstall": "node .output/cli.js onboard || true",
|
|
38
39
|
"typecheck": "tsc --noEmit",
|
|
39
40
|
"lint": "eslint .",
|
|
40
41
|
"format": "biome format --write .",
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool detection for the onboard subcommand (and the SKILL.md instructions
|
|
3
|
+
* that read this code path). Pure functions only — no side effects, no fs
|
|
4
|
+
* watchers. Each detector returns a discriminated union so callers can tell
|
|
5
|
+
* a "found" from a "not found" without throwing.
|
|
6
|
+
*
|
|
7
|
+
* Detection is heuristic and best-effort. A miss is never an error — the
|
|
8
|
+
* user might have a tool installed in a non-standard location, or might be
|
|
9
|
+
* using a tool we don't enumerate. The skill falls through to a generic
|
|
10
|
+
* `curl` example in that case.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { execFileSync } from "node:child_process";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
|
|
18
|
+
export type DetectedTool = {
|
|
19
|
+
readonly found: true;
|
|
20
|
+
/** Absolute path to the most distinctive artifact (config dir or binary). */
|
|
21
|
+
readonly path: string;
|
|
22
|
+
/** Best-effort version string, if we can cheaply read one. */
|
|
23
|
+
readonly versionHint?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type MissingTool = { readonly found: false };
|
|
27
|
+
|
|
28
|
+
export type ToolDetectionResult = DetectedTool | MissingTool;
|
|
29
|
+
|
|
30
|
+
export type SupportedToolId = "claude-code" | "opencode" | "mimo" | "cursor" | "cody";
|
|
31
|
+
|
|
32
|
+
export type DetectedToolEntry = {
|
|
33
|
+
readonly id: SupportedToolId;
|
|
34
|
+
readonly displayName: string;
|
|
35
|
+
readonly result: ToolDetectionResult;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Run `command -v <bin>` (bash) or `where <bin>` (cmd) and return the first
|
|
40
|
+
* line of stdout. Returns `null` if the binary isn't on PATH. We use the
|
|
41
|
+
* platform's own lookup so we don't have to maintain a hard-coded list of
|
|
42
|
+
* candidate install dirs.
|
|
43
|
+
*/
|
|
44
|
+
function which(bin: string): string | null {
|
|
45
|
+
try {
|
|
46
|
+
if (process.platform === "win32") {
|
|
47
|
+
const out = execFileSync("where", [bin], {
|
|
48
|
+
encoding: "utf8",
|
|
49
|
+
timeout: 3000,
|
|
50
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
51
|
+
});
|
|
52
|
+
const first = out.split(/\r?\n/).find((line) => line.trim().length > 0);
|
|
53
|
+
return first?.trim() ?? null;
|
|
54
|
+
}
|
|
55
|
+
const out = execFileSync("sh", ["-c", `command -v ${bin}`], {
|
|
56
|
+
encoding: "utf8",
|
|
57
|
+
timeout: 3000,
|
|
58
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
59
|
+
});
|
|
60
|
+
return out.trim() || null;
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function tryDir(path: string): string | null {
|
|
67
|
+
return existsSync(path) ? path : null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function detectClaudeCode(): ToolDetectionResult {
|
|
71
|
+
// Claude Code stores its config under ~/.claude/. The binary is `claude`.
|
|
72
|
+
const configDir = tryDir(join(homedir(), ".claude"));
|
|
73
|
+
const bin = which("claude");
|
|
74
|
+
if (configDir === null && bin === null) return { found: false };
|
|
75
|
+
return { found: true, path: configDir ?? bin ?? "" };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function detectOpenCode(): ToolDetectionResult {
|
|
79
|
+
const configDir = tryDir(join(homedir(), ".config", "opencode"));
|
|
80
|
+
const bin = which("opencode");
|
|
81
|
+
if (configDir === null && bin === null) return { found: false };
|
|
82
|
+
return { found: true, path: configDir ?? bin ?? "" };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function detectMiMo(): ToolDetectionResult {
|
|
86
|
+
const configDir = tryDir(join(homedir(), ".mimo"));
|
|
87
|
+
const bin = which("mimo");
|
|
88
|
+
if (configDir === null && bin === null) return { found: false };
|
|
89
|
+
return { found: true, path: configDir ?? bin ?? "" };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function detectCursor(): ToolDetectionResult {
|
|
93
|
+
const configDir = tryDir(join(homedir(), ".cursor"));
|
|
94
|
+
const bin = which("cursor");
|
|
95
|
+
if (configDir === null && bin === null) return { found: false };
|
|
96
|
+
return { found: true, path: configDir ?? bin ?? "" };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function detectCody(): ToolDetectionResult {
|
|
100
|
+
// Sourcegraph's Cody uses `~/.config/cody/` (Linux/macOS) and stores
|
|
101
|
+
// its binary on PATH as `cody`. Note: `~/.codex/` is OpenAI Codex CLI's
|
|
102
|
+
// config dir, *not* Cody's — keep these distinct.
|
|
103
|
+
const configDir = tryDir(join(homedir(), ".config", "cody"));
|
|
104
|
+
const bin = which("cody");
|
|
105
|
+
if (configDir === null && bin === null) return { found: false };
|
|
106
|
+
return { found: true, path: configDir ?? bin ?? "" };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const DETECTORS: ReadonlyArray<{
|
|
110
|
+
id: SupportedToolId;
|
|
111
|
+
displayName: string;
|
|
112
|
+
detect: () => ToolDetectionResult;
|
|
113
|
+
}> = [
|
|
114
|
+
{ id: "claude-code", displayName: "Claude Code", detect: detectClaudeCode },
|
|
115
|
+
{ id: "opencode", displayName: "OpenCode", detect: detectOpenCode },
|
|
116
|
+
{ id: "mimo", displayName: "MiMo Code", detect: detectMiMo },
|
|
117
|
+
{ id: "cursor", displayName: "Cursor", detect: detectCursor },
|
|
118
|
+
{ id: "cody", displayName: "Cody", detect: detectCody },
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Run every detector and return the full list, including misses. Useful for
|
|
123
|
+
* the SKILL.md instructions that want to give the user a summary of what's
|
|
124
|
+
* available ("detected: Claude Code, OpenCode; not detected: Cursor, Cody").
|
|
125
|
+
*/
|
|
126
|
+
export function detectAll(): ReadonlyArray<DetectedToolEntry> {
|
|
127
|
+
return DETECTORS.map(({ id, displayName, detect }) => ({
|
|
128
|
+
id,
|
|
129
|
+
displayName,
|
|
130
|
+
result: detect(),
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Return the first tool that the detector finds. Used by the onboard
|
|
136
|
+
* subcommand when it needs to pick a single "wiring example" to print.
|
|
137
|
+
* Order in `DETECTORS` is the priority order — Claude Code first because
|
|
138
|
+
* it's the namesake of the project.
|
|
139
|
+
*/
|
|
140
|
+
export function detectFirst(): DetectedToolEntry | null {
|
|
141
|
+
for (const entry of DETECTORS) {
|
|
142
|
+
const result = entry.detect();
|
|
143
|
+
if (result.found) return { id: entry.id, displayName: entry.displayName, result };
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|