@tonyclaw/agent-inspector 3.0.44 → 3.0.46

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 (347) hide show
  1. package/.output/{nitro.json → backend/nitro.json} +3 -3
  2. package/.output/backend-public/assets/index-D4LX-sw-.js +11 -0
  3. package/.output/cli.js +22707 -17099
  4. package/.output/server/_libs/extend.mjs +4 -8
  5. package/.output/server/_libs/jszip.mjs +9 -35
  6. package/.output/server/_libs/modelcontextprotocol__core.mjs +25 -25
  7. package/.output/server/_libs/modelcontextprotocol__server.mjs +2 -2
  8. package/.output/server/_libs/react-dom.mjs +2 -3
  9. package/.output/server/_libs/react.mjs +1 -27
  10. package/.output/server/_libs/tanstack__react-router.mjs +1 -329
  11. package/.output/server/_libs/tanstack__router-core.mjs +42 -100
  12. package/.output/server/_libs/use-sync-external-store.mjs +1 -64
  13. package/.output/server/_libs/ws.mjs +1 -1
  14. package/.output/server/_libs/zod.mjs +6 -6
  15. package/.output/server/_ssr/index.mjs +5 -4
  16. package/.output/server/_ssr/publicBasePathContext-IH2ilOfu.mjs +176 -0
  17. package/.output/server/_ssr/{router-DWcUFPR3.mjs → router-D18yUq36.mjs} +7877 -5597
  18. package/.output/server/_ssr/start-COQu_AgD.mjs +57 -0
  19. package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
  20. package/.output/server/index.mjs +5 -145
  21. package/.output/{public/assets/CompareDrawer-DQHjxFO6.js → ui/assets/CompareDrawer-DAUuIJ6G.js} +1 -1
  22. package/.output/{public/assets/InspectorPet-D1A4505B.js → ui/assets/InspectorPet-BRBVjOWI.js} +1 -1
  23. package/.output/ui/assets/ProxyViewerContainer-D7Sq0ctc.js +59 -0
  24. package/.output/{public/assets/ReplayDialog-C5vmbecv.js → ui/assets/ReplayDialog-nDLsjOhs.js} +1 -1
  25. package/.output/{public/assets/RequestAnatomy-CPGNB8lk.js → ui/assets/RequestAnatomy-zd4BDgL0.js} +1 -1
  26. package/.output/ui/assets/ResponseView-AdIXGcSn.js +2 -0
  27. package/.output/ui/assets/StreamingChunkSequence-CesTz8He.js +1 -0
  28. package/.output/{public/assets/_sessionId-CDhRgzf6.js → ui/assets/_sessionId-BAfzrhSU.js} +1 -1
  29. package/.output/{public/assets/_sessionId-mw3aA8Bp.js → ui/assets/_sessionId-QnBomgPD.js} +1 -1
  30. package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
  31. package/.output/{public/assets/index-B2eoeT-Z.js → ui/assets/index-BcsdxBAd.js} +1 -1
  32. package/.output/ui/assets/index-BvXp42al.css +1 -0
  33. package/.output/{public/assets/index-CX7_rf7o.js → ui/assets/index-D0rtCN9V.js} +1 -1
  34. package/.output/ui/assets/index-DHpwr08Z.js +73 -0
  35. package/.output/{public/assets/index-BfRhTvOd.js → ui/assets/index-dNuk2dsU.js} +1 -1
  36. package/.output/ui/assets/json-viewer-BvFHglMb.js +1 -0
  37. package/.output/{public/assets/jszip.min-C9rCFoU3.js → ui/assets/jszip.min-B5Z7gNZB.js} +1 -1
  38. package/.output/ui/index.html +229 -0
  39. package/.output/ui/runtime-config.js +2 -0
  40. package/.output/workers/logFinalizer.worker.js +983 -414
  41. package/.output/workers/sessionWorkerEntry.js +983 -414
  42. package/README.md +363 -35
  43. package/docs/instance-control.openapi.yaml +361 -0
  44. package/package.json +28 -5
  45. package/scripts/generate-theme-scales.mjs +3 -3
  46. package/src/{router.tsx → backend/router.tsx} +3 -15
  47. package/src/backend/routes/$.ts +26 -0
  48. package/src/backend/routes/__root.ts +4 -0
  49. package/src/backend/routes/api/-instances.ts +109 -0
  50. package/src/{routes → backend/routes}/api/alerts.summary.ts +3 -3
  51. package/src/{routes → backend/routes}/api/alerts.ts +4 -4
  52. package/src/{routes → backend/routes}/api/config.paths.ts +1 -1
  53. package/src/{routes → backend/routes}/api/config.ts +11 -2
  54. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.help.ts +1 -1
  55. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.install.ts +1 -1
  56. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.runner-presets.ts +1 -1
  57. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.upgrade.ts +1 -1
  58. package/src/{routes → backend/routes}/api/ecosystem.packages.ts +5 -1
  59. package/src/{routes → backend/routes}/api/ecosystem.recipes.$recipeId.run.ts +1 -1
  60. package/src/{routes → backend/routes}/api/ecosystem.tasks.$taskId.ts +1 -1
  61. package/src/{routes → backend/routes}/api/ecosystem.tasks.ts +1 -1
  62. package/src/{routes → backend/routes}/api/groups.$groupId.evidence.ts +2 -2
  63. package/src/{routes → backend/routes}/api/groups.$groupId.sessions.ts +2 -2
  64. package/src/{routes → backend/routes}/api/groups.$groupId.ts +2 -2
  65. package/src/{routes → backend/routes}/api/groups.ts +2 -2
  66. package/src/{routes → backend/routes}/api/health.ts +3 -3
  67. package/src/backend/routes/api/instances.$name.connection.ts +12 -0
  68. package/src/backend/routes/api/instances.$name.restart.ts +23 -0
  69. package/src/backend/routes/api/instances.$name.start.ts +18 -0
  70. package/src/backend/routes/api/instances.$name.stop.ts +23 -0
  71. package/src/backend/routes/api/instances.$name.ts +12 -0
  72. package/src/backend/routes/api/instances.ts +16 -0
  73. package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.promote.ts +2 -2
  74. package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.ts +2 -2
  75. package/src/{routes → backend/routes}/api/knowledge.candidates.ts +1 -1
  76. package/src/{routes → backend/routes}/api/knowledge.project-context.ts +2 -2
  77. package/src/{routes → backend/routes}/api/knowledge.search.ts +2 -2
  78. package/src/{routes → backend/routes}/api/knowledge.sessions.$sessionId.candidates.ts +3 -3
  79. package/src/{routes → backend/routes}/api/logs.$id.body.ts +6 -6
  80. package/src/{routes → backend/routes}/api/logs.$id.chunks.ts +5 -4
  81. package/src/{routes → backend/routes}/api/logs.$id.replay.ts +12 -11
  82. package/src/{routes → backend/routes}/api/logs.$id.ts +4 -3
  83. package/src/{routes → backend/routes}/api/logs.import.ts +3 -3
  84. package/src/{routes → backend/routes}/api/logs.stream.ts +11 -7
  85. package/src/{routes → backend/routes}/api/logs.ts +17 -9
  86. package/src/{routes → backend/routes}/api/mcp.ts +1 -1
  87. package/src/{routes → backend/routes}/api/models.ts +1 -1
  88. package/src/{routes → backend/routes}/api/pi-agent.ts +2 -2
  89. package/src/{routes → backend/routes}/api/providers.$providerId.model-metadata.ts +5 -5
  90. package/src/{routes → backend/routes}/api/providers.$providerId.test.log.ts +7 -7
  91. package/src/{routes → backend/routes}/api/providers.$providerId.ts +4 -4
  92. package/src/{routes → backend/routes}/api/providers.export.ts +1 -1
  93. package/src/{routes → backend/routes}/api/providers.import.ts +3 -3
  94. package/src/{routes → backend/routes}/api/providers.scan.ts +2 -2
  95. package/src/{routes → backend/routes}/api/providers.ts +9 -4
  96. package/src/{routes → backend/routes}/api/runs.$runId.evidence.ts +2 -2
  97. package/src/{routes → backend/routes}/api/runs.$runId.ts +2 -2
  98. package/src/{routes → backend/routes}/api/runs.ts +4 -4
  99. package/src/backend/routes/api/runtime.ts +46 -0
  100. package/src/{routes → backend/routes}/api/sessions.ts +3 -3
  101. package/src/{routes → backend/routes}/proxy/$.ts +1 -1
  102. package/src/{routes → backend/routes}/readyz.ts +1 -1
  103. package/src/backend/start.ts +10 -0
  104. package/src/cli/alias.ts +431 -0
  105. package/src/cli/doctor.ts +32 -9
  106. package/src/cli/instance.ts +1050 -0
  107. package/src/cli/instanceArgs.ts +285 -0
  108. package/src/cli/instanceControl.ts +181 -0
  109. package/src/cli/instanceModel.ts +267 -0
  110. package/src/cli/instanceRegistry.ts +731 -0
  111. package/src/cli/networkHints.ts +27 -14
  112. package/src/cli/onboard.ts +190 -35
  113. package/src/cli/onboardTarget.ts +228 -0
  114. package/src/cli/templates/codex-skill-onboard.ts +109 -31
  115. package/src/cli/templates/skill-onboard.ts +140 -70
  116. package/src/cli.ts +338 -77
  117. package/src/components/ProxyViewer.tsx +20 -10
  118. package/src/components/ProxyViewerContainer.tsx +12 -11
  119. package/src/components/pi-agent/PiAgentPanel.tsx +2 -2
  120. package/src/components/providers/ProviderCard.tsx +1 -1
  121. package/src/components/providers/ProviderTestResultsView.tsx +1 -1
  122. package/src/components/providers/SettingsDialog.tsx +160 -140
  123. package/src/components/proxy-viewer/ApplicationBar.tsx +2 -1
  124. package/src/components/proxy-viewer/LogEntry.tsx +1 -1
  125. package/src/components/proxy-viewer/log-formats/index.ts +1 -1
  126. package/src/contracts/index.ts +5 -0
  127. package/src/contracts/log.ts +33 -3
  128. package/src/knowledge/types.ts +3 -2
  129. package/src/lib/alertContract.ts +2 -2
  130. package/src/lib/apiClient.ts +30 -7
  131. package/src/lib/apiFormat.ts +29 -0
  132. package/src/lib/basePath.ts +31 -7
  133. package/src/lib/browserRuntimeContract.ts +124 -0
  134. package/src/lib/browserRuntimeResolver.ts +244 -0
  135. package/src/{proxy → lib}/claudeCodeStrip.ts +6 -7
  136. package/src/lib/codingAgentEndpoints.ts +54 -0
  137. package/src/lib/instanceContract.ts +236 -0
  138. package/src/lib/managedInstance.ts +104 -0
  139. package/src/lib/piAgentContract.ts +3 -2
  140. package/src/lib/publicBasePathContext.ts +137 -0
  141. package/src/lib/resourceLimits.ts +2 -0
  142. package/src/lib/runContract.ts +3 -3
  143. package/src/lib/sessionInfoContract.ts +3 -2
  144. package/src/mcp/instanceHandlers.ts +150 -0
  145. package/src/mcp/loopback.ts +16 -5
  146. package/src/mcp/mode.ts +25 -0
  147. package/src/mcp/server.ts +274 -39
  148. package/src/mcp/toolHandlers.ts +2 -2
  149. package/src/proxy/config.ts +25 -30
  150. package/src/proxy/dataDir.ts +43 -7
  151. package/src/proxy/ecosystemTasks.ts +161 -70
  152. package/src/proxy/formats/registry.ts +6 -21
  153. package/src/proxy/handler.ts +129 -29
  154. package/src/proxy/identityProxy.ts +1049 -50
  155. package/src/proxy/jsonlRecovery.ts +554 -0
  156. package/src/proxy/logFinalizer.ts +25 -10
  157. package/src/proxy/logImporter.ts +2 -1
  158. package/src/proxy/logIndex.ts +191 -95
  159. package/src/proxy/logger.ts +77 -14
  160. package/src/proxy/platformCommands.ts +41 -0
  161. package/src/proxy/privateDataPath.ts +310 -88
  162. package/src/proxy/rawStreamCapture.ts +194 -13
  163. package/src/proxy/runtimeAdmission.ts +5 -2
  164. package/src/proxy/runtimeHealth.ts +14 -1
  165. package/src/proxy/runtimeShutdown.ts +84 -2
  166. package/src/proxy/schemas.ts +7 -1
  167. package/src/proxy/sessionArchive.ts +78 -14
  168. package/src/proxy/sessionInfo.ts +5 -4
  169. package/src/proxy/sqliteLogIndex.ts +65 -2
  170. package/src/proxy/store.ts +141 -34
  171. package/src/proxy/uiAssetServer.ts +106 -0
  172. package/src/proxy/upstream.ts +29 -2
  173. package/src/ui/bootstrap.ts +167 -0
  174. package/src/ui/index.html +38 -0
  175. package/src/ui/logsStreamClient.ts +20 -0
  176. package/src/ui/main.tsx +13 -0
  177. package/src/ui/public/runtime-config.js +2 -0
  178. package/src/ui/router.tsx +13 -0
  179. package/src/ui/routes/__root.tsx +69 -0
  180. package/src/{routes → ui/routes}/index.tsx +2 -3
  181. package/src/{routes → ui/routes}/session/$sessionId.tsx +5 -11
  182. package/src/ui/runtimeDiscovery.ts +50 -0
  183. package/styles/globals.css +1 -0
  184. package/.output/public/assets/ProxyViewerContainer-BhpIgfBi.js +0 -126
  185. package/.output/public/assets/ResponseView-DUfrajCm.js +0 -2
  186. package/.output/public/assets/StreamingChunkSequence-nbeCQqOz.js +0 -1
  187. package/.output/public/assets/index-BWjeqxbk.css +0 -1
  188. package/.output/public/assets/index-C6qZwYlR.js +0 -70
  189. package/.output/public/assets/json-viewer-BLmF1sOZ.js +0 -1
  190. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +0 -1
  191. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +0 -344
  192. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +0 -2
  193. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +0 -2
  194. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +0 -2
  195. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +0 -11
  196. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +0 -69
  197. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +0 -1
  198. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +0 -28
  199. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +0 -6
  200. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +0 -34
  201. package/.output/server/_libs/aria-hidden.mjs +0 -122
  202. package/.output/server/_libs/bail.mjs +0 -8
  203. package/.output/server/_libs/character-entities.mjs +0 -2130
  204. package/.output/server/_libs/class-variance-authority.mjs +0 -44
  205. package/.output/server/_libs/clsx.mjs +0 -16
  206. package/.output/server/_libs/comma-separated-tokens.mjs +0 -10
  207. package/.output/server/_libs/decode-named-character-reference+[...].mjs +0 -8
  208. package/.output/server/_libs/dequal.mjs +0 -27
  209. package/.output/server/_libs/detect-node-es.mjs +0 -1
  210. package/.output/server/_libs/devlop.mjs +0 -8
  211. package/.output/server/_libs/diff.mjs +0 -320
  212. package/.output/server/_libs/estree-util-is-identifier-name.mjs +0 -11
  213. package/.output/server/_libs/floating-ui__core.mjs +0 -725
  214. package/.output/server/_libs/floating-ui__dom.mjs +0 -622
  215. package/.output/server/_libs/floating-ui__react-dom.mjs +0 -292
  216. package/.output/server/_libs/floating-ui__utils.mjs +0 -320
  217. package/.output/server/_libs/get-nonce.mjs +0 -9
  218. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +0 -388
  219. package/.output/server/_libs/hast-util-whitespace.mjs +0 -10
  220. package/.output/server/_libs/html-url-attributes.mjs +0 -26
  221. package/.output/server/_libs/inline-style-parser.mjs +0 -142
  222. package/.output/server/_libs/is-plain-obj.mjs +0 -10
  223. package/.output/server/_libs/lucide-react.mjs +0 -1027
  224. package/.output/server/_libs/mdast-util-from-markdown.mjs +0 -717
  225. package/.output/server/_libs/mdast-util-to-hast.mjs +0 -710
  226. package/.output/server/_libs/mdast-util-to-string.mjs +0 -38
  227. package/.output/server/_libs/micromark-core-commonmark.mjs +0 -2259
  228. package/.output/server/_libs/micromark-factory-destination.mjs +0 -94
  229. package/.output/server/_libs/micromark-factory-label.mjs +0 -63
  230. package/.output/server/_libs/micromark-factory-space.mjs +0 -24
  231. package/.output/server/_libs/micromark-factory-title.mjs +0 -65
  232. package/.output/server/_libs/micromark-factory-whitespace.mjs +0 -22
  233. package/.output/server/_libs/micromark-util-character.mjs +0 -44
  234. package/.output/server/_libs/micromark-util-chunked.mjs +0 -36
  235. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +0 -12
  236. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +0 -41
  237. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -19
  238. package/.output/server/_libs/micromark-util-decode-string.mjs +0 -21
  239. package/.output/server/_libs/micromark-util-encode.mjs +0 -1
  240. package/.output/server/_libs/micromark-util-html-tag-name.mjs +0 -69
  241. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +0 -6
  242. package/.output/server/_libs/micromark-util-resolve-all.mjs +0 -15
  243. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +0 -41
  244. package/.output/server/_libs/micromark-util-subtokenize.mjs +0 -346
  245. package/.output/server/_libs/micromark.mjs +0 -906
  246. package/.output/server/_libs/property-information.mjs +0 -1209
  247. package/.output/server/_libs/radix-ui.mjs +0 -1
  248. package/.output/server/_libs/radix-ui__number.mjs +0 -6
  249. package/.output/server/_libs/radix-ui__primitive.mjs +0 -11
  250. package/.output/server/_libs/radix-ui__react-accordion.mjs +0 -1
  251. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +0 -1
  252. package/.output/server/_libs/radix-ui__react-arrow.mjs +0 -23
  253. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +0 -1
  254. package/.output/server/_libs/radix-ui__react-avatar.mjs +0 -1
  255. package/.output/server/_libs/radix-ui__react-checkbox.mjs +0 -1
  256. package/.output/server/_libs/radix-ui__react-collapsible.mjs +0 -144
  257. package/.output/server/_libs/radix-ui__react-collection.mjs +0 -69
  258. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +0 -38
  259. package/.output/server/_libs/radix-ui__react-context-menu.mjs +0 -1
  260. package/.output/server/_libs/radix-ui__react-context.mjs +0 -64
  261. package/.output/server/_libs/radix-ui__react-dialog.mjs +0 -280
  262. package/.output/server/_libs/radix-ui__react-direction.mjs +0 -9
  263. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +0 -1
  264. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +0 -39
  265. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +0 -210
  266. package/.output/server/_libs/radix-ui__react-form.mjs +0 -1
  267. package/.output/server/_libs/radix-ui__react-hover-card.mjs +0 -1
  268. package/.output/server/_libs/radix-ui__react-id.mjs +0 -14
  269. package/.output/server/_libs/radix-ui__react-label.mjs +0 -1
  270. package/.output/server/_libs/radix-ui__react-menu.mjs +0 -1
  271. package/.output/server/_libs/radix-ui__react-menubar.mjs +0 -1
  272. package/.output/server/_libs/radix-ui__react-popover.mjs +0 -1
  273. package/.output/server/_libs/radix-ui__react-popper.mjs +0 -340
  274. package/.output/server/_libs/radix-ui__react-portal.mjs +0 -16
  275. package/.output/server/_libs/radix-ui__react-presence.mjs +0 -173
  276. package/.output/server/_libs/radix-ui__react-primitive.mjs +0 -42
  277. package/.output/server/_libs/radix-ui__react-progress.mjs +0 -1
  278. package/.output/server/_libs/radix-ui__react-radio-group.mjs +0 -1
  279. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +0 -235
  280. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +0 -731
  281. package/.output/server/_libs/radix-ui__react-select.mjs +0 -1207
  282. package/.output/server/_libs/radix-ui__react-separator.mjs +0 -28
  283. package/.output/server/_libs/radix-ui__react-slider.mjs +0 -1
  284. package/.output/server/_libs/radix-ui__react-slot.mjs +0 -132
  285. package/.output/server/_libs/radix-ui__react-switch.mjs +0 -1
  286. package/.output/server/_libs/radix-ui__react-tabs.mjs +0 -194
  287. package/.output/server/_libs/radix-ui__react-toast.mjs +0 -2
  288. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +0 -1
  289. package/.output/server/_libs/radix-ui__react-toggle.mjs +0 -1
  290. package/.output/server/_libs/radix-ui__react-toolbar.mjs +0 -1
  291. package/.output/server/_libs/radix-ui__react-tooltip.mjs +0 -498
  292. package/.output/server/_libs/radix-ui__react-use-previous.mjs +0 -14
  293. package/.output/server/_libs/radix-ui__react-use-size.mjs +0 -39
  294. package/.output/server/_libs/react-markdown.mjs +0 -235
  295. package/.output/server/_libs/react-remove-scroll-bar.mjs +0 -82
  296. package/.output/server/_libs/react-remove-scroll.mjs +0 -328
  297. package/.output/server/_libs/react-style-singleton.mjs +0 -69
  298. package/.output/server/_libs/remark-parse.mjs +0 -19
  299. package/.output/server/_libs/remark-rehype.mjs +0 -21
  300. package/.output/server/_libs/space-separated-tokens.mjs +0 -6
  301. package/.output/server/_libs/style-to-js.mjs +0 -72
  302. package/.output/server/_libs/style-to-object.mjs +0 -38
  303. package/.output/server/_libs/swr.mjs +0 -947
  304. package/.output/server/_libs/tailwind-merge.mjs +0 -3255
  305. package/.output/server/_libs/tanstack__react-virtual.mjs +0 -130
  306. package/.output/server/_libs/tanstack__virtual-core.mjs +0 -1319
  307. package/.output/server/_libs/three.mjs +0 -26016
  308. package/.output/server/_libs/trim-lines.mjs +0 -41
  309. package/.output/server/_libs/trough.mjs +0 -85
  310. package/.output/server/_libs/tslib.mjs +0 -1
  311. package/.output/server/_libs/ungap__structured-clone.mjs +0 -212
  312. package/.output/server/_libs/unified.mjs +0 -661
  313. package/.output/server/_libs/unist-util-is.mjs +0 -100
  314. package/.output/server/_libs/unist-util-position.mjs +0 -27
  315. package/.output/server/_libs/unist-util-stringify-position.mjs +0 -27
  316. package/.output/server/_libs/unist-util-visit-parents.mjs +0 -82
  317. package/.output/server/_libs/unist-util-visit.mjs +0 -24
  318. package/.output/server/_libs/use-callback-ref.mjs +0 -66
  319. package/.output/server/_libs/use-sidecar.mjs +0 -106
  320. package/.output/server/_libs/vfile-message.mjs +0 -138
  321. package/.output/server/_libs/vfile.mjs +0 -467
  322. package/.output/server/_sessionId-E_Dmopc-.mjs +0 -144
  323. package/.output/server/_sessionId-U54BAqdp.mjs +0 -82
  324. package/.output/server/_ssr/CompareDrawer-CksatPed.mjs +0 -1058
  325. package/.output/server/_ssr/InspectorPet-DNc4GQ7z.mjs +0 -936
  326. package/.output/server/_ssr/ProxyViewerContainer-B02Ey0p_.mjs +0 -17607
  327. package/.output/server/_ssr/ReplayDialog-DdMvHJF1.mjs +0 -723
  328. package/.output/server/_ssr/RequestAnatomy--vh2Z8__.mjs +0 -835
  329. package/.output/server/_ssr/ResponseView-Dhxc-cKC.mjs +0 -755
  330. package/.output/server/_ssr/StreamingChunkSequence-BG0EQmaD.mjs +0 -272
  331. package/.output/server/_ssr/index-D0At9nfd.mjs +0 -82
  332. package/.output/server/_ssr/index-lcfulIXa.mjs +0 -133
  333. package/.output/server/_ssr/json-viewer-My1J1_5R.mjs +0 -481
  334. package/.output/server/_ssr/start-HYkvq4Ni.mjs +0 -4
  335. package/.output/server/_tanstack-start-manifest_v-B2chR8ef.mjs +0 -4
  336. package/.output/server/node_modules/tslib/modules/index.js +0 -70
  337. package/.output/server/node_modules/tslib/modules/package.json +0 -3
  338. package/.output/server/node_modules/tslib/package.json +0 -47
  339. package/.output/server/node_modules/tslib/tslib.js +0 -484
  340. package/.output/server/package.json +0 -9
  341. package/src/routes/__root.tsx +0 -170
  342. /package/.output/{public → ui}/assets/agent-inspector-58K1_MsC.ico +0 -0
  343. /package/.output/{public → ui}/assets/alibaba-TTwafVwX.svg +0 -0
  344. /package/.output/{public → ui}/assets/minimax-BPMzvuL-.jpeg +0 -0
  345. /package/.output/{public → ui}/assets/qwen-mMn3f5ul.webp +0 -0
  346. /package/.output/{public → ui}/assets/zhipuai-BPNAnxo-.svg +0 -0
  347. /package/src/{routes → backend/routes}/livez.ts +0 -0
