@tonyclaw/agent-inspector 3.0.45 → 3.0.47

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 (343) 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 +8018 -5451
  4. package/.output/server/_libs/extend.mjs +4 -8
  5. package/.output/server/_libs/jszip.mjs +9 -35
  6. package/.output/server/_libs/react-dom.mjs +2 -3
  7. package/.output/server/_libs/react.mjs +1 -27
  8. package/.output/server/_libs/tanstack__react-router.mjs +1 -329
  9. package/.output/server/_libs/tanstack__router-core.mjs +42 -100
  10. package/.output/server/_libs/use-sync-external-store.mjs +1 -64
  11. package/.output/server/_libs/ws.mjs +1 -1
  12. package/.output/server/_ssr/index.mjs +4 -4
  13. package/.output/server/_ssr/{publicBasePathContext-5264L3rX.mjs → publicBasePathContext-IH2ilOfu.mjs} +52 -24
  14. package/.output/server/_ssr/{router-BJ_ltLim.mjs → router-BwZEsYfS.mjs} +19794 -19444
  15. package/.output/server/_ssr/{start-C6MjPjxp.mjs → start-COQu_AgD.mjs} +1 -1
  16. package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
  17. package/.output/server/index.mjs +5 -145
  18. package/.output/{public/assets/CompareDrawer-B3_TLTJh.js → ui/assets/CompareDrawer-V-8lPASC.js} +1 -1
  19. package/.output/{public/assets/InspectorPet-Cpn6hv4P.js → ui/assets/InspectorPet-D4CVnfdf.js} +1 -1
  20. package/.output/ui/assets/ProxyViewerContainer-CO3ZVHLX.js +59 -0
  21. package/.output/{public/assets/ReplayDialog-B3EKVdJk.js → ui/assets/ReplayDialog-CpGyTLtt.js} +1 -1
  22. package/.output/{public/assets/RequestAnatomy-COOQjyUC.js → ui/assets/RequestAnatomy-BLuJL9dZ.js} +1 -1
  23. package/.output/ui/assets/ResponseView-BuSC-CH7.js +2 -0
  24. package/.output/ui/assets/StreamingChunkSequence-DeA-JJKa.js +1 -0
  25. package/.output/{public/assets/_sessionId-zbgYl7ZJ.js → ui/assets/_sessionId-8HuHFhjo.js} +1 -1
  26. package/.output/{public/assets/_sessionId-BJlM3nmt.js → ui/assets/_sessionId-Chp67th6.js} +1 -1
  27. package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
  28. package/.output/ui/assets/index-BvXp42al.css +1 -0
  29. package/.output/{public/assets/index-xF_NY8Yb.js → ui/assets/index-DPmKK_5d.js} +5 -5
  30. package/.output/{public/assets/index-BIK4bPTv.js → ui/assets/index-atoQrlb8.js} +1 -1
  31. package/.output/ui/assets/index-nY3E1vxV.js +73 -0
  32. package/.output/{public/assets/index-D2Qw6Ri2.js → ui/assets/index-nl9-dpZn.js} +1 -1
  33. package/.output/ui/assets/json-viewer-B9kIzqeX.js +1 -0
  34. package/.output/{public/assets/jszip.min-B_rfAUCe.js → ui/assets/jszip.min-B7tfyE-I.js} +1 -1
  35. package/.output/ui/index.html +229 -0
  36. package/.output/ui/runtime-config.js +2 -0
  37. package/.output/workers/logFinalizer.worker.js +979 -414
  38. package/.output/workers/sessionWorkerEntry.js +979 -414
  39. package/README.md +182 -43
  40. package/docs/instance-control.openapi.yaml +59 -4
  41. package/package.json +40 -6
  42. package/scripts/generate-theme-scales.mjs +3 -3
  43. package/src/{router.tsx → backend/router.tsx} +3 -15
  44. package/src/backend/routes/$.ts +26 -0
  45. package/src/backend/routes/__root.ts +4 -0
  46. package/src/backend/routes/api/-instances.ts +7 -0
  47. package/src/{routes → backend/routes}/api/alerts.summary.ts +3 -3
  48. package/src/{routes → backend/routes}/api/alerts.ts +4 -4
  49. package/src/{routes → backend/routes}/api/config.paths.ts +1 -1
  50. package/src/{routes → backend/routes}/api/config.ts +11 -2
  51. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.help.ts +1 -1
  52. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.install.ts +1 -1
  53. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.runner-presets.ts +1 -1
  54. package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.upgrade.ts +1 -1
  55. package/src/{routes → backend/routes}/api/ecosystem.packages.ts +5 -1
  56. package/src/{routes → backend/routes}/api/ecosystem.recipes.$recipeId.run.ts +1 -1
  57. package/src/{routes → backend/routes}/api/ecosystem.tasks.$taskId.ts +1 -1
  58. package/src/{routes → backend/routes}/api/ecosystem.tasks.ts +1 -1
  59. package/src/{routes → backend/routes}/api/groups.$groupId.evidence.ts +2 -2
  60. package/src/{routes → backend/routes}/api/groups.$groupId.sessions.ts +2 -2
  61. package/src/{routes → backend/routes}/api/groups.$groupId.ts +2 -2
  62. package/src/{routes → backend/routes}/api/groups.ts +2 -2
  63. package/src/{routes → backend/routes}/api/health.ts +3 -3
  64. package/src/{routes → backend/routes}/api/instances.$name.connection.ts +1 -1
  65. package/src/{routes → backend/routes}/api/instances.$name.restart.ts +2 -2
  66. package/src/{routes → backend/routes}/api/instances.$name.start.ts +2 -2
  67. package/src/{routes → backend/routes}/api/instances.$name.stop.ts +2 -2
  68. package/src/{routes → backend/routes}/api/instances.$name.ts +1 -1
  69. package/src/{routes → backend/routes}/api/instances.ts +1 -1
  70. package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.promote.ts +2 -2
  71. package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.ts +2 -2
  72. package/src/{routes → backend/routes}/api/knowledge.candidates.ts +1 -1
  73. package/src/{routes → backend/routes}/api/knowledge.project-context.ts +2 -2
  74. package/src/{routes → backend/routes}/api/knowledge.search.ts +2 -2
  75. package/src/{routes → backend/routes}/api/knowledge.sessions.$sessionId.candidates.ts +3 -3
  76. package/src/{routes → backend/routes}/api/logs.$id.body.ts +6 -6
  77. package/src/{routes → backend/routes}/api/logs.$id.chunks.ts +5 -4
  78. package/src/{routes → backend/routes}/api/logs.$id.replay.ts +12 -11
  79. package/src/{routes → backend/routes}/api/logs.$id.ts +4 -3
  80. package/src/{routes → backend/routes}/api/logs.import.ts +3 -3
  81. package/src/{routes → backend/routes}/api/logs.stream.ts +11 -7
  82. package/src/{routes → backend/routes}/api/logs.ts +17 -9
  83. package/src/{routes → backend/routes}/api/mcp.ts +1 -1
  84. package/src/{routes → backend/routes}/api/models.ts +1 -1
  85. package/src/{routes → backend/routes}/api/pi-agent.ts +2 -2
  86. package/src/{routes → backend/routes}/api/providers.$providerId.model-metadata.ts +5 -5
  87. package/src/{routes → backend/routes}/api/providers.$providerId.test.log.ts +7 -7
  88. package/src/{routes → backend/routes}/api/providers.$providerId.ts +4 -4
  89. package/src/{routes → backend/routes}/api/providers.export.ts +1 -1
  90. package/src/{routes → backend/routes}/api/providers.import.ts +3 -3
  91. package/src/{routes → backend/routes}/api/providers.scan.ts +2 -2
  92. package/src/{routes → backend/routes}/api/providers.ts +9 -4
  93. package/src/{routes → backend/routes}/api/runs.$runId.evidence.ts +2 -2
  94. package/src/{routes → backend/routes}/api/runs.$runId.ts +2 -2
  95. package/src/{routes → backend/routes}/api/runs.ts +4 -4
  96. package/src/backend/routes/api/runtime.ts +46 -0
  97. package/src/{routes → backend/routes}/api/sessions.ts +3 -3
  98. package/src/{routes → backend/routes}/proxy/$.ts +1 -1
  99. package/src/{routes → backend/routes}/readyz.ts +1 -1
  100. package/src/{start.ts → backend/start.ts} +1 -1
  101. package/src/cli/alias.ts +2 -11
  102. package/src/cli/doctor.ts +32 -9
  103. package/src/cli/instance.ts +36 -13
  104. package/src/cli/instanceApi.ts +213 -0
  105. package/src/cli/instanceArgs.ts +46 -11
  106. package/src/cli/instanceControl.ts +10 -2
  107. package/src/cli/instanceModel.ts +18 -17
  108. package/src/cli/instanceRegistry.ts +0 -9
  109. package/src/cli/networkHints.ts +27 -14
  110. package/src/cli/onboard.ts +69 -2
  111. package/src/cli/onboardTarget.ts +89 -40
  112. package/src/cli/rustBackendPackage.ts +450 -0
  113. package/src/cli/templates/codex-skill-onboard.ts +44 -14
  114. package/src/cli/templates/skill-onboard.ts +64 -28
  115. package/src/cli.ts +341 -75
  116. package/src/components/ProxyViewer.tsx +11 -9
  117. package/src/components/ProxyViewerContainer.tsx +12 -11
  118. package/src/components/pi-agent/PiAgentPanel.tsx +2 -2
  119. package/src/components/providers/ProviderCard.tsx +1 -1
  120. package/src/components/providers/ProviderTestResultsView.tsx +1 -1
  121. package/src/components/providers/SettingsDialog.tsx +159 -144
  122. package/src/components/proxy-viewer/ApplicationBar.tsx +2 -1
  123. package/src/components/proxy-viewer/LogEntry.tsx +1 -1
  124. package/src/components/proxy-viewer/log-formats/index.ts +1 -1
  125. package/src/contracts/index.ts +5 -0
  126. package/src/contracts/log.ts +33 -3
  127. package/src/knowledge/types.ts +3 -2
  128. package/src/lib/alertContract.ts +2 -2
  129. package/src/lib/apiClient.ts +30 -7
  130. package/src/lib/apiFormat.ts +29 -0
  131. package/src/lib/backendImplementation.ts +16 -0
  132. package/src/lib/basePath.ts +29 -11
  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 +38 -0
  137. package/src/lib/instanceContract.ts +30 -11
  138. package/src/lib/managedInstance.ts +9 -1
  139. package/src/lib/piAgentContract.ts +3 -2
  140. package/src/lib/publicBasePathContext.ts +40 -10
  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 +2 -0
  145. package/src/mcp/server.ts +19 -24
  146. package/src/proxy/config.ts +25 -30
  147. package/src/proxy/dataDir.ts +43 -7
  148. package/src/proxy/ecosystemTasks.ts +161 -70
  149. package/src/proxy/formats/registry.ts +6 -21
  150. package/src/proxy/handler.ts +129 -29
  151. package/src/proxy/identityProxy.ts +567 -39
  152. package/src/proxy/jsonlRecovery.ts +554 -0
  153. package/src/proxy/logFinalizer.ts +25 -10
  154. package/src/proxy/logImporter.ts +2 -1
  155. package/src/proxy/logIndex.ts +191 -95
  156. package/src/proxy/logger.ts +77 -14
  157. package/src/proxy/platformCommands.ts +41 -0
  158. package/src/proxy/privateDataPath.ts +310 -88
  159. package/src/proxy/rawStreamCapture.ts +194 -13
  160. package/src/proxy/runtimeAdmission.ts +5 -2
  161. package/src/proxy/runtimeHealth.ts +14 -1
  162. package/src/proxy/runtimeShutdown.ts +11 -1
  163. package/src/proxy/schemas.ts +7 -1
  164. package/src/proxy/sessionArchive.ts +70 -14
  165. package/src/proxy/sqliteLogIndex.ts +65 -42
  166. package/src/proxy/store.ts +141 -34
  167. package/src/proxy/uiAssetServer.ts +106 -0
  168. package/src/proxy/upstream.ts +29 -2
  169. package/src/ui/bootstrap.ts +167 -0
  170. package/src/ui/index.html +38 -0
  171. package/src/ui/logsStreamClient.ts +20 -0
  172. package/src/ui/main.tsx +13 -0
  173. package/src/ui/public/runtime-config.js +2 -0
  174. package/src/ui/router.tsx +13 -0
  175. package/src/ui/routes/__root.tsx +69 -0
  176. package/src/{routes → ui/routes}/index.tsx +2 -3
  177. package/src/{routes → ui/routes}/session/$sessionId.tsx +5 -11
  178. package/src/ui/runtimeDiscovery.ts +50 -0
  179. package/styles/globals.css +1 -0
  180. package/.output/public/assets/ProxyViewerContainer-BEAhuGOJ.js +0 -126
  181. package/.output/public/assets/ResponseView-DBCjkwye.js +0 -2
  182. package/.output/public/assets/StreamingChunkSequence-CuXhDgMo.js +0 -1
  183. package/.output/public/assets/index-BZo_8koU.js +0 -70
  184. package/.output/public/assets/index-ZWschkCh.css +0 -1
  185. package/.output/public/assets/json-viewer-B-Ao6pwW.js +0 -1
  186. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +0 -1
  187. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +0 -344
  188. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +0 -2
  189. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +0 -2
  190. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +0 -2
  191. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +0 -11
  192. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +0 -69
  193. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +0 -1
  194. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +0 -28
  195. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +0 -6
  196. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +0 -34
  197. package/.output/server/_libs/aria-hidden.mjs +0 -122
  198. package/.output/server/_libs/bail.mjs +0 -8
  199. package/.output/server/_libs/character-entities.mjs +0 -2130
  200. package/.output/server/_libs/class-variance-authority.mjs +0 -44
  201. package/.output/server/_libs/clsx.mjs +0 -16
  202. package/.output/server/_libs/comma-separated-tokens.mjs +0 -10
  203. package/.output/server/_libs/decode-named-character-reference+[...].mjs +0 -8
  204. package/.output/server/_libs/dequal.mjs +0 -27
  205. package/.output/server/_libs/detect-node-es.mjs +0 -1
  206. package/.output/server/_libs/devlop.mjs +0 -8
  207. package/.output/server/_libs/diff.mjs +0 -320
  208. package/.output/server/_libs/estree-util-is-identifier-name.mjs +0 -11
  209. package/.output/server/_libs/floating-ui__core.mjs +0 -725
  210. package/.output/server/_libs/floating-ui__dom.mjs +0 -622
  211. package/.output/server/_libs/floating-ui__react-dom.mjs +0 -292
  212. package/.output/server/_libs/floating-ui__utils.mjs +0 -320
  213. package/.output/server/_libs/get-nonce.mjs +0 -9
  214. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +0 -388
  215. package/.output/server/_libs/hast-util-whitespace.mjs +0 -10
  216. package/.output/server/_libs/html-url-attributes.mjs +0 -26
  217. package/.output/server/_libs/inline-style-parser.mjs +0 -142
  218. package/.output/server/_libs/is-plain-obj.mjs +0 -10
  219. package/.output/server/_libs/lucide-react.mjs +0 -1027
  220. package/.output/server/_libs/mdast-util-from-markdown.mjs +0 -717
  221. package/.output/server/_libs/mdast-util-to-hast.mjs +0 -710
  222. package/.output/server/_libs/mdast-util-to-string.mjs +0 -38
  223. package/.output/server/_libs/micromark-core-commonmark.mjs +0 -2259
  224. package/.output/server/_libs/micromark-factory-destination.mjs +0 -94
  225. package/.output/server/_libs/micromark-factory-label.mjs +0 -63
  226. package/.output/server/_libs/micromark-factory-space.mjs +0 -24
  227. package/.output/server/_libs/micromark-factory-title.mjs +0 -65
  228. package/.output/server/_libs/micromark-factory-whitespace.mjs +0 -22
  229. package/.output/server/_libs/micromark-util-character.mjs +0 -44
  230. package/.output/server/_libs/micromark-util-chunked.mjs +0 -36
  231. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +0 -12
  232. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +0 -41
  233. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -19
  234. package/.output/server/_libs/micromark-util-decode-string.mjs +0 -21
  235. package/.output/server/_libs/micromark-util-encode.mjs +0 -1
  236. package/.output/server/_libs/micromark-util-html-tag-name.mjs +0 -69
  237. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +0 -6
  238. package/.output/server/_libs/micromark-util-resolve-all.mjs +0 -15
  239. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +0 -41
  240. package/.output/server/_libs/micromark-util-subtokenize.mjs +0 -346
  241. package/.output/server/_libs/micromark.mjs +0 -906
  242. package/.output/server/_libs/property-information.mjs +0 -1209
  243. package/.output/server/_libs/radix-ui.mjs +0 -1
  244. package/.output/server/_libs/radix-ui__number.mjs +0 -6
  245. package/.output/server/_libs/radix-ui__primitive.mjs +0 -11
  246. package/.output/server/_libs/radix-ui__react-accordion.mjs +0 -1
  247. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +0 -1
  248. package/.output/server/_libs/radix-ui__react-arrow.mjs +0 -23
  249. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +0 -1
  250. package/.output/server/_libs/radix-ui__react-avatar.mjs +0 -1
  251. package/.output/server/_libs/radix-ui__react-checkbox.mjs +0 -1
  252. package/.output/server/_libs/radix-ui__react-collapsible.mjs +0 -144
  253. package/.output/server/_libs/radix-ui__react-collection.mjs +0 -69
  254. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +0 -38
  255. package/.output/server/_libs/radix-ui__react-context-menu.mjs +0 -1
  256. package/.output/server/_libs/radix-ui__react-context.mjs +0 -64
  257. package/.output/server/_libs/radix-ui__react-dialog.mjs +0 -280
  258. package/.output/server/_libs/radix-ui__react-direction.mjs +0 -9
  259. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +0 -1
  260. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +0 -39
  261. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +0 -210
  262. package/.output/server/_libs/radix-ui__react-form.mjs +0 -1
  263. package/.output/server/_libs/radix-ui__react-hover-card.mjs +0 -1
  264. package/.output/server/_libs/radix-ui__react-id.mjs +0 -14
  265. package/.output/server/_libs/radix-ui__react-label.mjs +0 -1
  266. package/.output/server/_libs/radix-ui__react-menu.mjs +0 -1
  267. package/.output/server/_libs/radix-ui__react-menubar.mjs +0 -1
  268. package/.output/server/_libs/radix-ui__react-popover.mjs +0 -1
  269. package/.output/server/_libs/radix-ui__react-popper.mjs +0 -340
  270. package/.output/server/_libs/radix-ui__react-portal.mjs +0 -16
  271. package/.output/server/_libs/radix-ui__react-presence.mjs +0 -173
  272. package/.output/server/_libs/radix-ui__react-primitive.mjs +0 -42
  273. package/.output/server/_libs/radix-ui__react-progress.mjs +0 -1
  274. package/.output/server/_libs/radix-ui__react-radio-group.mjs +0 -1
  275. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +0 -235
  276. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +0 -731
  277. package/.output/server/_libs/radix-ui__react-select.mjs +0 -1207
  278. package/.output/server/_libs/radix-ui__react-separator.mjs +0 -28
  279. package/.output/server/_libs/radix-ui__react-slider.mjs +0 -1
  280. package/.output/server/_libs/radix-ui__react-slot.mjs +0 -132
  281. package/.output/server/_libs/radix-ui__react-switch.mjs +0 -1
  282. package/.output/server/_libs/radix-ui__react-tabs.mjs +0 -194
  283. package/.output/server/_libs/radix-ui__react-toast.mjs +0 -2
  284. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +0 -1
  285. package/.output/server/_libs/radix-ui__react-toggle.mjs +0 -1
  286. package/.output/server/_libs/radix-ui__react-toolbar.mjs +0 -1
  287. package/.output/server/_libs/radix-ui__react-tooltip.mjs +0 -498
  288. package/.output/server/_libs/radix-ui__react-use-previous.mjs +0 -14
  289. package/.output/server/_libs/radix-ui__react-use-size.mjs +0 -39
  290. package/.output/server/_libs/react-markdown.mjs +0 -235
  291. package/.output/server/_libs/react-remove-scroll-bar.mjs +0 -82
  292. package/.output/server/_libs/react-remove-scroll.mjs +0 -328
  293. package/.output/server/_libs/react-style-singleton.mjs +0 -69
  294. package/.output/server/_libs/remark-parse.mjs +0 -19
  295. package/.output/server/_libs/remark-rehype.mjs +0 -21
  296. package/.output/server/_libs/space-separated-tokens.mjs +0 -6
  297. package/.output/server/_libs/style-to-js.mjs +0 -72
  298. package/.output/server/_libs/style-to-object.mjs +0 -38
  299. package/.output/server/_libs/swr.mjs +0 -947
  300. package/.output/server/_libs/tailwind-merge.mjs +0 -3255
  301. package/.output/server/_libs/tanstack__react-virtual.mjs +0 -130
  302. package/.output/server/_libs/tanstack__virtual-core.mjs +0 -1319
  303. package/.output/server/_libs/three.mjs +0 -26016
  304. package/.output/server/_libs/trim-lines.mjs +0 -41
  305. package/.output/server/_libs/trough.mjs +0 -85
  306. package/.output/server/_libs/tslib.mjs +0 -1
  307. package/.output/server/_libs/ungap__structured-clone.mjs +0 -212
  308. package/.output/server/_libs/unified.mjs +0 -661
  309. package/.output/server/_libs/unist-util-is.mjs +0 -100
  310. package/.output/server/_libs/unist-util-position.mjs +0 -27
  311. package/.output/server/_libs/unist-util-stringify-position.mjs +0 -27
  312. package/.output/server/_libs/unist-util-visit-parents.mjs +0 -82
  313. package/.output/server/_libs/unist-util-visit.mjs +0 -24
  314. package/.output/server/_libs/use-callback-ref.mjs +0 -66
  315. package/.output/server/_libs/use-sidecar.mjs +0 -106
  316. package/.output/server/_libs/vfile-message.mjs +0 -138
  317. package/.output/server/_libs/vfile.mjs +0 -467
  318. package/.output/server/_sessionId-CJ99gZFV.mjs +0 -84
  319. package/.output/server/_sessionId-DEjScBpK.mjs +0 -146
  320. package/.output/server/_ssr/CompareDrawer-DtOIMeQB.mjs +0 -1060
  321. package/.output/server/_ssr/InspectorPet-CXc4oCBQ.mjs +0 -938
  322. package/.output/server/_ssr/ProxyViewerContainer-DVPlwfkt.mjs +0 -17632
  323. package/.output/server/_ssr/ReplayDialog-BQEA95qC.mjs +0 -725
  324. package/.output/server/_ssr/RequestAnatomy-BMyd8B7Q.mjs +0 -837
  325. package/.output/server/_ssr/ResponseView-qrTaEIM8.mjs +0 -757
  326. package/.output/server/_ssr/StreamingChunkSequence-BFTL8mIy.mjs +0 -274
  327. package/.output/server/_ssr/index-Bcj1Hcy4.mjs +0 -135
  328. package/.output/server/_ssr/index-DW-M7XUG.mjs +0 -84
  329. package/.output/server/_ssr/json-viewer-DiI0Yjsn.mjs +0 -483
  330. package/.output/server/_tanstack-start-manifest_v-C6pXXX9R.mjs +0 -4
  331. package/.output/server/node_modules/tslib/modules/index.js +0 -70
  332. package/.output/server/node_modules/tslib/modules/package.json +0 -3
  333. package/.output/server/node_modules/tslib/package.json +0 -47
  334. package/.output/server/node_modules/tslib/tslib.js +0 -484
  335. package/.output/server/package.json +0 -9
  336. package/src/routes/__root.tsx +0 -170
  337. package/src/routes/api/-instances.ts +0 -109
  338. /package/.output/{public → ui}/assets/agent-inspector-58K1_MsC.ico +0 -0
  339. /package/.output/{public → ui}/assets/alibaba-TTwafVwX.svg +0 -0
  340. /package/.output/{public → ui}/assets/minimax-BPMzvuL-.jpeg +0 -0
  341. /package/.output/{public → ui}/assets/qwen-mMn3f5ul.webp +0 -0
  342. /package/.output/{public → ui}/assets/zhipuai-BPNAnxo-.svg +0 -0
  343. /package/src/{routes → backend/routes}/livez.ts +0 -0
