@tonyclaw/agent-inspector 2.0.18 → 2.0.19
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 +137 -8
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-CepU-dLW.js → CompareDrawer-D-90PIPw.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-CxRDWacg.js +114 -0
- package/.output/public/assets/ReplayDialog-DzlLYoTO.js +1 -0
- package/.output/public/assets/{RequestAnatomy-C_C6ZU3T.js → RequestAnatomy-0hbyf6oa.js} +1 -1
- package/.output/public/assets/ResponseView-CKe0tNqr.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-enhfdeNh.js +1 -0
- package/.output/public/assets/_sessionId-CJ-SusES.js +1 -0
- package/.output/public/assets/index-BbFsmQRC.js +1 -0
- package/.output/public/assets/index-BfBgrkgU.css +1 -0
- package/.output/public/assets/{main-BRXsrxtv.js → main-o9-hg8g1.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +141 -118
- package/.output/server/_libs/tanstack__react-virtual.mjs +13 -2
- package/.output/server/_libs/tanstack__virtual-core.mjs +24 -1
- package/.output/server/{_sessionId-B8Bbfs-v.mjs → _sessionId-F8lm6PIb.mjs} +3 -2
- package/.output/server/_ssr/{CompareDrawer-TgGZLf1J.mjs → CompareDrawer-Cf1yfwfd.mjs} +4 -3
- package/.output/server/_ssr/{ProxyViewerContainer-B_ppaNmQ.mjs → ProxyViewerContainer-Bmu9867L.mjs} +349 -74
- package/.output/server/_ssr/{ReplayDialog-BXlajnMC.mjs → ReplayDialog-DxZfLBOe.mjs} +199 -17
- package/.output/server/_ssr/{RequestAnatomy-CCrx09-i.mjs → RequestAnatomy-CbdERGZd.mjs} +4 -3
- package/.output/server/_ssr/{ResponseView-BxtMJrov.mjs → ResponseView-CvLd6qxI.mjs} +4 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BlpdSPb8.mjs → StreamingChunkSequence-B_lkRB6o.mjs} +4 -3
- package/.output/server/_ssr/{index-BeTMNSJy.mjs → index-ejrSItfz.mjs} +3 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-Ddl1tuU7.mjs → router-SbCnbDc2.mjs} +872 -232
- package/.output/server/{_tanstack-start-manifest_v-Bvdz_U0f.mjs → _tanstack-start-manifest_v-yx8ftqWz.mjs} +1 -1
- package/.output/server/index.mjs +54 -54
- package/README.md +11 -109
- package/package.json +2 -1
- package/src/cli/doctor.ts +150 -5
- package/src/components/OnboardingBanner.tsx +13 -13
- package/src/components/ProxyViewer.tsx +55 -38
- package/src/components/ProxyViewerContainer.tsx +5 -0
- package/src/components/providers/SettingsDialog.tsx +113 -2
- package/src/components/proxy-viewer/ConversationGroup.tsx +20 -3
- package/src/components/proxy-viewer/ConversationGroupList.tsx +144 -0
- package/src/components/proxy-viewer/ConversationHeader.tsx +0 -2
- package/src/components/proxy-viewer/ReplayDialog.tsx +200 -13
- package/src/components/proxy-viewer/index.ts +1 -1
- package/src/knowledge/openclawClient.ts +0 -8
- package/src/knowledge/types.ts +0 -2
- package/src/lib/export-logs.ts +72 -5
- package/src/lib/providerTestContract.ts +0 -1
- package/src/lib/useProviders.ts +1 -1
- package/src/mcp/server.ts +14 -6
- package/src/mcp/toolHandlers.ts +21 -4
- package/src/proxy/chunkStorage.ts +2 -4
- package/src/proxy/dataDir.ts +3 -3
- package/src/proxy/formats/anthropic/index.ts +0 -1
- package/src/proxy/formats/anthropic/schemas.ts +0 -2
- package/src/proxy/handler.ts +41 -29
- package/src/proxy/logFinalizer.ts +93 -11
- package/src/proxy/logger.ts +35 -10
- package/src/proxy/providers.ts +12 -5
- package/src/proxy/rawStreamCapture.ts +85 -0
- package/src/proxy/schemas.ts +1 -51
- package/src/proxy/sessionRuntime.ts +0 -9
- package/src/proxy/socketTracker.ts +15 -8
- package/src/proxy/store.ts +414 -13
- package/src/routes/api/logs.$id.replay.ts +66 -1
- package/src/routes/api/logs.stream.ts +11 -3
- package/src/routes/api/logs.ts +51 -17
- package/src/routes/api/providers.$providerId.ts +10 -3
- package/src/routes/api/providers.ts +6 -3
- package/.output/public/assets/ProxyViewerContainer-BG7rc33d.js +0 -114
- package/.output/public/assets/ReplayDialog-DK6SPv8X.js +0 -1
- package/.output/public/assets/ResponseView-Bqpra4Zw.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-CdPbpprq.js +0 -1
- package/.output/public/assets/_sessionId-CsNARHj5.js +0 -1
- package/.output/public/assets/index-37NfO0zx.js +0 -1
- package/.output/public/assets/index-D_nZj9Vt.css +0 -1
- package/src/components/ui/json-expansion-button.tsx +0 -56
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/knowledge/sessions/$sessionId/candidates"], "preloads": ["/assets/main-
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/knowledge/sessions/$sessionId/candidates"], "preloads": ["/assets/main-o9-hg8g1.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-BbFsmQRC.js", "/assets/ProxyViewerContainer-CxRDWacg.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/mcp": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/mcp.ts" }, "/api/models": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/agent-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/agent-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/proxy/$.ts" }, "/session/$sessionId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/session/$sessionId.tsx", "assets": [], "preloads": ["/assets/_sessionId-CJ-SusES.js", "/assets/ProxyViewerContainer-CxRDWacg.js"] }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.paths.ts" }, "/api/knowledge/candidates": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.candidates.ts", "children": ["/api/knowledge/candidates/$candidateId"] }, "/api/knowledge/project-context": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.project-context.ts" }, "/api/knowledge/search": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.search.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/model-metadata", "/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.import.ts" }, "/api/providers/scan": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.scan.ts" }, "/api/knowledge/candidates/$candidateId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.candidates.$candidateId.ts", "children": ["/api/knowledge/candidates/$candidateId/promote"] }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/model-metadata": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.model-metadata.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.test.ts", "children": ["/api/providers/$providerId/test/log"] }, "/api/knowledge/candidates/$candidateId/promote": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.candidates.$candidateId.promote.ts" }, "/api/knowledge/sessions/$sessionId/candidates": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.sessions.$sessionId.candidates.ts" }, "/api/providers/$providerId/test/log": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.test.log.ts" } }, "clientEntry": "/assets/main-o9-hg8g1.js" });
|
|
2
2
|
export {
|
|
3
3
|
tsrStartManifest
|
|
4
4
|
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -38,100 +38,100 @@ const assets = {
|
|
|
38
38
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
39
39
|
"type": "image/svg+xml",
|
|
40
40
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
41
|
-
"mtime": "2026-06-
|
|
41
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
42
42
|
"size": 5915,
|
|
43
43
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
44
44
|
},
|
|
45
|
-
"/assets/
|
|
46
|
-
"type": "text/
|
|
47
|
-
"etag": '"
|
|
48
|
-
"mtime": "2026-06-
|
|
49
|
-
"size":
|
|
50
|
-
"path": "../public/assets/
|
|
45
|
+
"/assets/index-BfBgrkgU.css": {
|
|
46
|
+
"type": "text/css; charset=utf-8",
|
|
47
|
+
"etag": '"1a2c9-oAW5yRzaizIi778RSlqZhPc85Pw"',
|
|
48
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
49
|
+
"size": 107209,
|
|
50
|
+
"path": "../public/assets/index-BfBgrkgU.css"
|
|
51
51
|
},
|
|
52
|
-
"/assets/index-
|
|
52
|
+
"/assets/index-BbFsmQRC.js": {
|
|
53
53
|
"type": "text/javascript; charset=utf-8",
|
|
54
|
-
"etag": '"74-
|
|
55
|
-
"mtime": "2026-06-
|
|
54
|
+
"etag": '"74-vI6w+1iyboIWfJVk8/ech/2b8UY"',
|
|
55
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
56
56
|
"size": 116,
|
|
57
|
-
"path": "../public/assets/index-
|
|
57
|
+
"path": "../public/assets/index-BbFsmQRC.js"
|
|
58
58
|
},
|
|
59
|
-
"/assets/
|
|
60
|
-
"type": "text/
|
|
61
|
-
"etag": '"
|
|
62
|
-
"mtime": "2026-06-
|
|
63
|
-
"size":
|
|
64
|
-
"path": "../public/assets/
|
|
59
|
+
"/assets/CompareDrawer-D-90PIPw.js": {
|
|
60
|
+
"type": "text/javascript; charset=utf-8",
|
|
61
|
+
"etag": '"49fe-wIGG2knR51mFyL2vstdm6VenVaI"',
|
|
62
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
63
|
+
"size": 18942,
|
|
64
|
+
"path": "../public/assets/CompareDrawer-D-90PIPw.js"
|
|
65
65
|
},
|
|
66
66
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
67
67
|
"type": "image/jpeg",
|
|
68
68
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
69
|
-
"mtime": "2026-06-
|
|
69
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
70
70
|
"size": 6918,
|
|
71
71
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
72
72
|
},
|
|
73
|
-
"/assets/ReplayDialog-
|
|
73
|
+
"/assets/ReplayDialog-DzlLYoTO.js": {
|
|
74
74
|
"type": "text/javascript; charset=utf-8",
|
|
75
|
-
"etag": '"
|
|
76
|
-
"mtime": "2026-06-
|
|
77
|
-
"size":
|
|
78
|
-
"path": "../public/assets/ReplayDialog-
|
|
75
|
+
"etag": '"318c-bOjCbSP/w/aeX1kn9QRZtFGLMFY"',
|
|
76
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
77
|
+
"size": 12684,
|
|
78
|
+
"path": "../public/assets/ReplayDialog-DzlLYoTO.js"
|
|
79
79
|
},
|
|
80
|
-
"/assets/RequestAnatomy-
|
|
80
|
+
"/assets/RequestAnatomy-0hbyf6oa.js": {
|
|
81
81
|
"type": "text/javascript; charset=utf-8",
|
|
82
|
-
"etag": '"4485-
|
|
83
|
-
"mtime": "2026-06-
|
|
82
|
+
"etag": '"4485-EusuohynIBF0h9+uJ+g1znFjMpc"',
|
|
83
|
+
"mtime": "2026-06-29T02:52:50.787Z",
|
|
84
84
|
"size": 17541,
|
|
85
|
-
"path": "../public/assets/RequestAnatomy-
|
|
85
|
+
"path": "../public/assets/RequestAnatomy-0hbyf6oa.js"
|
|
86
86
|
},
|
|
87
|
-
"/assets/
|
|
87
|
+
"/assets/StreamingChunkSequence-enhfdeNh.js": {
|
|
88
88
|
"type": "text/javascript; charset=utf-8",
|
|
89
|
-
"etag": '"
|
|
90
|
-
"mtime": "2026-06-
|
|
91
|
-
"size":
|
|
92
|
-
"path": "../public/assets/
|
|
89
|
+
"etag": '"d57-tC/D5hLCBdTaOabqUAFaXVthebA"',
|
|
90
|
+
"mtime": "2026-06-29T02:52:50.787Z",
|
|
91
|
+
"size": 3415,
|
|
92
|
+
"path": "../public/assets/StreamingChunkSequence-enhfdeNh.js"
|
|
93
93
|
},
|
|
94
|
-
"/assets/
|
|
94
|
+
"/assets/ResponseView-CKe0tNqr.js": {
|
|
95
95
|
"type": "text/javascript; charset=utf-8",
|
|
96
|
-
"etag": '"
|
|
97
|
-
"mtime": "2026-06-
|
|
98
|
-
"size":
|
|
99
|
-
"path": "../public/assets/
|
|
96
|
+
"etag": '"30d0-N2ASszGo1KTiM+aCCKGHlqvDV+0"',
|
|
97
|
+
"mtime": "2026-06-29T02:52:50.787Z",
|
|
98
|
+
"size": 12496,
|
|
99
|
+
"path": "../public/assets/ResponseView-CKe0tNqr.js"
|
|
100
100
|
},
|
|
101
|
-
"/assets/
|
|
101
|
+
"/assets/_sessionId-CJ-SusES.js": {
|
|
102
102
|
"type": "text/javascript; charset=utf-8",
|
|
103
|
-
"etag": '"
|
|
104
|
-
"mtime": "2026-06-
|
|
105
|
-
"size":
|
|
106
|
-
"path": "../public/assets/
|
|
103
|
+
"etag": '"d2-B/4bxwxZCrYG2uo6f9Vw/Iubu34"',
|
|
104
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
105
|
+
"size": 210,
|
|
106
|
+
"path": "../public/assets/_sessionId-CJ-SusES.js"
|
|
107
107
|
},
|
|
108
108
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
109
109
|
"type": "image/svg+xml",
|
|
110
110
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
111
|
-
"mtime": "2026-06-
|
|
111
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
112
112
|
"size": 11256,
|
|
113
113
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
114
114
|
},
|
|
115
|
-
"/assets/
|
|
115
|
+
"/assets/main-o9-hg8g1.js": {
|
|
116
116
|
"type": "text/javascript; charset=utf-8",
|
|
117
|
-
"etag": '"
|
|
118
|
-
"mtime": "2026-06-
|
|
119
|
-
"size":
|
|
120
|
-
"path": "../public/assets/
|
|
117
|
+
"etag": '"51726-j0zx0pW0MFG6YpQKGgNUrH681sU"',
|
|
118
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
119
|
+
"size": 333606,
|
|
120
|
+
"path": "../public/assets/main-o9-hg8g1.js"
|
|
121
121
|
},
|
|
122
122
|
"/assets/qwen-CONDcHqt.png": {
|
|
123
123
|
"type": "image/png",
|
|
124
124
|
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
125
|
-
"mtime": "2026-06-
|
|
125
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
126
126
|
"size": 357059,
|
|
127
127
|
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
128
128
|
},
|
|
129
|
-
"/assets/ProxyViewerContainer-
|
|
129
|
+
"/assets/ProxyViewerContainer-CxRDWacg.js": {
|
|
130
130
|
"type": "text/javascript; charset=utf-8",
|
|
131
|
-
"etag": '"
|
|
132
|
-
"mtime": "2026-06-
|
|
133
|
-
"size":
|
|
134
|
-
"path": "../public/assets/ProxyViewerContainer-
|
|
131
|
+
"etag": '"ac0f7-VR6Thj9R1PGTEGYWEufABFZwNSM"',
|
|
132
|
+
"mtime": "2026-06-29T02:52:50.787Z",
|
|
133
|
+
"size": 704759,
|
|
134
|
+
"path": "../public/assets/ProxyViewerContainer-CxRDWacg.js"
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
137
|
function readAsset(id) {
|
package/README.md
CHANGED
|
@@ -103,6 +103,15 @@ ANTHROPIC_BASE_URL=http://localhost:25947/proxy <tool>
|
|
|
103
103
|
|
|
104
104
|
The web UI runs at http://localhost:25947.
|
|
105
105
|
|
|
106
|
+
## Documentation Map
|
|
107
|
+
|
|
108
|
+
- [Installation](docs/Installation.md): install and runtime notes.
|
|
109
|
+
- [Usage](docs/Usage.md): daily capture, browsing, replay, and export workflows.
|
|
110
|
+
- [MCP Server](docs/MCP-Server.md): MCP setup and tool usage for coding agents.
|
|
111
|
+
- [Troubleshooting](docs/TROUBLESHOOTING.md): port, provider, MCP, Replay, Jenkins, and GitCode fixes.
|
|
112
|
+
- [Jenkins + GitCode WebHook](docs/JENKINS_GITCODE_WEBHOOK_TUNNEL.md): team CI and tunnel setup.
|
|
113
|
+
- [Local Release Helper](docs/LOCAL_RELEASE.md): local maintainer release helper.
|
|
114
|
+
|
|
106
115
|
## Capture Modes
|
|
107
116
|
|
|
108
117
|
Agent Inspector starts in `simple` capture mode by default:
|
|
@@ -133,116 +142,9 @@ can also set `AGENT_INSPECTOR_MODE=full` or
|
|
|
133
142
|
`AGENT_INSPECTOR_CAPTURE_MODE=full`; the CLI flag takes precedence over the
|
|
134
143
|
environment.
|
|
135
144
|
|
|
136
|
-
## Jenkins
|
|
137
|
-
|
|
138
|
-
The `agent-inspector-release` Jenkins pipeline can be triggered from GitCode by
|
|
139
|
-
using the Jenkins Git plugin `notifyCommit` endpoint. The Jenkins instance must
|
|
140
|
-
be reachable from GitCode; `localhost`, LAN-only addresses, or NAT public IPs
|
|
141
|
-
without port forwarding will not work. Use a public Jenkins URL, a reverse
|
|
142
|
-
proxy, or a tunnel such as Cloudflare Tunnel, frp, or ngrok.
|
|
143
|
-
|
|
144
|
-
Create a GitCode WebHook under the repository settings with these values:
|
|
145
|
-
|
|
146
|
-
```text
|
|
147
|
-
URL:
|
|
148
|
-
https://<public-jenkins-host>/git/notifyCommit?url=https://gitcode.com/TonyClaw/agent-inspector&token=<jenkins-git-notify-token>
|
|
149
|
-
|
|
150
|
-
WebHook password/signing secret:
|
|
151
|
-
leave empty
|
|
152
|
-
|
|
153
|
-
POST content type:
|
|
154
|
-
application/json
|
|
155
|
-
|
|
156
|
-
Events:
|
|
157
|
-
Push events only
|
|
158
|
-
|
|
159
|
-
Active:
|
|
160
|
-
enabled
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
The Jenkins job must have SCM polling enabled so the Git plugin can schedule the
|
|
164
|
-
pipeline after receiving the `notifyCommit` request. Do not commit the real
|
|
165
|
-
Jenkins notify token to the repository.
|
|
166
|
-
|
|
167
|
-
### Local Push Fallback
|
|
168
|
-
|
|
169
|
-
When GitCode cannot reach a local Jenkins instance from the public internet, the
|
|
170
|
-
tracked Husky `pre-push` hook can notify Jenkins from the developer machine that
|
|
171
|
-
runs `git push`.
|
|
172
|
-
|
|
173
|
-
Configure the local secret values once per clone:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
git config --local agentInspector.jenkinsUrl http://localhost:8080
|
|
177
|
-
git config --local agentInspector.repositoryUrl https://gitcode.com/TonyClaw/agent-inspector
|
|
178
|
-
git config --local agentInspector.jenkinsNotifyToken <jenkins-git-notify-token>
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
On Windows PowerShell:
|
|
182
|
-
|
|
183
|
-
```powershell
|
|
184
|
-
git config --local agentInspector.jenkinsUrl http://localhost:8080
|
|
185
|
-
git config --local agentInspector.repositoryUrl https://gitcode.com/TonyClaw/agent-inspector
|
|
186
|
-
git config --local agentInspector.jenkinsNotifyToken <jenkins-git-notify-token>
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
After a `main` branch push, the hook waits briefly and then calls Jenkins
|
|
190
|
-
`/git/notifyCommit` from the local machine. The hook can also be configured with
|
|
191
|
-
environment variables instead of local Git config:
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
AGENT_INSPECTOR_JENKINS_URL=http://localhost:8080
|
|
195
|
-
AGENT_INSPECTOR_REPOSITORY_URL=https://gitcode.com/TonyClaw/agent-inspector
|
|
196
|
-
AGENT_INSPECTOR_JENKINS_NOTIFY_TOKEN=<jenkins-git-notify-token>
|
|
197
|
-
AGENT_INSPECTOR_JENKINS_PUSH_DELAY_SECONDS=10
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
The hook writes local diagnostics to `.git/hooks/jenkins-pre-push.log`. The
|
|
201
|
-
tracked template contains no secret values; every developer must configure their
|
|
202
|
-
own token locally.
|
|
203
|
-
|
|
204
|
-
For repositories that do not use Husky, install the same template as a native Git
|
|
205
|
-
hook:
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
cp scripts/hooks/pre-push-jenkins-notify .git/hooks/pre-push
|
|
209
|
-
chmod +x .git/hooks/pre-push
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Verified PR Workflow
|
|
213
|
-
|
|
214
|
-
For local Jenkins instances that GitCode cannot reach, use the verified PR script
|
|
215
|
-
instead of relying on GitCode WebHook delivery. The entire flow is outbound from
|
|
216
|
-
the developer machine:
|
|
217
|
-
|
|
218
|
-
1. Push the current commit to a temporary GitCode branch.
|
|
219
|
-
2. Trigger the local Jenkins job with `GIT_REF=<temporary-branch>`.
|
|
220
|
-
3. Wait for the Jenkins result.
|
|
221
|
-
4. Create a GitCode Pull Request to `main` only when Jenkins returns `SUCCESS`.
|
|
222
|
-
|
|
223
|
-
Configure local secrets once per clone:
|
|
224
|
-
|
|
225
|
-
```powershell
|
|
226
|
-
git config --local agentInspector.jenkinsUrl http://localhost:8080
|
|
227
|
-
git config --local agentInspector.jenkinsJob agent-inspector-release
|
|
228
|
-
git config --local agentInspector.jenkinsUser <jenkins-user>
|
|
229
|
-
git config --local agentInspector.jenkinsApiToken <jenkins-api-token>
|
|
230
|
-
git config --local agentInspector.gitcodeAccessToken <gitcode-access-token>
|
|
231
|
-
git config --local agentInspector.gitcodeOwner TonyClaw
|
|
232
|
-
git config --local agentInspector.gitcodeRepo agent-inspector
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Then run:
|
|
236
|
-
|
|
237
|
-
```powershell
|
|
238
|
-
.\scripts\jenkins\verified-pr.ps1
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
The script pushes a branch named like `jenkins-verify/<user>/<sha>`, waits for
|
|
242
|
-
Jenkins, and creates a PR through the GitCode API after a successful build. The
|
|
243
|
-
temporary branch is kept as the PR source branch and is configured for deletion
|
|
244
|
-
after merge when GitCode supports source-branch pruning.
|
|
145
|
+
## Jenkins And GitCode
|
|
245
146
|
|
|
147
|
+
Team CI, GitCode WebHook setup, Cloudflare Tunnel notes, local push fallback, and the verified PR workflow live in [Jenkins + GitCode WebHook](docs/JENKINS_GITCODE_WEBHOOK_TUNNEL.md). Keep real Jenkins notify tokens, GitCode access tokens, and tunnel URLs out of the repository.
|
|
246
148
|
## Project Direction
|
|
247
149
|
|
|
248
150
|
Agent Inspector should stay close to the proven inspector codebase while growing into an agent knowledge layer. The memory flow has four layers:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonyclaw/agent-inspector",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent observability and knowledge capture layer for AI coding tools.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"format:check": "biome format .",
|
|
58
58
|
"extension:zip": "node scripts/pack-chrome-extension.mjs",
|
|
59
59
|
"extension:release": "node scripts/release-chrome-extension.mjs",
|
|
60
|
+
"release": "node scripts/release.mjs",
|
|
60
61
|
"knip": "knip",
|
|
61
62
|
"check": "bun format && bun typecheck && bun lint",
|
|
62
63
|
"prepare": "husky",
|
package/src/cli/doctor.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join, resolve } from "node:path";
|
|
3
3
|
import { createConnection } from "node:net";
|
|
4
|
-
import { resolveDataDir } from "../proxy/dataDir";
|
|
4
|
+
import { migrateLegacyDataDirs, resolveDataDir } from "../proxy/dataDir";
|
|
5
5
|
|
|
6
6
|
const DEFAULT_PORT = 25947;
|
|
7
7
|
const PROBE_TIMEOUT_MS = 2000;
|
|
@@ -32,6 +32,9 @@ export type DoctorOptions = {
|
|
|
32
32
|
configDir: string | null;
|
|
33
33
|
providersJson: string | null;
|
|
34
34
|
chromeExtension: boolean;
|
|
35
|
+
fix: boolean;
|
|
36
|
+
json: boolean;
|
|
37
|
+
verbose: boolean;
|
|
35
38
|
help: boolean;
|
|
36
39
|
};
|
|
37
40
|
|
|
@@ -51,6 +54,7 @@ export type DoctorDeps = {
|
|
|
51
54
|
readText: (path: string) => string | null;
|
|
52
55
|
exists: (path: string) => boolean;
|
|
53
56
|
listDir: (path: string) => readonly string[] | null;
|
|
57
|
+
stat: (path: string) => { isDirectory: boolean; size: number } | null;
|
|
54
58
|
fetchHealth: (port: number) => Promise<HealthProbe>;
|
|
55
59
|
isPortOpen: (port: number) => Promise<boolean>;
|
|
56
60
|
};
|
|
@@ -89,6 +93,9 @@ export function parseDoctorArgs(
|
|
|
89
93
|
configDir: null,
|
|
90
94
|
providersJson: null,
|
|
91
95
|
chromeExtension: false,
|
|
96
|
+
fix: false,
|
|
97
|
+
json: false,
|
|
98
|
+
verbose: false,
|
|
92
99
|
help: false,
|
|
93
100
|
};
|
|
94
101
|
|
|
@@ -132,6 +139,15 @@ export function parseDoctorArgs(
|
|
|
132
139
|
case "--chrome-extension":
|
|
133
140
|
options.chromeExtension = true;
|
|
134
141
|
break;
|
|
142
|
+
case "--fix":
|
|
143
|
+
options.fix = true;
|
|
144
|
+
break;
|
|
145
|
+
case "--json":
|
|
146
|
+
options.json = true;
|
|
147
|
+
break;
|
|
148
|
+
case "--verbose":
|
|
149
|
+
options.verbose = true;
|
|
150
|
+
break;
|
|
135
151
|
default:
|
|
136
152
|
return { kind: "error", message: `doctor: unknown option ${arg}` };
|
|
137
153
|
}
|
|
@@ -307,6 +323,112 @@ function checkPackage(rootDir: string, deps: DoctorDeps): DoctorCheck {
|
|
|
307
323
|
}
|
|
308
324
|
}
|
|
309
325
|
|
|
326
|
+
function countFilesInDir(dir: string, deps: Pick<DoctorDeps, "listDir" | "stat">): number | null {
|
|
327
|
+
const files = deps.listDir(dir);
|
|
328
|
+
if (files === null) return null;
|
|
329
|
+
let count = 0;
|
|
330
|
+
for (const file of files) {
|
|
331
|
+
const fileStat = deps.stat(join(dir, file));
|
|
332
|
+
if (fileStat !== null && !fileStat.isDirectory) count += 1;
|
|
333
|
+
}
|
|
334
|
+
return count;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function formatBytes(bytes: number): string {
|
|
338
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
339
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
340
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MiB`;
|
|
341
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GiB`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function dirSize(
|
|
345
|
+
dir: string,
|
|
346
|
+
deps: Pick<DoctorDeps, "listDir" | "stat">,
|
|
347
|
+
depth = 0,
|
|
348
|
+
): number | null {
|
|
349
|
+
const dirStat = deps.stat(dir);
|
|
350
|
+
if (dirStat === null) return null;
|
|
351
|
+
if (!dirStat.isDirectory) return dirStat.size;
|
|
352
|
+
if (depth > 4) return 0;
|
|
353
|
+
|
|
354
|
+
const files = deps.listDir(dir);
|
|
355
|
+
if (files === null) return null;
|
|
356
|
+
let total = 0;
|
|
357
|
+
for (const file of files) {
|
|
358
|
+
const childSize = dirSize(join(dir, file), deps, depth + 1);
|
|
359
|
+
if (childSize !== null) total += childSize;
|
|
360
|
+
}
|
|
361
|
+
return total;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function verboseChecks(options: DoctorOptions, deps: DoctorDeps): readonly DoctorCheck[] {
|
|
365
|
+
const dataDir = resolveDefaultDataDir(deps.env, deps.platform, deps.exists);
|
|
366
|
+
const logsDir = join(dataDir, "logs");
|
|
367
|
+
const chunksDir = join(dataDir, "chunks");
|
|
368
|
+
const providerCandidates = providerConfigCandidates(options, deps);
|
|
369
|
+
const captureMode =
|
|
370
|
+
deps.env["AGENT_INSPECTOR_MODE"] ?? deps.env["AGENT_INSPECTOR_CAPTURE_MODE"] ?? "simple";
|
|
371
|
+
const logCount = countFilesInDir(logsDir, deps);
|
|
372
|
+
const logSize = dirSize(logsDir, deps);
|
|
373
|
+
const chunkSize = dirSize(chunksDir, deps);
|
|
374
|
+
const homeDir =
|
|
375
|
+
deps.platform === "win32"
|
|
376
|
+
? (deps.env["USERPROFILE"] ?? deps.env["APPDATA"] ?? null)
|
|
377
|
+
: (deps.env["HOME"] ?? null);
|
|
378
|
+
const claudeSkill =
|
|
379
|
+
homeDir === null
|
|
380
|
+
? null
|
|
381
|
+
: join(homeDir, ".claude", "skills", "agent-inspector-onboard", "SKILL.md");
|
|
382
|
+
const claudeCommand =
|
|
383
|
+
homeDir === null ? null : join(homeDir, ".claude", "commands", "agent-inspector-onboard.md");
|
|
384
|
+
const codexSkill =
|
|
385
|
+
homeDir === null
|
|
386
|
+
? null
|
|
387
|
+
: join(homeDir, ".codex", "skills", "agent-inspector-onboard", "SKILL.md");
|
|
388
|
+
const hasClaudeOnboarding =
|
|
389
|
+
claudeSkill !== null &&
|
|
390
|
+
claudeCommand !== null &&
|
|
391
|
+
deps.exists(claudeSkill) &&
|
|
392
|
+
deps.exists(claudeCommand);
|
|
393
|
+
const hasCodexOnboarding = codexSkill !== null && deps.exists(codexSkill);
|
|
394
|
+
|
|
395
|
+
return [
|
|
396
|
+
check("Data directory", "pass", dataDir),
|
|
397
|
+
check("Provider config search", "pass", providerCandidates.join(", ")),
|
|
398
|
+
check("Capture mode env", "pass", captureMode),
|
|
399
|
+
check(
|
|
400
|
+
"Log storage",
|
|
401
|
+
logCount === null ? "warn" : "pass",
|
|
402
|
+
logCount === null
|
|
403
|
+
? `Log directory was not found or could not be read: ${logsDir}`
|
|
404
|
+
: `${logCount} file(s), ${formatBytes(logSize ?? 0)} under ${logsDir}`,
|
|
405
|
+
),
|
|
406
|
+
check(
|
|
407
|
+
"Chunk storage",
|
|
408
|
+
chunkSize === null ? "warn" : "pass",
|
|
409
|
+
chunkSize === null
|
|
410
|
+
? `Chunk directory was not found or could not be read: ${chunksDir}`
|
|
411
|
+
: `${formatBytes(chunkSize)} under ${chunksDir}`,
|
|
412
|
+
),
|
|
413
|
+
check(
|
|
414
|
+
"Claude onboarding",
|
|
415
|
+
hasClaudeOnboarding ? "pass" : "warn",
|
|
416
|
+
hasClaudeOnboarding
|
|
417
|
+
? "Claude Code skill and slash command are installed."
|
|
418
|
+
: "Claude Code onboarding files were not found.",
|
|
419
|
+
"Run `agent-inspector onboard --force` after installing or upgrading.",
|
|
420
|
+
),
|
|
421
|
+
check(
|
|
422
|
+
"Codex onboarding",
|
|
423
|
+
hasCodexOnboarding ? "pass" : "warn",
|
|
424
|
+
hasCodexOnboarding
|
|
425
|
+
? "Codex onboarding skill is installed."
|
|
426
|
+
: "Codex onboarding skill was not found.",
|
|
427
|
+
"Run `agent-inspector onboard --force` after installing or upgrading.",
|
|
428
|
+
),
|
|
429
|
+
];
|
|
430
|
+
}
|
|
431
|
+
|
|
310
432
|
function checkExtensionSource(rootDir: string, deps: DoctorDeps): DoctorCheck {
|
|
311
433
|
const extensionDir = join(rootDir, "extensions", "chrome");
|
|
312
434
|
const missing = EXTENSION_REQUIRED_FILES.filter((file) => !deps.exists(join(extensionDir, file)));
|
|
@@ -406,9 +528,12 @@ export async function buildDoctorReport(
|
|
|
406
528
|
checkProviderConfig(options, deps),
|
|
407
529
|
checkPackage(rootDir, deps),
|
|
408
530
|
];
|
|
409
|
-
const
|
|
531
|
+
const checksWithExtension = options.chromeExtension
|
|
410
532
|
? [...coreChecks, checkExtensionSource(rootDir, deps), checkExtensionPackage(rootDir, deps)]
|
|
411
533
|
: coreChecks;
|
|
534
|
+
const checks = options.verbose
|
|
535
|
+
? [...checksWithExtension, ...verboseChecks(options, deps)]
|
|
536
|
+
: checksWithExtension;
|
|
412
537
|
|
|
413
538
|
const passCount = checks.filter((item) => item.severity === "pass").length;
|
|
414
539
|
const warnCount = checks.filter((item) => item.severity === "warn").length;
|
|
@@ -438,14 +563,21 @@ export function formatDoctorReport(report: DoctorReport): string {
|
|
|
438
563
|
return `${lines.join("\n")}\n`;
|
|
439
564
|
}
|
|
440
565
|
|
|
566
|
+
export function formatDoctorJson(report: DoctorReport): string {
|
|
567
|
+
return `${JSON.stringify(report, null, 2)}\n`;
|
|
568
|
+
}
|
|
569
|
+
|
|
441
570
|
export function doctorHelp(): string {
|
|
442
571
|
return [
|
|
443
572
|
"agent-inspector doctor",
|
|
444
573
|
"",
|
|
445
574
|
"Usage:",
|
|
446
|
-
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>] [--chrome-extension]",
|
|
575
|
+
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>] [--fix] [--json] [--verbose] [--chrome-extension]",
|
|
447
576
|
"",
|
|
448
577
|
"Checks local proxy health, provider config presence, and package metadata.",
|
|
578
|
+
"Pass --fix to run safe local repairs before checks, including legacy data-dir migration.",
|
|
579
|
+
"Pass --json to emit a machine-readable report for CI, scripts, and Jenkins.",
|
|
580
|
+
"Pass --verbose to include local paths, capture mode, and log storage checks.",
|
|
449
581
|
"Pass --chrome-extension to also check Chrome companion source and packaged artifacts.",
|
|
450
582
|
"",
|
|
451
583
|
].join("\n");
|
|
@@ -499,6 +631,15 @@ function listDir(path: string): readonly string[] | null {
|
|
|
499
631
|
}
|
|
500
632
|
}
|
|
501
633
|
|
|
634
|
+
function stat(path: string): { isDirectory: boolean; size: number } | null {
|
|
635
|
+
try {
|
|
636
|
+
const fileStat = statSync(path);
|
|
637
|
+
return { isDirectory: fileStat.isDirectory(), size: fileStat.size };
|
|
638
|
+
} catch {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
502
643
|
export function createDoctorDeps(): DoctorDeps {
|
|
503
644
|
return {
|
|
504
645
|
env: process.env,
|
|
@@ -507,6 +648,7 @@ export function createDoctorDeps(): DoctorDeps {
|
|
|
507
648
|
exists: existsSync,
|
|
508
649
|
readText,
|
|
509
650
|
listDir,
|
|
651
|
+
stat,
|
|
510
652
|
fetchHealth,
|
|
511
653
|
isPortOpen,
|
|
512
654
|
};
|
|
@@ -522,7 +664,10 @@ export async function runDoctor(argv: readonly string[]): Promise<number> {
|
|
|
522
664
|
process.stdout.write(doctorHelp());
|
|
523
665
|
return 0;
|
|
524
666
|
}
|
|
667
|
+
if (parsed.options.fix) {
|
|
668
|
+
migrateLegacyDataDirs();
|
|
669
|
+
}
|
|
525
670
|
const report = await buildDoctorReport(parsed.options);
|
|
526
|
-
process.stdout.write(formatDoctorReport(report));
|
|
671
|
+
process.stdout.write(parsed.options.json ? formatDoctorJson(report) : formatDoctorReport(report));
|
|
527
672
|
return report.exitCode;
|
|
528
673
|
}
|
|
@@ -25,41 +25,41 @@ export function OnboardingBanner(): JSX.Element | null {
|
|
|
25
25
|
? "Agent Inspector is ready in Full mode"
|
|
26
26
|
: "Agent Inspector is ready in Simple mode"}
|
|
27
27
|
</div>
|
|
28
|
-
<
|
|
28
|
+
<ol className="space-y-0.5 text-xs leading-relaxed text-muted-foreground">
|
|
29
|
+
<li>
|
|
30
|
+
<strong>1. Start in the right mode</strong>: this process is currently running in{" "}
|
|
31
|
+
<code>{captureMode}</code>. Mode is fixed at startup.
|
|
32
|
+
</li>
|
|
29
33
|
{isFullMode ? (
|
|
30
34
|
<>
|
|
31
35
|
<li>
|
|
32
|
-
<strong>Full
|
|
33
|
-
for
|
|
36
|
+
<strong>2. Full diagnostics</strong>: raw headers, raw response, and SSE chunks are
|
|
37
|
+
captured for deep investigations.
|
|
34
38
|
</li>
|
|
35
39
|
<li>
|
|
36
|
-
<strong>Daily work</strong>: restart with
|
|
37
|
-
to reduce capture overhead.
|
|
40
|
+
<strong>3. Daily work</strong>: restart with{" "}
|
|
41
|
+
<code>agent-inspector --mode simple</code> to reduce capture overhead.
|
|
38
42
|
</li>
|
|
39
43
|
</>
|
|
40
44
|
) : (
|
|
41
45
|
<>
|
|
42
46
|
<li>
|
|
43
|
-
<strong>Simple
|
|
44
|
-
|
|
47
|
+
<strong>2. Simple capture</strong>: requests, responses, tools, timing, tokens,
|
|
48
|
+
replay, and memory candidates are available with lower overhead.
|
|
45
49
|
</li>
|
|
46
50
|
<li>
|
|
47
|
-
<strong>Need diagnostics?</strong> Restart with{" "}
|
|
51
|
+
<strong>3. Need raw diagnostics?</strong> Restart with{" "}
|
|
48
52
|
<code>agent-inspector --mode full</code> for raw headers, raw response, and SSE
|
|
49
53
|
chunks.
|
|
50
54
|
</li>
|
|
51
55
|
</>
|
|
52
56
|
)}
|
|
53
|
-
<li>
|
|
54
|
-
<strong>Replay and Memory</strong>: available in both modes for provider checks and
|
|
55
|
-
reviewable knowledge candidates.
|
|
56
|
-
</li>
|
|
57
57
|
<li>
|
|
58
58
|
<strong>Agent setup</strong>: run <code>agent-inspector onboard --status</code>, then
|
|
59
59
|
use <code>/agent-inspector:onboard</code> in Claude Code or ask Codex to use{" "}
|
|
60
60
|
<code>agent-inspector-onboard</code>.
|
|
61
61
|
</li>
|
|
62
|
-
</
|
|
62
|
+
</ol>
|
|
63
63
|
</div>
|
|
64
64
|
<button
|
|
65
65
|
type="button"
|