@@ -0,0 +1,150 @@
1
+ import { z } from "zod";
2
+ import {
3
+ InstanceConnectionOutputSchema,
4
+ InstanceEmptyRequestSchema,
5
+ InstanceErrorOutputSchema,
6
+ InstanceListOutputSchema,
7
+ InstanceOperationOutputSchema,
8
+ InstanceStartRequestSchema,
9
+ InstanceStatusOutputSchema,
10
+ type InstanceStartRequest,
11
+ } from "../lib/instanceContract";
12
+ import type { CallApiOptions } from "./loopback";
13
+ import type { ToolResult } from "./toolHandlers";
14
+
15
+ export const INSTANCE_LIFECYCLE_TIMEOUT_MS = 60_000;
16
+
17
+ export const InstanceToolNameSchema = z.string().trim().min(1).max(64);
18
+
19
+ export const InstanceLifecycleToolInputSchema = InstanceStartRequestSchema.extend({
20
+ name: InstanceToolNameSchema,
21
+ });
22
+
23
+ export const InstanceNameToolInputSchema = z
24
+ .object({
25
+ name: InstanceToolNameSchema,
26
+ })
27
+ .strict();
28
+
29
+ export type InstanceCallApiFn = (path: string, options?: CallApiOptions) => Promise<Response>;
30
+
31
+ export type InstanceLifecycleToolInput = InstanceStartRequest & { name: string };
32
+
33
+ function textJson(data: unknown): ToolResult {
34
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
35
+ }
36
+
37
+ function toolError(message: string): ToolResult {
38
+ return { content: [{ type: "text", text: message }], isError: true };
39
+ }
40
+
41
+ async function responseJson(response: Response): Promise<unknown | null> {
42
+ try {
43
+ const value: unknown = await response.json();
44
+ return value;
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+
50
+ async function validatedInstanceResponse(
51
+ response: Response,
52
+ schema: z.ZodType,
53
+ operation: string,
54
+ ): Promise<ToolResult> {
55
+ const value = await responseJson(response);
56
+ if (!response.ok) {
57
+ const error = InstanceErrorOutputSchema.safeParse(value);
58
+ return error.success
59
+ ? { ...textJson(error.data), isError: true }
60
+ : toolError(
61
+ `${operation} returned HTTP ${String(response.status)} with an invalid error body`,
62
+ );
63
+ }
64
+
65
+ const parsed = schema.safeParse(value);
66
+ return parsed.success
67
+ ? textJson(parsed.data)
68
+ : toolError(`${operation} returned an invalid public instance document`);
69
+ }
70
+
71
+ function instancePath(name: string, suffix = ""): string {
72
+ return `/api/instances/${encodeURIComponent(name)}${suffix}`;
73
+ }
74
+
75
+ function jsonPost(body: unknown): CallApiOptions {
76
+ return {
77
+ method: "POST",
78
+ headers: {
79
+ accept: "application/json",
80
+ "content-type": "application/json",
81
+ },
82
+ body: JSON.stringify(body),
83
+ timeoutMs: INSTANCE_LIFECYCLE_TIMEOUT_MS,
84
+ };
85
+ }
86
+
87
+ function lifecycleRequest(input: InstanceLifecycleToolInput): InstanceStartRequest {
88
+ return {
89
+ port: input.port,
90
+ basePath: input.basePath,
91
+ host: input.host,
92
+ captureMode: input.captureMode,
93
+ uiEnabled: input.uiEnabled,
94
+ dataDir: input.dataDir,
95
+ };
96
+ }
97
+
98
+ export async function listInstancesImpl(callApi: InstanceCallApiFn): Promise<ToolResult> {
99
+ const response = await callApi("/api/instances", {
100
+ headers: { accept: "application/json" },
101
+ });
102
+ return validatedInstanceResponse(response, InstanceListOutputSchema, "GET /api/instances");
103
+ }
104
+
105
+ export async function getInstanceImpl(
106
+ callApi: InstanceCallApiFn,
107
+ name: string,
108
+ ): Promise<ToolResult> {
109
+ const path = instancePath(name);
110
+ const response = await callApi(path, { headers: { accept: "application/json" } });
111
+ return validatedInstanceResponse(response, InstanceStatusOutputSchema, `GET ${path}`);
112
+ }
113
+
114
+ export async function getInstanceConnectionImpl(
115
+ callApi: InstanceCallApiFn,
116
+ name: string,
117
+ ): Promise<ToolResult> {
118
+ const path = instancePath(name, "/connection");
119
+ const response = await callApi(path, { headers: { accept: "application/json" } });
120
+ return validatedInstanceResponse(response, InstanceConnectionOutputSchema, `GET ${path}`);
121
+ }
122
+
123
+ export async function startInstanceImpl(
124
+ callApi: InstanceCallApiFn,
125
+ input: InstanceLifecycleToolInput,
126
+ ): Promise<ToolResult> {
127
+ const path = instancePath(input.name, "/start");
128
+ const request = lifecycleRequest(input);
129
+ const response = await callApi(path, jsonPost(InstanceStartRequestSchema.parse(request)));
130
+ return validatedInstanceResponse(response, InstanceOperationOutputSchema, `POST ${path}`);
131
+ }
132
+
133
+ export async function stopInstanceImpl(
134
+ callApi: InstanceCallApiFn,
135
+ name: string,
136
+ ): Promise<ToolResult> {
137
+ const path = instancePath(name, "/stop");
138
+ const response = await callApi(path, jsonPost(InstanceEmptyRequestSchema.parse({})));
139
+ return validatedInstanceResponse(response, InstanceOperationOutputSchema, `POST ${path}`);
140
+ }
141
+
142
+ export async function restartInstanceImpl(
143
+ callApi: InstanceCallApiFn,
144
+ input: InstanceLifecycleToolInput,
145
+ ): Promise<ToolResult> {
146
+ const path = instancePath(input.name, "/restart");
147
+ const request = lifecycleRequest(input);
148
+ const response = await callApi(path, jsonPost(InstanceStartRequestSchema.parse(request)));
149
+ return validatedInstanceResponse(response, InstanceOperationOutputSchema, `POST ${path}`);
150
+ }
@@ -16,8 +16,12 @@
16
16
  * — should stay identical so callers don't change.
17
17
  */
18
18
 
19
- import { getConfiguredBasePath, withBasePath } from "../lib/basePath";
20
- import { getCurrentPort } from "../lib/serverPort";
19
+ import {
20
+ AGENT_INSPECTOR_PUBLIC_BASE_PATH_HEADER,
21
+ AGENT_INSPECTOR_PUBLIC_PORT_HEADER,
22
+ withBasePath,
23
+ } from "../lib/basePath";
24
+ import { getPublicBasePath, getPublicPort } from "../lib/publicBasePathContext";
21
25
 
22
26
  const DEFAULT_TIMEOUT_MS = 30_000;
23
27
 
@@ -47,10 +51,17 @@ export async function callApi(path: string, options: CallApiOptions = {}): Promi
47
51
  if (!path.startsWith("/")) {
48
52
  throw new Error(`callApi: path must start with '/', got: ${path}`);
49
53
  }
50
- const port = getCurrentPort();
51
- const url = `http://127.0.0.1:${port}${withBasePath(path, getConfiguredBasePath(process.env))}`;
54
+ const port = getPublicPort();
55
+ const publicBasePath = getPublicBasePath();
56
+ const url = `http://127.0.0.1:${port}${withBasePath(path, publicBasePath)}`;
52
57
 
53
58
  const { timeoutMs = DEFAULT_TIMEOUT_MS, signal: userSignal, ...rest } = options;
59
+ const headers = new Headers(rest.headers);
60
+ headers.set(
61
+ AGENT_INSPECTOR_PUBLIC_BASE_PATH_HEADER,
62
+ publicBasePath.length === 0 ? "/" : publicBasePath,
63
+ );
64
+ headers.set(AGENT_INSPECTOR_PUBLIC_PORT_HEADER, String(port));
54
65
 
55
66
  const controller = new AbortController();
56
67
  const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
@@ -65,7 +76,7 @@ export async function callApi(path: string, options: CallApiOptions = {}): Promi
65
76
  }
66
77
 
67
78
  try {
68
- return await fetch(url, { ...rest, signal: controller.signal });
79
+ return await fetch(url, { ...rest, headers, signal: controller.signal });
69
80
  } catch (err) {
70
81
  if (err instanceof Error && err.name === "AbortError") {
71
82
  throw new LoopbackTimeoutError(path, timeoutMs);
package/src/mcp/mode.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export type McpWriteMode = "enabled" | "readonly";
2
2
 
3
+ export const MCP_INSTANCE_WRITES_ENV = "AGENT_INSPECTOR_MCP_INSTANCE_WRITES";
4
+
3
5
  function parseFlag(value: string | undefined): boolean | null {
4
6
  if (value === undefined) return null;
5
7
  switch (value.trim().toLowerCase()) {
@@ -26,6 +28,29 @@ export function isMcpWriteEnabled(): boolean {
26
28
  return writesFlag === true;
27
29
  }
28
30
 
31
+ export function isMcpInstanceWriteEnabled(): boolean {
32
+ return process.env[MCP_INSTANCE_WRITES_ENV] === "1";
33
+ }
34
+
35
+ export function getMcpInstanceModeInfo(): {
36
+ writeMode: McpWriteMode;
37
+ writesEnabled: boolean;
38
+ env: { AGENT_INSPECTOR_MCP_INSTANCE_WRITES: string | null };
39
+ note: string;
40
+ } {
41
+ const writesEnabled = isMcpInstanceWriteEnabled();
42
+ return {
43
+ writeMode: writesEnabled ? "enabled" : "readonly",
44
+ writesEnabled,
45
+ env: {
46
+ AGENT_INSPECTOR_MCP_INSTANCE_WRITES: process.env[MCP_INSTANCE_WRITES_ENV] ?? null,
47
+ },
48
+ note: writesEnabled
49
+ ? "Named-instance lifecycle tools passed the instance-specific opt-in. General MCP writes must also be enabled."
50
+ : "Named-instance lifecycle tools require AGENT_INSPECTOR_MCP_INSTANCE_WRITES=1 in addition to general MCP writes.",
51
+ };
52
+ }
53
+
29
54
  export function getMcpModeInfo(): {
30
55
  writeMode: McpWriteMode;
31
56
  writesEnabled: boolean;
package/src/mcp/server.ts CHANGED
@@ -33,9 +33,14 @@ import {
33
33
  UpdateInspectorGroupInputSchema,
34
34
  } from "../lib/groupContract";
35
35
  import { InspectorRunStatusSchema, UpdateInspectorRunInputSchema } from "../lib/runContract";
36
- import { getCurrentPort, setCurrentPort } from "../lib/serverPort";
37
- import { getConfiguredBasePath, withBasePath } from "../lib/basePath";
38
- import { JsonValueSchema } from "../contracts";
36
+ import { withBasePath } from "../lib/basePath";
37
+ import {
38
+ getPublicBasePath,
39
+ getPublicOrigin,
40
+ runWithRequestPublicBasePath,
41
+ } from "../lib/publicBasePathContext";
42
+ import { JsonValueSchema, LogIdSchema, parseLogId } from "../contracts";
43
+ import { InstanceListOutputSchema } from "../lib/instanceContract";
39
44
  import {
40
45
  MAX_PROVIDER_MODEL_NAME_CHARS,
41
46
  MAX_PROVIDER_MODELS,
@@ -43,7 +48,22 @@ import {
43
48
  MAX_SEARCH_QUERY_CHARS,
44
49
  } from "../lib/resourceLimits";
45
50
  import { getCurrentContext } from "./currentContext";
46
- import { getMcpModeInfo, isMcpWriteEnabled } from "./mode";
51
+ import {
52
+ getMcpInstanceModeInfo,
53
+ getMcpModeInfo,
54
+ isMcpInstanceWriteEnabled,
55
+ isMcpWriteEnabled,
56
+ } from "./mode";
57
+ import {
58
+ getInstanceConnectionImpl,
59
+ getInstanceImpl,
60
+ InstanceLifecycleToolInputSchema,
61
+ InstanceNameToolInputSchema,
62
+ listInstancesImpl,
63
+ restartInstanceImpl,
64
+ startInstanceImpl,
65
+ stopInstanceImpl,
66
+ } from "./instanceHandlers";
47
67
  import {
48
68
  getInspectorGroup,
49
69
  listInspectorGroups,
@@ -178,17 +198,10 @@ export async function _resetForTests(): Promise<void> {
178
198
  * handler — accepts a Web `Request`, returns a `Promise<Response>`.
179
199
  */
180
200
  export async function handleMcpRequest(request: Request): Promise<Response> {
181
- // Extract port from the incoming request URL so loopback calls work even
182
- // when PORT env var is unset (e.g. MCP client connected before server init).
183
- try {
184
- const url = new URL(request.url);
185
- const port = Number(url.port);
186
- if (port > 0) setCurrentPort(port);
187
- } catch {
188
- // URL parse failure → fall through to PORT env var in getCurrentPort()
189
- }
190
- const { transport } = await getServer();
191
- return transport.handleRequest(request);
201
+ return runWithRequestPublicBasePath(request, async () => {
202
+ const { transport } = await getServer();
203
+ return transport.handleRequest(request);
204
+ });
192
205
  }
193
206
 
194
207
  // ---------------------------------------------------------------------------
@@ -219,6 +232,27 @@ Either preview field is null when the body is unknown format, unparseable, or th
219
232
  const PROVIDER_WRITE_WARNING =
220
233
  "⚠ This tool mutates provider configuration. Confirm with the user before invoking.";
221
234
 
235
+ const INSTANCE_LIFECYCLE_WRITE_WARNING =
236
+ "This tool changes a local Agent Inspector process. Obtain explicit user approval before invoking it.";
237
+
238
+ const INSTANCE_READ_TOOL_NAMES = [
239
+ "inspector_list_instances",
240
+ "inspector_get_instance",
241
+ "inspector_get_instance_connection",
242
+ ] as const;
243
+
244
+ const INSTANCE_WRITE_TOOL_NAMES = [
245
+ "inspector_start_instance",
246
+ "inspector_stop_instance",
247
+ "inspector_restart_instance",
248
+ ] as const;
249
+
250
+ const INSTANCE_RESOURCE_URIS = [
251
+ "inspector://instances",
252
+ "inspector://instances/{name}",
253
+ "inspector://instances/{name}/connection",
254
+ ] as const;
255
+
222
256
  const AddProviderInputSchema = z
223
257
  .object({
224
258
  name: z.string().min(1).describe("Provider display name."),
@@ -301,7 +335,15 @@ const UpdateProviderInputSchema = z.object({
301
335
  });
302
336
 
303
337
  const LogResourceListResponseSchema = z.object({
304
- logs: z.array(z.object({ id: z.number().int().positive() })),
338
+ logs: z.array(z.object({ id: LogIdSchema })),
339
+ });
340
+
341
+ export const McpLogIdInputSchema = z.object({
342
+ id: LogIdSchema.describe("The log id."),
343
+ });
344
+
345
+ export const McpOptionalLogIdInputSchema = z.object({
346
+ id: LogIdSchema.optional().describe("Optional log id to inspect."),
305
347
  });
306
348
 
307
349
  const ProcessResourceListResponseSchema = z.object({
@@ -327,10 +369,7 @@ function jsonResource(uri: URL, data: unknown): ReadResourceResult {
327
369
  }
328
370
 
329
371
  function mcpEndpointUrl(): string {
330
- return `http://localhost:${String(getCurrentPort())}${withBasePath(
331
- "/api/mcp",
332
- getConfiguredBasePath(process.env),
333
- )}`;
372
+ return `${getPublicOrigin()}${withBasePath("/api/mcp", getPublicBasePath())}`;
334
373
  }
335
374
 
336
375
  function mcpHealth(): Record<string, unknown> {
@@ -342,7 +381,7 @@ function mcpHealth(): Record<string, unknown> {
342
381
  },
343
382
  transport: {
344
383
  primary: "streamable-http",
345
- endpoint: withBasePath("/api/mcp", getConfiguredBasePath(process.env)),
384
+ endpoint: mcpEndpointUrl(),
346
385
  stateless: true,
347
386
  },
348
387
  mode: getMcpModeInfo(),
@@ -355,6 +394,7 @@ function mcpHealth(): Record<string, unknown> {
355
394
  }
356
395
 
357
396
  const WRITE_TOOL_NAMES = new Set<string>([
397
+ ...INSTANCE_WRITE_TOOL_NAMES,
358
398
  "inspector_create_run",
359
399
  "inspector_update_run",
360
400
  "inspector_export_evidence",
@@ -379,18 +419,36 @@ const WRITE_TOOL_NAMES = new Set<string>([
379
419
  function mcpCapabilities(): Record<string, unknown> {
380
420
  const readTools = TOOL_NAMES.filter((name) => !WRITE_TOOL_NAMES.has(name));
381
421
  const writeTools = TOOL_NAMES.filter((name) => WRITE_TOOL_NAMES.has(name));
422
+ const generalWriteMode = getMcpModeInfo();
423
+ const instanceWriteMode = getMcpInstanceModeInfo();
382
424
  return {
383
425
  serverInfo: {
384
426
  name: "agent-inspector",
385
427
  version: MCP_SERVER_VERSION,
386
428
  },
387
- mode: getMcpModeInfo(),
429
+ mode: generalWriteMode,
388
430
  tools: {
389
431
  read: readTools,
390
432
  writeOrAction: writeTools,
391
433
  },
392
434
  resources: RESOURCE_NAMES,
393
435
  prompts: PROMPT_NAMES,
436
+ instanceControl: {
437
+ tools: {
438
+ read: INSTANCE_READ_TOOL_NAMES,
439
+ writeOrAction: INSTANCE_WRITE_TOOL_NAMES,
440
+ },
441
+ resources: INSTANCE_RESOURCE_URIS,
442
+ writeGates: {
443
+ general: generalWriteMode,
444
+ instance: instanceWriteMode,
445
+ lifecycleWritesEnabled: generalWriteMode.writesEnabled && instanceWriteMode.writesEnabled,
446
+ },
447
+ limitations: {
448
+ selfStopOrRestart:
449
+ "The serving managed instance cannot stop or restart itself over REST or MCP. Use the CLI or a sibling controller instance.",
450
+ },
451
+ },
394
452
  };
395
453
  }
396
454
 
@@ -473,6 +531,36 @@ function safeWriteCall(
473
531
  });
474
532
  }
475
533
 
534
+ function disabledInstanceWriteTool(toolName: string): ToolResult {
535
+ return {
536
+ content: [
537
+ {
538
+ type: "text",
539
+ text: JSON.stringify(
540
+ {
541
+ error: "mcp-instance-write-disabled",
542
+ tool: toolName,
543
+ generalMode: getMcpModeInfo(),
544
+ instanceMode: getMcpInstanceModeInfo(),
545
+ },
546
+ null,
547
+ 2,
548
+ ),
549
+ },
550
+ ],
551
+ isError: true,
552
+ };
553
+ }
554
+
555
+ function safeInstanceWriteCall(
556
+ toolName: string,
557
+ fn: () => ToolResult | Promise<ToolResult>,
558
+ ): Promise<ToolResult> {
559
+ return safeWriteCall(toolName, () =>
560
+ isMcpInstanceWriteEnabled() ? fn() : disabledInstanceWriteTool(toolName),
561
+ );
562
+ }
563
+
476
564
  function variableString(variables: Variables, name: string): string | null {
477
565
  const value = variables[name];
478
566
  if (Array.isArray(value)) return value[0] ?? null;
@@ -504,6 +592,41 @@ function readServiceJsonResource<T>(
504
592
  return jsonResource(uri, result.value);
505
593
  }
506
594
 
595
+ async function readInstanceToolResource(
596
+ uri: URL,
597
+ resultPromise: Promise<ToolResult>,
598
+ ): Promise<ReadResourceResult> {
599
+ const result = await resultPromise;
600
+ const text = result.content[0]?.text ?? "";
601
+ return textResource(uri, result.isError === true ? "text/plain" : "application/json", text);
602
+ }
603
+
604
+ async function listInstanceTemplateResources(connection: boolean): Promise<ListResourcesResult> {
605
+ try {
606
+ const response = await callApi("/api/instances", {
607
+ headers: { accept: "application/json" },
608
+ });
609
+ if (!response.ok) return listResult([]);
610
+ const parsed = InstanceListOutputSchema.safeParse(await response.json());
611
+ if (!parsed.success) return listResult([]);
612
+ return listResult(
613
+ parsed.data.instances.map((instance) => ({
614
+ uri: connection
615
+ ? `inspector://instances/${encodeURIComponent(instance.name)}/connection`
616
+ : `inspector://instances/${encodeURIComponent(instance.name)}`,
617
+ name: connection ? `instance-connection:${instance.name}` : `instance:${instance.name}`,
618
+ title: connection
619
+ ? `Agent Inspector connection for ${instance.name}`
620
+ : `Agent Inspector instance ${instance.name}`,
621
+ mimeType: "application/json",
622
+ description: `${instance.state} at ${instance.urls.ui}`,
623
+ })),
624
+ );
625
+ } catch {
626
+ return listResult([]);
627
+ }
628
+ }
629
+
507
630
  async function listSessionResources(): Promise<ListResourcesResult> {
508
631
  try {
509
632
  const response = await callApi("/api/sessions");
@@ -707,6 +830,74 @@ function userPrompt(text: string): GetPromptResult {
707
830
  // ---------------------------------------------------------------------------
708
831
 
709
832
  function registerTools(server: McpServer): void {
833
+ // ----- Named instance discovery and lifecycle -----
834
+
835
+ server.registerTool(
836
+ "inspector_list_instances",
837
+ {
838
+ title: "List named Agent Inspector instances",
839
+ description:
840
+ "Returns the versioned, token-free REST instance list with live state, saved configuration, and public URLs. Available in readonly mode.",
841
+ inputSchema: z.object({}).strict(),
842
+ },
843
+ () => safeCall(() => listInstancesImpl(callApi)),
844
+ );
845
+
846
+ server.registerTool(
847
+ "inspector_get_instance",
848
+ {
849
+ title: "Get a named Agent Inspector instance",
850
+ description:
851
+ "Returns one versioned, token-free named-instance status document from the REST control plane. Available in readonly mode.",
852
+ inputSchema: InstanceNameToolInputSchema,
853
+ },
854
+ ({ name }) => safeCall(() => getInstanceImpl(callApi, name)),
855
+ );
856
+
857
+ server.registerTool(
858
+ "inspector_get_instance_connection",
859
+ {
860
+ title: "Get coding-agent connection settings for an instance",
861
+ description:
862
+ "Returns the REST connection descriptor for one named instance, including protocol-correct proxy, OpenAI /v1, MCP, health, environment, and Codex values. It never includes credentials.",
863
+ inputSchema: InstanceNameToolInputSchema,
864
+ },
865
+ ({ name }) => safeCall(() => getInstanceConnectionImpl(callApi, name)),
866
+ );
867
+
868
+ server.registerTool(
869
+ "inspector_start_instance",
870
+ {
871
+ title: "Start or create a named Agent Inspector instance",
872
+ description: `${INSTANCE_LIFECYCLE_WRITE_WARNING} Starts, creates, or idempotently reuses a named sibling instance through the REST lifecycle API. Requires both AGENT_INSPECTOR_MCP_WRITES=1 and AGENT_INSPECTOR_MCP_INSTANCE_WRITES=1.`,
873
+ inputSchema: InstanceLifecycleToolInputSchema,
874
+ },
875
+ (args) =>
876
+ safeInstanceWriteCall("inspector_start_instance", () => startInstanceImpl(callApi, args)),
877
+ );
878
+
879
+ server.registerTool(
880
+ "inspector_stop_instance",
881
+ {
882
+ title: "Stop a named Agent Inspector instance",
883
+ description: `${INSTANCE_LIFECYCLE_WRITE_WARNING} Gracefully stops a sibling instance after authenticated ownership checks. The instance serving this MCP connection cannot stop itself. Requires both MCP write gates.`,
884
+ inputSchema: InstanceNameToolInputSchema,
885
+ },
886
+ ({ name }) =>
887
+ safeInstanceWriteCall("inspector_stop_instance", () => stopInstanceImpl(callApi, name)),
888
+ );
889
+
890
+ server.registerTool(
891
+ "inspector_restart_instance",
892
+ {
893
+ title: "Restart a named Agent Inspector instance",
894
+ description: `${INSTANCE_LIFECYCLE_WRITE_WARNING} Validates and restarts a sibling instance through the bounded REST lifecycle path. The instance serving this MCP connection cannot restart itself. Requires both MCP write gates.`,
895
+ inputSchema: InstanceLifecycleToolInputSchema,
896
+ },
897
+ (args) =>
898
+ safeInstanceWriteCall("inspector_restart_instance", () => restartInstanceImpl(callApi, args)),
899
+ );
900
+
710
901
  // ----- Read tools -----
711
902
 
712
903
  server.registerTool(
@@ -782,9 +973,7 @@ function registerTools(server: McpServer): void {
782
973
  title: "Get a single captured log by id",
783
974
  description:
784
975
  "Returns the full CapturedLog for the given id, including rawRequestBody and responseText with no truncation. SSE streaming chunks are NOT included — use inspector_get_log_chunks for those. Returns an error if the id does not exist.",
785
- inputSchema: z.object({
786
- id: z.number().int().positive().describe("The log id."),
787
- }),
976
+ inputSchema: McpLogIdInputSchema,
788
977
  },
789
978
  ({ id }) => safeCall(() => getLogImpl(callApi, id)),
790
979
  );
@@ -795,9 +984,7 @@ function registerTools(server: McpServer): void {
795
984
  title: "Get SSE streaming chunks for a captured log",
796
985
  description:
797
986
  "Returns the SSE chunks array for a streaming log, in the order they were received. Returns an error if the log has no chunks (i.e. was non-streaming or the log id is unknown).",
798
- inputSchema: z.object({
799
- id: z.number().int().positive().describe("The log id."),
800
- }),
987
+ inputSchema: McpLogIdInputSchema,
801
988
  },
802
989
  ({ id }) => safeCall(() => getLogChunksImpl(callApi, id)),
803
990
  );
@@ -808,9 +995,7 @@ function registerTools(server: McpServer): void {
808
995
  title: "Get captured log headers",
809
996
  description:
810
997
  "Returns header-focused evidence for one log without large request/response bodies: raw headers, upstream headers, user-agent, origin, client PID/port, session id, model, and API path.",
811
- inputSchema: z.object({
812
- id: z.number().int().positive().describe("The log id."),
813
- }),
998
+ inputSchema: McpLogIdInputSchema,
814
999
  },
815
1000
  ({ id }) => safeCall(() => getLogHeadersImpl(callApi, id)),
816
1001
  );
@@ -988,9 +1173,7 @@ function registerTools(server: McpServer): void {
988
1173
  title: "Diagnose capture detail availability",
989
1174
  description:
990
1175
  "Explains why headers or bodies may be missing for the current runtime or a specific log, including captureMode, compact body mode, rawHeaders presence, and next-step recommendations.",
991
- inputSchema: z.object({
992
- id: z.number().int().positive().optional().describe("Optional log id to inspect."),
993
- }),
1176
+ inputSchema: McpOptionalLogIdInputSchema,
994
1177
  },
995
1178
  (args) => safeCall(() => diagnoseCaptureImpl(callApi, args)),
996
1179
  );
@@ -1318,9 +1501,7 @@ function registerTools(server: McpServer): void {
1318
1501
  title: "Replay a captured log against its provider",
1319
1502
  description:
1320
1503
  "Re-sends the captured request body to the upstream LLM and returns the response summary: success flag, status, responseText, input/output token counts, elapsedMs, and whether the response was streaming. Useful for re-running a request after a fix or a transient failure. Returns an error if the log id is unknown or the upstream call fails.",
1321
- inputSchema: z.object({
1322
- id: z.number().int().positive().describe("The log id to replay."),
1323
- }),
1504
+ inputSchema: McpLogIdInputSchema,
1324
1505
  },
1325
1506
  (args) => safeWriteCall("inspector_replay_log", () => replayLogImpl(callApi, args)),
1326
1507
  );
@@ -1460,6 +1641,55 @@ PATCH-style update: only the fields you supply are changed. Use models to update
1460
1641
  }
1461
1642
 
1462
1643
  function registerResources(server: McpServer): void {
1644
+ server.registerResource(
1645
+ "inspector_instances",
1646
+ "inspector://instances",
1647
+ {
1648
+ title: "Named Agent Inspector instances",
1649
+ description: "Versioned, token-free named-instance list backed by GET /api/instances.",
1650
+ mimeType: "application/json",
1651
+ },
1652
+ (uri) => readInstanceToolResource(uri, listInstancesImpl(callApi)),
1653
+ );
1654
+
1655
+ server.registerResource(
1656
+ "inspector_instance",
1657
+ new ResourceTemplate("inspector://instances/{name}", {
1658
+ list: async () => await listInstanceTemplateResources(false),
1659
+ }),
1660
+ {
1661
+ title: "Named Agent Inspector instance",
1662
+ description:
1663
+ "Versioned, token-free status for one named instance backed by GET /api/instances/{name}.",
1664
+ mimeType: "application/json",
1665
+ },
1666
+ (uri, variables) => {
1667
+ const name = variableString(variables, "name");
1668
+ return name === null
1669
+ ? textResource(uri, "text/plain", "Missing instance name")
1670
+ : readInstanceToolResource(uri, getInstanceImpl(callApi, name));
1671
+ },
1672
+ );
1673
+
1674
+ server.registerResource(
1675
+ "inspector_instance_connection",
1676
+ new ResourceTemplate("inspector://instances/{name}/connection", {
1677
+ list: async () => await listInstanceTemplateResources(true),
1678
+ }),
1679
+ {
1680
+ title: "Named instance coding-agent connection",
1681
+ description:
1682
+ "Token-free connection descriptor backed by GET /api/instances/{name}/connection.",
1683
+ mimeType: "application/json",
1684
+ },
1685
+ (uri, variables) => {
1686
+ const name = variableString(variables, "name");
1687
+ return name === null
1688
+ ? textResource(uri, "text/plain", "Missing instance name")
1689
+ : readInstanceToolResource(uri, getInstanceConnectionImpl(callApi, name));
1690
+ },
1691
+ );
1692
+
1463
1693
  server.registerResource(
1464
1694
  "inspector_mcp_health",
1465
1695
  "inspector://mcp/health",
@@ -1580,8 +1810,8 @@ function registerResources(server: McpServer): void {
1580
1810
  },
1581
1811
  async (uri, variables) => {
1582
1812
  const id = variableString(variables, "id");
1583
- const parsed = id === null ? Number.NaN : Number(id);
1584
- if (!Number.isInteger(parsed) || parsed <= 0) {
1813
+ const parsed = id === null ? null : parseLogId(id);
1814
+ if (parsed === null) {
1585
1815
  return textResource(uri, "text/plain", "Invalid log id");
1586
1816
  }
1587
1817
  const result = await getLogImpl(callApi, parsed);
@@ -1958,6 +2188,8 @@ Return:
1958
2188
 
1959
2189
  // Surface the tool catalog for tests that assert on the tool name set.
1960
2190
  export const TOOL_NAMES = [
2191
+ ...INSTANCE_READ_TOOL_NAMES,
2192
+ ...INSTANCE_WRITE_TOOL_NAMES,
1961
2193
  "inspector_list_logs",
1962
2194
  "inspector_search_logs",
1963
2195
  "inspector_get_log",
@@ -2006,6 +2238,9 @@ export const TOOL_NAMES = [
2006
2238
  ] as const;
2007
2239
 
2008
2240
  export const RESOURCE_NAMES = [
2241
+ "inspector_instances",
2242
+ "inspector_instance",
2243
+ "inspector_instance_connection",
2009
2244
  "inspector_mcp_health",
2010
2245
  "inspector_mcp_capabilities",
2011
2246
  "inspector_mcp_config",