package/src/cli.ts CHANGED
@@ -8,9 +8,18 @@ import { existsSync } from "node:fs";
8
8
  import type { Readable, Writable } from "node:stream";
9
9
  import packageJson from "../package.json";
10
10
  import {
11
+ AGENT_INSPECTOR_BACKEND_ENV,
12
+ AGENT_INSPECTOR_BACKEND_HEADER,
13
+ BackendImplementationSchema,
14
+ parseBackendImplementation,
15
+ type BackendImplementation,
16
+ } from "./lib/backendImplementation.js";
17
+ import {
18
+ AGENT_INSPECTOR_BASE_PATH_ENV,
11
19
  AGENT_INSPECTOR_INTERNAL_STRIPPED_BASE_PATH_ENV,
12
20
  appendBasePathToOrigin,
13
21
  getConfiguredBasePath,
22
+ normalizePublicBasePath,
14
23
  } from "./lib/basePath.js";
15
24
  import {
16
25
  AGENT_INSPECTOR_CLI_ENTRY_ENV,
@@ -31,9 +40,12 @@ import {
31
40
  shouldSuppressServerOutputLine,
32
41
  type ServerOutputFilterContext,
33
42
  } from "./cli/startupOutput.js";
43
+ import { resolveRustBackendPackage } from "./cli/rustBackendPackage.js";
44
+ import { handleNamedInstanceApi } from "./cli/instanceApi.js";
34
45
  import {
35
46
  closeIdentityProxyGracefully,
36
47
  forceCloseIdentityProxy,
48
+ parseUiOriginAllowlist,
37
49
  startIdentityProxy,
38
50
  stopIdentityProxyAdmission,
39
51
  type ManagedInstanceControlOptions,
@@ -83,6 +95,15 @@ Global options:
83
95
  -h, --help Show this help without starting a runtime
84
96
  -v, --version Print the package version
85
97
 
98
+ Start options:
99
+ --backend <typescript|rust> Select the backend implementation (default: typescript)
100
+ --backend-only, --headless Start the API, proxy, and MCP runtime without serving the UI
101
+ --with-ui Serve the independently built UI through the protected ingress
102
+ --port, -p <port> Public ingress port (default: 9527)
103
+ --host, -H <host> Bind host (default: 127.0.0.1)
104
+ --background Start a hidden supervisor and return after readiness
105
+ --no-open Do not open the UI after startup
106
+
86
107
  Run \`agent-inspector instance --help\`, \`agent-inspector onboard --help\`, or
87
108
  \`agent-inspector doctor --help\` for command-specific options.`);
88
109
  }
