@tonyclaw/agent-inspector 2.0.17 → 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 +149 -40
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-DDg7Cs4N.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-DR8OICOJ.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-bwZlEXw2.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-BEuJJhqT.mjs → _sessionId-F8lm6PIb.mjs} +3 -2
- package/.output/server/_ssr/{CompareDrawer-yTO93GMz.mjs → CompareDrawer-Cf1yfwfd.mjs} +4 -3
- package/.output/server/_ssr/{ProxyViewerContainer-C8qCkHGB.mjs → ProxyViewerContainer-Bmu9867L.mjs} +349 -74
- package/.output/server/_ssr/{ReplayDialog-DRF9PG7Z.mjs → ReplayDialog-DxZfLBOe.mjs} +199 -17
- package/.output/server/_ssr/{RequestAnatomy-DBcuV_jV.mjs → RequestAnatomy-CbdERGZd.mjs} +4 -3
- package/.output/server/_ssr/{ResponseView-JJm78HZT.mjs → ResponseView-CvLd6qxI.mjs} +4 -3
- package/.output/server/_ssr/{StreamingChunkSequence-DyGKjBYx.mjs → StreamingChunkSequence-B_lkRB6o.mjs} +4 -3
- package/.output/server/_ssr/{index-T7JG28t6.mjs → index-ejrSItfz.mjs} +3 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-BJob8RN3.mjs → router-SbCnbDc2.mjs} +896 -240
- package/.output/server/{_tanstack-start-manifest_v-CuiFi3XC.mjs → _tanstack-start-manifest_v-yx8ftqWz.mjs} +1 -1
- package/.output/server/index.mjs +60 -60
- package/README.md +26 -109
- package/package.json +2 -1
- package/src/cli/doctor.ts +160 -8
- package/src/cli/templates/skill-onboard.ts +2 -20
- 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 +37 -15
- 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-DbbK1y7N.js +0 -114
- package/.output/public/assets/ReplayDialog-C1zWNkoz.js +0 -1
- package/.output/public/assets/ResponseView-Dh9iSj6h.js +0 -1
- package/.output/public/assets/StreamingChunkSequence-B_xElyH3.js +0 -1
- package/.output/public/assets/_sessionId-gv1a_NNu.js +0 -1
- package/.output/public/assets/index-D_nZj9Vt.css +0 -1
- package/.output/public/assets/index-u-LwDaeH.js +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/javascript; charset=utf-8",
|
|
47
|
-
"etag": '"49fe-ST4mvhJApf3tK3AHGe/jnh7b8dA"',
|
|
48
|
-
"mtime": "2026-06-27T08:05:44.395Z",
|
|
49
|
-
"size": 18942,
|
|
50
|
-
"path": "../public/assets/CompareDrawer-DDg7Cs4N.js"
|
|
51
|
-
},
|
|
52
|
-
"/assets/index-D_nZj9Vt.css": {
|
|
45
|
+
"/assets/index-BfBgrkgU.css": {
|
|
53
46
|
"type": "text/css; charset=utf-8",
|
|
54
|
-
"etag": '"
|
|
55
|
-
"mtime": "2026-06-
|
|
56
|
-
"size":
|
|
57
|
-
"path": "../public/assets/index-
|
|
47
|
+
"etag": '"1a2c9-oAW5yRzaizIi778RSlqZhPc85Pw"',
|
|
48
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
49
|
+
"size": 107209,
|
|
50
|
+
"path": "../public/assets/index-BfBgrkgU.css"
|
|
58
51
|
},
|
|
59
|
-
"/assets/index-
|
|
52
|
+
"/assets/index-BbFsmQRC.js": {
|
|
60
53
|
"type": "text/javascript; charset=utf-8",
|
|
61
|
-
"etag": '"74-
|
|
62
|
-
"mtime": "2026-06-
|
|
54
|
+
"etag": '"74-vI6w+1iyboIWfJVk8/ech/2b8UY"',
|
|
55
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
63
56
|
"size": 116,
|
|
64
|
-
"path": "../public/assets/index-
|
|
57
|
+
"path": "../public/assets/index-BbFsmQRC.js"
|
|
65
58
|
},
|
|
66
|
-
"/assets/
|
|
59
|
+
"/assets/CompareDrawer-D-90PIPw.js": {
|
|
67
60
|
"type": "text/javascript; charset=utf-8",
|
|
68
|
-
"etag": '"
|
|
69
|
-
"mtime": "2026-06-
|
|
70
|
-
"size":
|
|
71
|
-
"path": "../public/assets/
|
|
72
|
-
},
|
|
73
|
-
"/assets/RequestAnatomy-DR8OICOJ.js": {
|
|
74
|
-
"type": "text/javascript; charset=utf-8",
|
|
75
|
-
"etag": '"4485-N9GhW/2QqcCw31XDu4TtvnszBGI"',
|
|
76
|
-
"mtime": "2026-06-27T08:05:44.396Z",
|
|
77
|
-
"size": 17541,
|
|
78
|
-
"path": "../public/assets/RequestAnatomy-DR8OICOJ.js"
|
|
61
|
+
"etag": '"49fe-wIGG2knR51mFyL2vstdm6VenVaI"',
|
|
62
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
63
|
+
"size": 18942,
|
|
64
|
+
"path": "../public/assets/CompareDrawer-D-90PIPw.js"
|
|
79
65
|
},
|
|
80
66
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
81
67
|
"type": "image/jpeg",
|
|
82
68
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
83
|
-
"mtime": "2026-06-
|
|
69
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
84
70
|
"size": 6918,
|
|
85
71
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
86
72
|
},
|
|
87
|
-
"/assets/
|
|
73
|
+
"/assets/ReplayDialog-DzlLYoTO.js": {
|
|
88
74
|
"type": "text/javascript; charset=utf-8",
|
|
89
|
-
"etag": '"
|
|
90
|
-
"mtime": "2026-06-
|
|
91
|
-
"size":
|
|
92
|
-
"path": "../public/assets/
|
|
75
|
+
"etag": '"318c-bOjCbSP/w/aeX1kn9QRZtFGLMFY"',
|
|
76
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
77
|
+
"size": 12684,
|
|
78
|
+
"path": "../public/assets/ReplayDialog-DzlLYoTO.js"
|
|
93
79
|
},
|
|
94
|
-
"/assets/
|
|
95
|
-
"type": "
|
|
96
|
-
"etag": '"
|
|
97
|
-
"mtime": "2026-06-
|
|
98
|
-
"size":
|
|
99
|
-
"path": "../public/assets/
|
|
80
|
+
"/assets/RequestAnatomy-0hbyf6oa.js": {
|
|
81
|
+
"type": "text/javascript; charset=utf-8",
|
|
82
|
+
"etag": '"4485-EusuohynIBF0h9+uJ+g1znFjMpc"',
|
|
83
|
+
"mtime": "2026-06-29T02:52:50.787Z",
|
|
84
|
+
"size": 17541,
|
|
85
|
+
"path": "../public/assets/RequestAnatomy-0hbyf6oa.js"
|
|
100
86
|
},
|
|
101
|
-
"/assets/StreamingChunkSequence-
|
|
87
|
+
"/assets/StreamingChunkSequence-enhfdeNh.js": {
|
|
102
88
|
"type": "text/javascript; charset=utf-8",
|
|
103
|
-
"etag": '"
|
|
104
|
-
"mtime": "2026-06-
|
|
105
|
-
"size":
|
|
106
|
-
"path": "../public/assets/StreamingChunkSequence-
|
|
89
|
+
"etag": '"d57-tC/D5hLCBdTaOabqUAFaXVthebA"',
|
|
90
|
+
"mtime": "2026-06-29T02:52:50.787Z",
|
|
91
|
+
"size": 3415,
|
|
92
|
+
"path": "../public/assets/StreamingChunkSequence-enhfdeNh.js"
|
|
107
93
|
},
|
|
108
|
-
"/assets/
|
|
94
|
+
"/assets/ResponseView-CKe0tNqr.js": {
|
|
109
95
|
"type": "text/javascript; charset=utf-8",
|
|
110
|
-
"etag": '"
|
|
111
|
-
"mtime": "2026-06-
|
|
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
|
+
},
|
|
101
|
+
"/assets/_sessionId-CJ-SusES.js": {
|
|
102
|
+
"type": "text/javascript; charset=utf-8",
|
|
103
|
+
"etag": '"d2-B/4bxwxZCrYG2uo6f9Vw/Iubu34"',
|
|
104
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
112
105
|
"size": 210,
|
|
113
|
-
"path": "../public/assets/_sessionId-
|
|
106
|
+
"path": "../public/assets/_sessionId-CJ-SusES.js"
|
|
107
|
+
},
|
|
108
|
+
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
109
|
+
"type": "image/svg+xml",
|
|
110
|
+
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
111
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
112
|
+
"size": 11256,
|
|
113
|
+
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
114
114
|
},
|
|
115
|
-
"/assets/main-
|
|
115
|
+
"/assets/main-o9-hg8g1.js": {
|
|
116
116
|
"type": "text/javascript; charset=utf-8",
|
|
117
|
-
"etag": '"51726-
|
|
118
|
-
"mtime": "2026-06-
|
|
117
|
+
"etag": '"51726-j0zx0pW0MFG6YpQKGgNUrH681sU"',
|
|
118
|
+
"mtime": "2026-06-29T02:52:50.786Z",
|
|
119
119
|
"size": 333606,
|
|
120
|
-
"path": "../public/assets/main-
|
|
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
|
@@ -80,6 +80,21 @@ bun install
|
|
|
80
80
|
bun run dev
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
Run a local health check when you need to verify the proxy and installed
|
|
84
|
+
configuration:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
agent-inspector doctor
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The default doctor check covers proxy health, provider configuration, and
|
|
91
|
+
package metadata. Chrome companion source and zip artifacts are optional and
|
|
92
|
+
only checked when you ask for them explicitly:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
agent-inspector doctor --chrome-extension
|
|
96
|
+
```
|
|
97
|
+
|
|
83
98
|
Then point an AI coding tool at the proxy:
|
|
84
99
|
|
|
85
100
|
```bash
|
|
@@ -88,6 +103,15 @@ ANTHROPIC_BASE_URL=http://localhost:25947/proxy <tool>
|
|
|
88
103
|
|
|
89
104
|
The web UI runs at http://localhost:25947.
|
|
90
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
|
+
|
|
91
115
|
## Capture Modes
|
|
92
116
|
|
|
93
117
|
Agent Inspector starts in `simple` capture mode by default:
|
|
@@ -118,116 +142,9 @@ can also set `AGENT_INSPECTOR_MODE=full` or
|
|
|
118
142
|
`AGENT_INSPECTOR_CAPTURE_MODE=full`; the CLI flag takes precedence over the
|
|
119
143
|
environment.
|
|
120
144
|
|
|
121
|
-
## Jenkins
|
|
122
|
-
|
|
123
|
-
The `agent-inspector-release` Jenkins pipeline can be triggered from GitCode by
|
|
124
|
-
using the Jenkins Git plugin `notifyCommit` endpoint. The Jenkins instance must
|
|
125
|
-
be reachable from GitCode; `localhost`, LAN-only addresses, or NAT public IPs
|
|
126
|
-
without port forwarding will not work. Use a public Jenkins URL, a reverse
|
|
127
|
-
proxy, or a tunnel such as Cloudflare Tunnel, frp, or ngrok.
|
|
128
|
-
|
|
129
|
-
Create a GitCode WebHook under the repository settings with these values:
|
|
130
|
-
|
|
131
|
-
```text
|
|
132
|
-
URL:
|
|
133
|
-
https://<public-jenkins-host>/git/notifyCommit?url=https://gitcode.com/TonyClaw/agent-inspector&token=<jenkins-git-notify-token>
|
|
134
|
-
|
|
135
|
-
WebHook password/signing secret:
|
|
136
|
-
leave empty
|
|
137
|
-
|
|
138
|
-
POST content type:
|
|
139
|
-
application/json
|
|
140
|
-
|
|
141
|
-
Events:
|
|
142
|
-
Push events only
|
|
143
|
-
|
|
144
|
-
Active:
|
|
145
|
-
enabled
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
The Jenkins job must have SCM polling enabled so the Git plugin can schedule the
|
|
149
|
-
pipeline after receiving the `notifyCommit` request. Do not commit the real
|
|
150
|
-
Jenkins notify token to the repository.
|
|
151
|
-
|
|
152
|
-
### Local Push Fallback
|
|
153
|
-
|
|
154
|
-
When GitCode cannot reach a local Jenkins instance from the public internet, the
|
|
155
|
-
tracked Husky `pre-push` hook can notify Jenkins from the developer machine that
|
|
156
|
-
runs `git push`.
|
|
157
|
-
|
|
158
|
-
Configure the local secret values once per clone:
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
git config --local agentInspector.jenkinsUrl http://localhost:8080
|
|
162
|
-
git config --local agentInspector.repositoryUrl https://gitcode.com/TonyClaw/agent-inspector
|
|
163
|
-
git config --local agentInspector.jenkinsNotifyToken <jenkins-git-notify-token>
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
On Windows PowerShell:
|
|
167
|
-
|
|
168
|
-
```powershell
|
|
169
|
-
git config --local agentInspector.jenkinsUrl http://localhost:8080
|
|
170
|
-
git config --local agentInspector.repositoryUrl https://gitcode.com/TonyClaw/agent-inspector
|
|
171
|
-
git config --local agentInspector.jenkinsNotifyToken <jenkins-git-notify-token>
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
After a `main` branch push, the hook waits briefly and then calls Jenkins
|
|
175
|
-
`/git/notifyCommit` from the local machine. The hook can also be configured with
|
|
176
|
-
environment variables instead of local Git config:
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
AGENT_INSPECTOR_JENKINS_URL=http://localhost:8080
|
|
180
|
-
AGENT_INSPECTOR_REPOSITORY_URL=https://gitcode.com/TonyClaw/agent-inspector
|
|
181
|
-
AGENT_INSPECTOR_JENKINS_NOTIFY_TOKEN=<jenkins-git-notify-token>
|
|
182
|
-
AGENT_INSPECTOR_JENKINS_PUSH_DELAY_SECONDS=10
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
The hook writes local diagnostics to `.git/hooks/jenkins-pre-push.log`. The
|
|
186
|
-
tracked template contains no secret values; every developer must configure their
|
|
187
|
-
own token locally.
|
|
188
|
-
|
|
189
|
-
For repositories that do not use Husky, install the same template as a native Git
|
|
190
|
-
hook:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
cp scripts/hooks/pre-push-jenkins-notify .git/hooks/pre-push
|
|
194
|
-
chmod +x .git/hooks/pre-push
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### Verified PR Workflow
|
|
198
|
-
|
|
199
|
-
For local Jenkins instances that GitCode cannot reach, use the verified PR script
|
|
200
|
-
instead of relying on GitCode WebHook delivery. The entire flow is outbound from
|
|
201
|
-
the developer machine:
|
|
202
|
-
|
|
203
|
-
1. Push the current commit to a temporary GitCode branch.
|
|
204
|
-
2. Trigger the local Jenkins job with `GIT_REF=<temporary-branch>`.
|
|
205
|
-
3. Wait for the Jenkins result.
|
|
206
|
-
4. Create a GitCode Pull Request to `main` only when Jenkins returns `SUCCESS`.
|
|
207
|
-
|
|
208
|
-
Configure local secrets once per clone:
|
|
209
|
-
|
|
210
|
-
```powershell
|
|
211
|
-
git config --local agentInspector.jenkinsUrl http://localhost:8080
|
|
212
|
-
git config --local agentInspector.jenkinsJob agent-inspector-release
|
|
213
|
-
git config --local agentInspector.jenkinsUser <jenkins-user>
|
|
214
|
-
git config --local agentInspector.jenkinsApiToken <jenkins-api-token>
|
|
215
|
-
git config --local agentInspector.gitcodeAccessToken <gitcode-access-token>
|
|
216
|
-
git config --local agentInspector.gitcodeOwner TonyClaw
|
|
217
|
-
git config --local agentInspector.gitcodeRepo agent-inspector
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Then run:
|
|
221
|
-
|
|
222
|
-
```powershell
|
|
223
|
-
.\scripts\jenkins\verified-pr.ps1
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
The script pushes a branch named like `jenkins-verify/<user>/<sha>`, waits for
|
|
227
|
-
Jenkins, and creates a PR through the GitCode API after a successful build. The
|
|
228
|
-
temporary branch is kept as the PR source branch and is configured for deletion
|
|
229
|
-
after merge when GitCode supports source-branch pruning.
|
|
145
|
+
## Jenkins And GitCode
|
|
230
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.
|
|
231
148
|
## Project Direction
|
|
232
149
|
|
|
233
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;
|
|
@@ -31,6 +31,10 @@ export type DoctorOptions = {
|
|
|
31
31
|
port: number;
|
|
32
32
|
configDir: string | null;
|
|
33
33
|
providersJson: string | null;
|
|
34
|
+
chromeExtension: boolean;
|
|
35
|
+
fix: boolean;
|
|
36
|
+
json: boolean;
|
|
37
|
+
verbose: boolean;
|
|
34
38
|
help: boolean;
|
|
35
39
|
};
|
|
36
40
|
|
|
@@ -50,6 +54,7 @@ export type DoctorDeps = {
|
|
|
50
54
|
readText: (path: string) => string | null;
|
|
51
55
|
exists: (path: string) => boolean;
|
|
52
56
|
listDir: (path: string) => readonly string[] | null;
|
|
57
|
+
stat: (path: string) => { isDirectory: boolean; size: number } | null;
|
|
53
58
|
fetchHealth: (port: number) => Promise<HealthProbe>;
|
|
54
59
|
isPortOpen: (port: number) => Promise<boolean>;
|
|
55
60
|
};
|
|
@@ -87,6 +92,10 @@ export function parseDoctorArgs(
|
|
|
87
92
|
port: envPort ?? DEFAULT_PORT,
|
|
88
93
|
configDir: null,
|
|
89
94
|
providersJson: null,
|
|
95
|
+
chromeExtension: false,
|
|
96
|
+
fix: false,
|
|
97
|
+
json: false,
|
|
98
|
+
verbose: false,
|
|
90
99
|
help: false,
|
|
91
100
|
};
|
|
92
101
|
|
|
@@ -127,6 +136,18 @@ export function parseDoctorArgs(
|
|
|
127
136
|
i++;
|
|
128
137
|
break;
|
|
129
138
|
}
|
|
139
|
+
case "--chrome-extension":
|
|
140
|
+
options.chromeExtension = true;
|
|
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;
|
|
130
151
|
default:
|
|
131
152
|
return { kind: "error", message: `doctor: unknown option ${arg}` };
|
|
132
153
|
}
|
|
@@ -302,6 +323,112 @@ function checkPackage(rootDir: string, deps: DoctorDeps): DoctorCheck {
|
|
|
302
323
|
}
|
|
303
324
|
}
|
|
304
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
|
+
|
|
305
432
|
function checkExtensionSource(rootDir: string, deps: DoctorDeps): DoctorCheck {
|
|
306
433
|
const extensionDir = join(rootDir, "extensions", "chrome");
|
|
307
434
|
const missing = EXTENSION_REQUIRED_FILES.filter((file) => !deps.exists(join(extensionDir, file)));
|
|
@@ -396,13 +523,17 @@ export async function buildDoctorReport(
|
|
|
396
523
|
deps: DoctorDeps = createDoctorDeps(),
|
|
397
524
|
): Promise<DoctorReport> {
|
|
398
525
|
const rootDir = findProjectRoot(deps.cwd, deps);
|
|
399
|
-
const
|
|
526
|
+
const coreChecks = [
|
|
400
527
|
await checkProxyHealth(options.port, deps),
|
|
401
528
|
checkProviderConfig(options, deps),
|
|
402
529
|
checkPackage(rootDir, deps),
|
|
403
|
-
checkExtensionSource(rootDir, deps),
|
|
404
|
-
checkExtensionPackage(rootDir, deps),
|
|
405
530
|
];
|
|
531
|
+
const checksWithExtension = options.chromeExtension
|
|
532
|
+
? [...coreChecks, checkExtensionSource(rootDir, deps), checkExtensionPackage(rootDir, deps)]
|
|
533
|
+
: coreChecks;
|
|
534
|
+
const checks = options.verbose
|
|
535
|
+
? [...checksWithExtension, ...verboseChecks(options, deps)]
|
|
536
|
+
: checksWithExtension;
|
|
406
537
|
|
|
407
538
|
const passCount = checks.filter((item) => item.severity === "pass").length;
|
|
408
539
|
const warnCount = checks.filter((item) => item.severity === "warn").length;
|
|
@@ -432,14 +563,22 @@ export function formatDoctorReport(report: DoctorReport): string {
|
|
|
432
563
|
return `${lines.join("\n")}\n`;
|
|
433
564
|
}
|
|
434
565
|
|
|
566
|
+
export function formatDoctorJson(report: DoctorReport): string {
|
|
567
|
+
return `${JSON.stringify(report, null, 2)}\n`;
|
|
568
|
+
}
|
|
569
|
+
|
|
435
570
|
export function doctorHelp(): string {
|
|
436
571
|
return [
|
|
437
572
|
"agent-inspector doctor",
|
|
438
573
|
"",
|
|
439
574
|
"Usage:",
|
|
440
|
-
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>]",
|
|
575
|
+
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>] [--fix] [--json] [--verbose] [--chrome-extension]",
|
|
441
576
|
"",
|
|
442
|
-
"Checks local proxy health, provider config presence, package metadata
|
|
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.",
|
|
581
|
+
"Pass --chrome-extension to also check Chrome companion source and packaged artifacts.",
|
|
443
582
|
"",
|
|
444
583
|
].join("\n");
|
|
445
584
|
}
|
|
@@ -492,6 +631,15 @@ function listDir(path: string): readonly string[] | null {
|
|
|
492
631
|
}
|
|
493
632
|
}
|
|
494
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
|
+
|
|
495
643
|
export function createDoctorDeps(): DoctorDeps {
|
|
496
644
|
return {
|
|
497
645
|
env: process.env,
|
|
@@ -500,6 +648,7 @@ export function createDoctorDeps(): DoctorDeps {
|
|
|
500
648
|
exists: existsSync,
|
|
501
649
|
readText,
|
|
502
650
|
listDir,
|
|
651
|
+
stat,
|
|
503
652
|
fetchHealth,
|
|
504
653
|
isPortOpen,
|
|
505
654
|
};
|
|
@@ -515,7 +664,10 @@ export async function runDoctor(argv: readonly string[]): Promise<number> {
|
|
|
515
664
|
process.stdout.write(doctorHelp());
|
|
516
665
|
return 0;
|
|
517
666
|
}
|
|
667
|
+
if (parsed.options.fix) {
|
|
668
|
+
migrateLegacyDataDirs();
|
|
669
|
+
}
|
|
518
670
|
const report = await buildDoctorReport(parsed.options);
|
|
519
|
-
process.stdout.write(formatDoctorReport(report));
|
|
671
|
+
process.stdout.write(parsed.options.json ? formatDoctorJson(report) : formatDoctorReport(report));
|
|
520
672
|
return report.exitCode;
|
|
521
673
|
}
|