@tonyclaw/agent-inspector 3.0.44 → 3.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/{nitro.json → backend/nitro.json} +3 -3
- package/.output/backend-public/assets/index-D4LX-sw-.js +11 -0
- package/.output/cli.js +22707 -17099
- package/.output/server/_libs/extend.mjs +4 -8
- package/.output/server/_libs/jszip.mjs +9 -35
- package/.output/server/_libs/modelcontextprotocol__core.mjs +25 -25
- package/.output/server/_libs/modelcontextprotocol__server.mjs +2 -2
- 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/_libs/zod.mjs +6 -6
- package/.output/server/_ssr/index.mjs +5 -4
- package/.output/server/_ssr/publicBasePathContext-IH2ilOfu.mjs +176 -0
- package/.output/server/_ssr/{router-DWcUFPR3.mjs → router-D18yUq36.mjs} +7877 -5597
- package/.output/server/_ssr/start-COQu_AgD.mjs +57 -0
- package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +4 -0
- package/.output/server/index.mjs +5 -145
- package/.output/{public/assets/CompareDrawer-DQHjxFO6.js → ui/assets/CompareDrawer-DAUuIJ6G.js} +1 -1
- package/.output/{public/assets/InspectorPet-D1A4505B.js → ui/assets/InspectorPet-BRBVjOWI.js} +1 -1
- package/.output/ui/assets/ProxyViewerContainer-D7Sq0ctc.js +59 -0
- package/.output/{public/assets/ReplayDialog-C5vmbecv.js → ui/assets/ReplayDialog-nDLsjOhs.js} +1 -1
- package/.output/{public/assets/RequestAnatomy-CPGNB8lk.js → ui/assets/RequestAnatomy-zd4BDgL0.js} +1 -1
- package/.output/ui/assets/ResponseView-AdIXGcSn.js +2 -0
- package/.output/ui/assets/StreamingChunkSequence-CesTz8He.js +1 -0
- package/.output/{public/assets/_sessionId-CDhRgzf6.js → ui/assets/_sessionId-BAfzrhSU.js} +1 -1
- package/.output/{public/assets/_sessionId-mw3aA8Bp.js → ui/assets/_sessionId-QnBomgPD.js} +1 -1
- package/.output/ui/assets/favicon-DYEkHSNl.svg +21 -0
- package/.output/{public/assets/index-B2eoeT-Z.js → ui/assets/index-BcsdxBAd.js} +1 -1
- package/.output/ui/assets/index-BvXp42al.css +1 -0
- package/.output/{public/assets/index-CX7_rf7o.js → ui/assets/index-D0rtCN9V.js} +1 -1
- package/.output/ui/assets/index-DHpwr08Z.js +73 -0
- package/.output/{public/assets/index-BfRhTvOd.js → ui/assets/index-dNuk2dsU.js} +1 -1
- package/.output/ui/assets/json-viewer-BvFHglMb.js +1 -0
- package/.output/{public/assets/jszip.min-C9rCFoU3.js → ui/assets/jszip.min-B5Z7gNZB.js} +1 -1
- package/.output/ui/index.html +229 -0
- package/.output/ui/runtime-config.js +2 -0
- package/.output/workers/logFinalizer.worker.js +983 -414
- package/.output/workers/sessionWorkerEntry.js +983 -414
- package/README.md +363 -35
- package/docs/instance-control.openapi.yaml +361 -0
- package/package.json +28 -5
- 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 +109 -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/backend/routes/api/instances.$name.connection.ts +12 -0
- package/src/backend/routes/api/instances.$name.restart.ts +23 -0
- package/src/backend/routes/api/instances.$name.start.ts +18 -0
- package/src/backend/routes/api/instances.$name.stop.ts +23 -0
- package/src/backend/routes/api/instances.$name.ts +12 -0
- package/src/backend/routes/api/instances.ts +16 -0
- 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/backend/start.ts +10 -0
- package/src/cli/alias.ts +431 -0
- package/src/cli/doctor.ts +32 -9
- package/src/cli/instance.ts +1050 -0
- package/src/cli/instanceArgs.ts +285 -0
- package/src/cli/instanceControl.ts +181 -0
- package/src/cli/instanceModel.ts +267 -0
- package/src/cli/instanceRegistry.ts +731 -0
- package/src/cli/networkHints.ts +27 -14
- package/src/cli/onboard.ts +190 -35
- package/src/cli/onboardTarget.ts +228 -0
- package/src/cli/templates/codex-skill-onboard.ts +109 -31
- package/src/cli/templates/skill-onboard.ts +140 -70
- package/src/cli.ts +338 -77
- package/src/components/ProxyViewer.tsx +20 -10
- 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 +160 -140
- 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/basePath.ts +31 -7
- 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 +54 -0
- package/src/lib/instanceContract.ts +236 -0
- package/src/lib/managedInstance.ts +104 -0
- package/src/lib/piAgentContract.ts +3 -2
- package/src/lib/publicBasePathContext.ts +137 -0
- 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 +150 -0
- package/src/mcp/loopback.ts +16 -5
- package/src/mcp/mode.ts +25 -0
- package/src/mcp/server.ts +274 -39
- package/src/mcp/toolHandlers.ts +2 -2
- 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 +1049 -50
- 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 +84 -2
- package/src/proxy/schemas.ts +7 -1
- package/src/proxy/sessionArchive.ts +78 -14
- package/src/proxy/sessionInfo.ts +5 -4
- package/src/proxy/sqliteLogIndex.ts +65 -2
- 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-BhpIgfBi.js +0 -126
- package/.output/public/assets/ResponseView-DUfrajCm.js +0 -2
- package/.output/public/assets/StreamingChunkSequence-nbeCQqOz.js +0 -1
- package/.output/public/assets/index-BWjeqxbk.css +0 -1
- package/.output/public/assets/index-C6qZwYlR.js +0 -70
- package/.output/public/assets/json-viewer-BLmF1sOZ.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-E_Dmopc-.mjs +0 -144
- package/.output/server/_sessionId-U54BAqdp.mjs +0 -82
- package/.output/server/_ssr/CompareDrawer-CksatPed.mjs +0 -1058
- package/.output/server/_ssr/InspectorPet-DNc4GQ7z.mjs +0 -936
- package/.output/server/_ssr/ProxyViewerContainer-B02Ey0p_.mjs +0 -17607
- package/.output/server/_ssr/ReplayDialog-DdMvHJF1.mjs +0 -723
- package/.output/server/_ssr/RequestAnatomy--vh2Z8__.mjs +0 -835
- package/.output/server/_ssr/ResponseView-Dhxc-cKC.mjs +0 -755
- package/.output/server/_ssr/StreamingChunkSequence-BG0EQmaD.mjs +0 -272
- package/.output/server/_ssr/index-D0At9nfd.mjs +0 -82
- package/.output/server/_ssr/index-lcfulIXa.mjs +0 -133
- package/.output/server/_ssr/json-viewer-My1J1_5R.mjs +0 -481
- package/.output/server/_ssr/start-HYkvq4Ni.mjs +0 -4
- package/.output/server/_tanstack-start-manifest_v-B2chR8ef.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/.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/alias.ts
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import { normalizeBasePath, normalizePublicBasePath } from "../lib/basePath";
|
|
2
|
+
|
|
3
|
+
const DEFAULT_ALIAS_HOST = "localhost";
|
|
4
|
+
const DEFAULT_ALIAS_PORT = 9527;
|
|
5
|
+
const ALIAS_CONTROL_PATH = "/.agent-inspector/base-path-aliases";
|
|
6
|
+
const REQUEST_TIMEOUT_MS = 5_000;
|
|
7
|
+
|
|
8
|
+
export type AliasFetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
9
|
+
|
|
10
|
+
export type AliasIo = {
|
|
11
|
+
stdout: (text: string) => void;
|
|
12
|
+
stderr: (text: string) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type AliasAction =
|
|
16
|
+
| { kind: "add"; basePath: string }
|
|
17
|
+
| { kind: "list" }
|
|
18
|
+
| { kind: "remove"; basePath: string };
|
|
19
|
+
|
|
20
|
+
type AliasOptions = {
|
|
21
|
+
action: AliasAction;
|
|
22
|
+
host: string;
|
|
23
|
+
port: number;
|
|
24
|
+
json: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type AliasParseResult =
|
|
28
|
+
| { kind: "help" }
|
|
29
|
+
| { kind: "ok"; options: AliasOptions }
|
|
30
|
+
| { kind: "error"; message: string };
|
|
31
|
+
|
|
32
|
+
type AliasSnapshot = {
|
|
33
|
+
canonicalBasePath: string;
|
|
34
|
+
aliases: readonly string[];
|
|
35
|
+
runtimeScoped: true;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type AliasRequestResult =
|
|
39
|
+
| { kind: "success"; snapshot: AliasSnapshot }
|
|
40
|
+
| { kind: "http-error"; status: number; detail: string | null }
|
|
41
|
+
| { kind: "network-error"; timedOut: boolean }
|
|
42
|
+
| { kind: "invalid-response" };
|
|
43
|
+
|
|
44
|
+
type AliasOutput = {
|
|
45
|
+
action: AliasAction["kind"];
|
|
46
|
+
canonicalBasePath: string;
|
|
47
|
+
canonicalUrl: string;
|
|
48
|
+
aliases: readonly string[];
|
|
49
|
+
aliasUrls: readonly string[];
|
|
50
|
+
runtimeScoped: true;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const processIo: AliasIo = {
|
|
54
|
+
stdout: (text) => {
|
|
55
|
+
process.stdout.write(text);
|
|
56
|
+
},
|
|
57
|
+
stderr: (text) => {
|
|
58
|
+
process.stderr.write(text);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function parsePort(raw: string | undefined): number | null {
|
|
63
|
+
if (raw === undefined || raw.trim() === "") return null;
|
|
64
|
+
const port = Number(raw);
|
|
65
|
+
if (!Number.isInteger(port) || port < 1 || port > 65_535) return null;
|
|
66
|
+
return port;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function normalizeAliasPath(raw: string): string | null {
|
|
70
|
+
return normalizePublicBasePath(raw);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function isValidHost(host: string): boolean {
|
|
74
|
+
const trimmed = host.trim();
|
|
75
|
+
return (
|
|
76
|
+
trimmed.length > 0 &&
|
|
77
|
+
!trimmed.includes("://") &&
|
|
78
|
+
!trimmed.includes("/") &&
|
|
79
|
+
!trimmed.includes("?") &&
|
|
80
|
+
!trimmed.includes("#") &&
|
|
81
|
+
!/\s/u.test(trimmed)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function formatHostForUrl(host: string): string {
|
|
86
|
+
if (host.startsWith("[") && host.endsWith("]")) return host;
|
|
87
|
+
return host.includes(":") ? `[${host}]` : host;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function parseAliasArgs(argv: readonly string[]): AliasParseResult {
|
|
91
|
+
let host = DEFAULT_ALIAS_HOST;
|
|
92
|
+
let port = DEFAULT_ALIAS_PORT;
|
|
93
|
+
let json = false;
|
|
94
|
+
let help = false;
|
|
95
|
+
const positional: string[] = [];
|
|
96
|
+
|
|
97
|
+
for (let index = 0; index < argv.length; index++) {
|
|
98
|
+
const arg = argv[index];
|
|
99
|
+
switch (arg) {
|
|
100
|
+
case undefined:
|
|
101
|
+
continue;
|
|
102
|
+
case "--help":
|
|
103
|
+
case "-h":
|
|
104
|
+
help = true;
|
|
105
|
+
break;
|
|
106
|
+
case "--host": {
|
|
107
|
+
const value = argv[index + 1];
|
|
108
|
+
if (value === undefined || !isValidHost(value)) {
|
|
109
|
+
return {
|
|
110
|
+
kind: "error",
|
|
111
|
+
message: "alias: --host requires a hostname or IP address without a protocol or path",
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
host = value.trim();
|
|
115
|
+
index++;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case "--port":
|
|
119
|
+
case "-p": {
|
|
120
|
+
const value = parsePort(argv[index + 1]);
|
|
121
|
+
if (value === null) {
|
|
122
|
+
return {
|
|
123
|
+
kind: "error",
|
|
124
|
+
message: "alias: --port must be an integer from 1 to 65535",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
port = value;
|
|
128
|
+
index++;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "--json":
|
|
132
|
+
json = true;
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
if (arg.startsWith("-")) {
|
|
136
|
+
return { kind: "error", message: `alias: unknown option ${arg}` };
|
|
137
|
+
}
|
|
138
|
+
positional.push(arg);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (help) return { kind: "help" };
|
|
143
|
+
|
|
144
|
+
const command = positional[0];
|
|
145
|
+
switch (command) {
|
|
146
|
+
case "list":
|
|
147
|
+
if (positional.length !== 1) {
|
|
148
|
+
return { kind: "error", message: "alias: list does not accept a base path" };
|
|
149
|
+
}
|
|
150
|
+
return { kind: "ok", options: { action: { kind: "list" }, host, port, json } };
|
|
151
|
+
case "add":
|
|
152
|
+
case "remove": {
|
|
153
|
+
const rawBasePath = positional[1];
|
|
154
|
+
if (rawBasePath === undefined || positional.length !== 2) {
|
|
155
|
+
return { kind: "error", message: `alias: ${command} requires exactly one base path` };
|
|
156
|
+
}
|
|
157
|
+
const basePath = normalizeAliasPath(rawBasePath);
|
|
158
|
+
if (basePath === null) {
|
|
159
|
+
return {
|
|
160
|
+
kind: "error",
|
|
161
|
+
message: `alias: ${command} base path must be an absolute URL path without a query or hash`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const action: AliasAction = { kind: command, basePath };
|
|
165
|
+
return { kind: "ok", options: { action, host, port, json } };
|
|
166
|
+
}
|
|
167
|
+
case undefined:
|
|
168
|
+
return { kind: "error", message: "alias: expected add <path>, list, or remove <path>" };
|
|
169
|
+
default:
|
|
170
|
+
return { kind: "error", message: `alias: unknown command ${command}` };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function aliasHelp(): string {
|
|
175
|
+
return `agent-inspector alias - mount additional base paths on a running runtime
|
|
176
|
+
|
|
177
|
+
Usage:
|
|
178
|
+
agent-inspector alias add <path> [--host <host>] [--port <port>] [--json]
|
|
179
|
+
agent-inspector alias list [--host <host>] [--port <port>] [--json]
|
|
180
|
+
agent-inspector alias remove <path> [--host <host>] [--port <port>] [--json]
|
|
181
|
+
|
|
182
|
+
Options:
|
|
183
|
+
--host <host> Running instance host (default: localhost)
|
|
184
|
+
--port <port> Running instance port (default: 9527)
|
|
185
|
+
--json Emit machine-readable output
|
|
186
|
+
--help, -h Show this help
|
|
187
|
+
|
|
188
|
+
Aliases are runtime-scoped. This command never starts another Agent Inspector runtime.
|
|
189
|
+
`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function isObject(value: unknown): value is Record<string, unknown> {
|
|
193
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function parseAliasSnapshot(value: unknown): AliasSnapshot | null {
|
|
197
|
+
if (!isObject(value)) return null;
|
|
198
|
+
const canonicalBasePath = value["canonicalBasePath"];
|
|
199
|
+
const aliases = value["aliases"];
|
|
200
|
+
const runtimeScoped = value["runtimeScoped"];
|
|
201
|
+
if (
|
|
202
|
+
typeof canonicalBasePath !== "string" ||
|
|
203
|
+
!Array.isArray(aliases) ||
|
|
204
|
+
!aliases.every((alias) => typeof alias === "string") ||
|
|
205
|
+
runtimeScoped !== true
|
|
206
|
+
) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
canonicalBasePath: normalizeBasePath(canonicalBasePath),
|
|
211
|
+
aliases: aliases.map((alias) => normalizeBasePath(alias)),
|
|
212
|
+
runtimeScoped: true,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function readErrorDetail(value: unknown): string | null {
|
|
217
|
+
if (!isObject(value)) return null;
|
|
218
|
+
const error = value["error"];
|
|
219
|
+
if (typeof error === "string" && error.trim() !== "") return error;
|
|
220
|
+
const message = value["message"];
|
|
221
|
+
return typeof message === "string" && message.trim() !== "" ? message : null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function readJson(response: Response): Promise<unknown | null> {
|
|
225
|
+
try {
|
|
226
|
+
const value: unknown = await response.json();
|
|
227
|
+
return value;
|
|
228
|
+
} catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function requestAliases(
|
|
234
|
+
endpoint: string,
|
|
235
|
+
action: AliasAction,
|
|
236
|
+
fetchImpl: AliasFetch,
|
|
237
|
+
): Promise<AliasRequestResult> {
|
|
238
|
+
const controller = new AbortController();
|
|
239
|
+
const timeout = setTimeout(() => {
|
|
240
|
+
controller.abort();
|
|
241
|
+
}, REQUEST_TIMEOUT_MS);
|
|
242
|
+
const method = action.kind === "list" ? "GET" : action.kind === "add" ? "POST" : "DELETE";
|
|
243
|
+
const basePath = action.kind === "list" ? null : action.basePath;
|
|
244
|
+
const init: RequestInit = {
|
|
245
|
+
method,
|
|
246
|
+
headers:
|
|
247
|
+
action.kind === "list"
|
|
248
|
+
? { accept: "application/json" }
|
|
249
|
+
: {
|
|
250
|
+
accept: "application/json",
|
|
251
|
+
"content-type": "application/json",
|
|
252
|
+
"x-agent-inspector-csrf": "1",
|
|
253
|
+
},
|
|
254
|
+
signal: controller.signal,
|
|
255
|
+
};
|
|
256
|
+
if (basePath !== null) init.body = JSON.stringify({ basePath });
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
const response = await fetchImpl(endpoint, init);
|
|
260
|
+
const value = await readJson(response);
|
|
261
|
+
if (!response.ok) {
|
|
262
|
+
return { kind: "http-error", status: response.status, detail: readErrorDetail(value) };
|
|
263
|
+
}
|
|
264
|
+
const snapshot = parseAliasSnapshot(value);
|
|
265
|
+
return snapshot === null ? { kind: "invalid-response" } : { kind: "success", snapshot };
|
|
266
|
+
} catch (error) {
|
|
267
|
+
const timedOut =
|
|
268
|
+
controller.signal.aborted || (error instanceof Error && error.name === "AbortError");
|
|
269
|
+
return { kind: "network-error", timedOut };
|
|
270
|
+
} finally {
|
|
271
|
+
clearTimeout(timeout);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function displayBasePath(basePath: string): string {
|
|
276
|
+
const normalized = normalizeBasePath(basePath);
|
|
277
|
+
return normalized === "" ? "/" : normalized;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function fullUrl(origin: string, basePath: string): string {
|
|
281
|
+
return `${origin}${normalizeBasePath(basePath)}`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function buildOutput(origin: string, action: AliasAction, snapshot: AliasSnapshot): AliasOutput {
|
|
285
|
+
return {
|
|
286
|
+
action: action.kind,
|
|
287
|
+
canonicalBasePath: displayBasePath(snapshot.canonicalBasePath),
|
|
288
|
+
canonicalUrl: fullUrl(origin, snapshot.canonicalBasePath),
|
|
289
|
+
aliases: snapshot.aliases.map(displayBasePath),
|
|
290
|
+
aliasUrls: snapshot.aliases.map((alias) => fullUrl(origin, alias)),
|
|
291
|
+
runtimeScoped: true,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function formatHumanOutput(output: AliasOutput): string {
|
|
296
|
+
const heading =
|
|
297
|
+
output.action === "add"
|
|
298
|
+
? "Base-path alias added."
|
|
299
|
+
: output.action === "remove"
|
|
300
|
+
? "Base-path alias removed."
|
|
301
|
+
: "Base-path aliases for the running runtime:";
|
|
302
|
+
const aliasPaths = output.aliases.length === 0 ? "(none)" : output.aliases.join(", ");
|
|
303
|
+
const aliasUrls =
|
|
304
|
+
output.aliasUrls.length === 0
|
|
305
|
+
? " (none)"
|
|
306
|
+
: output.aliasUrls.map((url) => ` - ${url}`).join("\n");
|
|
307
|
+
return `${heading}
|
|
308
|
+
Canonical base path: ${output.canonicalBasePath}
|
|
309
|
+
Canonical URL: ${output.canonicalUrl}
|
|
310
|
+
Alias base paths: ${aliasPaths}
|
|
311
|
+
Alias URLs:
|
|
312
|
+
${aliasUrls}
|
|
313
|
+
Scope: current runtime only; no second runtime was started and aliases are not persisted.
|
|
314
|
+
`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function writeError(io: AliasIo, json: boolean, code: string, message: string): void {
|
|
318
|
+
if (json) {
|
|
319
|
+
io.stderr(`${JSON.stringify({ error: code, message, runtimeStarted: false })}\n`);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
io.stderr(`agent-inspector alias: ${message}\n`);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function oldRuntimeMessage(origin: string): string {
|
|
326
|
+
return `the runtime at ${origin} does not support base-path aliases. Upgrade Agent Inspector and restart that instance, then retry; this command did not start a runtime.`;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function handleHttpError(
|
|
330
|
+
options: AliasOptions,
|
|
331
|
+
endpoint: string,
|
|
332
|
+
origin: string,
|
|
333
|
+
result: Extract<AliasRequestResult, { kind: "http-error" }>,
|
|
334
|
+
fetchImpl: AliasFetch,
|
|
335
|
+
io: AliasIo,
|
|
336
|
+
): Promise<number> {
|
|
337
|
+
if (result.status === 404 && options.action.kind === "remove") {
|
|
338
|
+
const probe = await requestAliases(endpoint, { kind: "list" }, fetchImpl);
|
|
339
|
+
if (probe.kind === "success") {
|
|
340
|
+
writeError(
|
|
341
|
+
io,
|
|
342
|
+
options.json,
|
|
343
|
+
"alias_not_found",
|
|
344
|
+
`base path ${displayBasePath(options.action.basePath)} is not mounted. Run "agent-inspector alias list --host ${options.host} --port ${options.port}" to inspect the current runtime.`,
|
|
345
|
+
);
|
|
346
|
+
return 1;
|
|
347
|
+
}
|
|
348
|
+
if (probe.kind === "network-error") {
|
|
349
|
+
writeError(
|
|
350
|
+
io,
|
|
351
|
+
options.json,
|
|
352
|
+
probe.timedOut ? "request_timeout" : "runtime_unreachable",
|
|
353
|
+
`${probe.timedOut ? "timed out contacting" : "cannot reach"} ${origin}. Confirm the existing runtime is running and the --host/--port values are correct; no runtime was started.`,
|
|
354
|
+
);
|
|
355
|
+
return 1;
|
|
356
|
+
}
|
|
357
|
+
if (probe.kind === "http-error" && (probe.status === 404 || probe.status === 405)) {
|
|
358
|
+
writeError(io, options.json, "unsupported_runtime", oldRuntimeMessage(origin));
|
|
359
|
+
return 1;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (result.status === 404 || result.status === 405) {
|
|
364
|
+
writeError(io, options.json, "unsupported_runtime", oldRuntimeMessage(origin));
|
|
365
|
+
return 1;
|
|
366
|
+
}
|
|
367
|
+
if (result.status === 409) {
|
|
368
|
+
writeError(
|
|
369
|
+
io,
|
|
370
|
+
options.json,
|
|
371
|
+
"alias_conflict",
|
|
372
|
+
`${result.detail ?? "the base path is already mounted or conflicts with another mount"}. Run "agent-inspector alias list --host ${options.host} --port ${options.port}" to inspect the current runtime.`,
|
|
373
|
+
);
|
|
374
|
+
return 1;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const detail = result.detail === null ? "the runtime rejected the request" : result.detail;
|
|
378
|
+
writeError(
|
|
379
|
+
io,
|
|
380
|
+
options.json,
|
|
381
|
+
"runtime_rejected_request",
|
|
382
|
+
`${detail} (HTTP ${result.status}). Check the running instance and retry; no runtime was started.`,
|
|
383
|
+
);
|
|
384
|
+
return 1;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export async function runAlias(
|
|
388
|
+
argv: readonly string[],
|
|
389
|
+
fetchImpl: AliasFetch = fetch,
|
|
390
|
+
io: AliasIo = processIo,
|
|
391
|
+
): Promise<number> {
|
|
392
|
+
const parsed = parseAliasArgs(argv);
|
|
393
|
+
if (parsed.kind === "help") {
|
|
394
|
+
io.stdout(aliasHelp());
|
|
395
|
+
return 0;
|
|
396
|
+
}
|
|
397
|
+
if (parsed.kind === "error") {
|
|
398
|
+
io.stderr(`${parsed.message}\n\n${aliasHelp()}`);
|
|
399
|
+
return 2;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const { options } = parsed;
|
|
403
|
+
const origin = `http://${formatHostForUrl(options.host)}:${options.port}`;
|
|
404
|
+
const endpoint = `${origin}${ALIAS_CONTROL_PATH}`;
|
|
405
|
+
const result = await requestAliases(endpoint, options.action, fetchImpl);
|
|
406
|
+
switch (result.kind) {
|
|
407
|
+
case "success": {
|
|
408
|
+
const output = buildOutput(origin, options.action, result.snapshot);
|
|
409
|
+
io.stdout(options.json ? `${JSON.stringify(output, null, 2)}\n` : formatHumanOutput(output));
|
|
410
|
+
return 0;
|
|
411
|
+
}
|
|
412
|
+
case "network-error":
|
|
413
|
+
writeError(
|
|
414
|
+
io,
|
|
415
|
+
options.json,
|
|
416
|
+
result.timedOut ? "request_timeout" : "runtime_unreachable",
|
|
417
|
+
`${result.timedOut ? "timed out contacting" : "cannot reach"} ${origin}. Confirm the existing runtime is running and the --host/--port values are correct; no runtime was started.`,
|
|
418
|
+
);
|
|
419
|
+
return 1;
|
|
420
|
+
case "invalid-response":
|
|
421
|
+
writeError(
|
|
422
|
+
io,
|
|
423
|
+
options.json,
|
|
424
|
+
"invalid_runtime_response",
|
|
425
|
+
`the runtime at ${origin} returned an invalid alias response. Upgrade and restart that instance, then retry; no runtime was started.`,
|
|
426
|
+
);
|
|
427
|
+
return 1;
|
|
428
|
+
case "http-error":
|
|
429
|
+
return handleHttpError(options, endpoint, origin, result, fetchImpl, io);
|
|
430
|
+
}
|
|
431
|
+
}
|
package/src/cli/doctor.ts
CHANGED
|
@@ -249,7 +249,7 @@ function checkProviderConfig(options: DoctorOptions, deps: DoctorDeps): DoctorCh
|
|
|
249
249
|
"Provider config",
|
|
250
250
|
"warn",
|
|
251
251
|
`Provider config exists but no providers were found: ${candidate}`,
|
|
252
|
-
"Add a provider
|
|
252
|
+
"Add a provider through the control API/MCP, or use Settings when a UI is available.",
|
|
253
253
|
);
|
|
254
254
|
}
|
|
255
255
|
|
|
@@ -257,29 +257,51 @@ function checkProviderConfig(options: DoctorOptions, deps: DoctorDeps): DoctorCh
|
|
|
257
257
|
"Provider config",
|
|
258
258
|
"warn",
|
|
259
259
|
"No provider config was found.",
|
|
260
|
-
"Add a provider
|
|
260
|
+
"Add a provider through the control API/MCP, use Settings when a UI is available, or pass --providers for this check.",
|
|
261
261
|
);
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
function publicOriginForDoctor(port: number, env: DoctorDeps["env"]): string {
|
|
265
|
+
const configured = env["AGENT_INSPECTOR_PUBLIC_ORIGIN"];
|
|
266
|
+
if (configured !== undefined && configured.trim() === configured) {
|
|
267
|
+
try {
|
|
268
|
+
const parsed = new URL(configured);
|
|
269
|
+
if (
|
|
270
|
+
(parsed.protocol === "http:" || parsed.protocol === "https:") &&
|
|
271
|
+
parsed.username.length === 0 &&
|
|
272
|
+
parsed.password.length === 0 &&
|
|
273
|
+
parsed.pathname === "/" &&
|
|
274
|
+
parsed.search.length === 0 &&
|
|
275
|
+
parsed.hash.length === 0
|
|
276
|
+
) {
|
|
277
|
+
return parsed.origin;
|
|
278
|
+
}
|
|
279
|
+
} catch {
|
|
280
|
+
// Startup reports invalid public-origin configuration; doctor keeps a safe local hint.
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return `http://localhost:${String(port)}`;
|
|
284
|
+
}
|
|
285
|
+
|
|
264
286
|
async function checkProxyHealth(port: number, deps: DoctorDeps): Promise<DoctorCheck> {
|
|
265
287
|
const basePath = getConfiguredBasePath(deps.env);
|
|
266
288
|
const health = await deps.fetchHealth(port, basePath);
|
|
267
|
-
const url =
|
|
289
|
+
const url = publicOriginForDoctor(port, deps.env);
|
|
268
290
|
const proxyUrl = appendBasePathToOrigin(url, "/proxy", basePath);
|
|
269
291
|
const healthPath = appendBasePathToOrigin("", "/api/health", basePath);
|
|
270
292
|
if (health.ok) {
|
|
271
293
|
return check(
|
|
272
|
-
"
|
|
294
|
+
"Backend health",
|
|
273
295
|
"pass",
|
|
274
|
-
`
|
|
275
|
-
`
|
|
296
|
+
`Agent Inspector backend is healthy at ${appendBasePathToOrigin(url, "/", basePath)}.`,
|
|
297
|
+
`Agent proxy URL: ${proxyUrl}. UI availability is not part of this backend check.`,
|
|
276
298
|
);
|
|
277
299
|
}
|
|
278
300
|
|
|
279
301
|
if (await deps.isPortOpen(port)) {
|
|
280
302
|
const suffix = health.status === null ? "" : ` (HTTP ${health.status})`;
|
|
281
303
|
return check(
|
|
282
|
-
"
|
|
304
|
+
"Backend health",
|
|
283
305
|
"fail",
|
|
284
306
|
`Port ${port} is accepting connections, but ${healthPath} is not healthy${suffix}.`,
|
|
285
307
|
"Stop that process, choose --port <n>, or start agent-inspector with --force-restart.",
|
|
@@ -287,7 +309,7 @@ async function checkProxyHealth(port: number, deps: DoctorDeps): Promise<DoctorC
|
|
|
287
309
|
}
|
|
288
310
|
|
|
289
311
|
return check(
|
|
290
|
-
"
|
|
312
|
+
"Backend health",
|
|
291
313
|
"warn",
|
|
292
314
|
`No process is listening on port ${port}.`,
|
|
293
315
|
"Start with `agent-inspector`, `agent-inspector --background`, or `bun run dev`.",
|
|
@@ -578,7 +600,8 @@ export function doctorHelp(): string {
|
|
|
578
600
|
"Usage:",
|
|
579
601
|
" agent-inspector doctor [--port <port>] [--config-dir <dir>] [--providers <json>] [--fix] [--json] [--verbose] [--chrome-extension]",
|
|
580
602
|
"",
|
|
581
|
-
"Checks local
|
|
603
|
+
"Checks local backend health, provider config presence, and package metadata.",
|
|
604
|
+
"The backend check probes the local health endpoint and does not require a composed Web UI.",
|
|
582
605
|
"Pass --fix to run safe local repairs before checks, including legacy data-dir migration.",
|
|
583
606
|
"Pass --json to emit a machine-readable report for CI, scripts, and Jenkins.",
|
|
584
607
|
"Pass --verbose to include local paths, capture mode, and log storage checks.",
|