@tonyclaw/agent-inspector 3.0.26 → 3.0.28
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 +80 -11
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-SZRUDQc9.js → CompareDrawer-TghZr5t1.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-BJvwOrSi.js → ProxyViewerContainer-fShBAZjj.js} +201 -201
- package/.output/public/assets/{ReplayDialog-DgfmqiM3.js → ReplayDialog-CZMApaF4.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CS6c7Qfn.js → RequestAnatomy-DNWccR7O.js} +1 -1
- package/.output/public/assets/{ResponseView-C0Ri_5gm.js → ResponseView-d25MdFhY.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-7dYcHWyZ.js → StreamingChunkSequence-DIFZEnWe.js} +1 -1
- package/.output/public/assets/{_sessionId-D-V84cgw.js → _sessionId-DRfvuE2k.js} +1 -1
- package/.output/public/assets/{index-DgFWCxOs.js → index-B3aAuqWq.js} +1 -1
- package/.output/public/assets/index-BsxAGqMA.css +1 -0
- package/.output/public/assets/{index-DrVJsks2.js → index-D4HkS7Ct.js} +1 -1
- package/.output/public/assets/{index-CSIL7-MK.js → index-DzARL2Fi.js} +3 -3
- package/.output/public/assets/{json-viewer-C9Ji3gYN.js → json-viewer-wuJSKaed.js} +1 -1
- package/.output/server/_libs/lucide-react.mjs +39 -39
- package/.output/server/{_sessionId-BQ6YQOO1.mjs → _sessionId-BJTNiP_O.mjs} +4 -2
- package/.output/server/_ssr/{CompareDrawer-CqNzIeMR.mjs → CompareDrawer-BMRH3N97.mjs} +5 -3
- package/.output/server/_ssr/{ProxyViewerContainer-CMC7Vsbw.mjs → ProxyViewerContainer-AFwcHAIR.mjs} +330 -223
- package/.output/server/_ssr/{ReplayDialog-D9p_LaTr.mjs → ReplayDialog-CbWvRHiN.mjs} +6 -4
- package/.output/server/_ssr/{RequestAnatomy-B4ge3qNZ.mjs → RequestAnatomy-C4kcPyqN.mjs} +4 -2
- package/.output/server/_ssr/{ResponseView-BCqMKApI.mjs → ResponseView-D8VYt-gZ.mjs} +5 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BA4zTLE4.mjs → StreamingChunkSequence-BUUo6vU0.mjs} +4 -2
- package/.output/server/_ssr/{index-CzxhDjlq.mjs → index-DTwMEEXO.mjs} +4 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-B3qV6iEJ.mjs → json-viewer-BqF1pSQD.mjs} +5 -3
- package/.output/server/_ssr/{router-CZe_R31M.mjs → router-C8BOns7y.mjs} +839 -368
- package/.output/server/{_tanstack-start-manifest_v-B50VTLrH.mjs → _tanstack-start-manifest_v-BBf2nRhb.mjs} +1 -1
- package/.output/server/index.mjs +70 -70
- package/README.md +8 -0
- package/package.json +4 -5
- package/src/cli.ts +43 -9
- package/src/components/ProxyViewer.tsx +57 -1
- package/src/components/clients/ClientLogo.tsx +43 -4
- package/src/components/inspector-pet/InspectorPet.tsx +0 -7
- package/src/components/providers/ProviderCard.tsx +3 -36
- package/src/components/providers/ProviderForm.tsx +13 -12
- package/src/components/providers/ProvidersPanel.tsx +2 -2
- package/src/components/providers/SettingsDialog.tsx +3 -3
- package/src/components/proxy-viewer/ConversationGroup.tsx +1 -1
- package/src/components/proxy-viewer/ConversationGroupList.tsx +233 -152
- package/src/components/proxy-viewer/ConversationHeader.tsx +29 -13
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +0 -3
- package/src/contracts/anthropic.ts +0 -5
- package/src/contracts/index.ts +0 -4
- package/src/contracts/log.ts +0 -1
- package/src/contracts/openai.ts +0 -3
- package/src/knowledge/openclawClient.ts +22 -9
- package/src/knowledge/openclawGatewayClient.ts +20 -13
- package/src/lib/alertContract.ts +0 -3
- package/src/lib/ecosystemContract.ts +0 -3
- package/src/lib/export-logs.ts +1 -4
- package/src/lib/jsonFile.ts +46 -0
- package/src/lib/safeFetch.ts +100 -0
- package/src/lib/ssrfGuard.ts +133 -0
- package/src/lib/stopReason.ts +1 -4
- package/src/lib/unknown.ts +27 -0
- package/src/lib/useProviders.ts +1 -1
- package/src/mcp/mode.ts +3 -9
- package/src/mcp/server.ts +5 -14
- package/src/mcp/toolHandlers.ts +45 -54
- package/src/proxy/constants.ts +17 -0
- package/src/proxy/evidenceAnalysis.ts +116 -117
- package/src/proxy/formats/anthropic/handler.ts +5 -1
- package/src/proxy/formats/anthropic/schemas.ts +1 -7
- package/src/proxy/formats/index.ts +1 -1
- package/src/proxy/formats/openai/schemas.ts +0 -3
- package/src/proxy/formats/registry.ts +0 -3
- package/src/proxy/groupEvidenceExporter.ts +4 -8
- package/src/proxy/groupStore.ts +3 -10
- package/src/proxy/handler.ts +91 -12
- package/src/proxy/identityProxy.ts +74 -1
- package/src/proxy/logImporter.ts +82 -12
- package/src/proxy/logIndex.ts +1 -4
- package/src/proxy/providerSecretStore.ts +177 -0
- package/src/proxy/providers.ts +84 -11
- package/src/proxy/runFailures.ts +4 -10
- package/src/proxy/runStore.ts +4 -11
- package/src/proxy/schemas.ts +1 -8
- package/src/proxy/sqliteLogIndex.ts +0 -16
- package/src/proxy/store.ts +1 -5
- package/src/proxy/toolSchemaWarnings.ts +1 -9
- package/src/routes/api/logs.$id.replay.ts +17 -5
- package/src/routes/api/providers.$providerId.model-metadata.ts +11 -1
- package/src/routes/api/providers.$providerId.ts +18 -5
- package/src/routes/api/providers.ts +18 -7
- package/.output/public/assets/index-CmeF5XXS.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ routes: { __root__: { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", children: ["/", "/api/alerts", "/api/config", "/api/groups", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/pi-agent", "/api/providers", "/api/runs", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/ecosystem/packages", "/api/ecosystem/tasks", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/ecosystem/recipes/$recipeId/run", "/api/knowledge/sessions/$sessionId/candidates"], preloads: ["/assets/index-
|
|
1
|
+
const tsrStartManifest = () => ({ routes: { __root__: { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", children: ["/", "/api/alerts", "/api/config", "/api/groups", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/pi-agent", "/api/providers", "/api/runs", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/ecosystem/packages", "/api/ecosystem/tasks", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/ecosystem/recipes/$recipeId/run", "/api/knowledge/sessions/$sessionId/candidates"], preloads: ["/assets/index-DzARL2Fi.js"], scripts: [{ attrs: { type: "module", async: true, src: "/assets/index-DzARL2Fi.js" } }] }, "/": { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", children: void 0, preloads: ["/assets/index-D4HkS7Ct.js", "/assets/ProxyViewerContainer-fShBAZjj.js"] }, "/session/$sessionId": { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/session/$sessionId.tsx", children: void 0, preloads: ["/assets/_sessionId-DRfvuE2k.js", "/assets/ProxyViewerContainer-fShBAZjj.js"] } } });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -20,121 +20,121 @@ const assets = {
|
|
|
20
20
|
"/assets/agent-inspector-58K1_MsC.ico": {
|
|
21
21
|
"type": "image/vnd.microsoft.icon",
|
|
22
22
|
"etag": '"38fa-ZD8kPABHYjPIkcH82FMY6iZM7fI"',
|
|
23
|
-
"mtime": "2026-07-
|
|
23
|
+
"mtime": "2026-07-11T07:25:10.079Z",
|
|
24
24
|
"size": 14586,
|
|
25
25
|
"path": "../public/assets/agent-inspector-58K1_MsC.ico"
|
|
26
26
|
},
|
|
27
|
+
"/assets/index-B3aAuqWq.js": {
|
|
28
|
+
"type": "text/javascript; charset=utf-8",
|
|
29
|
+
"etag": '"1cd2d-NtF7W+NRjTmAvD+1JKZI8rtHI7U"',
|
|
30
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
31
|
+
"size": 118061,
|
|
32
|
+
"path": "../public/assets/index-B3aAuqWq.js"
|
|
33
|
+
},
|
|
27
34
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
28
35
|
"type": "image/svg+xml",
|
|
29
36
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
30
|
-
"mtime": "2026-07-
|
|
37
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
31
38
|
"size": 5915,
|
|
32
39
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
33
40
|
},
|
|
34
|
-
"/assets/json-viewer-
|
|
41
|
+
"/assets/json-viewer-wuJSKaed.js": {
|
|
35
42
|
"type": "text/javascript; charset=utf-8",
|
|
36
|
-
"etag": '"1ae7-
|
|
37
|
-
"mtime": "2026-07-
|
|
43
|
+
"etag": '"1ae7-BU19qUySeFzJhdQR46CWzhjoXCo"',
|
|
44
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
38
45
|
"size": 6887,
|
|
39
|
-
"path": "../public/assets/json-viewer-
|
|
46
|
+
"path": "../public/assets/json-viewer-wuJSKaed.js"
|
|
40
47
|
},
|
|
41
|
-
"/assets/
|
|
42
|
-
"type": "text/
|
|
43
|
-
"etag": '"
|
|
44
|
-
"mtime": "2026-07-
|
|
45
|
-
"size":
|
|
46
|
-
"path": "../public/assets/
|
|
48
|
+
"/assets/index-BsxAGqMA.css": {
|
|
49
|
+
"type": "text/css; charset=utf-8",
|
|
50
|
+
"etag": '"28b55-jHTF06GuUcizq3n19QXDY4Rs9bY"',
|
|
51
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
52
|
+
"size": 166741,
|
|
53
|
+
"path": "../public/assets/index-BsxAGqMA.css"
|
|
47
54
|
},
|
|
48
55
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
49
56
|
"type": "image/jpeg",
|
|
50
57
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
51
|
-
"mtime": "2026-07-
|
|
58
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
52
59
|
"size": 6918,
|
|
53
60
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
54
61
|
},
|
|
55
|
-
"/assets/index-
|
|
62
|
+
"/assets/index-DzARL2Fi.js": {
|
|
56
63
|
"type": "text/javascript; charset=utf-8",
|
|
57
|
-
"etag": '"537cd-
|
|
58
|
-
"mtime": "2026-07-
|
|
64
|
+
"etag": '"537cd-n0LgXNt1QLHB07TADWQSjwwA7ao"',
|
|
65
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
59
66
|
"size": 341965,
|
|
60
|
-
"path": "../public/assets/index-
|
|
61
|
-
},
|
|
62
|
-
"/assets/index-CmeF5XXS.css": {
|
|
63
|
-
"type": "text/css; charset=utf-8",
|
|
64
|
-
"etag": '"28a56-x7Wmw+oL5ZFDjFw5JRwjxSop3gg"',
|
|
65
|
-
"mtime": "2026-07-11T00:24:54.156Z",
|
|
66
|
-
"size": 166486,
|
|
67
|
-
"path": "../public/assets/index-CmeF5XXS.css"
|
|
67
|
+
"path": "../public/assets/index-DzARL2Fi.js"
|
|
68
68
|
},
|
|
69
|
-
"/assets/
|
|
69
|
+
"/assets/CompareDrawer-TghZr5t1.js": {
|
|
70
70
|
"type": "text/javascript; charset=utf-8",
|
|
71
|
-
"etag": '"
|
|
72
|
-
"mtime": "2026-07-
|
|
73
|
-
"size":
|
|
74
|
-
"path": "../public/assets/
|
|
71
|
+
"etag": '"4bc4-EO0Pced4VNvNgQhISz9DCokb9HU"',
|
|
72
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
73
|
+
"size": 19396,
|
|
74
|
+
"path": "../public/assets/CompareDrawer-TghZr5t1.js"
|
|
75
75
|
},
|
|
76
|
-
"/assets/
|
|
76
|
+
"/assets/index-D4HkS7Ct.js": {
|
|
77
77
|
"type": "text/javascript; charset=utf-8",
|
|
78
|
-
"etag": '"
|
|
79
|
-
"mtime": "2026-07-
|
|
80
|
-
"size":
|
|
81
|
-
"path": "../public/assets/
|
|
78
|
+
"etag": '"265-GATgiXd9lc1ztQtCZI0flLv7tLY"',
|
|
79
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
80
|
+
"size": 613,
|
|
81
|
+
"path": "../public/assets/index-D4HkS7Ct.js"
|
|
82
82
|
},
|
|
83
|
-
"/assets/
|
|
83
|
+
"/assets/ResponseView-d25MdFhY.js": {
|
|
84
84
|
"type": "text/javascript; charset=utf-8",
|
|
85
|
-
"etag": '"
|
|
86
|
-
"mtime": "2026-07-
|
|
87
|
-
"size":
|
|
88
|
-
"path": "../public/assets/
|
|
85
|
+
"etag": '"47fe-Po8oiwgEzmPD5hRtGam0HQony8k"',
|
|
86
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
87
|
+
"size": 18430,
|
|
88
|
+
"path": "../public/assets/ResponseView-d25MdFhY.js"
|
|
89
89
|
},
|
|
90
|
-
"/assets/
|
|
90
|
+
"/assets/RequestAnatomy-DNWccR7O.js": {
|
|
91
91
|
"type": "text/javascript; charset=utf-8",
|
|
92
|
-
"etag": '"
|
|
93
|
-
"mtime": "2026-07-
|
|
94
|
-
"size":
|
|
95
|
-
"path": "../public/assets/
|
|
92
|
+
"etag": '"43f3-aiF5LhFVPVUreSkzjdqgZFSwONM"',
|
|
93
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
94
|
+
"size": 17395,
|
|
95
|
+
"path": "../public/assets/RequestAnatomy-DNWccR7O.js"
|
|
96
96
|
},
|
|
97
|
-
"/assets/
|
|
97
|
+
"/assets/ReplayDialog-CZMApaF4.js": {
|
|
98
98
|
"type": "text/javascript; charset=utf-8",
|
|
99
|
-
"etag": '"
|
|
100
|
-
"mtime": "2026-07-
|
|
101
|
-
"size":
|
|
102
|
-
"path": "../public/assets/
|
|
99
|
+
"etag": '"3348-CNibW415vjAp7j+7orWWQiIbLDA"',
|
|
100
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
101
|
+
"size": 13128,
|
|
102
|
+
"path": "../public/assets/ReplayDialog-CZMApaF4.js"
|
|
103
103
|
},
|
|
104
|
-
"/assets/StreamingChunkSequence-
|
|
104
|
+
"/assets/StreamingChunkSequence-DIFZEnWe.js": {
|
|
105
105
|
"type": "text/javascript; charset=utf-8",
|
|
106
|
-
"etag": '"e96-
|
|
107
|
-
"mtime": "2026-07-
|
|
106
|
+
"etag": '"e96-uRF1QBlYJ4LJvlyn05RZzDtEbkE"',
|
|
107
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
108
108
|
"size": 3734,
|
|
109
|
-
"path": "../public/assets/StreamingChunkSequence-
|
|
109
|
+
"path": "../public/assets/StreamingChunkSequence-DIFZEnWe.js"
|
|
110
|
+
},
|
|
111
|
+
"/assets/qwen-CONDcHqt.png": {
|
|
112
|
+
"type": "image/png",
|
|
113
|
+
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
114
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
115
|
+
"size": 357059,
|
|
116
|
+
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
110
117
|
},
|
|
111
118
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
112
119
|
"type": "image/svg+xml",
|
|
113
120
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
114
|
-
"mtime": "2026-07-
|
|
121
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
115
122
|
"size": 11256,
|
|
116
123
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
117
124
|
},
|
|
118
|
-
"/assets/_sessionId-
|
|
125
|
+
"/assets/_sessionId-DRfvuE2k.js": {
|
|
119
126
|
"type": "text/javascript; charset=utf-8",
|
|
120
|
-
"etag": '"36d-
|
|
121
|
-
"mtime": "2026-07-
|
|
127
|
+
"etag": '"36d-DdOUH1ep4qcEQKZ8gAcubBJENCU"',
|
|
128
|
+
"mtime": "2026-07-11T07:25:10.085Z",
|
|
122
129
|
"size": 877,
|
|
123
|
-
"path": "../public/assets/_sessionId-
|
|
124
|
-
},
|
|
125
|
-
"/assets/qwen-CONDcHqt.png": {
|
|
126
|
-
"type": "image/png",
|
|
127
|
-
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
128
|
-
"mtime": "2026-07-11T00:24:54.156Z",
|
|
129
|
-
"size": 357059,
|
|
130
|
-
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
130
|
+
"path": "../public/assets/_sessionId-DRfvuE2k.js"
|
|
131
131
|
},
|
|
132
|
-
"/assets/ProxyViewerContainer-
|
|
132
|
+
"/assets/ProxyViewerContainer-fShBAZjj.js": {
|
|
133
133
|
"type": "text/javascript; charset=utf-8",
|
|
134
|
-
"etag": '"
|
|
135
|
-
"mtime": "2026-07-
|
|
136
|
-
"size":
|
|
137
|
-
"path": "../public/assets/ProxyViewerContainer-
|
|
134
|
+
"etag": '"140e7c-9dZ35KxZynE0VFMwXVZlbDNocic"',
|
|
135
|
+
"mtime": "2026-07-11T07:25:10.087Z",
|
|
136
|
+
"size": 1314428,
|
|
137
|
+
"path": "../public/assets/ProxyViewerContainer-fShBAZjj.js"
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
140
|
function readAsset(id) {
|
package/README.md
CHANGED
|
@@ -31,6 +31,14 @@ npm install -g @tonyclaw/agent-inspector-mcp
|
|
|
31
31
|
agent-inspector-mcp doctor
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
Agent Inspector requires Node.js 22 or newer. Node.js 24 LTS is recommended for production use.
|
|
35
|
+
|
|
36
|
+
By default, Agent Inspector binds to `127.0.0.1`. With `--host 0.0.0.0`, remote coding tools may
|
|
37
|
+
use `/proxy`, while the UI, REST API, and MCP control plane remain local-only. Set
|
|
38
|
+
`AGENT_INSPECTOR_CONTROL_TOKEN` for authenticated remote API/MCP clients, or explicitly set
|
|
39
|
+
`AGENT_INSPECTOR_ALLOW_REMOTE_CONTROL=1` only behind a trusted firewall or loopback-only port
|
|
40
|
+
mapping.
|
|
41
|
+
|
|
34
42
|
`@tonyclaw/agent-inspector` runs the local UI, proxy, REST API, storage, and built-in
|
|
35
43
|
`/api/mcp` endpoint. `@tonyclaw/agent-inspector-mcp` is the enhancement package for
|
|
36
44
|
stdio-first MCP clients and setup automation; it bridges to the local Inspector endpoint without
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonyclaw/agent-inspector",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent observability and knowledge capture layer for AI coding tools.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=22.0.0"
|
|
9
9
|
},
|
|
10
10
|
"author": "TonyClaw",
|
|
11
11
|
"repository": {
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"dev": "vite dev",
|
|
56
56
|
"start": "node .output/cli.js",
|
|
57
57
|
"build": "vite build && bun build:cli && bun build:mcp",
|
|
58
|
-
"build:cli": "npx esbuild src/cli.ts --bundle --platform=node --target=
|
|
59
|
-
"build:mcp": "npx esbuild packages/agent-inspector-mcp/src/cli.ts --bundle --platform=node --target=
|
|
58
|
+
"build:cli": "npx esbuild src/cli.ts --bundle --platform=node --target=node22 --format=esm --outfile=.output/cli.js",
|
|
59
|
+
"build:mcp": "npx esbuild packages/agent-inspector-mcp/src/cli.ts --bundle --platform=node --target=node22 --format=esm --outfile=packages/agent-inspector-mcp/dist/cli.js",
|
|
60
60
|
"postinstall": "node scripts/setup-windows-runtime.mjs && node scripts/setup-agent-skills.mjs",
|
|
61
61
|
"prepublishOnly": "npm run build",
|
|
62
62
|
"typecheck": "tsc --noEmit",
|
|
@@ -102,7 +102,6 @@
|
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
104
|
"@biomejs/biome": "^2.3.14",
|
|
105
|
-
"@cfworker/json-schema": "^4.1.1",
|
|
106
105
|
"@eslint/js": "^10.0.1",
|
|
107
106
|
"@ladle/react": "^5.1.1",
|
|
108
107
|
"@tailwindcss/vite": "^4.1.18",
|
package/src/cli.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { existsSync } from "node:fs";
|
|
|
8
8
|
import type { Readable, Writable } from "node:stream";
|
|
9
9
|
import {
|
|
10
10
|
formatAccessHintLines,
|
|
11
|
+
isLoopbackHost,
|
|
11
12
|
isValidBindHost,
|
|
12
13
|
localUrlForPort,
|
|
13
14
|
networkUrlsForBindHost,
|
|
@@ -31,6 +32,7 @@ const __dirname = dirname(__filename);
|
|
|
31
32
|
const DEFAULT_PORT = 9527;
|
|
32
33
|
const LEGACY_ALIAS_PORT = 9527;
|
|
33
34
|
const DEFAULT_UPSTREAM_PORT = 9529;
|
|
35
|
+
const DEFAULT_BIND_HOST = "127.0.0.1";
|
|
34
36
|
const LOCAL_PROBE_TIMEOUT_MS = 2000;
|
|
35
37
|
const BRANDED_WINDOWS_RUNTIME_EXE = "agent-inspector.exe";
|
|
36
38
|
const DEFAULT_CAPTURE_MODE = "simple";
|
|
@@ -229,6 +231,16 @@ function printAccessHints(port: number, host?: string): void {
|
|
|
229
231
|
for (const line of formatAccessHintLines(port, networkUrls, host)) {
|
|
230
232
|
console.log(line);
|
|
231
233
|
}
|
|
234
|
+
if (!isLoopbackHost(host)) {
|
|
235
|
+
if (process.env["AGENT_INSPECTOR_ALLOW_REMOTE_CONTROL"] === "1") {
|
|
236
|
+
console.warn(" Control plane: REMOTE ACCESS ENABLED by administrator override");
|
|
237
|
+
} else {
|
|
238
|
+
console.log(" Control plane: local only; remote clients may use /proxy");
|
|
239
|
+
if ((process.env["AGENT_INSPECTOR_CONTROL_TOKEN"] ?? "") !== "") {
|
|
240
|
+
console.log(" Remote API: Bearer token authentication enabled");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
232
244
|
}
|
|
233
245
|
|
|
234
246
|
type BackgroundSupervisorOptions = {
|
|
@@ -289,13 +301,18 @@ function pickUpstreamPort(publicPort: number, legacyAliasPort: number | null): n
|
|
|
289
301
|
async function tryStartIdentityProxy(
|
|
290
302
|
identityPort: number,
|
|
291
303
|
upstreamPort: number,
|
|
292
|
-
|
|
304
|
+
listenHost: string,
|
|
305
|
+
upstreamHost: string,
|
|
293
306
|
): Promise<import("node:http").Server | null> {
|
|
294
307
|
try {
|
|
295
308
|
const server = await startIdentityProxy({
|
|
296
309
|
listenPort: identityPort,
|
|
297
|
-
|
|
310
|
+
listenHost,
|
|
311
|
+
upstreamHost,
|
|
298
312
|
upstreamPort,
|
|
313
|
+
restrictRemoteControl: !isLoopbackHost(listenHost),
|
|
314
|
+
allowRemoteControl: process.env["AGENT_INSPECTOR_ALLOW_REMOTE_CONTROL"] === "1",
|
|
315
|
+
controlToken: process.env["AGENT_INSPECTOR_CONTROL_TOKEN"],
|
|
299
316
|
});
|
|
300
317
|
return server;
|
|
301
318
|
} catch (err) {
|
|
@@ -317,7 +334,8 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
317
334
|
process.env["AGENT_INSPECTOR_CAPTURE_MODE"] ?? process.env["AGENT_INSPECTOR_MODE"];
|
|
318
335
|
|
|
319
336
|
let port = portDefault;
|
|
320
|
-
let host =
|
|
337
|
+
let host =
|
|
338
|
+
envHost !== undefined && envHost.trim().length > 0 ? envHost.trim() : DEFAULT_BIND_HOST;
|
|
321
339
|
let open = true;
|
|
322
340
|
let openWasSpecified = false;
|
|
323
341
|
let background = false;
|
|
@@ -457,6 +475,18 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
457
475
|
return;
|
|
458
476
|
}
|
|
459
477
|
|
|
478
|
+
if (
|
|
479
|
+
!enableIdentityProxy &&
|
|
480
|
+
!isLoopbackHost(host) &&
|
|
481
|
+
process.env["AGENT_INSPECTOR_ALLOW_REMOTE_CONTROL"] !== "1"
|
|
482
|
+
) {
|
|
483
|
+
console.error(
|
|
484
|
+
"Refusing an unprotected remote bind with --no-identity-proxy. Keep the identity proxy enabled or set AGENT_INSPECTOR_ALLOW_REMOTE_CONTROL=1 explicitly.",
|
|
485
|
+
);
|
|
486
|
+
process.exitCode = 1;
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
460
490
|
/**
|
|
461
491
|
* Check if a port is in use and kill the process using it
|
|
462
492
|
*/
|
|
@@ -475,6 +505,7 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
475
505
|
// the public-facing port(s). When the identity proxy is disabled we fall
|
|
476
506
|
// back to TanStack listening on the public port directly.
|
|
477
507
|
const upstreamPort = enableIdentityProxy ? pickUpstreamPort(port, legacyAliasPort) : port;
|
|
508
|
+
const upstreamHost = enableIdentityProxy ? DEFAULT_BIND_HOST : host;
|
|
478
509
|
process.env["PORT"] = String(upstreamPort);
|
|
479
510
|
|
|
480
511
|
const url = urlForHost(port, host);
|
|
@@ -627,10 +658,8 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
627
658
|
if (providersJson !== undefined) {
|
|
628
659
|
serverEnv["AGENT_INSPECTOR_PROVIDERS_JSON"] = providersJson;
|
|
629
660
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
serverEnv["NITRO_HOST"] = host;
|
|
633
|
-
}
|
|
661
|
+
serverEnv["HOST"] = upstreamHost;
|
|
662
|
+
serverEnv["NITRO_HOST"] = upstreamHost;
|
|
634
663
|
serverEnv["AGENT_INSPECTOR_PUBLIC_PORT"] = String(port);
|
|
635
664
|
serverEnv["PROXY_PORT"] = String(port);
|
|
636
665
|
serverEnv["AGENT_INSPECTOR_CAPTURE_MODE"] = captureMode;
|
|
@@ -664,12 +693,17 @@ async function runStart(args: string[]): Promise<void> {
|
|
|
664
693
|
server: import("node:http").Server;
|
|
665
694
|
}> = [];
|
|
666
695
|
if (enableIdentityProxy) {
|
|
667
|
-
const primaryProxy = await tryStartIdentityProxy(port, upstreamPort, host);
|
|
696
|
+
const primaryProxy = await tryStartIdentityProxy(port, upstreamPort, host, upstreamHost);
|
|
668
697
|
if (primaryProxy !== null) {
|
|
669
698
|
identityProxies.push({ label: "primary", port, server: primaryProxy });
|
|
670
699
|
}
|
|
671
700
|
if (legacyAliasPort !== null) {
|
|
672
|
-
const legacyProxy = await tryStartIdentityProxy(
|
|
701
|
+
const legacyProxy = await tryStartIdentityProxy(
|
|
702
|
+
legacyAliasPort,
|
|
703
|
+
upstreamPort,
|
|
704
|
+
host,
|
|
705
|
+
upstreamHost,
|
|
706
|
+
);
|
|
673
707
|
if (legacyProxy !== null) {
|
|
674
708
|
identityProxies.push({ label: "legacy", port: legacyAliasPort, server: legacyProxy });
|
|
675
709
|
}
|
|
@@ -933,6 +933,32 @@ function ThemeModeToggle(): JSX.Element {
|
|
|
933
933
|
);
|
|
934
934
|
}
|
|
935
935
|
|
|
936
|
+
function PetVisibilityToggle({
|
|
937
|
+
visible,
|
|
938
|
+
onToggle,
|
|
939
|
+
}: {
|
|
940
|
+
visible: boolean;
|
|
941
|
+
onToggle: () => void;
|
|
942
|
+
}): JSX.Element {
|
|
943
|
+
const label = visible ? "Hide Inspector pet" : "Summon Inspector pet";
|
|
944
|
+
|
|
945
|
+
return (
|
|
946
|
+
<button
|
|
947
|
+
type="button"
|
|
948
|
+
onClick={onToggle}
|
|
949
|
+
className={cn(
|
|
950
|
+
"border-border/70 bg-muted/70 inline-flex size-8 shrink-0 items-center justify-center rounded-md border text-muted-foreground shadow-sm transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
951
|
+
visible && "bg-background text-amber-500 shadow-sm",
|
|
952
|
+
)}
|
|
953
|
+
aria-label={label}
|
|
954
|
+
aria-pressed={visible}
|
|
955
|
+
title={label}
|
|
956
|
+
>
|
|
957
|
+
<CrabLogo className={cn("size-4 transition-opacity", !visible && "opacity-45")} />
|
|
958
|
+
</button>
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
|
|
936
962
|
function UiScaleControl({
|
|
937
963
|
preference,
|
|
938
964
|
resolvedScale,
|
|
@@ -1056,6 +1082,7 @@ function BrandHeader({
|
|
|
1056
1082
|
}
|
|
1057
1083
|
|
|
1058
1084
|
const DETAILS_PANEL_COLLAPSED_STORAGE_KEY = "agent-inspector.detailsPanelCollapsed";
|
|
1085
|
+
const INSPECTOR_PET_VISIBLE_STORAGE_KEY = "agent-inspector.pet.visible";
|
|
1059
1086
|
|
|
1060
1087
|
function readStoredDetailsPanelCollapsed(): boolean {
|
|
1061
1088
|
if (typeof window === "undefined") return true;
|
|
@@ -1063,6 +1090,15 @@ function readStoredDetailsPanelCollapsed(): boolean {
|
|
|
1063
1090
|
return stored === null || stored === "1";
|
|
1064
1091
|
}
|
|
1065
1092
|
|
|
1093
|
+
function readStoredInspectorPetVisible(): boolean {
|
|
1094
|
+
if (typeof window === "undefined") return true;
|
|
1095
|
+
try {
|
|
1096
|
+
return window.localStorage.getItem(INSPECTOR_PET_VISIBLE_STORAGE_KEY) !== "0";
|
|
1097
|
+
} catch {
|
|
1098
|
+
return true;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1066
1102
|
function SessionContextLogButton({ label, logId }: { label: string; logId: number }): JSX.Element {
|
|
1067
1103
|
return (
|
|
1068
1104
|
<button
|
|
@@ -1451,6 +1487,8 @@ export function ProxyViewer({
|
|
|
1451
1487
|
const [deletingCurrentView, setDeletingCurrentView] = useState(false);
|
|
1452
1488
|
const [detailsPanelCollapsed, setDetailsPanelCollapsed] = useState(true);
|
|
1453
1489
|
const [detailsPanelStorageLoaded, setDetailsPanelStorageLoaded] = useState(false);
|
|
1490
|
+
const [petVisible, setPetVisible] = useState(true);
|
|
1491
|
+
const [petVisibilityStorageLoaded, setPetVisibilityStorageLoaded] = useState(false);
|
|
1454
1492
|
const [comparePair, setComparePair] = useState<[CapturedLog, CapturedLog] | null>(null);
|
|
1455
1493
|
const [crabEntrancePhase, setCrabEntrancePhase] = useState<"hidden" | "playing" | "done">(
|
|
1456
1494
|
"hidden",
|
|
@@ -1504,6 +1542,20 @@ export function ProxyViewer({
|
|
|
1504
1542
|
);
|
|
1505
1543
|
}, [detailsPanelCollapsed, detailsPanelStorageLoaded]);
|
|
1506
1544
|
|
|
1545
|
+
useEffect(() => {
|
|
1546
|
+
setPetVisible(readStoredInspectorPetVisible());
|
|
1547
|
+
setPetVisibilityStorageLoaded(true);
|
|
1548
|
+
}, []);
|
|
1549
|
+
|
|
1550
|
+
useEffect(() => {
|
|
1551
|
+
if (!petVisibilityStorageLoaded) return;
|
|
1552
|
+
try {
|
|
1553
|
+
window.localStorage.setItem(INSPECTOR_PET_VISIBLE_STORAGE_KEY, petVisible ? "1" : "0");
|
|
1554
|
+
} catch {
|
|
1555
|
+
// Local storage can be unavailable in hardened browser profiles.
|
|
1556
|
+
}
|
|
1557
|
+
}, [petVisibilityStorageLoaded, petVisible]);
|
|
1558
|
+
|
|
1507
1559
|
useEffect(() => {
|
|
1508
1560
|
if (pinnedSessionId === undefined) {
|
|
1509
1561
|
document.title = "Agent Inspector";
|
|
@@ -1640,6 +1692,9 @@ export function ProxyViewer({
|
|
|
1640
1692
|
const toggleDetailsPanelCollapsed = useCallback(() => {
|
|
1641
1693
|
setDetailsPanelCollapsed((value) => !value);
|
|
1642
1694
|
}, []);
|
|
1695
|
+
const togglePetVisibility = useCallback(() => {
|
|
1696
|
+
setPetVisible((value) => !value);
|
|
1697
|
+
}, []);
|
|
1643
1698
|
|
|
1644
1699
|
const groups = useMemo(() => groupLogsByConversation(logs), [logs]);
|
|
1645
1700
|
const displayNumberByLogId = useMemo(() => buildDisplayNumberByLogId(groups), [groups]);
|
|
@@ -1741,7 +1796,7 @@ export function ProxyViewer({
|
|
|
1741
1796
|
<PanelRightClose className="size-3.5" />
|
|
1742
1797
|
)}
|
|
1743
1798
|
</button>
|
|
1744
|
-
{
|
|
1799
|
+
{petVisibilityStorageLoaded && petVisible && <InspectorPet logs={logs} />}
|
|
1745
1800
|
<div
|
|
1746
1801
|
className={cn(
|
|
1747
1802
|
"grid w-full min-w-0 grid-cols-1 lg:min-h-0 lg:flex-1 lg:overflow-hidden",
|
|
@@ -1892,6 +1947,7 @@ export function ProxyViewer({
|
|
|
1892
1947
|
{activeScopeLabel}
|
|
1893
1948
|
</div>
|
|
1894
1949
|
</div>
|
|
1950
|
+
<PetVisibilityToggle visible={petVisible} onToggle={togglePetVisibility} />
|
|
1895
1951
|
{onImportLogs !== undefined && (
|
|
1896
1952
|
<>
|
|
1897
1953
|
<input
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { JSX } from "react";
|
|
2
|
+
import { Code2 } from "lucide-react";
|
|
2
3
|
import { cn } from "../../lib/utils";
|
|
3
4
|
import ClaudeCodeLogoSvg from "../../assets/IDE/claudecode-color.svg";
|
|
4
5
|
import CodexLogoSvg from "../../assets/IDE/codex-color.svg";
|
|
@@ -12,6 +13,7 @@ export type ClientApp =
|
|
|
12
13
|
| "opencode"
|
|
13
14
|
| "mimo-code"
|
|
14
15
|
| "claude-code"
|
|
16
|
+
| "ai-sdk"
|
|
15
17
|
| "unknown";
|
|
16
18
|
|
|
17
19
|
export type ClientAppDetectionInput = {
|
|
@@ -26,6 +28,7 @@ const CLIENT_LABELS: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
|
26
28
|
opencode: "OpenCode",
|
|
27
29
|
"mimo-code": "MiMo Code",
|
|
28
30
|
"claude-code": "Claude Code",
|
|
31
|
+
"ai-sdk": "AI SDK",
|
|
29
32
|
};
|
|
30
33
|
|
|
31
34
|
function normalize(value: string | null | undefined): string {
|
|
@@ -59,6 +62,7 @@ export function detectClientApp(input: ClientAppDetectionInput): ClientApp {
|
|
|
59
62
|
if (matchesAny(haystack, ["codex desktop", "codex-cli", "openai-codex", "codex"])) {
|
|
60
63
|
return "codex";
|
|
61
64
|
}
|
|
65
|
+
if (matchesAny(normalize(input.userAgent), ["ai-sdk", "ai/"])) return "ai-sdk";
|
|
62
66
|
|
|
63
67
|
return "unknown";
|
|
64
68
|
}
|
|
@@ -70,13 +74,30 @@ export function clientAppLabel(client: ClientApp): string | null {
|
|
|
70
74
|
case "opencode":
|
|
71
75
|
case "mimo-code":
|
|
72
76
|
case "claude-code":
|
|
77
|
+
case "ai-sdk":
|
|
73
78
|
return CLIENT_LABELS[client];
|
|
74
79
|
case "unknown":
|
|
75
80
|
return null;
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
export function clientAppTypeLabel(client: ClientApp): "IDE" | "CLIENT" {
|
|
85
|
+
switch (client) {
|
|
86
|
+
case "codex":
|
|
87
|
+
case "opencode":
|
|
88
|
+
case "mimo-code":
|
|
89
|
+
case "claude-code":
|
|
90
|
+
return "IDE";
|
|
91
|
+
case "agent-inspector":
|
|
92
|
+
case "ai-sdk":
|
|
93
|
+
case "unknown":
|
|
94
|
+
return "CLIENT";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type ImageClientApp = Exclude<ClientApp, "unknown" | "ai-sdk">;
|
|
99
|
+
|
|
100
|
+
const CLIENT_LOGOS: Record<ImageClientApp, string> = {
|
|
80
101
|
"agent-inspector": AgentInspectorLogo,
|
|
81
102
|
codex: CodexLogoSvg,
|
|
82
103
|
opencode: OpenCodeLogoSvg,
|
|
@@ -84,7 +105,7 @@ const CLIENT_LOGOS: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
|
84
105
|
"claude-code": ClaudeCodeLogoSvg,
|
|
85
106
|
};
|
|
86
107
|
|
|
87
|
-
const CLIENT_LOGO_FRAMES: Record<
|
|
108
|
+
const CLIENT_LOGO_FRAMES: Record<ImageClientApp, string> = {
|
|
88
109
|
"agent-inspector": "border-orange-200/25 bg-orange-300/[0.12]",
|
|
89
110
|
codex: "border-cyan-200/20 bg-cyan-300/[0.08]",
|
|
90
111
|
opencode: "border-sky-200/25 bg-sky-300/[0.12]",
|
|
@@ -92,7 +113,7 @@ const CLIENT_LOGO_FRAMES: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
|
92
113
|
"claude-code": "border-amber-100/20 bg-amber-300/[0.09]",
|
|
93
114
|
};
|
|
94
115
|
|
|
95
|
-
const CLIENT_LOGO_IMAGES: Record<
|
|
116
|
+
const CLIENT_LOGO_IMAGES: Record<ImageClientApp, string> = {
|
|
96
117
|
"agent-inspector": "p-0.5 drop-shadow-[0_0_8px_rgba(251,146,60,0.35)]",
|
|
97
118
|
codex: "p-0.5",
|
|
98
119
|
opencode: "p-1 drop-shadow-[0_0_8px_rgba(125,211,252,0.35)]",
|
|
@@ -103,13 +124,30 @@ const CLIENT_LOGO_IMAGES: Record<Exclude<ClientApp, "unknown">, string> = {
|
|
|
103
124
|
export function ClientLogo({
|
|
104
125
|
client,
|
|
105
126
|
className,
|
|
127
|
+
decorative = false,
|
|
106
128
|
}: {
|
|
107
129
|
client: ClientApp;
|
|
108
130
|
className?: string;
|
|
131
|
+
decorative?: boolean;
|
|
109
132
|
}): JSX.Element | null {
|
|
110
133
|
if (client === "unknown") return null;
|
|
111
134
|
const label = clientAppLabel(client);
|
|
112
135
|
if (label === null) return null;
|
|
136
|
+
if (client === "ai-sdk") {
|
|
137
|
+
return (
|
|
138
|
+
<span
|
|
139
|
+
className={cn(
|
|
140
|
+
"inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-cyan-200/20 bg-cyan-300/[0.08] text-cyan-100 shadow-sm",
|
|
141
|
+
className,
|
|
142
|
+
)}
|
|
143
|
+
aria-label={decorative ? undefined : label}
|
|
144
|
+
aria-hidden={decorative ? true : undefined}
|
|
145
|
+
title={label}
|
|
146
|
+
>
|
|
147
|
+
<Code2 className="size-1/2" aria-hidden="true" />
|
|
148
|
+
</span>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
113
151
|
const logoSrc = CLIENT_LOGOS[client];
|
|
114
152
|
|
|
115
153
|
return (
|
|
@@ -119,7 +157,8 @@ export function ClientLogo({
|
|
|
119
157
|
CLIENT_LOGO_FRAMES[client],
|
|
120
158
|
className,
|
|
121
159
|
)}
|
|
122
|
-
aria-label={label}
|
|
160
|
+
aria-label={decorative ? undefined : label}
|
|
161
|
+
aria-hidden={decorative ? true : undefined}
|
|
123
162
|
title={label}
|
|
124
163
|
>
|
|
125
164
|
<img
|
|
@@ -349,13 +349,6 @@ export function InspectorPet({ logs }: InspectorPetProps): JSX.Element {
|
|
|
349
349
|
/>
|
|
350
350
|
</span>
|
|
351
351
|
</span>
|
|
352
|
-
<span
|
|
353
|
-
className={cn(
|
|
354
|
-
"absolute right-0 top-2 size-3 rounded-full border border-background/90",
|
|
355
|
-
moodDotClass(status.mood),
|
|
356
|
-
status.mood === "active" && !reduceMotion && "animate-pulse",
|
|
357
|
-
)}
|
|
358
|
-
/>
|
|
359
352
|
{reactionVisible && (
|
|
360
353
|
<Heart
|
|
361
354
|
key={reactionTick}
|