@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.
Files changed (72) hide show
  1. package/.output/cli.js +137 -8
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-CepU-dLW.js → CompareDrawer-D-90PIPw.js} +1 -1
  4. package/.output/public/assets/ProxyViewerContainer-CxRDWacg.js +114 -0
  5. package/.output/public/assets/ReplayDialog-DzlLYoTO.js +1 -0
  6. package/.output/public/assets/{RequestAnatomy-C_C6ZU3T.js → RequestAnatomy-0hbyf6oa.js} +1 -1
  7. package/.output/public/assets/ResponseView-CKe0tNqr.js +1 -0
  8. package/.output/public/assets/StreamingChunkSequence-enhfdeNh.js +1 -0
  9. package/.output/public/assets/_sessionId-CJ-SusES.js +1 -0
  10. package/.output/public/assets/index-BbFsmQRC.js +1 -0
  11. package/.output/public/assets/index-BfBgrkgU.css +1 -0
  12. package/.output/public/assets/{main-BRXsrxtv.js → main-o9-hg8g1.js} +2 -2
  13. package/.output/server/_libs/lucide-react.mjs +141 -118
  14. package/.output/server/_libs/tanstack__react-virtual.mjs +13 -2
  15. package/.output/server/_libs/tanstack__virtual-core.mjs +24 -1
  16. package/.output/server/{_sessionId-B8Bbfs-v.mjs → _sessionId-F8lm6PIb.mjs} +3 -2
  17. package/.output/server/_ssr/{CompareDrawer-TgGZLf1J.mjs → CompareDrawer-Cf1yfwfd.mjs} +4 -3
  18. package/.output/server/_ssr/{ProxyViewerContainer-B_ppaNmQ.mjs → ProxyViewerContainer-Bmu9867L.mjs} +349 -74
  19. package/.output/server/_ssr/{ReplayDialog-BXlajnMC.mjs → ReplayDialog-DxZfLBOe.mjs} +199 -17
  20. package/.output/server/_ssr/{RequestAnatomy-CCrx09-i.mjs → RequestAnatomy-CbdERGZd.mjs} +4 -3
  21. package/.output/server/_ssr/{ResponseView-BxtMJrov.mjs → ResponseView-CvLd6qxI.mjs} +4 -3
  22. package/.output/server/_ssr/{StreamingChunkSequence-BlpdSPb8.mjs → StreamingChunkSequence-B_lkRB6o.mjs} +4 -3
  23. package/.output/server/_ssr/{index-BeTMNSJy.mjs → index-ejrSItfz.mjs} +3 -2
  24. package/.output/server/_ssr/index.mjs +2 -2
  25. package/.output/server/_ssr/{router-Ddl1tuU7.mjs → router-SbCnbDc2.mjs} +872 -232
  26. package/.output/server/{_tanstack-start-manifest_v-Bvdz_U0f.mjs → _tanstack-start-manifest_v-yx8ftqWz.mjs} +1 -1
  27. package/.output/server/index.mjs +54 -54
  28. package/README.md +11 -109
  29. package/package.json +2 -1
  30. package/src/cli/doctor.ts +150 -5
  31. package/src/components/OnboardingBanner.tsx +13 -13
  32. package/src/components/ProxyViewer.tsx +55 -38
  33. package/src/components/ProxyViewerContainer.tsx +5 -0
  34. package/src/components/providers/SettingsDialog.tsx +113 -2
  35. package/src/components/proxy-viewer/ConversationGroup.tsx +20 -3
  36. package/src/components/proxy-viewer/ConversationGroupList.tsx +144 -0
  37. package/src/components/proxy-viewer/ConversationHeader.tsx +0 -2
  38. package/src/components/proxy-viewer/ReplayDialog.tsx +200 -13
  39. package/src/components/proxy-viewer/index.ts +1 -1
  40. package/src/knowledge/openclawClient.ts +0 -8
  41. package/src/knowledge/types.ts +0 -2
  42. package/src/lib/export-logs.ts +72 -5
  43. package/src/lib/providerTestContract.ts +0 -1
  44. package/src/lib/useProviders.ts +1 -1
  45. package/src/mcp/server.ts +14 -6
  46. package/src/mcp/toolHandlers.ts +21 -4
  47. package/src/proxy/chunkStorage.ts +2 -4
  48. package/src/proxy/dataDir.ts +3 -3
  49. package/src/proxy/formats/anthropic/index.ts +0 -1
  50. package/src/proxy/formats/anthropic/schemas.ts +0 -2
  51. package/src/proxy/handler.ts +41 -29
  52. package/src/proxy/logFinalizer.ts +93 -11
  53. package/src/proxy/logger.ts +35 -10
  54. package/src/proxy/providers.ts +12 -5
  55. package/src/proxy/rawStreamCapture.ts +85 -0
  56. package/src/proxy/schemas.ts +1 -51
  57. package/src/proxy/sessionRuntime.ts +0 -9
  58. package/src/proxy/socketTracker.ts +15 -8
  59. package/src/proxy/store.ts +414 -13
  60. package/src/routes/api/logs.$id.replay.ts +66 -1
  61. package/src/routes/api/logs.stream.ts +11 -3
  62. package/src/routes/api/logs.ts +51 -17
  63. package/src/routes/api/providers.$providerId.ts +10 -3
  64. package/src/routes/api/providers.ts +6 -3
  65. package/.output/public/assets/ProxyViewerContainer-BG7rc33d.js +0 -114
  66. package/.output/public/assets/ReplayDialog-DK6SPv8X.js +0 -1
  67. package/.output/public/assets/ResponseView-Bqpra4Zw.js +0 -1
  68. package/.output/public/assets/StreamingChunkSequence-CdPbpprq.js +0 -1
  69. package/.output/public/assets/_sessionId-CsNARHj5.js +0 -1
  70. package/.output/public/assets/index-37NfO0zx.js +0 -1
  71. package/.output/public/assets/index-D_nZj9Vt.css +0 -1
  72. 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-BRXsrxtv.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-37NfO0zx.js", "/assets/ProxyViewerContainer-BG7rc33d.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-CsNARHj5.js", "/assets/ProxyViewerContainer-BG7rc33d.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-BRXsrxtv.js" });
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
  };
