@tonyclaw/agent-inspector 2.0.0

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 (400) hide show
  1. package/.output/cli.js +1611 -0
  2. package/.output/nitro.json +17 -0
  3. package/.output/public/assets/CompareDrawer-CU5ZrWcL.js +1 -0
  4. package/.output/public/assets/ProxyViewerContainer-pEBqVp1d.js +101 -0
  5. package/.output/public/assets/ReplayDialog-F58yNg5j.js +1 -0
  6. package/.output/public/assets/RequestAnatomy-C9lT0qE_.js +1 -0
  7. package/.output/public/assets/ResponseView-DHJq6bnz.js +1 -0
  8. package/.output/public/assets/StreamingChunkSequence-BTgfpFUT.js +1 -0
  9. package/.output/public/assets/_sessionId-DsNRbnNm.js +1 -0
  10. package/.output/public/assets/alibaba-TTwafVwX.svg +1 -0
  11. package/.output/public/assets/index-CpWG2hFn.css +1 -0
  12. package/.output/public/assets/index-DmBV8Gve.js +1 -0
  13. package/.output/public/assets/json-viewer-CZVYLR8j.js +14 -0
  14. package/.output/public/assets/main-DHs7FBK3.js +18 -0
  15. package/.output/public/assets/minimax-BPMzvuL-.jpeg +0 -0
  16. package/.output/public/assets/qwen-CONDcHqt.png +0 -0
  17. package/.output/public/assets/zhipuai-BPNAnxo-.svg +219 -0
  18. package/.output/server/_chunks/ssr-renderer.mjs +22 -0
  19. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +1 -0
  20. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +210 -0
  21. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +2 -0
  22. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +2 -0
  23. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +2 -0
  24. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +11 -0
  25. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +69 -0
  26. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +1 -0
  27. package/.output/server/_libs/@radix-ui/react-use-escape-keydown+[...].mjs +17 -0
  28. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +1 -0
  29. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +6 -0
  30. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +34 -0
  31. package/.output/server/_libs/ajv-formats.mjs +330 -0
  32. package/.output/server/_libs/ajv.mjs +11444 -0
  33. package/.output/server/_libs/aria-hidden.mjs +122 -0
  34. package/.output/server/_libs/atomically.mjs +152 -0
  35. package/.output/server/_libs/bail.mjs +8 -0
  36. package/.output/server/_libs/cfworker__json-schema.mjs +1 -0
  37. package/.output/server/_libs/character-entities.mjs +2130 -0
  38. package/.output/server/_libs/class-variance-authority.mjs +44 -0
  39. package/.output/server/_libs/clsx.mjs +16 -0
  40. package/.output/server/_libs/comma-separated-tokens.mjs +10 -0
  41. package/.output/server/_libs/conf.mjs +635 -0
  42. package/.output/server/_libs/cookie-es.mjs +58 -0
  43. package/.output/server/_libs/core-util-is.mjs +75 -0
  44. package/.output/server/_libs/croner.mjs +1 -0
  45. package/.output/server/_libs/crossws.mjs +1 -0
  46. package/.output/server/_libs/debounce-fn.mjs +69 -0
  47. package/.output/server/_libs/decode-named-character-reference+[...].mjs +8 -0
  48. package/.output/server/_libs/dequal.mjs +27 -0
  49. package/.output/server/_libs/detect-node-es.mjs +1 -0
  50. package/.output/server/_libs/devlop.mjs +8 -0
  51. package/.output/server/_libs/diff.mjs +320 -0
  52. package/.output/server/_libs/dot-prop.mjs +265 -0
  53. package/.output/server/_libs/env-paths.mjs +57 -0
  54. package/.output/server/_libs/estree-util-is-identifier-name.mjs +11 -0
  55. package/.output/server/_libs/extend.mjs +97 -0
  56. package/.output/server/_libs/fast-deep-equal.mjs +38 -0
  57. package/.output/server/_libs/fast-uri.mjs +812 -0
  58. package/.output/server/_libs/floating-ui__core.mjs +725 -0
  59. package/.output/server/_libs/floating-ui__dom.mjs +622 -0
  60. package/.output/server/_libs/floating-ui__react-dom.mjs +292 -0
  61. package/.output/server/_libs/floating-ui__utils.mjs +320 -0
  62. package/.output/server/_libs/get-nonce.mjs +9 -0
  63. package/.output/server/_libs/h3-v2.mjs +276 -0
  64. package/.output/server/_libs/h3.mjs +408 -0
  65. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +388 -0
  66. package/.output/server/_libs/hast-util-whitespace.mjs +10 -0
  67. package/.output/server/_libs/hookable.mjs +1 -0
  68. package/.output/server/_libs/html-url-attributes.mjs +26 -0
  69. package/.output/server/_libs/immediate.mjs +74 -0
  70. package/.output/server/_libs/inherits.mjs +50 -0
  71. package/.output/server/_libs/inline-style-parser.mjs +142 -0
  72. package/.output/server/_libs/is-plain-obj.mjs +10 -0
  73. package/.output/server/_libs/isarray.mjs +14 -0
  74. package/.output/server/_libs/isbot.mjs +20 -0
  75. package/.output/server/_libs/json-schema-traverse.mjs +180 -0
  76. package/.output/server/_libs/jszip.mjs +3051 -0
  77. package/.output/server/_libs/lie.mjs +273 -0
  78. package/.output/server/_libs/lucide-react.mjs +492 -0
  79. package/.output/server/_libs/mdast-util-from-markdown.mjs +717 -0
  80. package/.output/server/_libs/mdast-util-to-hast.mjs +710 -0
  81. package/.output/server/_libs/mdast-util-to-string.mjs +38 -0
  82. package/.output/server/_libs/micromark-core-commonmark.mjs +2259 -0
  83. package/.output/server/_libs/micromark-factory-destination.mjs +94 -0
  84. package/.output/server/_libs/micromark-factory-label.mjs +63 -0
  85. package/.output/server/_libs/micromark-factory-space.mjs +24 -0
  86. package/.output/server/_libs/micromark-factory-title.mjs +65 -0
  87. package/.output/server/_libs/micromark-factory-whitespace.mjs +22 -0
  88. package/.output/server/_libs/micromark-util-character.mjs +44 -0
  89. package/.output/server/_libs/micromark-util-chunked.mjs +36 -0
  90. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +12 -0
  91. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +41 -0
  92. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +19 -0
  93. package/.output/server/_libs/micromark-util-decode-string.mjs +21 -0
  94. package/.output/server/_libs/micromark-util-encode.mjs +1 -0
  95. package/.output/server/_libs/micromark-util-html-tag-name.mjs +69 -0
  96. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +6 -0
  97. package/.output/server/_libs/micromark-util-resolve-all.mjs +15 -0
  98. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +41 -0
  99. package/.output/server/_libs/micromark-util-subtokenize.mjs +346 -0
  100. package/.output/server/_libs/micromark.mjs +906 -0
  101. package/.output/server/_libs/mimic-function.mjs +47 -0
  102. package/.output/server/_libs/modelcontextprotocol__server.mjs +9738 -0
  103. package/.output/server/_libs/ocache.mjs +1 -0
  104. package/.output/server/_libs/ohash.mjs +1 -0
  105. package/.output/server/_libs/pako.mjs +4223 -0
  106. package/.output/server/_libs/process-nextick-args.mjs +48 -0
  107. package/.output/server/_libs/property-information.mjs +1209 -0
  108. package/.output/server/_libs/radix-ui.mjs +1 -0
  109. package/.output/server/_libs/radix-ui__number.mjs +6 -0
  110. package/.output/server/_libs/radix-ui__primitive.mjs +11 -0
  111. package/.output/server/_libs/radix-ui__react-accordion.mjs +1 -0
  112. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +1 -0
  113. package/.output/server/_libs/radix-ui__react-arrow.mjs +23 -0
  114. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +1 -0
  115. package/.output/server/_libs/radix-ui__react-avatar.mjs +1 -0
  116. package/.output/server/_libs/radix-ui__react-checkbox.mjs +1 -0
  117. package/.output/server/_libs/radix-ui__react-collapsible.mjs +144 -0
  118. package/.output/server/_libs/radix-ui__react-collection.mjs +69 -0
  119. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +39 -0
  120. package/.output/server/_libs/radix-ui__react-context-menu.mjs +1 -0
  121. package/.output/server/_libs/radix-ui__react-context.mjs +78 -0
  122. package/.output/server/_libs/radix-ui__react-dialog.mjs +325 -0
  123. package/.output/server/_libs/radix-ui__react-direction.mjs +9 -0
  124. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +1 -0
  125. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +29 -0
  126. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +206 -0
  127. package/.output/server/_libs/radix-ui__react-form.mjs +1 -0
  128. package/.output/server/_libs/radix-ui__react-hover-card.mjs +1 -0
  129. package/.output/server/_libs/radix-ui__react-id.mjs +14 -0
  130. package/.output/server/_libs/radix-ui__react-label.mjs +1 -0
  131. package/.output/server/_libs/radix-ui__react-menu.mjs +1 -0
  132. package/.output/server/_libs/radix-ui__react-menubar.mjs +1 -0
  133. package/.output/server/_libs/radix-ui__react-popover.mjs +1 -0
  134. package/.output/server/_libs/radix-ui__react-popper.mjs +286 -0
  135. package/.output/server/_libs/radix-ui__react-portal.mjs +16 -0
  136. package/.output/server/_libs/radix-ui__react-presence.mjs +128 -0
  137. package/.output/server/_libs/radix-ui__react-primitive.mjs +42 -0
  138. package/.output/server/_libs/radix-ui__react-progress.mjs +1 -0
  139. package/.output/server/_libs/radix-ui__react-radio-group.mjs +1 -0
  140. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +224 -0
  141. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +721 -0
  142. package/.output/server/_libs/radix-ui__react-select.mjs +1163 -0
  143. package/.output/server/_libs/radix-ui__react-separator.mjs +28 -0
  144. package/.output/server/_libs/radix-ui__react-slider.mjs +1 -0
  145. package/.output/server/_libs/radix-ui__react-slot.mjs +99 -0
  146. package/.output/server/_libs/radix-ui__react-switch.mjs +1 -0
  147. package/.output/server/_libs/radix-ui__react-tabs.mjs +189 -0
  148. package/.output/server/_libs/radix-ui__react-toast.mjs +2 -0
  149. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +1 -0
  150. package/.output/server/_libs/radix-ui__react-toggle.mjs +1 -0
  151. package/.output/server/_libs/radix-ui__react-toolbar.mjs +1 -0
  152. package/.output/server/_libs/radix-ui__react-tooltip.mjs +495 -0
  153. package/.output/server/_libs/radix-ui__react-use-previous.mjs +14 -0
  154. package/.output/server/_libs/radix-ui__react-use-size.mjs +39 -0
  155. package/.output/server/_libs/react-dom.mjs +10781 -0
  156. package/.output/server/_libs/react-markdown.mjs +147 -0
  157. package/.output/server/_libs/react-remove-scroll-bar.mjs +82 -0
  158. package/.output/server/_libs/react-remove-scroll.mjs +328 -0
  159. package/.output/server/_libs/react-style-singleton.mjs +69 -0
  160. package/.output/server/_libs/react.mjs +515 -0
  161. package/.output/server/_libs/readable-stream.mjs +1518 -0
  162. package/.output/server/_libs/remark-parse.mjs +19 -0
  163. package/.output/server/_libs/remark-rehype.mjs +21 -0
  164. package/.output/server/_libs/rou3.mjs +14 -0
  165. package/.output/server/_libs/safe-buffer.mjs +64 -0
  166. package/.output/server/_libs/semver.mjs +1938 -0
  167. package/.output/server/_libs/seroval-plugins.mjs +58 -0
  168. package/.output/server/_libs/seroval.mjs +1765 -0
  169. package/.output/server/_libs/setimmediate.mjs +152 -0
  170. package/.output/server/_libs/space-separated-tokens.mjs +6 -0
  171. package/.output/server/_libs/srvx.mjs +1029 -0
  172. package/.output/server/_libs/stubborn-fs.mjs +91 -0
  173. package/.output/server/_libs/stubborn-utils.mjs +66 -0
  174. package/.output/server/_libs/style-to-js.mjs +72 -0
  175. package/.output/server/_libs/style-to-object.mjs +38 -0
  176. package/.output/server/_libs/swr.mjs +939 -0
  177. package/.output/server/_libs/tailwind-merge.mjs +3010 -0
  178. package/.output/server/_libs/tanstack__history.mjs +217 -0
  179. package/.output/server/_libs/tanstack__react-router.mjs +1480 -0
  180. package/.output/server/_libs/tanstack__react-store.mjs +1 -0
  181. package/.output/server/_libs/tanstack__react-virtual.mjs +44 -0
  182. package/.output/server/_libs/tanstack__router-core.mjs +4827 -0
  183. package/.output/server/_libs/tanstack__store.mjs +1 -0
  184. package/.output/server/_libs/tanstack__virtual-core.mjs +1225 -0
  185. package/.output/server/_libs/tiny-invariant.mjs +12 -0
  186. package/.output/server/_libs/tiny-warning.mjs +5 -0
  187. package/.output/server/_libs/trim-lines.mjs +41 -0
  188. package/.output/server/_libs/trough.mjs +85 -0
  189. package/.output/server/_libs/tslib.mjs +1 -0
  190. package/.output/server/_libs/ufo.mjs +54 -0
  191. package/.output/server/_libs/uint8array-extras.mjs +69 -0
  192. package/.output/server/_libs/ungap__structured-clone.mjs +212 -0
  193. package/.output/server/_libs/unified.mjs +661 -0
  194. package/.output/server/_libs/unist-util-is.mjs +100 -0
  195. package/.output/server/_libs/unist-util-position.mjs +27 -0
  196. package/.output/server/_libs/unist-util-stringify-position.mjs +27 -0
  197. package/.output/server/_libs/unist-util-visit-parents.mjs +82 -0
  198. package/.output/server/_libs/unist-util-visit.mjs +24 -0
  199. package/.output/server/_libs/unstorage.mjs +1 -0
  200. package/.output/server/_libs/use-callback-ref.mjs +66 -0
  201. package/.output/server/_libs/use-sidecar.mjs +106 -0
  202. package/.output/server/_libs/use-sync-external-store.mjs +64 -0
  203. package/.output/server/_libs/util-deprecate.mjs +12 -0
  204. package/.output/server/_libs/vfile-message.mjs +138 -0
  205. package/.output/server/_libs/vfile.mjs +467 -0
  206. package/.output/server/_libs/when-exit.mjs +53 -0
  207. package/.output/server/_libs/zod.mjs +4524 -0
  208. package/.output/server/_sessionId-wMLPvC5g.mjs +123 -0
  209. package/.output/server/_ssr/CompareDrawer-BU4V0uVf.mjs +1041 -0
  210. package/.output/server/_ssr/ProxyViewerContainer-BnRwFEnn.mjs +5972 -0
  211. package/.output/server/_ssr/ReplayDialog-C7dn9pd_.mjs +322 -0
  212. package/.output/server/_ssr/RequestAnatomy-C1rWpe9-.mjs +353 -0
  213. package/.output/server/_ssr/ResponseView-hGpPaYsf.mjs +602 -0
  214. package/.output/server/_ssr/StreamingChunkSequence-BRWI1r_G.mjs +302 -0
  215. package/.output/server/_ssr/index-BKURLVPz.mjs +118 -0
  216. package/.output/server/_ssr/index.mjs +1184 -0
  217. package/.output/server/_ssr/json-viewer-BBd2DtQP.mjs +515 -0
  218. package/.output/server/_ssr/router-BcZ0D6AB.mjs +6317 -0
  219. package/.output/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  220. package/.output/server/_tanstack-start-manifest_v-1y8ZVxRI.mjs +4 -0
  221. package/.output/server/index.mjs +436 -0
  222. package/.output/server/node_modules/tslib/modules/index.js +70 -0
  223. package/.output/server/node_modules/tslib/modules/package.json +3 -0
  224. package/.output/server/node_modules/tslib/package.json +47 -0
  225. package/.output/server/node_modules/tslib/tslib.js +484 -0
  226. package/.output/server/package.json +9 -0
  227. package/LICENSE +21 -0
  228. package/README.md +52 -0
  229. package/package.json +110 -0
  230. package/src/assets/favicon.svg +31 -0
  231. package/src/assets/logos/alibaba.svg +1 -0
  232. package/src/assets/logos/anthropic.svg +1 -0
  233. package/src/assets/logos/claude-code.svg +4 -0
  234. package/src/assets/logos/deepseek.svg +1 -0
  235. package/src/assets/logos/mcp.png +0 -0
  236. package/src/assets/logos/minimax.jpeg +0 -0
  237. package/src/assets/logos/openai.svg +1 -0
  238. package/src/assets/logos/opencode.svg +4 -0
  239. package/src/assets/logos/qwen.png +0 -0
  240. package/src/assets/logos/zhipuai.svg +219 -0
  241. package/src/cli/detect-tools.ts +147 -0
  242. package/src/cli/doctor.ts +521 -0
  243. package/src/cli/onboard.ts +224 -0
  244. package/src/cli/templates/command-onboard.ts +17 -0
  245. package/src/cli/templates/skill-onboard.ts +547 -0
  246. package/src/cli.ts +345 -0
  247. package/src/components/OnboardingBanner.tsx +67 -0
  248. package/src/components/ProxyViewer.tsx +545 -0
  249. package/src/components/ProxyViewerContainer.tsx +363 -0
  250. package/src/components/providers/ImportWizardDialog.tsx +349 -0
  251. package/src/components/providers/ProviderCard.tsx +474 -0
  252. package/src/components/providers/ProviderForm.tsx +494 -0
  253. package/src/components/providers/ProviderLogo.tsx +117 -0
  254. package/src/components/providers/ProvidersPanel.tsx +619 -0
  255. package/src/components/providers/SettingsDialog.tsx +202 -0
  256. package/src/components/proxy-viewer/CompareDrawer.tsx +893 -0
  257. package/src/components/proxy-viewer/ConversationGroup.tsx +107 -0
  258. package/src/components/proxy-viewer/ConversationHeader.tsx +300 -0
  259. package/src/components/proxy-viewer/LogEntry.tsx +543 -0
  260. package/src/components/proxy-viewer/LogEntryHeader.tsx +501 -0
  261. package/src/components/proxy-viewer/ReplayDialog.tsx +218 -0
  262. package/src/components/proxy-viewer/ResponseView.tsx +171 -0
  263. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +188 -0
  264. package/src/components/proxy-viewer/ThreadConnector.tsx +136 -0
  265. package/src/components/proxy-viewer/TurnGroup.tsx +337 -0
  266. package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +98 -0
  267. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +196 -0
  268. package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +53 -0
  269. package/src/components/proxy-viewer/anatomy/types.ts +39 -0
  270. package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +114 -0
  271. package/src/components/proxy-viewer/cacheTrend.ts +50 -0
  272. package/src/components/proxy-viewer/diff/DiffView.tsx +321 -0
  273. package/src/components/proxy-viewer/diff/computeDiff.ts +178 -0
  274. package/src/components/proxy-viewer/diff/index.ts +3 -0
  275. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +157 -0
  276. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +66 -0
  277. package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +21 -0
  278. package/src/components/proxy-viewer/formats/index.tsx +33 -0
  279. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +170 -0
  280. package/src/components/proxy-viewer/index.ts +9 -0
  281. package/src/components/proxy-viewer/lazy.ts +37 -0
  282. package/src/components/proxy-viewer/log-formats/anthropic.ts +194 -0
  283. package/src/components/proxy-viewer/log-formats/index.ts +23 -0
  284. package/src/components/proxy-viewer/log-formats/openai.ts +167 -0
  285. package/src/components/proxy-viewer/log-formats/types.ts +40 -0
  286. package/src/components/proxy-viewer/log-formats/unknown.ts +18 -0
  287. package/src/components/proxy-viewer/logEntryVisibility.ts +39 -0
  288. package/src/components/proxy-viewer/requestDiff.ts +277 -0
  289. package/src/components/proxy-viewer/useCopyFeedback.ts +36 -0
  290. package/src/components/proxy-viewer/useKeyboardNavigation.ts +190 -0
  291. package/src/components/proxy-viewer/viewerState.ts +66 -0
  292. package/src/components/ui/badge.tsx +47 -0
  293. package/src/components/ui/button.tsx +47 -0
  294. package/src/components/ui/collapsible.tsx +21 -0
  295. package/src/components/ui/confirm-dialog.tsx +51 -0
  296. package/src/components/ui/crab-logo.tsx +95 -0
  297. package/src/components/ui/crab-variants.tsx +467 -0
  298. package/src/components/ui/dialog.tsx +129 -0
  299. package/src/components/ui/json-expansion-button.tsx +56 -0
  300. package/src/components/ui/json-viewer-bulk.ts +97 -0
  301. package/src/components/ui/json-viewer.tsx +494 -0
  302. package/src/components/ui/mcp-logo.tsx +20 -0
  303. package/src/components/ui/scroll-area.tsx +54 -0
  304. package/src/components/ui/select.tsx +178 -0
  305. package/src/components/ui/separator.tsx +28 -0
  306. package/src/components/ui/tabs.tsx +88 -0
  307. package/src/components/ui/tooltip.tsx +51 -0
  308. package/src/index.css +11 -0
  309. package/src/knowledge/candidateStore.ts +63 -0
  310. package/src/knowledge/distiller.ts +98 -0
  311. package/src/knowledge/openclawClient.ts +118 -0
  312. package/src/knowledge/redactor.ts +80 -0
  313. package/src/knowledge/types.ts +84 -0
  314. package/src/lib/apiClient.ts +49 -0
  315. package/src/lib/export-logs.ts +51 -0
  316. package/src/lib/mask.ts +4 -0
  317. package/src/lib/objectUtils.ts +22 -0
  318. package/src/lib/providerContract.ts +26 -0
  319. package/src/lib/providerTestContract.ts +107 -0
  320. package/src/lib/runtimeConfig.ts +25 -0
  321. package/src/lib/serverPort.ts +41 -0
  322. package/src/lib/sessionUrl.ts +44 -0
  323. package/src/lib/stopReason.ts +58 -0
  324. package/src/lib/useOnboarding.ts +80 -0
  325. package/src/lib/useProviders.ts +30 -0
  326. package/src/lib/useStripConfig.ts +108 -0
  327. package/src/lib/utils.ts +21 -0
  328. package/src/mcp/loopback.ts +76 -0
  329. package/src/mcp/previewExtractor.ts +166 -0
  330. package/src/mcp/server.ts +396 -0
  331. package/src/mcp/toolHandlers.ts +341 -0
  332. package/src/proxy/chunkStorage.ts +112 -0
  333. package/src/proxy/claudeCodeStrip.ts +99 -0
  334. package/src/proxy/config.ts +172 -0
  335. package/src/proxy/constants.ts +47 -0
  336. package/src/proxy/dataDir.ts +86 -0
  337. package/src/proxy/formats/anthropic/anthropicProvider.ts +75 -0
  338. package/src/proxy/formats/anthropic/handler.ts +71 -0
  339. package/src/proxy/formats/anthropic/index.ts +14 -0
  340. package/src/proxy/formats/anthropic/register.ts +4 -0
  341. package/src/proxy/formats/anthropic/schemas.ts +237 -0
  342. package/src/proxy/formats/anthropic/stream.ts +205 -0
  343. package/src/proxy/formats/handler.ts +46 -0
  344. package/src/proxy/formats/index.ts +12 -0
  345. package/src/proxy/formats/jsonSchema.ts +36 -0
  346. package/src/proxy/formats/openai/alibabaProvider.ts +38 -0
  347. package/src/proxy/formats/openai/handler.ts +96 -0
  348. package/src/proxy/formats/openai/index.ts +25 -0
  349. package/src/proxy/formats/openai/provider.ts +50 -0
  350. package/src/proxy/formats/openai/register.ts +4 -0
  351. package/src/proxy/formats/openai/schemas.ts +187 -0
  352. package/src/proxy/formats/openai/stream.ts +206 -0
  353. package/src/proxy/formats/protocol.ts +50 -0
  354. package/src/proxy/formats/providerRegistry.ts +51 -0
  355. package/src/proxy/formats/providers/index.ts +3 -0
  356. package/src/proxy/formats/registry.ts +66 -0
  357. package/src/proxy/handler.ts +334 -0
  358. package/src/proxy/logFinalizer.ts +305 -0
  359. package/src/proxy/logFinalizer.worker.ts +24 -0
  360. package/src/proxy/logIndex.ts +268 -0
  361. package/src/proxy/logger.ts +179 -0
  362. package/src/proxy/openaiOrphanToolStrip.ts +142 -0
  363. package/src/proxy/providerImporters.ts +491 -0
  364. package/src/proxy/providers.ts +613 -0
  365. package/src/proxy/schemas.ts +209 -0
  366. package/src/proxy/sessionProcess.ts +140 -0
  367. package/src/proxy/sessionRuntime.ts +85 -0
  368. package/src/proxy/sessionSupervisor.ts +283 -0
  369. package/src/proxy/sessionWorkerEntry.ts +26 -0
  370. package/src/proxy/socketTracker.ts +255 -0
  371. package/src/proxy/store.ts +412 -0
  372. package/src/proxy/upstream.ts +90 -0
  373. package/src/router.tsx +16 -0
  374. package/src/routes/__root.tsx +45 -0
  375. package/src/routes/api/config.paths.ts +14 -0
  376. package/src/routes/api/config.ts +53 -0
  377. package/src/routes/api/health.ts +15 -0
  378. package/src/routes/api/knowledge.candidates.$candidateId.promote.ts +32 -0
  379. package/src/routes/api/knowledge.candidates.ts +10 -0
  380. package/src/routes/api/knowledge.project-context.ts +18 -0
  381. package/src/routes/api/knowledge.search.ts +31 -0
  382. package/src/routes/api/knowledge.sessions.$sessionId.candidates.ts +16 -0
  383. package/src/routes/api/logs.$id.chunks.ts +36 -0
  384. package/src/routes/api/logs.$id.replay.ts +191 -0
  385. package/src/routes/api/logs.$id.ts +22 -0
  386. package/src/routes/api/logs.stream.ts +74 -0
  387. package/src/routes/api/logs.ts +59 -0
  388. package/src/routes/api/mcp.ts +25 -0
  389. package/src/routes/api/models.ts +10 -0
  390. package/src/routes/api/providers.$providerId.test.log.ts +293 -0
  391. package/src/routes/api/providers.$providerId.ts +50 -0
  392. package/src/routes/api/providers.export.ts +26 -0
  393. package/src/routes/api/providers.import.ts +47 -0
  394. package/src/routes/api/providers.scan.ts +23 -0
  395. package/src/routes/api/providers.ts +45 -0
  396. package/src/routes/api/sessions.ts +17 -0
  397. package/src/routes/index.tsx +6 -0
  398. package/src/routes/proxy/$.ts +15 -0
  399. package/src/routes/session/$sessionId.tsx +23 -0
  400. package/styles/globals.css +188 -0
