@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.
- package/.output/{nitro.json → backend/nitro.json} +3 -3
- package/.output/backend-public/assets/index-D4LX-sw-.js +11 -0
- package/.output/cli.js +8018 -5451
- package/.output/server/_libs/extend.mjs +4 -8
- package/.output/server/_libs/jszip.mjs +9 -35
- package/.output/server/_libs/react-dom.mjs +2 -3
- package/.output/server/_libs/react.mjs +1 -27
- package/.output/server/_libs/tanstack__react-router.mjs +1 -329
- package/.output/server/_libs/tanstack__router-core.mjs +42 -100
- package/.output/server/_libs/use-sync-external-store.mjs +1 -64
- package/.output/server/_libs/ws.mjs +1 -1
- package/.output/server/_ssr/index.mjs +4 -4
- package/.output/server/_ssr/{publicBasePathContext-5264L3rX.mjs → publicBasePathContext-IH2ilOfu.mjs} +52 -24
- package/.output/server/_ssr/{router-BJ_ltLim.mjs → router-BwZEsYfS.mjs} +19794 -19444
- package/.output/server/_ssr/{start-C6MjPjxp.mjs → start-COQu_AgD.mjs} +1 -1
- package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
- package/.output/server/index.mjs +5 -145
- package/.output/{public/assets/CompareDrawer-B3_TLTJh.js → ui/assets/CompareDrawer-V-8lPASC.js} +1 -1
- package/.output/{public/assets/InspectorPet-Cpn6hv4P.js → ui/assets/InspectorPet-D4CVnfdf.js} +1 -1
- package/.output/ui/assets/ProxyViewerContainer-CO3ZVHLX.js +59 -0
- package/.output/{public/assets/ReplayDialog-B3EKVdJk.js → ui/assets/ReplayDialog-CpGyTLtt.js} +1 -1
- package/.output/{public/assets/RequestAnatomy-COOQjyUC.js → ui/assets/RequestAnatomy-BLuJL9dZ.js} +1 -1
- package/.output/ui/assets/ResponseView-BuSC-CH7.js +2 -0
- package/.output/ui/assets/StreamingChunkSequence-DeA-JJKa.js +1 -0
- package/.output/{public/assets/_sessionId-zbgYl7ZJ.js → ui/assets/_sessionId-8HuHFhjo.js} +1 -1
- package/.output/{public/assets/_sessionId-BJlM3nmt.js → ui/assets/_sessionId-Chp67th6.js} +1 -1
- package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
- package/.output/ui/assets/index-BvXp42al.css +1 -0
- package/.output/{public/assets/index-xF_NY8Yb.js → ui/assets/index-DPmKK_5d.js} +5 -5
- package/.output/{public/assets/index-BIK4bPTv.js → ui/assets/index-atoQrlb8.js} +1 -1
- package/.output/ui/assets/index-nY3E1vxV.js +73 -0
- package/.output/{public/assets/index-D2Qw6Ri2.js → ui/assets/index-nl9-dpZn.js} +1 -1
- package/.output/ui/assets/json-viewer-B9kIzqeX.js +1 -0
- package/.output/{public/assets/jszip.min-B_rfAUCe.js → ui/assets/jszip.min-B7tfyE-I.js} +1 -1
- package/.output/ui/index.html +229 -0
- package/.output/ui/runtime-config.js +2 -0
- package/.output/workers/logFinalizer.worker.js +979 -414
- package/.output/workers/sessionWorkerEntry.js +979 -414
- package/README.md +182 -43
- package/docs/instance-control.openapi.yaml +59 -4
- package/package.json +40 -6
- package/scripts/generate-theme-scales.mjs +3 -3
- package/src/{router.tsx → backend/router.tsx} +3 -15
- package/src/backend/routes/$.ts +26 -0
- package/src/backend/routes/__root.ts +4 -0
- package/src/backend/routes/api/-instances.ts +7 -0
- package/src/{routes → backend/routes}/api/alerts.summary.ts +3 -3
- package/src/{routes → backend/routes}/api/alerts.ts +4 -4
- package/src/{routes → backend/routes}/api/config.paths.ts +1 -1
- package/src/{routes → backend/routes}/api/config.ts +11 -2
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.help.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.install.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.runner-presets.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.$packageId.upgrade.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.packages.ts +5 -1
- package/src/{routes → backend/routes}/api/ecosystem.recipes.$recipeId.run.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.tasks.$taskId.ts +1 -1
- package/src/{routes → backend/routes}/api/ecosystem.tasks.ts +1 -1
- package/src/{routes → backend/routes}/api/groups.$groupId.evidence.ts +2 -2
- package/src/{routes → backend/routes}/api/groups.$groupId.sessions.ts +2 -2
- package/src/{routes → backend/routes}/api/groups.$groupId.ts +2 -2
- package/src/{routes → backend/routes}/api/groups.ts +2 -2
- package/src/{routes → backend/routes}/api/health.ts +3 -3
- package/src/{routes → backend/routes}/api/instances.$name.connection.ts +1 -1
- package/src/{routes → backend/routes}/api/instances.$name.restart.ts +2 -2
- package/src/{routes → backend/routes}/api/instances.$name.start.ts +2 -2
- package/src/{routes → backend/routes}/api/instances.$name.stop.ts +2 -2
- package/src/{routes → backend/routes}/api/instances.$name.ts +1 -1
- package/src/{routes → backend/routes}/api/instances.ts +1 -1
- package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.promote.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.candidates.$candidateId.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.candidates.ts +1 -1
- package/src/{routes → backend/routes}/api/knowledge.project-context.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.search.ts +2 -2
- package/src/{routes → backend/routes}/api/knowledge.sessions.$sessionId.candidates.ts +3 -3
- package/src/{routes → backend/routes}/api/logs.$id.body.ts +6 -6
- package/src/{routes → backend/routes}/api/logs.$id.chunks.ts +5 -4
- package/src/{routes → backend/routes}/api/logs.$id.replay.ts +12 -11
- package/src/{routes → backend/routes}/api/logs.$id.ts +4 -3
- package/src/{routes → backend/routes}/api/logs.import.ts +3 -3
- package/src/{routes → backend/routes}/api/logs.stream.ts +11 -7
- package/src/{routes → backend/routes}/api/logs.ts +17 -9
- package/src/{routes → backend/routes}/api/mcp.ts +1 -1
- package/src/{routes → backend/routes}/api/models.ts +1 -1
- package/src/{routes → backend/routes}/api/pi-agent.ts +2 -2
- package/src/{routes → backend/routes}/api/providers.$providerId.model-metadata.ts +5 -5
- package/src/{routes → backend/routes}/api/providers.$providerId.test.log.ts +7 -7
- package/src/{routes → backend/routes}/api/providers.$providerId.ts +4 -4
- package/src/{routes → backend/routes}/api/providers.export.ts +1 -1
- package/src/{routes → backend/routes}/api/providers.import.ts +3 -3
- package/src/{routes → backend/routes}/api/providers.scan.ts +2 -2
- package/src/{routes → backend/routes}/api/providers.ts +9 -4
- package/src/{routes → backend/routes}/api/runs.$runId.evidence.ts +2 -2
- package/src/{routes → backend/routes}/api/runs.$runId.ts +2 -2
- package/src/{routes → backend/routes}/api/runs.ts +4 -4
- package/src/backend/routes/api/runtime.ts +46 -0
- package/src/{routes → backend/routes}/api/sessions.ts +3 -3
- package/src/{routes → backend/routes}/proxy/$.ts +1 -1
- package/src/{routes → backend/routes}/readyz.ts +1 -1
- package/src/{start.ts → backend/start.ts} +1 -1
- package/src/cli/alias.ts +2 -11
- package/src/cli/doctor.ts +32 -9
- package/src/cli/instance.ts +36 -13
- package/src/cli/instanceApi.ts +213 -0
- package/src/cli/instanceArgs.ts +46 -11
- package/src/cli/instanceControl.ts +10 -2
- package/src/cli/instanceModel.ts +18 -17
- package/src/cli/instanceRegistry.ts +0 -9
- package/src/cli/networkHints.ts +27 -14
- package/src/cli/onboard.ts +69 -2
- package/src/cli/onboardTarget.ts +89 -40
- package/src/cli/rustBackendPackage.ts +450 -0
- package/src/cli/templates/codex-skill-onboard.ts +44 -14
- package/src/cli/templates/skill-onboard.ts +64 -28
- package/src/cli.ts +341 -75
- package/src/components/ProxyViewer.tsx +11 -9
- package/src/components/ProxyViewerContainer.tsx +12 -11
- package/src/components/pi-agent/PiAgentPanel.tsx +2 -2
- package/src/components/providers/ProviderCard.tsx +1 -1
- package/src/components/providers/ProviderTestResultsView.tsx +1 -1
- package/src/components/providers/SettingsDialog.tsx +159 -144
- package/src/components/proxy-viewer/ApplicationBar.tsx +2 -1
- package/src/components/proxy-viewer/LogEntry.tsx +1 -1
- package/src/components/proxy-viewer/log-formats/index.ts +1 -1
- package/src/contracts/index.ts +5 -0
- package/src/contracts/log.ts +33 -3
- package/src/knowledge/types.ts +3 -2
- package/src/lib/alertContract.ts +2 -2
- package/src/lib/apiClient.ts +30 -7
- package/src/lib/apiFormat.ts +29 -0
- package/src/lib/backendImplementation.ts +16 -0
- package/src/lib/basePath.ts +29 -11
- package/src/lib/browserRuntimeContract.ts +124 -0
- package/src/lib/browserRuntimeResolver.ts +244 -0
- package/src/{proxy → lib}/claudeCodeStrip.ts +6 -7
- package/src/lib/codingAgentEndpoints.ts +38 -0
- package/src/lib/instanceContract.ts +30 -11
- package/src/lib/managedInstance.ts +9 -1
- package/src/lib/piAgentContract.ts +3 -2
- package/src/lib/publicBasePathContext.ts +40 -10
- package/src/lib/resourceLimits.ts +2 -0
- package/src/lib/runContract.ts +3 -3
- package/src/lib/sessionInfoContract.ts +3 -2
- package/src/mcp/instanceHandlers.ts +2 -0
- package/src/mcp/server.ts +19 -24
- package/src/proxy/config.ts +25 -30
- package/src/proxy/dataDir.ts +43 -7
- package/src/proxy/ecosystemTasks.ts +161 -70
- package/src/proxy/formats/registry.ts +6 -21
- package/src/proxy/handler.ts +129 -29
- package/src/proxy/identityProxy.ts +567 -39
- package/src/proxy/jsonlRecovery.ts +554 -0
- package/src/proxy/logFinalizer.ts +25 -10
- package/src/proxy/logImporter.ts +2 -1
- package/src/proxy/logIndex.ts +191 -95
- package/src/proxy/logger.ts +77 -14
- package/src/proxy/platformCommands.ts +41 -0
- package/src/proxy/privateDataPath.ts +310 -88
- package/src/proxy/rawStreamCapture.ts +194 -13
- package/src/proxy/runtimeAdmission.ts +5 -2
- package/src/proxy/runtimeHealth.ts +14 -1
- package/src/proxy/runtimeShutdown.ts +11 -1
- package/src/proxy/schemas.ts +7 -1
- package/src/proxy/sessionArchive.ts +70 -14
- package/src/proxy/sqliteLogIndex.ts +65 -42
- package/src/proxy/store.ts +141 -34
- package/src/proxy/uiAssetServer.ts +106 -0
- package/src/proxy/upstream.ts +29 -2
- package/src/ui/bootstrap.ts +167 -0
- package/src/ui/index.html +38 -0
- package/src/ui/logsStreamClient.ts +20 -0
- package/src/ui/main.tsx +13 -0
- package/src/ui/public/runtime-config.js +2 -0
- package/src/ui/router.tsx +13 -0
- package/src/ui/routes/__root.tsx +69 -0
- package/src/{routes → ui/routes}/index.tsx +2 -3
- package/src/{routes → ui/routes}/session/$sessionId.tsx +5 -11
- package/src/ui/runtimeDiscovery.ts +50 -0
- package/styles/globals.css +1 -0
- package/.output/public/assets/ProxyViewerContainer-BEAhuGOJ.js +0 -126
- package/.output/public/assets/ResponseView-DBCjkwye.js +0 -2
- package/.output/public/assets/StreamingChunkSequence-CuXhDgMo.js +0 -1
- package/.output/public/assets/index-BZo_8koU.js +0 -70
- package/.output/public/assets/index-ZWschkCh.css +0 -1
- package/.output/public/assets/json-viewer-B-Ao6pwW.js +0 -1
- package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +0 -1
- package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +0 -344
- package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +0 -2
- package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +0 -2
- package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +0 -2
- package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +0 -11
- package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +0 -69
- package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +0 -1
- package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +0 -28
- package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +0 -6
- package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +0 -34
- package/.output/server/_libs/aria-hidden.mjs +0 -122
- package/.output/server/_libs/bail.mjs +0 -8
- package/.output/server/_libs/character-entities.mjs +0 -2130
- package/.output/server/_libs/class-variance-authority.mjs +0 -44
- package/.output/server/_libs/clsx.mjs +0 -16
- package/.output/server/_libs/comma-separated-tokens.mjs +0 -10
- package/.output/server/_libs/decode-named-character-reference+[...].mjs +0 -8
- package/.output/server/_libs/dequal.mjs +0 -27
- package/.output/server/_libs/detect-node-es.mjs +0 -1
- package/.output/server/_libs/devlop.mjs +0 -8
- package/.output/server/_libs/diff.mjs +0 -320
- package/.output/server/_libs/estree-util-is-identifier-name.mjs +0 -11
- package/.output/server/_libs/floating-ui__core.mjs +0 -725
- package/.output/server/_libs/floating-ui__dom.mjs +0 -622
- package/.output/server/_libs/floating-ui__react-dom.mjs +0 -292
- package/.output/server/_libs/floating-ui__utils.mjs +0 -320
- package/.output/server/_libs/get-nonce.mjs +0 -9
- package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +0 -388
- package/.output/server/_libs/hast-util-whitespace.mjs +0 -10
- package/.output/server/_libs/html-url-attributes.mjs +0 -26
- package/.output/server/_libs/inline-style-parser.mjs +0 -142
- package/.output/server/_libs/is-plain-obj.mjs +0 -10
- package/.output/server/_libs/lucide-react.mjs +0 -1027
- package/.output/server/_libs/mdast-util-from-markdown.mjs +0 -717
- package/.output/server/_libs/mdast-util-to-hast.mjs +0 -710
- package/.output/server/_libs/mdast-util-to-string.mjs +0 -38
- package/.output/server/_libs/micromark-core-commonmark.mjs +0 -2259
- package/.output/server/_libs/micromark-factory-destination.mjs +0 -94
- package/.output/server/_libs/micromark-factory-label.mjs +0 -63
- package/.output/server/_libs/micromark-factory-space.mjs +0 -24
- package/.output/server/_libs/micromark-factory-title.mjs +0 -65
- package/.output/server/_libs/micromark-factory-whitespace.mjs +0 -22
- package/.output/server/_libs/micromark-util-character.mjs +0 -44
- package/.output/server/_libs/micromark-util-chunked.mjs +0 -36
- package/.output/server/_libs/micromark-util-classify-character+[...].mjs +0 -12
- package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +0 -41
- package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -19
- package/.output/server/_libs/micromark-util-decode-string.mjs +0 -21
- package/.output/server/_libs/micromark-util-encode.mjs +0 -1
- package/.output/server/_libs/micromark-util-html-tag-name.mjs +0 -69
- package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +0 -6
- package/.output/server/_libs/micromark-util-resolve-all.mjs +0 -15
- package/.output/server/_libs/micromark-util-sanitize-uri.mjs +0 -41
- package/.output/server/_libs/micromark-util-subtokenize.mjs +0 -346
- package/.output/server/_libs/micromark.mjs +0 -906
- package/.output/server/_libs/property-information.mjs +0 -1209
- package/.output/server/_libs/radix-ui.mjs +0 -1
- package/.output/server/_libs/radix-ui__number.mjs +0 -6
- package/.output/server/_libs/radix-ui__primitive.mjs +0 -11
- package/.output/server/_libs/radix-ui__react-accordion.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-arrow.mjs +0 -23
- package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-avatar.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-checkbox.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-collapsible.mjs +0 -144
- package/.output/server/_libs/radix-ui__react-collection.mjs +0 -69
- package/.output/server/_libs/radix-ui__react-compose-refs.mjs +0 -38
- package/.output/server/_libs/radix-ui__react-context-menu.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-context.mjs +0 -64
- package/.output/server/_libs/radix-ui__react-dialog.mjs +0 -280
- package/.output/server/_libs/radix-ui__react-direction.mjs +0 -9
- package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-focus-guards.mjs +0 -39
- package/.output/server/_libs/radix-ui__react-focus-scope.mjs +0 -210
- package/.output/server/_libs/radix-ui__react-form.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-hover-card.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-id.mjs +0 -14
- package/.output/server/_libs/radix-ui__react-label.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-menu.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-menubar.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-popover.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-popper.mjs +0 -340
- package/.output/server/_libs/radix-ui__react-portal.mjs +0 -16
- package/.output/server/_libs/radix-ui__react-presence.mjs +0 -173
- package/.output/server/_libs/radix-ui__react-primitive.mjs +0 -42
- package/.output/server/_libs/radix-ui__react-progress.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-radio-group.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-roving-focus.mjs +0 -235
- package/.output/server/_libs/radix-ui__react-scroll-area.mjs +0 -731
- package/.output/server/_libs/radix-ui__react-select.mjs +0 -1207
- package/.output/server/_libs/radix-ui__react-separator.mjs +0 -28
- package/.output/server/_libs/radix-ui__react-slider.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-slot.mjs +0 -132
- package/.output/server/_libs/radix-ui__react-switch.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-tabs.mjs +0 -194
- package/.output/server/_libs/radix-ui__react-toast.mjs +0 -2
- package/.output/server/_libs/radix-ui__react-toggle-group.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-toggle.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-toolbar.mjs +0 -1
- package/.output/server/_libs/radix-ui__react-tooltip.mjs +0 -498
- package/.output/server/_libs/radix-ui__react-use-previous.mjs +0 -14
- package/.output/server/_libs/radix-ui__react-use-size.mjs +0 -39
- package/.output/server/_libs/react-markdown.mjs +0 -235
- package/.output/server/_libs/react-remove-scroll-bar.mjs +0 -82
- package/.output/server/_libs/react-remove-scroll.mjs +0 -328
- package/.output/server/_libs/react-style-singleton.mjs +0 -69
- package/.output/server/_libs/remark-parse.mjs +0 -19
- package/.output/server/_libs/remark-rehype.mjs +0 -21
- package/.output/server/_libs/space-separated-tokens.mjs +0 -6
- package/.output/server/_libs/style-to-js.mjs +0 -72
- package/.output/server/_libs/style-to-object.mjs +0 -38
- package/.output/server/_libs/swr.mjs +0 -947
- package/.output/server/_libs/tailwind-merge.mjs +0 -3255
- package/.output/server/_libs/tanstack__react-virtual.mjs +0 -130
- package/.output/server/_libs/tanstack__virtual-core.mjs +0 -1319
- package/.output/server/_libs/three.mjs +0 -26016
- package/.output/server/_libs/trim-lines.mjs +0 -41
- package/.output/server/_libs/trough.mjs +0 -85
- package/.output/server/_libs/tslib.mjs +0 -1
- package/.output/server/_libs/ungap__structured-clone.mjs +0 -212
- package/.output/server/_libs/unified.mjs +0 -661
- package/.output/server/_libs/unist-util-is.mjs +0 -100
- package/.output/server/_libs/unist-util-position.mjs +0 -27
- package/.output/server/_libs/unist-util-stringify-position.mjs +0 -27
- package/.output/server/_libs/unist-util-visit-parents.mjs +0 -82
- package/.output/server/_libs/unist-util-visit.mjs +0 -24
- package/.output/server/_libs/use-callback-ref.mjs +0 -66
- package/.output/server/_libs/use-sidecar.mjs +0 -106
- package/.output/server/_libs/vfile-message.mjs +0 -138
- package/.output/server/_libs/vfile.mjs +0 -467
- package/.output/server/_sessionId-CJ99gZFV.mjs +0 -84
- package/.output/server/_sessionId-DEjScBpK.mjs +0 -146
- package/.output/server/_ssr/CompareDrawer-DtOIMeQB.mjs +0 -1060
- package/.output/server/_ssr/InspectorPet-CXc4oCBQ.mjs +0 -938
- package/.output/server/_ssr/ProxyViewerContainer-DVPlwfkt.mjs +0 -17632
- package/.output/server/_ssr/ReplayDialog-BQEA95qC.mjs +0 -725
- package/.output/server/_ssr/RequestAnatomy-BMyd8B7Q.mjs +0 -837
- package/.output/server/_ssr/ResponseView-qrTaEIM8.mjs +0 -757
- package/.output/server/_ssr/StreamingChunkSequence-BFTL8mIy.mjs +0 -274
- package/.output/server/_ssr/index-Bcj1Hcy4.mjs +0 -135
- package/.output/server/_ssr/index-DW-M7XUG.mjs +0 -84
- package/.output/server/_ssr/json-viewer-DiI0Yjsn.mjs +0 -483
- package/.output/server/_tanstack-start-manifest_v-C6pXXX9R.mjs +0 -4
- package/.output/server/node_modules/tslib/modules/index.js +0 -70
- package/.output/server/node_modules/tslib/modules/package.json +0 -3
- package/.output/server/node_modules/tslib/package.json +0 -47
- package/.output/server/node_modules/tslib/tslib.js +0 -484
- package/.output/server/package.json +0 -9
- package/src/routes/__root.tsx +0 -170
- package/src/routes/api/-instances.ts +0 -109
- /package/.output/{public → ui}/assets/agent-inspector-58K1_MsC.ico +0 -0
- /package/.output/{public → ui}/assets/alibaba-TTwafVwX.svg +0 -0
- /package/.output/{public → ui}/assets/minimax-BPMzvuL-.jpeg +0 -0
- /package/.output/{public → ui}/assets/qwen-mMn3f5ul.webp +0 -0
- /package/.output/{public → ui}/assets/zhipuai-BPNAnxo-.svg +0 -0
- /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
|
-
|
|
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
|
|
288
|
-
|
|
289
|
-
|
|
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(
|
|
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 = [
|
|
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
|
|
399
|
-
*
|
|
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
|
|
660
|
-
const
|
|
661
|
-
const
|
|
662
|
-
const
|
|
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
|
-
|
|
678
|
-
|
|
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(
|
|
742
|
-
|
|
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=${
|
|
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 ${
|
|
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
|
-
:
|
|
845
|
-
?
|
|
846
|
-
|
|
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
|
|
938
|
-
|
|
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(
|
|
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=${
|
|
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 ${
|
|
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 ${
|
|
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();
|