@@ -183,6 +204,33 @@ async function getRunningCaptureMode(
183
204
  }
184
205
  }
185
206
 
207
+ async function getRunningBackend(
208
+ port: number,
209
+ host?: string,
210
+ basePath = "",
211
+ ): Promise<BackendImplementation | null> {
212
+ const controller = new AbortController();
213
+ const timeout = setTimeout(() => controller.abort(), LOCAL_PROBE_TIMEOUT_MS);
214
+ try {
215
+ const response = await fetch(
216
+ appendBasePathToOrigin(urlForHost(port, probeHostForBindHost(host)), "/api/health", basePath),
217
+ {
218
+ cache: "no-store",
219
+ signal: controller.signal,
220
+ },
221
+ );
222
+ if (!response.ok) return null;
223
+ const header = response.headers.get(AGENT_INSPECTOR_BACKEND_HEADER);
224
+ if (header === null) return "typescript";
225
+ const parsed = BackendImplementationSchema.safeParse(header.trim().toLowerCase());
226
+ return parsed.success ? parsed.data : null;
227
+ } catch {
228
+ return null;
229
+ } finally {
230
+ clearTimeout(timeout);
231
+ }
232
+ }
233
+
186
234
  function isPortAcceptingConnections(port: number, host?: string): Promise<boolean> {
187
235
  return new Promise((resolve) => {
188
236
  const socket = createConnection({ host: probeHostForBindHost(host), port });
@@ -282,11 +330,35 @@ type ServerCommand = {
282
330
  args: string[];
283
331
  };
284
332
 
285
- function resolveServerCommand(outputDir: string, serverPath: string): ServerCommand {
333
+ type ServerCommandResolution =
334
+ | { kind: "success"; command: ServerCommand }
335
+ | { kind: "error"; message: string };
336
+
337
+ function resolveServerCommand(
338
+ outputDir: string,
339
+ serverPath: string,
340
+ backend: BackendImplementation,
341
+ ): ServerCommandResolution {
342
+ if (backend === "rust") {
343
+ const resolved = resolveRustBackendPackage({ rootVersion: packageJson.version });
344
+ return resolved.kind === "error"
345
+ ? {
346
+ kind: "error",
347
+ message: `Cannot start the Rust backend (${resolved.error.code}): ${resolved.error.message}`,
348
+ }
349
+ : {
350
+ kind: "success",
351
+ command: { command: resolved.value.command, args: [...resolved.value.args] },
352
+ };
353
+ }
286
354
  const brandedRuntime = join(outputDir, BRANDED_WINDOWS_RUNTIME_EXE);
287
- return process.platform === "win32" && existsSync(brandedRuntime)
288
- ? { command: brandedRuntime, args: [serverPath] }
289
- : { command: process.execPath, args: [serverPath] };
355
+ return {
356
+ kind: "success",
357
+ command:
358
+ process.platform === "win32" && existsSync(brandedRuntime)
359
+ ? { command: brandedRuntime, args: [serverPath] }
360
+ : { command: process.execPath, args: [serverPath] },
361
+ };
290
362
  }
291
363
 
292
364
  function parseCaptureMode(value: string | undefined): CaptureMode | null {
@@ -309,11 +381,26 @@ function readCaptureMode(raw: unknown): CaptureMode | null {
309
381
  return typeof value === "string" ? parseCaptureMode(value) : null;
310
382
  }
311
383
 
312
- function printAccessHints(port: number, host?: string, basePath = ""): void {
384
+ function printAccessHints(
385
+ port: number,
386
+ host: string | undefined,
387
+ basePath: string,
388
+ serveUi: boolean,
389
+ publicOrigin: string | undefined,
390
+ ): void {
313
391
  const networkUrls = networkUrlsForBindHost(port, host);
314
- for (const line of formatAccessHintLines(port, networkUrls, host, basePath)) {
392
+ for (const line of formatAccessHintLines(port, networkUrls, host, basePath, serveUi)) {
315
393
  console.log(line);
316
394
  }
395
+ if (publicOrigin !== undefined) {
396
+ const publicBaseUrl = appendBasePathToOrigin(publicOrigin, "/", basePath);
397
+ if (serveUi) console.log(` Public UI: ${publicBaseUrl}`);
398
+ console.log(` Public control Base: ${publicBaseUrl}`);
399
+ console.log(` Public agent Base: ${publicBaseUrl}`);
400
+ console.log(` Public REST API: ${appendBasePathToOrigin(publicOrigin, "/api", basePath)}`);
401
+ console.log(` Public proxy: ${appendBasePathToOrigin(publicOrigin, "/proxy", basePath)}`);
402
+ console.log(` Public MCP: ${appendBasePathToOrigin(publicOrigin, "/api/mcp", basePath)}`);
403
+ }
317
404
  if (!isLoopbackHost(host)) {
318
405
  const proxyTokenConfigured = (process.env["AGENT_INSPECTOR_PROXY_TOKEN"] ?? "") !== "";
319
406
  const legacyProxyEnabled =
@@ -345,7 +432,21 @@ function readPositiveIntegerEnv(name: string): number | undefined {
345
432
  return undefined;
346
433
  }
347
434
 
435
+ function normalizeExplicitPublicOrigin(value: string | undefined): string | null | undefined {
436
+ if (value === undefined || value.trim().length === 0) return undefined;
437
+ try {
438
+ const parsed = new URL(value.trim());
439
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
440
+ if (parsed.username.length > 0 || parsed.password.length > 0) return null;
441
+ if (parsed.pathname !== "/" || parsed.search.length > 0 || parsed.hash.length > 0) return null;
442
+ return parsed.origin;
443
+ } catch {
444
+ return null;
445
+ }
446
+ }
447
+
348
448
  type BackgroundSupervisorOptions = {
449
+ backend: BackendImplementation;
349
450
  port: number;
350
451
  host: string | undefined;
351
452
  configDir: string | undefined;
@@ -353,10 +454,19 @@ type BackgroundSupervisorOptions = {
353
454
  captureMode: CaptureMode;
354
455
  enableIdentityProxy: boolean;
355
456
  legacyAliasEnabled: boolean;
457
+ serveUi: boolean;
356
458
  };
357
459
 
358
460
  function buildBackgroundSupervisorArgs(options: BackgroundSupervisorOptions): string[] {
359
- const args = ["--no-open", "--port", String(options.port), "--mode", options.captureMode];
461
+ const args = [
462
+ "--no-open",
463
+ "--backend",
464
+ options.backend,
465
+ "--port",
466
+ String(options.port),
467
+ "--mode",
468
+ options.captureMode,
469
+ ];
360
470
  if (options.host !== undefined) {
361
471
  args.push("--host", options.host);
362
472
  }
@@ -372,6 +482,9 @@ function buildBackgroundSupervisorArgs(options: BackgroundSupervisorOptions): st
372
482
  if (options.legacyAliasEnabled) {
373
483
  args.push("--legacy-port");
374
484
  }
485
+ if (!options.serveUi) {
486
+ args.push("--backend-only");
487
+ }
375
488
  return args;
376
489
  }
377
490
 
@@ -395,17 +508,18 @@ function pickUpstreamPort(publicPort: number, legacyAliasPort: number | null): n
395
508
  return DEFAULT_UPSTREAM_PORT;
396
509
  }
397
510
 
398
- /** Try to start the identity proxy. Returns `null` (and prints a warning)
399
- * if the listen port is already in use by another process — e.g. when
400
- * restarting a previous instance that didn't shut down cleanly. The
401
- * TanStack Start server keeps running either way; clients just lose the
402
- * per-PID attribution until they fall back to direct port `port` access. */
511
+ /** Try to start an identity-proxy ingress. The primary caller treats a
512
+ * `null` result as fatal; only an optional compatibility alias may degrade. */
403
513
  async function tryStartIdentityProxy(
404
514
  identityPort: number,
405
515
  upstreamPort: number,
406
516
  listenHost: string,
407
517
  upstreamHost: string,
408
518
  managedInstance: ManagedInstanceControlOptions | undefined,
519
+ allowedUiOrigins: readonly string[],
520
+ uiDirectory: string | undefined,
521
+ publicOrigin: string | undefined,
522
+ backend: BackendImplementation,
409
523
  ): Promise<import("node:http").Server | null> {
410
524
  try {
411
525
  const server = await startIdentityProxy({
@@ -413,6 +527,7 @@ async function tryStartIdentityProxy(
413
527
  listenHost,
414
528
  upstreamHost,
415
529
  upstreamPort,
530
+ backendImplementation: backend,
416
531
  restrictRemoteControl: !isLoopbackHost(listenHost),
417
532
  allowRemoteControl: process.env["AGENT_INSPECTOR_ALLOW_REMOTE_CONTROL"] === "1",
418
533
  controlToken: process.env["AGENT_INSPECTOR_CONTROL_TOKEN"],
@@ -423,18 +538,18 @@ async function tryStartIdentityProxy(
423
538
  .split(",")
424
539
  .map((host) => host.trim())
425
540
  .filter((host) => host.length > 0),
541
+ allowedUiOrigins,
542
+ uiDirectory,
543
+ publicOrigin,
426
544
  maxRequestBytes: readPositiveIntegerEnv("AGENT_INSPECTOR_MAX_REQUEST_BYTES"),
427
545
  requestTimeoutMs: readPositiveIntegerEnv("AGENT_INSPECTOR_REQUEST_TIMEOUT_MS"),
428
546
  managedInstance,
547
+ instanceApiHandler: backend === "rust" ? handleNamedInstanceApi : undefined,
429
548
  });
430
549
  return server;
431
550
  } catch (err) {
432
551
  const message = err instanceof Error ? err.message : String(err);
433
- console.warn(
434
- `[identity-proxy] Could not listen on port ${identityPort}: ${message}. ` +
435
- `Falling back to OS-scan heuristic on port ${upstreamPort}. ` +
436
- `Pass --identity-proxy-port <n> to choose another port, or --no-identity-proxy to disable.`,
437
- );
552
+ console.warn(`[identity-proxy] Could not listen on port ${identityPort}: ${message}.`);
438
553
  return null;
439
554
  }
440
555
  }
@@ -453,6 +568,14 @@ async function runStart(args: string[]): Promise<void> {
453
568
  const envHost = process.env["NITRO_HOST"] ?? process.env["HOST"];
454
569
  const envMode =
455
570
  process.env["AGENT_INSPECTOR_CAPTURE_MODE"] ?? process.env["AGENT_INSPECTOR_MODE"];
571
+ const envBackend = parseBackendImplementation(process.env[AGENT_INSPECTOR_BACKEND_ENV]);
572
+ if (envBackend === null) {
573
+ console.error(
574
+ `Invalid ${AGENT_INSPECTOR_BACKEND_ENV}. Use typescript or rust; no backend was started.`,
575
+ );
576
+ process.exitCode = 1;
577
+ return;
578
+ }
456
579
 
457
580
  let port = portDefault;
458
581
  let host =
@@ -467,6 +590,8 @@ async function runStart(args: string[]): Promise<void> {
467
590
  let captureModeWasSpecified = false;
468
591
  let enableIdentityProxy = true;
469
592
  let legacyAliasEnabled = false;
593
+ let serveUi = process.env["AGENT_INSPECTOR_BACKEND_ONLY"] !== "1";
594
+ let backend: BackendImplementation = envBackend;
470
595
 
471
596
  if (envMode !== undefined && envMode !== "") {
472
597
  const parsedMode = parseCaptureMode(envMode);
@@ -513,6 +638,21 @@ async function runStart(args: string[]): Promise<void> {
513
638
  captureModeWasSpecified = true;
514
639
  continue;
515
640
  }
641
+ if (arg.startsWith("--backend=")) {
642
+ const parsedBackend = BackendImplementationSchema.safeParse(
643
+ arg
644
+ .slice(arg.indexOf("=") + 1)
645
+ .trim()
646
+ .toLowerCase(),
647
+ );
648
+ if (!parsedBackend.success) {
649
+ console.error("Invalid backend implementation. Use typescript or rust.");
650
+ process.exitCode = 1;
651
+ return;
652
+ }
653
+ backend = parsedBackend.data;
654
+ continue;
655
+ }
516
656
  switch (arg) {
517
657
  case "--port":
518
658
  case "-p":
@@ -531,6 +671,19 @@ async function runStart(args: string[]): Promise<void> {
531
671
  i++;
532
672
  break;
533
673
  }
674
+ case "--backend": {
675
+ const parsedBackend = BackendImplementationSchema.safeParse(
676
+ args[i + 1]?.trim().toLowerCase(),
677
+ );
678
+ if (!parsedBackend.success) {
679
+ console.error("Invalid backend implementation. Use typescript or rust.");
680
+ process.exitCode = 1;
681
+ return;
682
+ }
683
+ backend = parsedBackend.data;
684
+ i++;
685
+ break;
686
+ }
534
687
  case "--no-open":
535
688
  open = false;
536
689
  openWasSpecified = true;
@@ -546,6 +699,14 @@ async function runStart(args: string[]): Promise<void> {
546
699
  case "--background":
547
700
  background = true;
548
701
  break;
702
+ case "--backend-only":
703
+ case "--headless":
704
+ serveUi = false;
705
+ open = false;
706
+ break;
707
+ case "--with-ui":
708
+ serveUi = true;
709
+ break;
549
710
  case "--config-dir":
550
711
  configDir = args[i + 1];
551
712
  i++;
@@ -611,6 +772,14 @@ async function runStart(args: string[]): Promise<void> {
611
772
  return;
612
773
  }
613
774
 
775
+ if (managedLaunch !== null && managedLaunch.backend !== backend) {
776
+ console.error(
777
+ `Managed instance backend mismatch: launch identity requires ${managedLaunch.backend}, but ${backend} was selected.`,
778
+ );
779
+ process.exitCode = 1;
780
+ return;
781
+ }
782
+
614
783
  if (!enableIdentityProxy && process.env["AGENT_INSPECTOR_ALLOW_UNPROTECTED_INGRESS"] !== "1") {
615
784
  console.error(
616
785
  "Refusing --no-identity-proxy because it also disables Host, CSRF, credential-scope, and first-hop budget enforcement. Keep the protected ingress enabled or set AGENT_INSPECTOR_ALLOW_UNPROTECTED_INGRESS=1 explicitly for temporary diagnostics.",
@@ -618,6 +787,50 @@ async function runStart(args: string[]): Promise<void> {
618
787
  process.exitCode = 1;
619
788
  return;
620
789
  }
790
+ if (!serveUi) open = false;
791
+ if (!enableIdentityProxy && serveUi) {
792
+ console.error(
793
+ "The decoupled UI is composed only by the protected ingress. Use --backend-only with --no-identity-proxy, or keep the identity proxy enabled.",
794
+ );
795
+ process.exitCode = 1;
796
+ return;
797
+ }
798
+ const uiOriginAllowlist = parseUiOriginAllowlist(process.env["AGENT_INSPECTOR_UI_ORIGINS"]);
799
+ if (uiOriginAllowlist.rejected.length > 0) {
800
+ console.error(
801
+ `Invalid AGENT_INSPECTOR_UI_ORIGINS entries: ${uiOriginAllowlist.rejected.join(", ")}. Only exact loopback http(s) origins are accepted; use a same-origin authenticated gateway for remote UI hosting.`,
802
+ );
803
+ process.exitCode = 1;
804
+ return;
805
+ }
806
+ const publicOrigin = normalizeExplicitPublicOrigin(process.env["AGENT_INSPECTOR_PUBLIC_ORIGIN"]);
807
+ if (publicOrigin === null) {
808
+ console.error(
809
+ "Invalid AGENT_INSPECTOR_PUBLIC_ORIGIN. Use an exact http(s) origin without credentials, path, query, or fragment.",
810
+ );
811
+ process.exitCode = 1;
812
+ return;
813
+ }
814
+ const uiDirectoryCandidate = join(__dirname, "../.output/ui");
815
+ const uiIndexPath = join(uiDirectoryCandidate, "index.html");
816
+ const uiDirectory = serveUi && existsSync(uiIndexPath) ? uiDirectoryCandidate : undefined;
817
+ if (serveUi && uiDirectory === undefined) {
818
+ console.error(
819
+ `Agent Inspector UI artifact is missing at ${uiIndexPath}. Run the composed build or use --backend-only.`,
820
+ );
821
+ process.exitCode = 1;
822
+ return;
823
+ }
824
+
825
+ const outputDir = __dirname;
826
+ const serverPath = join(outputDir, "../.output/server/index.mjs");
827
+ const serverCommandResolution = resolveServerCommand(outputDir, serverPath, backend);
828
+ if (serverCommandResolution.kind === "error") {
829
+ console.error(serverCommandResolution.message);
830
+ process.exitCode = 1;
831
+ return;
832
+ }
833
+ const serverCommand = serverCommandResolution.command;
621
834
 
622
835
  /**
623
836
  * Check if a port is in use and kill the process using it
@@ -655,11 +868,22 @@ async function runStart(args: string[]): Promise<void> {
655
868
  const upstreamHost = enableIdentityProxy ? DEFAULT_BIND_HOST : host;
656
869
  process.env["PORT"] = String(upstreamPort);
657
870
 
871
+ const configuredBasePath = process.env[AGENT_INSPECTOR_BASE_PATH_ENV];
872
+ if (configuredBasePath !== undefined && normalizePublicBasePath(configuredBasePath) === null) {
873
+ console.error(
874
+ `Invalid ${AGENT_INSPECTOR_BASE_PATH_ENV}. Use / for root or URL-safe path segments such as /inspector or /foo-bar/v1.`,
875
+ );
876
+ process.exitCode = 1;
877
+ return;
878
+ }
658
879
  const basePath = getConfiguredBasePath(process.env);
659
- const url = urlForHost(port, host);
660
- const uiUrl = appendBasePathToOrigin(url, "/", basePath);
661
- const proxyUrl = appendBasePathToOrigin(url, "/proxy", basePath);
662
- const proxyMessagesUrl = appendBasePathToOrigin(url, "/proxy/v1/messages", basePath);
880
+ const bindOrigin = urlForHost(port, host);
881
+ const outwardOrigin = publicOrigin ?? bindOrigin;
882
+ const surfaceBaseUrl = appendBasePathToOrigin(outwardOrigin, "/", basePath);
883
+ const uiUrl = serveUi ? surfaceBaseUrl : null;
884
+ const proxyUrl = appendBasePathToOrigin(outwardOrigin, "/proxy", basePath);
885
+ const openAiProxyUrl = appendBasePathToOrigin(outwardOrigin, "/proxy/v1", basePath);
886
+ const proxyMessagesUrl = appendBasePathToOrigin(outwardOrigin, "/proxy/v1/messages", basePath);
663
887
  const legacyUrl =
664
888
  legacyAliasPort === null
665
889
  ? null
@@ -674,8 +898,20 @@ async function runStart(args: string[]): Promise<void> {
674
898
  : appendBasePathToOrigin(localUrlForPort(legacyAliasPort), "/api/mcp", basePath);
675
899
 
676
900
  if (!forceRestart && (await isInspectorHealthy(port, host, basePath))) {
677
- console.log(`agent-inspector is already running at ${uiUrl}`);
678
- printAccessHints(port, host, basePath);
901
+ const runningBackend = await getRunningBackend(port, host, basePath);
902
+ if (runningBackend !== backend) {
903
+ console.error(
904
+ runningBackend === null
905
+ ? `A healthy Agent Inspector is already running at ${surfaceBaseUrl}, but its backend implementation cannot be verified. Use --force-restart to replace it safely.`
906
+ : `Agent Inspector at ${surfaceBaseUrl} uses ${runningBackend}, but ${backend} was requested. Use --force-restart to switch implementations.`,
907
+ );
908
+ process.exitCode = 1;
909
+ return;
910
+ }
911
+ console.log(
912
+ `agent-inspector ${serveUi ? "is already running" : "backend is already running"} at ${surfaceBaseUrl}`,
913
+ );
914
+ printAccessHints(port, host, basePath, serveUi, publicOrigin);
679
915
  if (captureModeWasSpecified) {
680
916
  const runningMode = await getRunningCaptureMode(port, host, basePath);
681
917
  if (runningMode !== null && runningMode !== captureMode) {
@@ -684,7 +920,7 @@ async function runStart(args: string[]): Promise<void> {
684
920
  }
685
921
  }
686
922
  console.log(`Use --force-restart to restart the existing instance.`);
687
- if (open && openWasSpecified) {
923
+ if (open && openWasSpecified && uiUrl !== null) {
688
924
  openBrowser(uiUrl);
689
925
  }
690
926
  return;
@@ -718,6 +954,7 @@ async function runStart(args: string[]): Promise<void> {
718
954
  }
719
955
 
720
956
  const supervisorArgs = buildBackgroundSupervisorArgs({
957
+ backend,
721
958
  port,
722
959
  host,
723
960
  configDir,
@@ -725,6 +962,7 @@ async function runStart(args: string[]): Promise<void> {
725
962
  captureMode,
726
963
  enableIdentityProxy,
727
964
  legacyAliasEnabled,
965
+ serveUi,
728
966
  });
729
967
  const supervisorProcess = spawn(process.execPath, [cliEntry, ...supervisorArgs], {
730
968
  stdio: "ignore",
@@ -738,8 +976,10 @@ async function runStart(args: string[]): Promise<void> {
738
976
  supervisorProcess.unref();
739
977
 
740
978
  if (await waitForInspectorHealthy(port, 10000, host, basePath)) {
741
- console.log(`agent-inspector background server is ready at ${uiUrl}`);
742
- printAccessHints(port, host, basePath);
979
+ console.log(
980
+ `agent-inspector background ${serveUi ? "server" : "backend"} is ready at ${surfaceBaseUrl}`,
981
+ );
982
+ printAccessHints(port, host, basePath, serveUi, publicOrigin);
743
983
  if (legacyProxyUrl !== null && legacyMcpUrl !== null) {
744
984
  console.log(` Legacy proxy: ${legacyProxyUrl}`);
745
985
  console.log(` Legacy MCP: ${legacyMcpUrl}`);
@@ -748,53 +988,18 @@ async function runStart(args: string[]): Promise<void> {
748
988
  console.log(`Route AI coding tools through the identity proxy for accurate PID attribution:`);
749
989
  console.log(` Claude Code: ANTHROPIC_BASE_URL=${proxyUrl} claude`);
750
990
  console.log(` OpenCode: LLM_BASE_URL=${proxyUrl} opencode`);
751
- console.log(` MiMo Code: OPENAI_BASE_URL=${proxyUrl} mimo`);
752
- if (open && openWasSpecified) {
991
+ console.log(` MiMo Code: OPENAI_BASE_URL=${openAiProxyUrl} mimo`);
992
+ if (open && openWasSpecified && uiUrl !== null) {
753
993
  openBrowser(uiUrl);
754
994
  }
755
995
  return;
756
996
  }
757
997
 
758
- console.error(`agent-inspector background server did not become ready at ${uiUrl}.`);
998
+ console.error(`agent-inspector background server did not become ready at ${surfaceBaseUrl}.`);
759
999
  process.exitCode = 1;
760
1000
  return;
761
1001
  }
762
1002
 
763
- console.log(`Server running at ${uiUrl}`);
764
- console.log(` Capture mode: ${captureMode}`);
765
- console.log(` Proxy: ${proxyUrl}`);
766
- printAccessHints(port, host, basePath);
767
- if (legacyUrl !== null && legacyProxyUrl !== null && legacyMcpUrl !== null) {
768
- console.log(` Legacy UI: ${legacyUrl}`);
769
- console.log(` Legacy proxy: ${legacyProxyUrl}`);
770
- console.log(` Legacy MCP: ${legacyMcpUrl}`);
771
- }
772
- console.log(``);
773
- console.log(`Route AI coding tools through the proxy:`);
774
- console.log(` Claude Code: ANTHROPIC_BASE_URL=${proxyUrl} claude`);
775
- console.log(` OpenCode: LLM_BASE_URL=${proxyUrl} opencode`);
776
- console.log(` MiMo Code: OPENAI_BASE_URL=${proxyUrl} mimo`);
777
- console.log(` Direct HTTP: curl ${proxyMessagesUrl} -d '{"model":"...","messages":[...]}'`);
778
- console.log(
779
- ` Remote/container tools: use the Network proxy URL above when shown; otherwise restart with --host 0.0.0.0 or a reachable IP.`,
780
- );
781
- console.log(``);
782
- console.log(`Routing environment variables:`);
783
- console.log(` ROUTES JSON map of model prefix -> upstream URL`);
784
- console.log(` DEFAULT_UPSTREAM Fallback upstream for unmatched models`);
785
- console.log(
786
- ` Example: ROUTES='{"claude-":"https://api.anthropic.com","MiniMax":"https://api.minimaxi.com/anthropic"}'`,
787
- );
788
-
789
- if (open) {
790
- openBrowser(uiUrl);
791
- }
792
-
793
- // Compute server path
794
- const outputDir = __dirname;
795
- const serverPath = join(outputDir, "../.output/server/index.mjs");
796
- const serverCommand = resolveServerCommand(outputDir, serverPath);
797
-
798
1003
  // Start the server with the branded Windows runtime when postinstall created it.
799
1004
  const serverEnv = { ...process.env };
800
1005
  const currentCliEntry = process.env[AGENT_INSPECTOR_CLI_ENTRY_ENV] ?? process.argv[1];
@@ -831,6 +1036,8 @@ async function runStart(args: string[]): Promise<void> {
831
1036
  serverEnv["AGENT_INSPECTOR_PUBLIC_PORT"] = String(port);
832
1037
  serverEnv["PROXY_PORT"] = String(port);
833
1038
  serverEnv["AGENT_INSPECTOR_CAPTURE_MODE"] = captureMode;
1039
+ serverEnv[AGENT_INSPECTOR_BACKEND_ENV] = backend;
1040
+ serverEnv["AGENT_INSPECTOR_BACKEND_ONLY"] = serveUi ? "0" : "1";
834
1041
  const workerDir = join(__dirname, "workers");
835
1042
  if (existsSync(workerDir)) {
836
1043
  serverEnv["AGENT_INSPECTOR_WORKER_DIR"] = workerDir;
@@ -841,9 +1048,13 @@ async function runStart(args: string[]): Promise<void> {
841
1048
  ? background
842
1049
  ? ["ignore", "ignore", "ignore"]
843
1050
  : ["ignore", "pipe", "pipe"]
844
- : background
845
- ? ["ignore", "ignore", "ignore", "ipc"]
846
- : ["ignore", "pipe", "pipe", "ipc"],
1051
+ : backend === "typescript"
1052
+ ? background
1053
+ ? ["ignore", "ignore", "ignore", "ipc"]
1054
+ : ["ignore", "pipe", "pipe", "ipc"]
1055
+ : background
1056
+ ? ["ignore", "ignore", "ignore"]
1057
+ : ["ignore", "pipe", "pipe"],
847
1058
  detached: background,
848
1059
  env: serverEnv,
849
1060
  windowsHide: background,
@@ -875,7 +1086,7 @@ async function runStart(args: string[]): Promise<void> {
875
1086
  const requestSupervisorShutdown = (signal: "SIGINT" | "SIGTERM"): void => {
876
1087
  if (supervisorShutdownPromise !== null) return;
877
1088
  for (const proxy of identityProxies) stopIdentityProxyAdmission(proxy.server);
878
- if (managedLaunch !== null && serverProcess.connected) {
1089
+ if (managedLaunch !== null && backend === "typescript" && serverProcess.connected) {
879
1090
  serverProcess.send(managedInstanceShutdownMessage(managedLaunch.controlToken), (error) => {
880
1091
  if (error !== null && serverProcess.exitCode === null) serverProcess.kill(signal);
881
1092
  });
@@ -922,6 +1133,7 @@ async function runStart(args: string[]): Promise<void> {
922
1133
  controlToken: managedLaunch.controlToken,
923
1134
  supervisorPid: process.pid,
924
1135
  startedAt: managedLaunch.startedAt,
1136
+ backend,
925
1137
  publicPort: port,
926
1138
  upstreamPort,
927
1139
  requestShutdown: () => requestSupervisorShutdown("SIGTERM"),
@@ -933,10 +1145,24 @@ async function runStart(args: string[]): Promise<void> {
933
1145
  host,
934
1146
  upstreamHost,
935
1147
  managedInstanceControl,
1148
+ uiOriginAllowlist.origins,
1149
+ uiDirectory,
1150
+ publicOrigin,
1151
+ backend,
936
1152
  );
937
- if (primaryProxy !== null) {
938
- identityProxies.push({ label: "primary", port, server: primaryProxy });
1153
+ if (primaryProxy === null) {
1154
+ console.error(
1155
+ `Agent Inspector could not bind its protected public ingress at ${bindOrigin}; stopping the private backend.`,
1156
+ );
1157
+ requestSupervisorShutdown("SIGTERM");
1158
+ const failedStartupShutdown = currentSupervisorShutdown();
1159
+ if (failedStartupShutdown !== null) await failedStartupShutdown;
1160
+ process.off("SIGINT", handleSigint);
1161
+ process.off("SIGTERM", handleSigterm);
1162
+ process.exitCode = 1;
1163
+ return;
939
1164
  }
1165
+ identityProxies.push({ label: "primary", port, server: primaryProxy });
940
1166
  if (legacyAliasPort !== null) {
941
1167
  const legacyProxy = await tryStartIdentityProxy(
942
1168
  legacyAliasPort,
@@ -944,6 +1170,10 @@ async function runStart(args: string[]): Promise<void> {
944
1170
  host,
945
1171
  upstreamHost,
946
1172
  managedInstanceControl,
1173
+ uiOriginAllowlist.origins,
1174
+ uiDirectory,
1175
+ publicOrigin,
1176
+ backend,
947
1177
  );
948
1178
  if (legacyProxy !== null) {
949
1179
  identityProxies.push({ label: "legacy", port: legacyAliasPort, server: legacyProxy });
@@ -957,11 +1187,13 @@ async function runStart(args: string[]): Promise<void> {
957
1187
  // not started yet so the public port is not yet accepting traffic.
958
1188
  const upstreamProbeBasePath = enableIdentityProxy ? "" : basePath;
959
1189
  if (await waitForInspectorHealthy(upstreamPort, 5000, host, upstreamProbeBasePath)) {
960
- console.log(`agent-inspector background server is ready at ${uiUrl}`);
1190
+ console.log(
1191
+ `agent-inspector background ${serveUi ? "server" : "backend"} is ready at ${surfaceBaseUrl}`,
1192
+ );
961
1193
  if (identityProxies.length > 0) {
962
1194
  console.log(`Identity proxy ready on port ${port} (PID-attributing proxy).`);
963
1195
  }
964
- printAccessHints(port, host, basePath);
1196
+ printAccessHints(port, host, basePath, serveUi, publicOrigin);
965
1197
  if (legacyProxyUrl !== null && legacyMcpUrl !== null) {
966
1198
  console.log(` Legacy proxy: ${legacyProxyUrl}`);
967
1199
  console.log(` Legacy MCP: ${legacyMcpUrl}`);
@@ -972,7 +1204,7 @@ async function runStart(args: string[]): Promise<void> {
972
1204
  `Route AI coding tools through the identity proxy for accurate PID attribution:`,
973
1205
  ` Claude Code: ANTHROPIC_BASE_URL=${proxyUrl} claude`,
974
1206
  ` OpenCode: LLM_BASE_URL=${proxyUrl} opencode`,
975
- ` MiMo Code: OPENAI_BASE_URL=${proxyUrl} mimo`,
1207
+ ` MiMo Code: OPENAI_BASE_URL=${openAiProxyUrl} mimo`,
976
1208
  legacyProxyUrl === null
977
1209
  ? ` Override the port with --port <n> when needed.`
978
1210
  : ` Legacy configs using ${legacyProxyUrl} still work.`,
@@ -980,14 +1212,25 @@ async function runStart(args: string[]): Promise<void> {
980
1212
  }
981
1213
  return;
982
1214
  }
983
- console.error(`agent-inspector background server did not become ready at ${uiUrl}.`);
1215
+ console.error(`agent-inspector background server did not become ready at ${surfaceBaseUrl}.`);
1216
+ process.exitCode = 1;
1217
+ return;
1218
+ }
1219
+
1220
+ if (!(await waitForInspectorHealthy(port, 10_000, host, basePath))) {
1221
+ console.error(`Agent Inspector did not become ready at ${surfaceBaseUrl}; stopping startup.`);
1222
+ requestSupervisorShutdown("SIGTERM");
1223
+ const failedStartupShutdown = currentSupervisorShutdown();
1224
+ if (failedStartupShutdown !== null) await failedStartupShutdown;
1225
+ process.off("SIGINT", handleSigint);
1226
+ process.off("SIGTERM", handleSigterm);
984
1227
  process.exitCode = 1;
985
1228
  return;
986
1229
  }
987
1230
 
988
1231
  if (identityProxies.length > 0) {
989
1232
  console.log(``);
990
- console.log(`Identity proxy ready at ${url} (PID-attributing public entrypoint).`);
1233
+ console.log(`Identity proxy ready at ${bindOrigin} (PID-attributing ingress).`);
991
1234
  if (legacyAliasPort !== null) {
992
1235
  const legacyReady = identityProxies.some((proxy) => proxy.label === "legacy");
993
1236
  if (legacyReady) {
@@ -999,6 +1242,29 @@ async function runStart(args: string[]): Promise<void> {
999
1242
  }
1000
1243
  }
1001
1244
 
1245
+ console.log(
1246
+ `${serveUi ? "UI and backend" : "Backend control and agent runtime"} running at ${surfaceBaseUrl}`,
1247
+ );
1248
+ console.log(` Capture mode: ${captureMode}`);
1249
+ console.log(` Backend: ${backend}`);
1250
+ console.log(` Proxy: ${proxyUrl}`);
1251
+ printAccessHints(port, host, basePath, serveUi, publicOrigin);
1252
+ if (legacyUrl !== null && legacyProxyUrl !== null && legacyMcpUrl !== null) {
1253
+ console.log(` Legacy UI: ${legacyUrl}`);
1254
+ console.log(` Legacy proxy: ${legacyProxyUrl}`);
1255
+ console.log(` Legacy MCP: ${legacyMcpUrl}`);
1256
+ }
1257
+ console.log(``);
1258
+ console.log(`Route AI coding tools through the proxy:`);
1259
+ console.log(` Claude Code: ANTHROPIC_BASE_URL=${proxyUrl} claude`);
1260
+ console.log(` OpenCode: LLM_BASE_URL=${proxyUrl} opencode`);
1261
+ console.log(` MiMo Code: OPENAI_BASE_URL=${openAiProxyUrl} mimo`);
1262
+ console.log(` Direct HTTP: curl ${proxyMessagesUrl} -d '{"model":"...","messages":[...]}'`);
1263
+ console.log(
1264
+ ` Remote/container tools: use the Network proxy URL above when shown; otherwise restart with --host 0.0.0.0 or a reachable IP.`,
1265
+ );
1266
+ if (open && uiUrl !== null) openBrowser(uiUrl);
1267
+
1002
1268
  process.exitCode = await serverExit;
1003
1269
 
1004
1270
  const activeSupervisorShutdown = currentSupervisorShutdown();