@@ -0,0 +1,547 @@
1
+ /**
2
+ * Renders `~/.claude/skills/agent-inspector-onboard/SKILL.md` for the
3
+ * `agent-inspector onboard` subcommand. The body is a multi-phase teaching
4
+ * workflow with `EXPLAIN / DO / PAUSE` markers — Claude reads it and walks
5
+ * the user through real actions (start the proxy, hit /api/health, post a
6
+ * test request, poll /api/logs) instead of just printing a static tutorial.
7
+ *
8
+ * The template embeds platform-aware shell snippets inline (bash + PowerShell
9
+ * side-by-side). Skills are pure Markdown — they can't `require()` from the
10
+ * package at runtime, so the duplication is the price of portability.
11
+ *
12
+ * All PowerShell snippets that use `$env:` variables are written so they
13
+ * work when invoked via the Bash tool. The pattern is:
14
+ * powershell -Command '<single-quoted block with $env:LITERAL>'
15
+ * NOT
16
+ * powershell -Command "<double-quoted block with escaped \$env:>"
17
+ * The latter collapses `$env:` to a literal in bash before PowerShell sees
18
+ * it, producing garbled paths. Single-quoted bash arguments pass through
19
+ * to PowerShell unchanged.
20
+ */
21
+
22
+ export type SkillOnboardContext = {
23
+ /** Package version (from `package.json`), stamped into the frontmatter. */
24
+ readonly version: string;
25
+ /** The default proxy port (mirrors `DEFAULT_PORT` in `src/cli.ts`). */
26
+ readonly port: number;
27
+ /**
28
+ * One-line "detected tools" summary written into the Preflight phase so the
29
+ * skill's instructions match the user's actual environment. Empty string
30
+ * means "no known tool detected — fall through to the curl example".
31
+ */
32
+ readonly detectedSummary: string;
33
+ };
34
+
35
+ /** The 9 phase headings the spec requires. The validator checks for these. */
36
+ export const REQUIRED_PHASE_HEADINGS = [
37
+ "Phase 0: Idempotency check",
38
+ "Preflight",
39
+ "Phase 1: Welcome",
40
+ "Phase 2: Provider setup",
41
+ "Phase 3: Start proxy",
42
+ "Phase 4: Wire tool",
43
+ "Phase 4.5: Wire MCP server",
44
+ "Phase 5: First capture",
45
+ "Phase 6: Tour & wrap",
46
+ ] as const;
47
+
48
+ export function renderSkillOnboard(ctx: SkillOnboardContext): string {
49
+ const { version, port, detectedSummary } = ctx;
50
+ return `---
51
+ name: agent-inspector-onboard
52
+ description: Guided setup for Agent Inspector v${version}: start the proxy, wire your AI coding tool, capture your first request, and learn the Web UI.
53
+ metadata:
54
+ author: agent-inspector
55
+ version: ${version}
56
+ ---
57
+
58
+ # Agent Inspector onboard
59
+
60
+ Guide the user from "I just installed Agent Inspector" to "I can see my AI tool's traffic in the Web UI". This is a teaching experience: you'll do real work in their environment while explaining each step.
61
+
62
+ Environment detected by the installer:
63
+ ${detectedSummary || " (no known AI tool detected — the user can still use the generic curl example in Phase 4)"}
64
+
65
+ Default proxy port: \`${port}\` (override with \`PORT=<n> agent-inspector\` or \`--port <n>\`).
66
+
67
+ > **PAUSE protocol.** Every \`**PAUSE**\` marker in this skill is a real stop.
68
+ > Use the \`AskUserQuestion\` tool to actually wait for the user before
69
+ > continuing. Do not stream past a PAUSE based on context — the user has
70
+ > not seen your output yet. Each PAUSE in the body below includes a sample
71
+ > question you can adapt.
72
+
73
+ ---
74
+
75
+ ## Phase 0: Idempotency check
76
+
77
+ **EXPLAIN:** "Before we do anything, let me see what's already set up. If some of the steps are already done, we can skip them."
78
+
79
+ **DO:** Probe the three pieces of state this skill touches. Use targeted checks — do **not** read large JSON files into the conversation.
80
+
81
+ \`\`\`bash
82
+ # 1. Is the proxy already up?
83
+ curl -fsS "http://localhost:${port}/api/health" 2>/dev/null && echo "PROXY: up" || echo "PROXY: down"
84
+
85
+ # 2. Does the provider config have a real provider key?
86
+ agent_inspector_data_dir() {
87
+ base="\${HOME:-/tmp}"
88
+ if [ -n "\${AGENT_INSPECTOR_DATA_DIR:-}" ]; then
89
+ case "$AGENT_INSPECTOR_DATA_DIR" in /*) printf '%s\n' "$AGENT_INSPECTOR_DATA_DIR" ;; *) printf '%s\n' "$base/$AGENT_INSPECTOR_DATA_DIR" ;; esac
90
+ elif [ -n "\${AGENT_INSPECTOR_CONFIG_DIR:-}" ]; then
91
+ case "$AGENT_INSPECTOR_CONFIG_DIR" in /*) printf '%s\n' "$AGENT_INSPECTOR_CONFIG_DIR" ;; *) printf '%s\n' "$base/$AGENT_INSPECTOR_CONFIG_DIR" ;; esac
92
+ elif { [ ! -e "$base/.agent-inspector/providers.json" ] && [ ! -e "$base/.agent-inspector/config.json" ] && [ ! -e "$base/.agent-inspector/logs" ] && [ ! -e "$base/.agent-inspector/chunks" ]; } && { [ -e "$base/.llm-inspector/providers.json" ] || [ -e "$base/.llm-inspector/config.json" ] || [ -e "$base/.llm-inspector/logs" ] || [ -e "$base/.llm-inspector/chunks" ]; }; then
93
+ printf '%s\n' "$base/.llm-inspector"
94
+ else
95
+ printf '%s\n' "$base/.agent-inspector"
96
+ fi
97
+ }
98
+ DATA_DIR="$(agent_inspector_data_dir)"
99
+ PROVIDERS="$DATA_DIR/providers.json"
100
+ LEGACY_CONFIG="$DATA_DIR/config.json"
101
+ if [ -f "$PROVIDERS" ] || [ -f "$LEGACY_CONFIG" ]; then
102
+ if grep -qE '"apiKey"[[:space:]]*:[[:space:]]*"sk-[^"]+"' "$PROVIDERS" "$LEGACY_CONFIG" 2>/dev/null; then
103
+ echo "CONFIG: has key (no REPLACE placeholder)"
104
+ elif grep -qE '"apiKey"[[:space:]]*:[[:space:]]*"REPLACE' "$PROVIDERS" "$LEGACY_CONFIG" 2>/dev/null; then
105
+ echo "CONFIG: missing or has placeholder key"
106
+ else
107
+ echo "CONFIG: missing or has placeholder key"
108
+ fi
109
+ else
110
+ echo "CONFIG: file does not exist"
111
+ fi
112
+
113
+ # 3. Is the MCP server already wired? (project .mcp.json wins)
114
+ PROJ_MCP=".mcp.json"
115
+ HOME_MCP="$HOME/.claude.json"
116
+ if [ -f "$PROJ_MCP" ] && grep -q '"agent-inspector"' "$PROJ_MCP"; then
117
+ echo "MCP: wired in $PROJ_MCP"
118
+ elif [ -f "$HOME_MCP" ] && grep -q '"agent-inspector"' "$HOME_MCP"; then
119
+ echo "MCP: wired in $HOME_MCP"
120
+ else
121
+ echo "MCP: not wired"
122
+ fi
123
+ \`\`\`
124
+
125
+ \`\`\`powershell
126
+ # Windows PowerShell — single-quoted so $env: expands correctly
127
+ $port = ${port}
128
+ function Resolve-AgentInspectorDataDir {
129
+ $base = $env:USERPROFILE
130
+ if (-not $base) { $base = $env:APPDATA }
131
+ if (-not $base) { $base = 'C:\\' }
132
+ if ($env:AGENT_INSPECTOR_DATA_DIR) {
133
+ if ([System.IO.Path]::IsPathRooted($env:AGENT_INSPECTOR_DATA_DIR)) { return $env:AGENT_INSPECTOR_DATA_DIR }
134
+ return (Join-Path $base $env:AGENT_INSPECTOR_DATA_DIR)
135
+ }
136
+ if ($env:AGENT_INSPECTOR_CONFIG_DIR) {
137
+ if ([System.IO.Path]::IsPathRooted($env:AGENT_INSPECTOR_CONFIG_DIR)) { return $env:AGENT_INSPECTOR_CONFIG_DIR }
138
+ return (Join-Path $base $env:AGENT_INSPECTOR_CONFIG_DIR)
139
+ }
140
+ $current = Join-Path $base '.agent-inspector'
141
+ $legacy = Join-Path $base '.llm-inspector'
142
+ $currentHasState = (Test-Path (Join-Path $current 'providers.json')) -or (Test-Path (Join-Path $current 'config.json')) -or (Test-Path (Join-Path $current 'logs')) -or (Test-Path (Join-Path $current 'chunks'))
143
+ $legacyHasState = (Test-Path (Join-Path $legacy 'providers.json')) -or (Test-Path (Join-Path $legacy 'config.json')) -or (Test-Path (Join-Path $legacy 'logs')) -or (Test-Path (Join-Path $legacy 'chunks'))
144
+ if (-not $currentHasState -and $legacyHasState) {
145
+ return $legacy
146
+ }
147
+ return $current
148
+ }
149
+ $dataDir = Resolve-AgentInspectorDataDir
150
+ $providers = Join-Path $dataDir 'providers.json'
151
+ $legacyConfig = Join-Path $dataDir 'config.json'
152
+
153
+ # 1. Is the proxy already up?
154
+ try {
155
+ $null = Invoke-RestMethod -Uri "http://localhost:$port/api/health" -TimeoutSec 2 -ErrorAction Stop
156
+ Write-Host 'PROXY: up'
157
+ } catch {
158
+ Write-Host 'PROXY: down'
159
+ }
160
+
161
+ # 2. Does the config have a real provider key?
162
+ if ((Test-Path $providers) -or (Test-Path $legacyConfig)) {
163
+ $content = ''
164
+ if (Test-Path $providers) { $content += Get-Content $providers -Raw }
165
+ if (Test-Path $legacyConfig) { $content += Get-Content $legacyConfig -Raw }
166
+ if ($content -match '"apiKey"[[:space:]]*:[[:space:]]*"(sk-[^"]+)"') {
167
+ Write-Host 'CONFIG: has key'
168
+ } elseif ($content -match 'REPLACE') {
169
+ Write-Host 'CONFIG: has placeholder key'
170
+ } else {
171
+ Write-Host 'CONFIG: missing key'
172
+ }
173
+ } else {
174
+ Write-Host 'CONFIG: file does not exist'
175
+ }
176
+
177
+ # 3. Is the MCP server already wired? (project .mcp.json wins)
178
+ $projMcp = Join-Path (Get-Location) '.mcp.json'
179
+ $homeMcp = Join-Path $env:USERPROFILE '.claude.json'
180
+ if ((Test-Path $projMcp) -and (Select-String -Path $projMcp -Pattern 'agent-inspector' -Quiet)) {
181
+ Write-Host "MCP: wired in $projMcp"
182
+ } elseif ((Test-Path $homeMcp) -and (Select-String -Path $homeMcp -Pattern 'agent-inspector' -Quiet)) {
183
+ Write-Host "MCP: wired in $homeMcp"
184
+ } else {
185
+ Write-Host 'MCP: not wired'
186
+ }
187
+ \`\`\`
188
+
189
+ **DO:** Summarize the three checks in one line, then use \`AskUserQuestion\` to ask whether to skip the corresponding phases.
190
+
191
+ > **PAUSE** — call \`AskUserQuestion\` with:
192
+ > - header: \`Skip done\`
193
+ > - question: \`Proxy/CONFIG/MCP state: <summary>. Skip the phases that are already done?\`
194
+ > - options: \`["Yes, skip what's done", "No, walk me through everything again"]\`
195
+ > Wait for the answer before moving to Preflight.
196
+
197
+ ---
198
+
199
+ ## Preflight
200
+
201
+ **EXPLAIN:** "Quick env sanity check — make sure Node and Claude Code are present."
202
+
203
+ **DO:** Run the platform-appropriate commands below.
204
+
205
+ \`\`\`bash
206
+ # Unix / macOS / WSL
207
+ node --version # expect >= 18
208
+ command -v claude >/dev/null && echo "claude-code: present" || echo "claude-code: not detected"
209
+ \`\`\`
210
+
211
+ \`\`\`powershell
212
+ # Windows PowerShell — single-quoted so $env: expands correctly
213
+ node --version # expect >= 18
214
+ $null = Get-Command claude -ErrorAction SilentlyContinue
215
+ if ($null) { Write-Host 'claude-code: present' } else { Write-Host 'claude-code: not detected' }
216
+ \`\`\`
217
+
218
+ > **PAUSE** — if Node is older than 18, ask the user to install a newer version (https://nodejs.org) before continuing. Use \`AskUserQuestion\` with header \`Node version\`.
219
+
220
+ ---
221
+
222
+ ## Phase 1: Welcome
223
+
224
+ **EXPLAIN:**
225
+
226
+ \`\`\`
227
+ ## Welcome to Agent Inspector!
228
+
229
+ Agent Inspector is an agent observability and knowledge-capture platform for AI coding tools. The \`agent-inspector\` CLI runs a transparent local proxy + Web UI, so you can see every model request and response: system prompts, tool definitions, message history, SSE streaming chunks, and token counts captured live in a browser tab.
230
+
231
+ **What we'll do in the next ~10 minutes:**
232
+ 1. Add your first LLM provider (Anthropic or OpenAI key)
233
+ 2. Start the proxy
234
+ 3. Wire your AI tool to use it
235
+ 4. Capture a first request end-to-end
236
+ 5. Tour the key UI affordances
237
+
238
+ Ready? Let's start with the provider.
239
+ \`\`\`
240
+
241
+ > **PAUSE** — use \`AskUserQuestion\` with header \`Ready?\` and options \`["Yes, let's go", "Wait, I have a question"]\`. Wait for the user before continuing.
242
+
243
+ ---
244
+
245
+ ## Phase 2: Provider setup
246
+
247
+ **EXPLAIN:** "A 'provider' is an upstream LLM endpoint — Anthropic, OpenAI, MiniMax, etc. agent-inspector routes each request to the right upstream based on the model name. You need at least one provider configured for the proxy to forward traffic."
248
+
249
+ **DO:** First, re-check whether \`<dataDir>/providers.json\` already has a real key (Phase 0 may have raced with a manual edit). Use the same data-dir resolution and \`grep -qE '"apiKey":"sk-'\` (bash) or \`Select-String\` (PowerShell) check from Phase 0. If a real key is present, skip the rest of this phase.
250
+
251
+ **DO:** If no real key, ask the user for the provider type and API key via \`AskUserQuestion\`. The question should be a free-form text field (no fixed options) — the API key is a secret, so don't echo it back in the question UI.
252
+
253
+ \`\`\`bash
254
+ # After collecting the key, write the config
255
+ agent_inspector_data_dir() {
256
+ base="\${HOME:-/tmp}"
257
+ if [ -n "\${AGENT_INSPECTOR_DATA_DIR:-}" ]; then
258
+ case "$AGENT_INSPECTOR_DATA_DIR" in /*) printf '%s\n' "$AGENT_INSPECTOR_DATA_DIR" ;; *) printf '%s\n' "$base/$AGENT_INSPECTOR_DATA_DIR" ;; esac
259
+ elif [ -n "\${AGENT_INSPECTOR_CONFIG_DIR:-}" ]; then
260
+ case "$AGENT_INSPECTOR_CONFIG_DIR" in /*) printf '%s\n' "$AGENT_INSPECTOR_CONFIG_DIR" ;; *) printf '%s\n' "$base/$AGENT_INSPECTOR_CONFIG_DIR" ;; esac
261
+ elif { [ ! -e "$base/.agent-inspector/providers.json" ] && [ ! -e "$base/.agent-inspector/config.json" ] && [ ! -e "$base/.agent-inspector/logs" ] && [ ! -e "$base/.agent-inspector/chunks" ]; } && { [ -e "$base/.llm-inspector/providers.json" ] || [ -e "$base/.llm-inspector/config.json" ] || [ -e "$base/.llm-inspector/logs" ] || [ -e "$base/.llm-inspector/chunks" ]; }; then
262
+ printf '%s\n' "$base/.llm-inspector"
263
+ else
264
+ printf '%s\n' "$base/.agent-inspector"
265
+ fi
266
+ }
267
+ DATA_DIR="$(agent_inspector_data_dir)"
268
+ mkdir -p "$DATA_DIR"
269
+ PROVIDERS="$DATA_DIR/providers.json"
270
+ NOW="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
271
+ cat > "$PROVIDERS" <<JSON
272
+ {
273
+ "providers": [
274
+ {
275
+ "id": "onboard-anthropic",
276
+ "name": "Anthropic",
277
+ "apiKey": "REPLACE_ME_BEFORE_WRITING",
278
+ "models": ["claude-sonnet-4-5-20250929"],
279
+ "format": "anthropic",
280
+ "anthropicBaseUrl": "https://api.anthropic.com",
281
+ "openaiBaseUrl": "",
282
+ "authHeader": "bearer",
283
+ "createdAt": "$NOW",
284
+ "updatedAt": "$NOW"
285
+ }
286
+ ]
287
+ }
288
+ JSON
289
+ # Then patch the apiKey with the user-provided value (use jq if available)
290
+ \`\`\`
291
+
292
+ \`\`\`powershell
293
+ # Windows PowerShell — single-quoted so $env: expands correctly
294
+ function Resolve-AgentInspectorDataDir {
295
+ $base = $env:USERPROFILE
296
+ if (-not $base) { $base = $env:APPDATA }
297
+ if (-not $base) { $base = 'C:\\' }
298
+ if ($env:AGENT_INSPECTOR_DATA_DIR) {
299
+ if ([System.IO.Path]::IsPathRooted($env:AGENT_INSPECTOR_DATA_DIR)) { return $env:AGENT_INSPECTOR_DATA_DIR }
300
+ return (Join-Path $base $env:AGENT_INSPECTOR_DATA_DIR)
301
+ }
302
+ if ($env:AGENT_INSPECTOR_CONFIG_DIR) {
303
+ if ([System.IO.Path]::IsPathRooted($env:AGENT_INSPECTOR_CONFIG_DIR)) { return $env:AGENT_INSPECTOR_CONFIG_DIR }
304
+ return (Join-Path $base $env:AGENT_INSPECTOR_CONFIG_DIR)
305
+ }
306
+ $current = Join-Path $base '.agent-inspector'
307
+ $legacy = Join-Path $base '.llm-inspector'
308
+ $currentHasState = (Test-Path (Join-Path $current 'providers.json')) -or (Test-Path (Join-Path $current 'config.json')) -or (Test-Path (Join-Path $current 'logs')) -or (Test-Path (Join-Path $current 'chunks'))
309
+ $legacyHasState = (Test-Path (Join-Path $legacy 'providers.json')) -or (Test-Path (Join-Path $legacy 'config.json')) -or (Test-Path (Join-Path $legacy 'logs')) -or (Test-Path (Join-Path $legacy 'chunks'))
310
+ if (-not $currentHasState -and $legacyHasState) {
311
+ return $legacy
312
+ }
313
+ return $current
314
+ }
315
+ $dir = Resolve-AgentInspectorDataDir
316
+ $file = Join-Path $dir 'providers.json'
317
+ New-Item -ItemType Directory -Force -Path $dir | Out-Null
318
+ $now = (Get-Date).ToUniversalTime().ToString('o')
319
+ $json = @{
320
+ providers = @(
321
+ @{
322
+ id = 'onboard-anthropic'
323
+ name = 'Anthropic'
324
+ apiKey = 'REPLACE_ME_BEFORE_WRITING'
325
+ models = @('claude-sonnet-4-5-20250929')
326
+ format = 'anthropic'
327
+ anthropicBaseUrl = 'https://api.anthropic.com'
328
+ openaiBaseUrl = ''
329
+ authHeader = 'bearer'
330
+ createdAt = $now
331
+ updatedAt = $now
332
+ }
333
+ )
334
+ } | ConvertTo-Json -Depth 5
335
+ $json | Set-Content -Path $file -Encoding UTF8
336
+ # Then patch the apiKey with the user-provided value
337
+ \`\`\`
338
+
339
+ **DO:** Patch the placeholder with the actual key using \`jq\` (preferred) or a simple \`sed\`. Then read the file back to confirm the key is no longer \`REPLACE_ME_BEFORE_WRITING\`.
340
+
341
+ **DO:** If the user declines to provide a key in the AskUserQuestion (selects "Skip for now"), do **not** write a placeholder config. Tell the user that Phase 5 (First capture) will be skipped, and that they can re-run the skill after adding a key.
342
+
343
+ > **PAUSE** — use \`AskUserQuestion\` with header \`Provider key\` and options \`["Key is in, continue", "Skip for now, I'll add it later"]\`. Wait for the answer.
344
+
345
+ ---
346
+
347
+ ## Phase 3: Start proxy
348
+
349
+ **EXPLAIN:** "Time to start the proxy. It binds to port ${port} by default, reuses an already-running healthy agent-inspector, and prints the URL. Use \`--force-restart\` only when you intentionally want to replace the existing process."
350
+
351
+ **DO:** Skip this phase entirely if the Phase 0 health check already reported \`PROXY: up\` and the user opted to skip done phases.
352
+
353
+ **DO:** Otherwise, start the proxy with the explicit \`--background --no-open\` flags. On Windows, resolve the npm shim first and launch it through \`Start-Process -WindowStyle Hidden\` so setup does not flash a command window.
354
+
355
+ \`\`\`bash
356
+ # Unix / macOS / WSL
357
+ agent-inspector --background --no-open > /tmp/agent-inspector.log 2>&1
358
+ \`\`\`
359
+
360
+ \`\`\`powershell
361
+ # Windows PowerShell — single-quoted so $env: expands correctly.
362
+ # Locate the binary on PATH first (works for npm, pnpm, yarn, volta, fnm).
363
+ # If not on PATH, fall back to the common npm global shim at $env:APPDATA.
364
+ # As a last resort, let cmd /c resolve it through PATHEXT.
365
+ $log = Join-Path $env:TEMP 'agent-inspector.log'
366
+ $err = Join-Path $env:TEMP 'agent-inspector.err.log'
367
+ $found = Get-Command agent-inspector -ErrorAction SilentlyContinue
368
+ if ($found) {
369
+ $shim = $found.Source
370
+ $args = '--background','--no-open'
371
+ } elseif (Test-Path (Join-Path $env:APPDATA 'npm/agent-inspector.cmd')) {
372
+ $shim = Join-Path $env:APPDATA 'npm/agent-inspector.cmd'
373
+ $args = '--background','--no-open'
374
+ } else {
375
+ # bin not on PATH and not at the default npm prefix — let cmd resolve it
376
+ $shim = 'cmd.exe'
377
+ $args = '/c','agent-inspector','--background','--no-open'
378
+ }
379
+ Start-Process -FilePath $shim -ArgumentList $args -RedirectStandardOutput $log -RedirectStandardError $err -WindowStyle Hidden
380
+ \`\`\`
381
+
382
+ Then wait for the port to be ready:
383
+
384
+ \`\`\`bash
385
+ for i in $(seq 1 20); do
386
+ curl -fsS "http://localhost:${port}/api/health" >/dev/null 2>&1 && echo "ready" && break
387
+ sleep 0.5
388
+ done
389
+ \`\`\`
390
+
391
+ **DO:** Hit the health endpoint to confirm the proxy is alive:
392
+
393
+ \`\`\`bash
394
+ curl -sS "http://localhost:${port}/api/health"
395
+ \`\`\`
396
+
397
+ > **PAUSE** — if the health check fails, show the user the log file (\`/tmp/agent-inspector.log\` or \`%TEMP%\\agent-inspector.log\`) and diagnose. Common issues: another process on the port, firewall, missing providers. Use \`AskUserQuestion\` with header \`Proxy up?\` and options \`["Yes, proxy is up", "No, I see an error in the log"]\`. Wait for the answer.
398
+
399
+ ---
400
+
401
+ ## Phase 4: Wire tool
402
+
403
+ **EXPLAIN:** "Now we tell your AI tool to send traffic through the proxy instead of directly to the upstream API. The exact env var depends on which tool you have."
404
+
405
+ **DO:** Based on the \`Environment detected\` block at the top of this skill, print the matching wiring command. Examples for each supported tool:
406
+
407
+ \`\`\`bash
408
+ # Claude Code
409
+ export ANTHROPIC_BASE_URL=http://localhost:${port}/proxy
410
+ claude
411
+
412
+ # OpenCode
413
+ export LLM_BASE_URL=http://localhost:${port}/proxy
414
+ opencode
415
+
416
+ # MiMo Code
417
+ export OPENAI_BASE_URL=http://localhost:${port}/proxy
418
+ mimo
419
+
420
+ # Cursor / Cody — set the OpenAI base URL in each tool's settings panel to http://localhost:${port}/proxy
421
+ \`\`\`
422
+
423
+ For a tool that wasn't auto-detected, fall through to the generic curl test in the next phase — the user can wire their tool later.
424
+
425
+ > **PAUSE** — use \`AskUserQuestion\` with header \`Tool wired?\` and options \`["Yes, env var is set, claude is running", "No, I'm going to use the curl test instead"]\`. Wait for the answer.
426
+
427
+ ---
428
+
429
+ ## Phase 4.5: Wire MCP server
430
+
431
+ **EXPLAIN:** "The proxy also exposes an MCP server at \`http://localhost:${port}/api/mcp\`. Your AI agent can query logs, replay requests, and test providers through it — no need to leave the editor."
432
+
433
+ **DO:** Skip this phase if Phase 0 reported \`MCP: wired in <path>\` and the user opted to skip done phases.
434
+
435
+ **DO:** Otherwise, check the project-level \`.mcp.json\` first (preferred — modern Claude Code convention), then fall back to \`~/.claude.json\`. Use the \`Read\` tool to inspect; do **not** \`cat\` a 40 KB file into the conversation.
436
+
437
+ If neither has an \`agent-inspector\` entry, add one. The simplest path is to write to project \`.mcp.json\` (create it if missing):
438
+
439
+ \`\`\`json
440
+ // .mcp.json (project root)
441
+ {
442
+ "mcpServers": {
443
+ "agent-inspector": {
444
+ "type": "http",
445
+ "url": "http://localhost:${port}/api/mcp"
446
+ }
447
+ }
448
+ }
449
+ \`\`\`
450
+
451
+ If \`mcpServers\` already exists in \`.mcp.json\`, merge the \`agent-inspector\` key into it via the \`Edit\` tool — do not overwrite other entries. If you can't create a project \`.mcp.json\` (no project root, permission, etc.), fall back to merging into \`~/.claude.json\` using the same \`Read\`/\`Edit\` pattern.
452
+
453
+ **DO:** Verify the handshake. The MCP \`initialize\` request should return 200 with a \`serverInfo\` payload — that proves the server is mounted and reachable:
454
+
455
+ \`\`\`bash
456
+ curl -sS -X POST "http://localhost:${port}/api/mcp" \\
457
+ -H "Content-Type: application/json" \\
458
+ -H "Accept: application/json, text/event-stream" \\
459
+ -d '{
460
+ "jsonrpc": "2.0",
461
+ "id": 1,
462
+ "method": "initialize",
463
+ "params": {
464
+ "protocolVersion": "2025-03-26",
465
+ "capabilities": {},
466
+ "clientInfo": { "name": "onboard-check", "version": "0" }
467
+ }
468
+ }' | grep -o '"name":"agent-inspector"' && echo "handshake OK"
469
+ \`\`\`
470
+
471
+ The \`grep -o '"name":"agent-inspector"'\` extracts only the serverInfo name — do not dump the full response. If the server returns session IDs, store the \`mcp-session-id\` header from the first response and use it for the follow-up \`tools/list\` call.
472
+
473
+ > **PAUSE** — use \`AskUserQuestion\` with header \`MCP OK?\` and options \`["Yes, handshake returned 200", "No, the call failed"]\`. Wait for the answer.
474
+
475
+ ---
476
+
477
+ ## Phase 5: First capture
478
+
479
+ **EXPLAIN:** "Let's prove the proxy works end-to-end. We'll send one real request through it and confirm the log shows up in the API."
480
+
481
+ **DO:** First, re-check the config. If the \`apiKey\` is still a \`REPLACE_ME_BEFORE_WRITING\` placeholder (user opted out in Phase 2), **skip the capture test** and tell the user to fill in their key and re-run the skill. A 401 from the upstream is fine if they did provide a real key — the proxy will still log the request.
482
+
483
+ Fire a minimal Anthropic-format request through the proxy:
484
+
485
+ \`\`\`bash
486
+ curl -sS -X POST "http://localhost:${port}/proxy/v1/messages" \\
487
+ -H "Content-Type: application/json" \\
488
+ -H "anthropic-version: 2023-06-01" \\
489
+ -H "x-api-key: \${AGENT_INSPECTOR_API_KEY:-sk-no-key-needed-for-routing}" \\
490
+ -d '{"model":"claude-3-5-sonnet-20241022","max_tokens":1,"messages":[{"role":"user","content":"ping"}]}' \\
491
+ -o /tmp/agent-inspector-capture.json -w 'STATUS:%{http_code}\\n'
492
+ \`\`\`
493
+
494
+ **DO:** Poll the logs API for up to 5 seconds. A 200 with at least one entry means the request reached the proxy:
495
+
496
+ \`\`\`bash
497
+ for i in $(seq 1 10); do
498
+ resp=$(curl -sS "http://localhost:${port}/api/logs?limit=1")
499
+ count=$(echo "$resp" | grep -o '"total":[0-9]*' | head -1 | grep -o '[0-9]*$')
500
+ if [ "\${count:-0}" -ge 1 ]; then
501
+ echo "captured"
502
+ echo "$resp" | head -c 400
503
+ break
504
+ fi
505
+ sleep 0.5
506
+ done
507
+ \`\`\`
508
+
509
+ **DO:** Diagnose the response based on the actual status and body. **Do not** default to "auth failure" for every 4xx.
510
+
511
+ | Status | Body hint | Meaning |
512
+ |--------|-----------|---------|
513
+ | 200 | normal | Real success — the upstream returned data |
514
+ | 401 | \`"unauthorized"\` or similar | Upstream rejected the key (expected with a test key) |
515
+ | 403 | \`"Request not allowed"\` | **Proxy's allowlist** — not an auth failure, the proxy rejected the model/config. Show the user the proxy log. |
516
+ | 403 | other text | Could be upstream ACL — different problem |
517
+ | 5xx | anything | Upstream network error |
518
+
519
+ > **PAUSE** — use \`AskUserQuestion\` with header \`Captured?\` and options matching the diagnosis above. Wait for the answer.
520
+
521
+ ---
522
+
523
+ ## Phase 6: Tour & wrap
524
+
525
+ **EXPLAIN:** "Everything's working. Here's the cheat sheet for the Web UI and the supporting surfaces:"
526
+
527
+ - **Web UI**: \`http://localhost:${port}/\` — collapsible log rows, per-tab Copy/Expand in the log header, Diff with Raw (request body), Diff with Previous (compare adjacent requests), Replay (re-send a request), Export (JSON ZIP).
528
+ - **MCP server**: \`http://localhost:${port}/api/mcp\` — connect from your coding agent to query logs, replay, and test providers without leaving the editor. Look for the "MCP Ready" badge in the Web UI header.
529
+ - **REST API**: \`/api/logs\`, \`/api/sessions\`, \`/api/providers\` — for scripting and shell-based inspection.
530
+ - **Stop the proxy**:
531
+
532
+ \`\`\`bash
533
+ # Unix / macOS
534
+ lsof -ti:${port} | xargs -r kill -9
535
+
536
+ # Windows PowerShell — single-quoted so $env: expands correctly
537
+ Get-NetTCPConnection -LocalPort $port | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }
538
+ \`\`\`
539
+
540
+ - **Re-run onboard**: \`agent-inspector onboard --force\` refreshes this skill.
541
+ - **Full docs**: see the project README (linked from the Web UI footer).
542
+
543
+ > **PAUSE** — use \`AskUserQuestion\` with header \`All set?\` and options \`["All set, I'm done", "Wait, I want to revisit a phase"]\`. Wait for the answer.
544
+
545
+ You're done. Happy inspecting.
546
+ `;
547
+ }