@@ -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-27T08:36:43.687Z",
41
+ "mtime": "2026-06-29T02:52:50.786Z",
42
42
  "size": 5915,
43
43
  "path": "../public/assets/alibaba-TTwafVwX.svg"
44
44
  },
45
- "/assets/CompareDrawer-CepU-dLW.js": {
46
- "type": "text/javascript; charset=utf-8",
47
- "etag": '"49fe-tnwk5QP+MvW6xIiE1eKLYM0+8Nk"',
48
- "mtime": "2026-06-27T08:36:43.690Z",
49
- "size": 18942,
50
- "path": "../public/assets/CompareDrawer-CepU-dLW.js"
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-37NfO0zx.js": {
52
+ "/assets/index-BbFsmQRC.js": {
53
53
  "type": "text/javascript; charset=utf-8",
54
- "etag": '"74-v4YTqp1BJEeiYpqdSM0kSIiMfRI"',
55
- "mtime": "2026-06-27T08:36:43.690Z",
54
+ "etag": '"74-vI6w+1iyboIWfJVk8/ech/2b8UY"',
55
+ "mtime": "2026-06-29T02:52:50.786Z",
56
56
  "size": 116,
57
- "path": "../public/assets/index-37NfO0zx.js"
57
+ "path": "../public/assets/index-BbFsmQRC.js"
58
58
  },
59
- "/assets/index-D_nZj9Vt.css": {
60
- "type": "text/css; charset=utf-8",
61
- "etag": '"1a275-7T1iSNG2p6BSsqLwdpfky+9evLw"',
62
- "mtime": "2026-06-27T08:36:43.690Z",
63
- "size": 107125,
64
- "path": "../public/assets/index-D_nZj9Vt.css"
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-27T08:36:43.689Z",
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-DK6SPv8X.js": {
73
+ "/assets/ReplayDialog-DzlLYoTO.js": {
74
74
  "type": "text/javascript; charset=utf-8",
75
- "etag": '"2361-0dSXxS+yW+fQ1Hwob3rFIHG/8kQ"',
76
- "mtime": "2026-06-27T08:36:43.690Z",
77
- "size": 9057,
78
- "path": "../public/assets/ReplayDialog-DK6SPv8X.js"
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-C_C6ZU3T.js": {
80
+ "/assets/RequestAnatomy-0hbyf6oa.js": {
81
81
  "type": "text/javascript; charset=utf-8",
82
- "etag": '"4485-V13BHPKtOZXhurKshD6hPJdOMjM"',
83
- "mtime": "2026-06-27T08:36:43.690Z",
82
+ "etag": '"4485-EusuohynIBF0h9+uJ+g1znFjMpc"',
83
+ "mtime": "2026-06-29T02:52:50.787Z",
84
84
  "size": 17541,
85
- "path": "../public/assets/RequestAnatomy-C_C6ZU3T.js"
85
+ "path": "../public/assets/RequestAnatomy-0hbyf6oa.js"
86
86
  },
87
- "/assets/ResponseView-Bqpra4Zw.js": {
87
+ "/assets/StreamingChunkSequence-enhfdeNh.js": {
88
88
  "type": "text/javascript; charset=utf-8",
89
- "etag": '"30cd-PKvvu6r831JLikIZLvwX2YM2ppo"',
90
- "mtime": "2026-06-27T08:36:43.690Z",
91
- "size": 12493,
92
- "path": "../public/assets/ResponseView-Bqpra4Zw.js"
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/main-BRXsrxtv.js": {
94
+ "/assets/ResponseView-CKe0tNqr.js": {
95
95
  "type": "text/javascript; charset=utf-8",
96
- "etag": '"51726-Qo0oVA+vO57y3JomfqOlDMWH9Rw"',
97
- "mtime": "2026-06-27T08:36:43.690Z",
98
- "size": 333606,
99
- "path": "../public/assets/main-BRXsrxtv.js"
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/StreamingChunkSequence-CdPbpprq.js": {
101
+ "/assets/_sessionId-CJ-SusES.js": {
102
102
  "type": "text/javascript; charset=utf-8",
103
- "etag": '"d5b-YkikdGZkub445VaoQLxeiOhJX2I"',
104
- "mtime": "2026-06-27T08:36:43.690Z",
105
- "size": 3419,
106
- "path": "../public/assets/StreamingChunkSequence-CdPbpprq.js"
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-27T08:36:43.689Z",
111
+ "mtime": "2026-06-29T02:52:50.786Z",
112
112
  "size": 11256,
113
113
  "path": "../public/assets/zhipuai-BPNAnxo-.svg"
114
114
  },
115
- "/assets/_sessionId-CsNARHj5.js": {
115
+ "/assets/main-o9-hg8g1.js": {
116
116
  "type": "text/javascript; charset=utf-8",
117
- "etag": '"d2-/1womMucNX0MQlv0PbfYhhW01rc"',
118
- "mtime": "2026-06-27T08:36:43.690Z",
119
- "size": 210,
120
- "path": "../public/assets/_sessionId-CsNARHj5.js"
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-27T08:36:43.689Z",
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-BG7rc33d.js": {
129
+ "/assets/ProxyViewerContainer-CxRDWacg.js": {
130
130
  "type": "text/javascript; charset=utf-8",
131
- "etag": '"aa779-KSDOFLdOzzw4sKAgeq6GqW/vv6k"',
132
- "mtime": "2026-06-27T08:36:43.690Z",
133
- "size": 698233,
134
- "path": "../public/assets/ProxyViewerContainer-BG7rc33d.js"
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 Release Webhook
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.18",
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 checks = options.chromeExtension
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
- <ul className="space-y-0.5 text-xs leading-relaxed text-muted-foreground">
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 mode</strong>: raw headers, raw response, and SSE chunks are captured
33
- for diagnostics.
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 <code>agent-inspector --mode simple</code>{" "}
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 mode</strong>: lightweight capture for requests, responses, tools,
44
- timing, and token usage.
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
- </ul>
62
+ </ol>
63
63
  </div>
64
64
  <button
65
65
  type="button"