@tonyclaw/agent-inspector 4.0.1 → 4.0.3
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/backend/nitro.json +1 -1
- package/.output/cli.js +193 -110
- package/.output/server/_ssr/index.mjs +1 -1
- package/.output/server/_ssr/{router-CTHqmroT.mjs → router-ChILzhmz.mjs} +92 -4
- package/.output/server/index.mjs +1 -1
- package/.output/ui/assets/{CompareDrawer-L3n4J-Or.js → CompareDrawer-Co3cUF_I.js} +1 -1
- package/.output/ui/assets/{InspectorPet-D5o_3OZS.js → InspectorPet-jFcrL37X.js} +1 -1
- package/.output/ui/assets/{ProxyViewerContainer-Ocagx75S.js → ProxyViewerContainer-BPzt_VpM.js} +4 -4
- package/.output/ui/assets/{ReplayDialog-Bk7x1h-y.js → ReplayDialog-C6O_zuwI.js} +1 -1
- package/.output/ui/assets/{RequestAnatomy-U4lzL7Sc.js → RequestAnatomy-Ca6NvB7L.js} +1 -1
- package/.output/ui/assets/{ResponseView-LOWfvBLK.js → ResponseView-BzqKcveJ.js} +1 -1
- package/.output/ui/assets/{StreamingChunkSequence-DPfsrrXQ.js → StreamingChunkSequence-9pCZIsS_.js} +1 -1
- package/.output/ui/assets/{_sessionId-0MlWS-CO.js → _sessionId-BMP3KVGR.js} +1 -1
- package/.output/ui/assets/{_sessionId-OdX2Jvt1.js → _sessionId-y4eRoT1H.js} +1 -1
- package/.output/ui/assets/{index-Ea-c8hPg.js → index-CH5w-haG.js} +1 -1
- package/.output/ui/assets/{index-zVVS53Hd.js → index-CmocEhyU.js} +1 -1
- package/.output/ui/assets/{index-Du4qNOOt.js → index-DT8sMJ_n.js} +2 -2
- package/.output/ui/assets/{index-gvFj_9K6.js → index-bfsbIRZa.js} +1 -1
- package/.output/ui/assets/{json-viewer-C1WAMzg3.js → json-viewer-BfFOSDG5.js} +1 -1
- package/.output/ui/assets/{jszip.min-B8AKu2zm.js → jszip.min-BkbVkOsp.js} +1 -1
- package/.output/ui/index.html +1 -1
- package/package.json +5 -10
- package/src/assets/IDE/claudecode-color.svg +0 -1
- package/src/assets/IDE/codex-color.svg +0 -1
- package/src/assets/IDE/opencode.svg +0 -1
- package/src/assets/IDE/xiaomimimo.svg +0 -1
- package/src/assets/favicon.svg +0 -21
- package/src/assets/logos/alibaba.svg +0 -1
- package/src/assets/logos/anthropic.svg +0 -1
- package/src/assets/logos/claude-code.svg +0 -4
- package/src/assets/logos/deepseek.svg +0 -1
- package/src/assets/logos/minimax.jpeg +0 -0
- package/src/assets/logos/openai.svg +0 -1
- package/src/assets/logos/opencode.svg +0 -4
- package/src/assets/logos/qwen.webp +0 -0
- package/src/assets/logos/zhipuai.svg +0 -219
- package/src/backend/router.tsx +0 -36
- package/src/backend/routes/$.ts +0 -26
- package/src/backend/routes/__root.ts +0 -4
- package/src/backend/routes/api/-instances.ts +0 -7
- package/src/backend/routes/api/alerts.summary.ts +0 -28
- package/src/backend/routes/api/alerts.ts +0 -70
- package/src/backend/routes/api/config.paths.ts +0 -14
- package/src/backend/routes/api/config.ts +0 -73
- package/src/backend/routes/api/ecosystem.packages.$packageId.help.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.$packageId.install.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.$packageId.runner-presets.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.$packageId.upgrade.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.ts +0 -21
- package/src/backend/routes/api/ecosystem.recipes.$recipeId.run.ts +0 -11
- package/src/backend/routes/api/ecosystem.tasks.$taskId.ts +0 -16
- package/src/backend/routes/api/ecosystem.tasks.ts +0 -12
- package/src/backend/routes/api/groups.$groupId.evidence.ts +0 -55
- package/src/backend/routes/api/groups.$groupId.sessions.ts +0 -50
- package/src/backend/routes/api/groups.$groupId.ts +0 -93
- package/src/backend/routes/api/groups.ts +0 -79
- package/src/backend/routes/api/health.ts +0 -22
- package/src/backend/routes/api/instances.$name.connection.ts +0 -12
- package/src/backend/routes/api/instances.$name.restart.ts +0 -23
- package/src/backend/routes/api/instances.$name.start.ts +0 -18
- package/src/backend/routes/api/instances.$name.stop.ts +0 -23
- package/src/backend/routes/api/instances.$name.ts +0 -12
- package/src/backend/routes/api/instances.ts +0 -16
- package/src/backend/routes/api/knowledge.candidates.$candidateId.promote.ts +0 -32
- package/src/backend/routes/api/knowledge.candidates.$candidateId.ts +0 -50
- package/src/backend/routes/api/knowledge.candidates.ts +0 -10
- package/src/backend/routes/api/knowledge.project-context.ts +0 -29
- package/src/backend/routes/api/knowledge.search.ts +0 -62
- package/src/backend/routes/api/knowledge.sessions.$sessionId.candidates.ts +0 -26
- package/src/backend/routes/api/logs.$id.body.ts +0 -58
- package/src/backend/routes/api/logs.$id.chunks.ts +0 -37
- package/src/backend/routes/api/logs.$id.replay.ts +0 -297
- package/src/backend/routes/api/logs.$id.ts +0 -23
- package/src/backend/routes/api/logs.import.ts +0 -39
- package/src/backend/routes/api/logs.stream.ts +0 -174
- package/src/backend/routes/api/logs.ts +0 -214
- package/src/backend/routes/api/mcp.ts +0 -25
- package/src/backend/routes/api/models.ts +0 -10
- package/src/backend/routes/api/pi-agent.ts +0 -29
- package/src/backend/routes/api/providers.$providerId.model-metadata.ts +0 -173
- package/src/backend/routes/api/providers.$providerId.test.log.ts +0 -342
- package/src/backend/routes/api/providers.$providerId.ts +0 -111
- package/src/backend/routes/api/providers.export.ts +0 -44
- package/src/backend/routes/api/providers.import.ts +0 -81
- package/src/backend/routes/api/providers.scan.ts +0 -28
- package/src/backend/routes/api/providers.ts +0 -102
- package/src/backend/routes/api/runs.$runId.evidence.ts +0 -55
- package/src/backend/routes/api/runs.$runId.ts +0 -50
- package/src/backend/routes/api/runs.ts +0 -62
- package/src/backend/routes/api/runtime.ts +0 -46
- package/src/backend/routes/api/sessions.ts +0 -51
- package/src/backend/routes/api/storage.ts +0 -56
- package/src/backend/routes/livez.ts +0 -13
- package/src/backend/routes/metrics.ts +0 -14
- package/src/backend/routes/proxy/$.ts +0 -15
- package/src/backend/routes/readyz.ts +0 -18
- package/src/backend/start.ts +0 -10
- package/src/cli/alias.ts +0 -431
- package/src/cli/detect-tools.ts +0 -123
- package/src/cli/doctor.ts +0 -836
- package/src/cli/instance.ts +0 -1071
- package/src/cli/instanceApi.ts +0 -213
- package/src/cli/instanceArgs.ts +0 -301
- package/src/cli/instanceControl.ts +0 -191
- package/src/cli/instanceModel.ts +0 -276
- package/src/cli/instanceRegistry.ts +0 -731
- package/src/cli/networkHints.ts +0 -170
- package/src/cli/onboard.ts +0 -1668
- package/src/cli/onboardTarget.ts +0 -228
- package/src/cli/rustBackendPackage.ts +0 -458
- package/src/cli/startupOutput.ts +0 -16
- package/src/cli/templates/codex-skill-onboard.ts +0 -320
- package/src/cli/templates/command-onboard.ts +0 -25
- package/src/cli/templates/skill-onboard.ts +0 -625
- package/src/cli.ts +0 -1433
- package/src/components/OnboardingBanner.tsx +0 -115
- package/src/components/ProxyViewer.tsx +0 -2259
- package/src/components/ProxyViewerContainer.tsx +0 -1076
- package/src/components/alerts/AlertsDialog.tsx +0 -615
- package/src/components/clients/ClientLogo.tsx +0 -175
- package/src/components/ecosystem/AgentLabDialog.tsx +0 -947
- package/src/components/errors/SafeErrorBoundary.tsx +0 -201
- package/src/components/groups/GroupsDialog.tsx +0 -1304
- package/src/components/inspector-pet/InspectorPet.tsx +0 -398
- package/src/components/inspector-pet/InspectorPetCrab3D.tsx +0 -455
- package/src/components/inspector-pet/inspectorPetLogic.ts +0 -272
- package/src/components/pi-agent/PiAgentPanel.tsx +0 -446
- package/src/components/pi-agent/piAgentChatLogic.ts +0 -273
- package/src/components/providers/ImportWizardDialog.tsx +0 -281
- package/src/components/providers/ProviderCard.tsx +0 -347
- package/src/components/providers/ProviderForm.tsx +0 -1183
- package/src/components/providers/ProviderLogo.tsx +0 -122
- package/src/components/providers/ProviderTestResultsView.tsx +0 -734
- package/src/components/providers/ProvidersPanel.tsx +0 -714
- package/src/components/providers/SettingsDialog.tsx +0 -1042
- package/src/components/providers/providerFormCapabilities.ts +0 -36
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +0 -902
- package/src/components/proxy-viewer/AnswerMarkdown.tsx +0 -51
- package/src/components/proxy-viewer/ApplicationBar.tsx +0 -123
- package/src/components/proxy-viewer/CompareDrawer.tsx +0 -984
- package/src/components/proxy-viewer/ConversationGroup.tsx +0 -208
- package/src/components/proxy-viewer/ConversationGroupList.tsx +0 -652
- package/src/components/proxy-viewer/ConversationHeader.tsx +0 -429
- package/src/components/proxy-viewer/LiveConnectionStatus.tsx +0 -186
- package/src/components/proxy-viewer/LogEntry.tsx +0 -1419
- package/src/components/proxy-viewer/LogEntryHeader.tsx +0 -596
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +0 -57
- package/src/components/proxy-viewer/RawExportWarning.tsx +0 -77
- package/src/components/proxy-viewer/ReplayDialog.tsx +0 -636
- package/src/components/proxy-viewer/RequestToolsPanel.tsx +0 -299
- package/src/components/proxy-viewer/ResponseView.tsx +0 -202
- package/src/components/proxy-viewer/SessionLoadProgressBar.tsx +0 -61
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +0 -265
- package/src/components/proxy-viewer/ThreadConnector.tsx +0 -165
- package/src/components/proxy-viewer/ToolTraceEvents.tsx +0 -64
- package/src/components/proxy-viewer/TurnGroup.tsx +0 -383
- package/src/components/proxy-viewer/TurnGroupList.tsx +0 -156
- package/src/components/proxy-viewer/accessibility.ts +0 -8
- package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +0 -887
- package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +0 -222
- package/src/components/proxy-viewer/anatomy/contextIntelligence.ts +0 -737
- package/src/components/proxy-viewer/anatomy/sessionContextSummary.ts +0 -268
- package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +0 -53
- package/src/components/proxy-viewer/anatomy/types.ts +0 -41
- package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +0 -114
- package/src/components/proxy-viewer/bodyHydration.ts +0 -123
- package/src/components/proxy-viewer/cacheTrend.ts +0 -50
- package/src/components/proxy-viewer/diff/DiffView.tsx +0 -321
- package/src/components/proxy-viewer/diff/computeDiff.ts +0 -178
- package/src/components/proxy-viewer/diff/index.ts +0 -3
- package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +0 -194
- package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +0 -81
- package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +0 -21
- package/src/components/proxy-viewer/formats/index.tsx +0 -47
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +0 -442
- package/src/components/proxy-viewer/index.ts +0 -9
- package/src/components/proxy-viewer/lazy.ts +0 -41
- package/src/components/proxy-viewer/liveConnectionState.ts +0 -158
- package/src/components/proxy-viewer/log-formats/anthropic.ts +0 -191
- package/src/components/proxy-viewer/log-formats/index.ts +0 -23
- package/src/components/proxy-viewer/log-formats/openai.ts +0 -256
- package/src/components/proxy-viewer/log-formats/types.ts +0 -40
- package/src/components/proxy-viewer/log-formats/unknown.ts +0 -18
- package/src/components/proxy-viewer/logEntryVisibility.ts +0 -73
- package/src/components/proxy-viewer/logFocus.ts +0 -54
- package/src/components/proxy-viewer/proxyViewerContainerLogic.ts +0 -124
- package/src/components/proxy-viewer/proxyViewerLogic.ts +0 -488
- package/src/components/proxy-viewer/replayComparison.ts +0 -131
- package/src/components/proxy-viewer/requestDiff.ts +0 -277
- package/src/components/proxy-viewer/requestTools.ts +0 -220
- package/src/components/proxy-viewer/useCopyFeedback.ts +0 -38
- package/src/components/proxy-viewer/useKeyboardNavigation.ts +0 -232
- package/src/components/proxy-viewer/viewerState.ts +0 -176
- package/src/components/ui/badge.tsx +0 -47
- package/src/components/ui/button.tsx +0 -47
- package/src/components/ui/collapsible.tsx +0 -21
- package/src/components/ui/confirm-dialog.tsx +0 -51
- package/src/components/ui/crab-logo.tsx +0 -45
- package/src/components/ui/crab-variants.tsx +0 -467
- package/src/components/ui/dialog.tsx +0 -130
- package/src/components/ui/icon-trigger.ts +0 -2
- package/src/components/ui/json-viewer-bulk.ts +0 -132
- package/src/components/ui/json-viewer.tsx +0 -508
- package/src/components/ui/scroll-area.tsx +0 -54
- package/src/components/ui/select.tsx +0 -178
- package/src/components/ui/separator.tsx +0 -28
- package/src/components/ui/tabs.tsx +0 -88
- package/src/components/ui/tooltip.tsx +0 -51
- package/src/components/ui/transient-toast.tsx +0 -105
- package/src/contracts/anthropic.ts +0 -230
- package/src/contracts/index.ts +0 -59
- package/src/contracts/json.ts +0 -37
- package/src/contracts/log.ts +0 -139
- package/src/contracts/openai.ts +0 -267
- package/src/index.css +0 -11
- package/src/knowledge/candidateStore.ts +0 -94
- package/src/knowledge/distiller.ts +0 -98
- package/src/knowledge/openclawClient.ts +0 -161
- package/src/knowledge/openclawGatewayClient.ts +0 -249
- package/src/knowledge/openclawMarkdown.ts +0 -146
- package/src/knowledge/redactor.ts +0 -80
- package/src/knowledge/types.ts +0 -83
- package/src/lib/alertContract.ts +0 -76
- package/src/lib/apiClient.ts +0 -166
- package/src/lib/apiFormat.ts +0 -29
- package/src/lib/backendImplementation.ts +0 -16
- package/src/lib/basePath.ts +0 -107
- package/src/lib/browserRuntimeContract.ts +0 -124
- package/src/lib/browserRuntimeResolver.ts +0 -333
- package/src/lib/chunkLoadRecovery.ts +0 -83
- package/src/lib/claudeCodeStrip.ts +0 -98
- package/src/lib/clipboard.ts +0 -67
- package/src/lib/codingAgentEndpoints.ts +0 -54
- package/src/lib/ecosystemContract.ts +0 -130
- package/src/lib/export-logs.ts +0 -287
- package/src/lib/groupContract.ts +0 -166
- package/src/lib/instanceContract.ts +0 -239
- package/src/lib/jsonFile.ts +0 -46
- package/src/lib/logImportContract.ts +0 -12
- package/src/lib/managedInstance.ts +0 -112
- package/src/lib/mask.ts +0 -4
- package/src/lib/objectUtils.ts +0 -22
- package/src/lib/piAgentContract.ts +0 -102
- package/src/lib/providerContract.ts +0 -125
- package/src/lib/providerImportContract.ts +0 -27
- package/src/lib/providerModelMetadata.ts +0 -458
- package/src/lib/providerTestContract.ts +0 -170
- package/src/lib/providerTestPrompt.ts +0 -100
- package/src/lib/publicBasePathContext.ts +0 -137
- package/src/lib/resourceLimits.ts +0 -345
- package/src/lib/runContract.ts +0 -164
- package/src/lib/runtimeConfig.ts +0 -43
- package/src/lib/safeDiagnostic.ts +0 -38
- package/src/lib/safeFetch.ts +0 -508
- package/src/lib/serverPort.ts +0 -47
- package/src/lib/sessionInfoContract.ts +0 -78
- package/src/lib/sessionUrl.ts +0 -46
- package/src/lib/ssrfGuard.ts +0 -133
- package/src/lib/stopReason.ts +0 -130
- package/src/lib/themeMode.ts +0 -41
- package/src/lib/timeDisplay.ts +0 -22
- package/src/lib/toolTrace.ts +0 -290
- package/src/lib/uiScale.ts +0 -117
- package/src/lib/unknown.ts +0 -27
- package/src/lib/upstreamUrl.ts +0 -150
- package/src/lib/useAlerts.ts +0 -82
- package/src/lib/useGroupEvidence.ts +0 -37
- package/src/lib/useGroups.ts +0 -32
- package/src/lib/useOnboarding.ts +0 -93
- package/src/lib/useProviders.ts +0 -30
- package/src/lib/useStripConfig.ts +0 -154
- package/src/lib/useThemeMode.ts +0 -40
- package/src/lib/useUiScale.ts +0 -52
- package/src/lib/utils.ts +0 -78
- package/src/mcp/currentContext.ts +0 -65
- package/src/mcp/instanceHandlers.ts +0 -151
- package/src/mcp/loopback.ts +0 -88
- package/src/mcp/mode.ts +0 -75
- package/src/mcp/previewExtractor.ts +0 -233
- package/src/mcp/server.ts +0 -2274
- package/src/mcp/toolHandlers.ts +0 -1533
- package/src/proxy/alerts.ts +0 -664
- package/src/proxy/chunkStorage.ts +0 -123
- package/src/proxy/config.ts +0 -218
- package/src/proxy/constants.ts +0 -66
- package/src/proxy/dataDir.ts +0 -147
- package/src/proxy/ecosystemExecutionConfirmation.ts +0 -114
- package/src/proxy/ecosystemExecutionRoute.ts +0 -116
- package/src/proxy/ecosystemRegistry.ts +0 -296
- package/src/proxy/ecosystemTasks.ts +0 -415
- package/src/proxy/evidenceAnalysis.ts +0 -526
- package/src/proxy/evidenceExporter.ts +0 -235
- package/src/proxy/formats/anthropic/anthropicProvider.ts +0 -75
- package/src/proxy/formats/anthropic/handler.ts +0 -75
- package/src/proxy/formats/anthropic/index.ts +0 -13
- package/src/proxy/formats/anthropic/register.ts +0 -4
- package/src/proxy/formats/anthropic/schemas.ts +0 -6
- package/src/proxy/formats/anthropic/stream.ts +0 -205
- package/src/proxy/formats/handler.ts +0 -46
- package/src/proxy/formats/index.ts +0 -13
- package/src/proxy/formats/jsonSchema.ts +0 -2
- package/src/proxy/formats/openai/alibabaProvider.ts +0 -34
- package/src/proxy/formats/openai/codexMetadata.ts +0 -61
- package/src/proxy/formats/openai/handler.ts +0 -133
- package/src/proxy/formats/openai/index.ts +0 -33
- package/src/proxy/formats/openai/provider.ts +0 -50
- package/src/proxy/formats/openai/register.ts +0 -4
- package/src/proxy/formats/openai/schemas.ts +0 -25
- package/src/proxy/formats/openai/stream.ts +0 -600
- package/src/proxy/formats/openai/zhipuProvider.ts +0 -31
- package/src/proxy/formats/providerAdapter.ts +0 -50
- package/src/proxy/formats/providerRegistry.ts +0 -51
- package/src/proxy/formats/providers/index.ts +0 -3
- package/src/proxy/formats/registry.ts +0 -65
- package/src/proxy/groupEvidenceExporter.ts +0 -371
- package/src/proxy/groupStore.ts +0 -336
- package/src/proxy/handler.ts +0 -729
- package/src/proxy/identityProxy.ts +0 -1842
- package/src/proxy/jsonlRecovery.ts +0 -554
- package/src/proxy/logBodyChunks.ts +0 -91
- package/src/proxy/logFinalizer.ts +0 -777
- package/src/proxy/logFinalizer.worker.ts +0 -24
- package/src/proxy/logImportUpload.ts +0 -128
- package/src/proxy/logImporter.ts +0 -813
- package/src/proxy/logIndex.ts +0 -663
- package/src/proxy/logSearch.ts +0 -122
- package/src/proxy/logger.ts +0 -537
- package/src/proxy/openaiOrphanToolStrip.ts +0 -142
- package/src/proxy/platformCommands.ts +0 -258
- package/src/proxy/privateDataPath.ts +0 -419
- package/src/proxy/providerImporters.ts +0 -578
- package/src/proxy/providerScanStore.ts +0 -87
- package/src/proxy/providerSecretStore.ts +0 -216
- package/src/proxy/providers.ts +0 -998
- package/src/proxy/rawStreamCapture.ts +0 -342
- package/src/proxy/runFailures.ts +0 -94
- package/src/proxy/runStore.ts +0 -214
- package/src/proxy/runtimeAdmission.ts +0 -55
- package/src/proxy/runtimeHealth.ts +0 -221
- package/src/proxy/runtimeMetrics.ts +0 -149
- package/src/proxy/runtimeShutdown.ts +0 -157
- package/src/proxy/schemas.ts +0 -112
- package/src/proxy/sessionArchive.ts +0 -479
- package/src/proxy/sessionInfo.ts +0 -266
- package/src/proxy/sessionProcess.ts +0 -194
- package/src/proxy/sessionRuntime.ts +0 -121
- package/src/proxy/sessionSupervisor.ts +0 -305
- package/src/proxy/sessionWorkerEntry.ts +0 -26
- package/src/proxy/shutdownCoordinator.ts +0 -90
- package/src/proxy/socketTracker.ts +0 -639
- package/src/proxy/sqliteLogIndex.ts +0 -733
- package/src/proxy/storageLifecycle.ts +0 -432
- package/src/proxy/store.ts +0 -1773
- package/src/proxy/streamTiming.ts +0 -31
- package/src/proxy/toolSchemaWarnings.ts +0 -529
- package/src/proxy/uiAssetServer.ts +0 -106
- package/src/proxy/upstream.ts +0 -127
- package/src/services/alerts.ts +0 -12
- package/src/services/groups.ts +0 -119
- package/src/services/piAgent.ts +0 -421
- package/src/services/piAgentRetrieval.ts +0 -1180
- package/src/services/result.ts +0 -17
- package/src/services/runs.ts +0 -76
- package/src/ui/bootstrap.ts +0 -167
- package/src/ui/index.html +0 -38
- package/src/ui/logsStreamClient.ts +0 -20
- package/src/ui/main.tsx +0 -13
- package/src/ui/public/runtime-config.js +0 -2
- package/src/ui/router.tsx +0 -13
- package/src/ui/routes/__root.tsx +0 -69
- package/src/ui/routes/index.tsx +0 -35
- package/src/ui/routes/session/$sessionId.tsx +0 -50
- package/src/ui/runtimeDiscovery.ts +0 -50
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import useSWR, { type SWRResponse, useSWRConfig } from "swr";
|
|
2
|
-
import { fetchJson } from "./apiClient";
|
|
3
|
-
import {
|
|
4
|
-
DEFAULT_CAPTURE_MODE,
|
|
5
|
-
DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
|
|
6
|
-
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
7
|
-
DEFAULT_TIME_DISPLAY_FORMAT,
|
|
8
|
-
type CaptureMode,
|
|
9
|
-
RuntimeConfigSchema,
|
|
10
|
-
type TimeDisplayFormat,
|
|
11
|
-
type RuntimeConfig,
|
|
12
|
-
} from "./runtimeConfig";
|
|
13
|
-
|
|
14
|
-
export const STRIP_CONFIG_SWR_KEY = "/api/config";
|
|
15
|
-
|
|
16
|
-
async function fetcher(url: string): Promise<RuntimeConfig> {
|
|
17
|
-
return fetchJson(
|
|
18
|
-
url,
|
|
19
|
-
RuntimeConfigSchema,
|
|
20
|
-
undefined,
|
|
21
|
-
(response) => `Failed to fetch ${url}: ${response.status}`,
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* PATCH the runtime config. Exported separately for testability.
|
|
27
|
-
*/
|
|
28
|
-
type RuntimeConfigPatch = Partial<Omit<RuntimeConfig, "captureMode">>;
|
|
29
|
-
|
|
30
|
-
export async function setRuntimeConfig(patch: RuntimeConfigPatch): Promise<RuntimeConfig> {
|
|
31
|
-
return fetchJson(
|
|
32
|
-
STRIP_CONFIG_SWR_KEY,
|
|
33
|
-
RuntimeConfigSchema,
|
|
34
|
-
{
|
|
35
|
-
method: "PATCH",
|
|
36
|
-
headers: { "content-type": "application/json" },
|
|
37
|
-
body: JSON.stringify(patch),
|
|
38
|
-
},
|
|
39
|
-
(response) => `PATCH failed with status ${response.status}`,
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export type UseStripConfig = {
|
|
44
|
-
strip: boolean;
|
|
45
|
-
captureMode: CaptureMode;
|
|
46
|
-
slowResponseThresholdSeconds: number;
|
|
47
|
-
providerTestTimeoutSeconds: number;
|
|
48
|
-
timeDisplayFormat: TimeDisplayFormat;
|
|
49
|
-
isLoading: boolean;
|
|
50
|
-
isError: boolean;
|
|
51
|
-
setStrip: (next: boolean) => Promise<void>;
|
|
52
|
-
setSlowResponseThresholdSeconds: (next: number) => Promise<void>;
|
|
53
|
-
setProviderTestTimeoutSeconds: (next: number) => Promise<void>;
|
|
54
|
-
setTimeDisplayFormat: (next: TimeDisplayFormat) => Promise<void>;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Hook reading the runtime config from /api/config.
|
|
59
|
-
*
|
|
60
|
-
* - `strip` is the live value from the server (or the optimistic value mid-PATCH).
|
|
61
|
-
* - `slowResponseThresholdSeconds` controls the UI's slow-response indicator.
|
|
62
|
-
* - `providerTestTimeoutSeconds` controls each per-model Provider Test probe.
|
|
63
|
-
* - `setStrip(next)` PATCHes the server with optimistic update; on failure
|
|
64
|
-
* it throws and SWR rolls back the optimistic value.
|
|
65
|
-
*/
|
|
66
|
-
export function useStripConfig(): UseStripConfig {
|
|
67
|
-
const response: SWRResponse<RuntimeConfig, Error> = useSWR<RuntimeConfig, Error>(
|
|
68
|
-
STRIP_CONFIG_SWR_KEY,
|
|
69
|
-
fetcher,
|
|
70
|
-
{
|
|
71
|
-
revalidateOnFocus: false,
|
|
72
|
-
revalidateIfStale: false,
|
|
73
|
-
},
|
|
74
|
-
);
|
|
75
|
-
const { mutate: globalMutate } = useSWRConfig();
|
|
76
|
-
|
|
77
|
-
const strip = response.data?.stripClaudeCodeBillingHeader ?? false;
|
|
78
|
-
const captureMode = response.data?.captureMode ?? DEFAULT_CAPTURE_MODE;
|
|
79
|
-
const slowResponseThresholdSeconds =
|
|
80
|
-
response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS;
|
|
81
|
-
const providerTestTimeoutSeconds =
|
|
82
|
-
response.data?.providerTestTimeoutSeconds ?? DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS;
|
|
83
|
-
const timeDisplayFormat = response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT;
|
|
84
|
-
|
|
85
|
-
const optimisticConfig = (patch: RuntimeConfigPatch): RuntimeConfig => ({
|
|
86
|
-
stripClaudeCodeBillingHeader: response.data?.stripClaudeCodeBillingHeader ?? false,
|
|
87
|
-
hasSeenOnboarding: response.data?.hasSeenOnboarding ?? false,
|
|
88
|
-
slowResponseThresholdSeconds:
|
|
89
|
-
response.data?.slowResponseThresholdSeconds ?? DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
90
|
-
providerTestTimeoutSeconds:
|
|
91
|
-
response.data?.providerTestTimeoutSeconds ?? DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS,
|
|
92
|
-
timeDisplayFormat: response.data?.timeDisplayFormat ?? DEFAULT_TIME_DISPLAY_FORMAT,
|
|
93
|
-
captureMode,
|
|
94
|
-
...patch,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const setStrip = async (next: boolean): Promise<void> => {
|
|
98
|
-
await globalMutate(
|
|
99
|
-
STRIP_CONFIG_SWR_KEY,
|
|
100
|
-
setRuntimeConfig({ stripClaudeCodeBillingHeader: next }),
|
|
101
|
-
{
|
|
102
|
-
optimisticData: optimisticConfig({ stripClaudeCodeBillingHeader: next }),
|
|
103
|
-
rollbackOnError: true,
|
|
104
|
-
revalidate: false,
|
|
105
|
-
},
|
|
106
|
-
);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const setSlowResponseThresholdSeconds = async (next: number): Promise<void> => {
|
|
110
|
-
await globalMutate(
|
|
111
|
-
STRIP_CONFIG_SWR_KEY,
|
|
112
|
-
setRuntimeConfig({ slowResponseThresholdSeconds: next }),
|
|
113
|
-
{
|
|
114
|
-
optimisticData: optimisticConfig({ slowResponseThresholdSeconds: next }),
|
|
115
|
-
rollbackOnError: true,
|
|
116
|
-
revalidate: false,
|
|
117
|
-
},
|
|
118
|
-
);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const setTimeDisplayFormat = async (next: TimeDisplayFormat): Promise<void> => {
|
|
122
|
-
await globalMutate(STRIP_CONFIG_SWR_KEY, setRuntimeConfig({ timeDisplayFormat: next }), {
|
|
123
|
-
optimisticData: optimisticConfig({ timeDisplayFormat: next }),
|
|
124
|
-
rollbackOnError: true,
|
|
125
|
-
revalidate: false,
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const setProviderTestTimeoutSeconds = async (next: number): Promise<void> => {
|
|
130
|
-
await globalMutate(
|
|
131
|
-
STRIP_CONFIG_SWR_KEY,
|
|
132
|
-
setRuntimeConfig({ providerTestTimeoutSeconds: next }),
|
|
133
|
-
{
|
|
134
|
-
optimisticData: optimisticConfig({ providerTestTimeoutSeconds: next }),
|
|
135
|
-
rollbackOnError: true,
|
|
136
|
-
revalidate: false,
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
return {
|
|
142
|
-
strip,
|
|
143
|
-
captureMode,
|
|
144
|
-
slowResponseThresholdSeconds,
|
|
145
|
-
providerTestTimeoutSeconds,
|
|
146
|
-
timeDisplayFormat,
|
|
147
|
-
isLoading: response.isLoading,
|
|
148
|
-
isError: response.error !== undefined,
|
|
149
|
-
setStrip,
|
|
150
|
-
setSlowResponseThresholdSeconds,
|
|
151
|
-
setProviderTestTimeoutSeconds,
|
|
152
|
-
setTimeDisplayFormat,
|
|
153
|
-
};
|
|
154
|
-
}
|
package/src/lib/useThemeMode.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
applyThemeMode,
|
|
4
|
-
normalizeThemeMode,
|
|
5
|
-
persistThemeMode,
|
|
6
|
-
readStoredThemeMode,
|
|
7
|
-
THEME_MODE_STORAGE_KEY,
|
|
8
|
-
type ThemeMode,
|
|
9
|
-
} from "./themeMode";
|
|
10
|
-
|
|
11
|
-
export function useThemeMode(): {
|
|
12
|
-
themeMode: ThemeMode;
|
|
13
|
-
setThemeMode: (themeMode: ThemeMode) => void;
|
|
14
|
-
} {
|
|
15
|
-
const [themeMode, setThemeModeState] = useState<ThemeMode>(readStoredThemeMode);
|
|
16
|
-
|
|
17
|
-
const setThemeMode = useCallback((nextThemeMode: ThemeMode) => {
|
|
18
|
-
setThemeModeState(nextThemeMode);
|
|
19
|
-
applyThemeMode(nextThemeMode);
|
|
20
|
-
persistThemeMode(nextThemeMode);
|
|
21
|
-
}, []);
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
applyThemeMode(themeMode);
|
|
25
|
-
}, [themeMode]);
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
function handleStorage(event: StorageEvent): void {
|
|
29
|
-
if (event.key !== THEME_MODE_STORAGE_KEY) return;
|
|
30
|
-
const nextThemeMode = normalizeThemeMode(event.newValue);
|
|
31
|
-
setThemeModeState(nextThemeMode);
|
|
32
|
-
applyThemeMode(nextThemeMode);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
window.addEventListener("storage", handleStorage);
|
|
36
|
-
return () => window.removeEventListener("storage", handleStorage);
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
return { themeMode, setThemeMode };
|
|
40
|
-
}
|
package/src/lib/useUiScale.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
applyUiScalePreference,
|
|
4
|
-
normalizeUiScalePreference,
|
|
5
|
-
persistUiScalePreference,
|
|
6
|
-
readStoredUiScalePreference,
|
|
7
|
-
UI_SCALE_STORAGE_KEY,
|
|
8
|
-
type UiScalePreference,
|
|
9
|
-
} from "./uiScale";
|
|
10
|
-
|
|
11
|
-
export function useUiScale(): {
|
|
12
|
-
uiScalePreference: UiScalePreference;
|
|
13
|
-
resolvedUiScale: number;
|
|
14
|
-
setUiScalePreference: (preference: UiScalePreference) => void;
|
|
15
|
-
} {
|
|
16
|
-
const [uiScalePreference, setUiScalePreferenceState] = useState<UiScalePreference>(
|
|
17
|
-
readStoredUiScalePreference,
|
|
18
|
-
);
|
|
19
|
-
const [resolvedUiScale, setResolvedUiScale] = useState(1);
|
|
20
|
-
|
|
21
|
-
const setUiScalePreference = useCallback((nextPreference: UiScalePreference) => {
|
|
22
|
-
setUiScalePreferenceState(nextPreference);
|
|
23
|
-
persistUiScalePreference(nextPreference);
|
|
24
|
-
setResolvedUiScale(applyUiScalePreference(nextPreference));
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
const refreshScale = (): void => {
|
|
29
|
-
setResolvedUiScale(applyUiScalePreference(uiScalePreference));
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
refreshScale();
|
|
33
|
-
if (uiScalePreference !== "auto") return;
|
|
34
|
-
|
|
35
|
-
window.addEventListener("resize", refreshScale);
|
|
36
|
-
return () => window.removeEventListener("resize", refreshScale);
|
|
37
|
-
}, [uiScalePreference]);
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
const handleStorage = (event: StorageEvent): void => {
|
|
41
|
-
if (event.key !== UI_SCALE_STORAGE_KEY) return;
|
|
42
|
-
const nextPreference = normalizeUiScalePreference(event.newValue);
|
|
43
|
-
setUiScalePreferenceState(nextPreference);
|
|
44
|
-
setResolvedUiScale(applyUiScalePreference(nextPreference));
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
window.addEventListener("storage", handleStorage);
|
|
48
|
-
return () => window.removeEventListener("storage", handleStorage);
|
|
49
|
-
}, []);
|
|
50
|
-
|
|
51
|
-
return { uiScalePreference, resolvedUiScale, setUiScalePreference };
|
|
52
|
-
}
|
package/src/lib/utils.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { type ClassValue, clsx } from "clsx";
|
|
2
|
-
import { twMerge } from "tailwind-merge";
|
|
3
|
-
|
|
4
|
-
export function cn(...inputs: ClassValue[]): string {
|
|
5
|
-
return twMerge(clsx(inputs));
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function formatTokens(count: number): string {
|
|
9
|
-
const absoluteCount = Math.abs(count);
|
|
10
|
-
if (absoluteCount < 1000) return String(count);
|
|
11
|
-
if (absoluteCount >= 1_000_000) {
|
|
12
|
-
return (count / 1_000_000).toFixed(1).replace(/\.0$/, "") + "M";
|
|
13
|
-
}
|
|
14
|
-
return (count / 1000).toFixed(1).replace(/\.0$/, "") + "K";
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function formatContextWindowTokens(count: number): string {
|
|
18
|
-
if (count >= 1024 * 1024) {
|
|
19
|
-
return (count / (1024 * 1024)).toFixed(1).replace(/\.0$/, "") + "M";
|
|
20
|
-
}
|
|
21
|
-
return (count / 1024).toFixed(1).replace(/\.0$/, "") + "K";
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function formatExactContextUnit(count: number, multiplier: number, unit: "K" | "M"): string | null {
|
|
25
|
-
const tenths = count * 10;
|
|
26
|
-
if (!Number.isSafeInteger(tenths) || tenths % multiplier !== 0) return null;
|
|
27
|
-
return (tenths / multiplier / 10).toFixed(1).replace(/\.0$/, "") + unit;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function formatContextWindowInput(count: number): string {
|
|
31
|
-
if (!Number.isSafeInteger(count) || count <= 0) return count.toString();
|
|
32
|
-
if (count >= 1024 * 1024) {
|
|
33
|
-
const megaValue = formatExactContextUnit(count, 1024 * 1024, "M");
|
|
34
|
-
if (megaValue !== null) return megaValue;
|
|
35
|
-
}
|
|
36
|
-
const kiloValue = formatExactContextUnit(count, 1024, "K");
|
|
37
|
-
if (kiloValue !== null) return kiloValue;
|
|
38
|
-
return count.toString();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function contextWindowUnitMultiplier(unit: string | undefined): number | null {
|
|
42
|
-
if (unit === undefined || unit === "") return 1;
|
|
43
|
-
switch (unit.toLowerCase()) {
|
|
44
|
-
case "k":
|
|
45
|
-
return 1024;
|
|
46
|
-
case "m":
|
|
47
|
-
return 1024 * 1024;
|
|
48
|
-
default:
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function parseContextWindowTokensInput(value: string): number | null {
|
|
54
|
-
const trimmed = value.trim().replaceAll(",", "");
|
|
55
|
-
if (trimmed === "") return null;
|
|
56
|
-
const match = /^(\d+(?:\.\d+)?)\s*([kKmM])?$/.exec(trimmed);
|
|
57
|
-
if (match === null) return null;
|
|
58
|
-
const amountText = match[1];
|
|
59
|
-
if (amountText === undefined) return null;
|
|
60
|
-
const amount = Number(amountText);
|
|
61
|
-
const unit = match[2];
|
|
62
|
-
const multiplier = contextWindowUnitMultiplier(unit);
|
|
63
|
-
if (!Number.isFinite(amount) || amount <= 0 || multiplier === null) return null;
|
|
64
|
-
if ((unit === undefined || unit === "") && !Number.isInteger(amount)) return null;
|
|
65
|
-
const tokens = Math.round(amount * multiplier);
|
|
66
|
-
if (!Number.isSafeInteger(tokens) || tokens <= 0) return null;
|
|
67
|
-
return tokens;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export type StatusCategory = "success" | "client_error" | "server_error" | "pending";
|
|
71
|
-
|
|
72
|
-
export function getStatusCategory(status: number | null): StatusCategory {
|
|
73
|
-
if (status === null) return "pending";
|
|
74
|
-
if (status >= 200 && status < 300) return "success";
|
|
75
|
-
if (status >= 400 && status < 500) return "client_error";
|
|
76
|
-
if (status >= 500) return "server_error";
|
|
77
|
-
return "pending";
|
|
78
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import type { JsonValue } from "../contracts";
|
|
2
|
-
|
|
3
|
-
export type InspectorCurrentContext = {
|
|
4
|
-
groupId: string | null;
|
|
5
|
-
runId: string | null;
|
|
6
|
-
sessionId: string | null;
|
|
7
|
-
model: string | null;
|
|
8
|
-
provider: string | null;
|
|
9
|
-
agent: string | null;
|
|
10
|
-
project: string | null;
|
|
11
|
-
task: string | null;
|
|
12
|
-
metadata: Record<string, JsonValue>;
|
|
13
|
-
updatedAt: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type InspectorCurrentContextPatch = Partial<
|
|
17
|
-
Omit<InspectorCurrentContext, "metadata" | "updatedAt">
|
|
18
|
-
> & {
|
|
19
|
-
metadata?: Record<string, JsonValue>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function envString(name: string): string | null {
|
|
23
|
-
const value = process.env[name];
|
|
24
|
-
if (value === undefined) return null;
|
|
25
|
-
const trimmed = value.trim();
|
|
26
|
-
return trimmed.length === 0 ? null : trimmed;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function initialContext(): InspectorCurrentContext {
|
|
30
|
-
return {
|
|
31
|
-
groupId: envString("INSPECTOR_GROUP_ID"),
|
|
32
|
-
runId: envString("INSPECTOR_RUN_ID"),
|
|
33
|
-
sessionId: envString("INSPECTOR_SESSION_ID"),
|
|
34
|
-
model: envString("INSPECTOR_MODEL"),
|
|
35
|
-
provider: envString("INSPECTOR_PROVIDER"),
|
|
36
|
-
agent: envString("INSPECTOR_AGENT"),
|
|
37
|
-
project: envString("INSPECTOR_PROJECT"),
|
|
38
|
-
task: envString("INSPECTOR_TASK"),
|
|
39
|
-
metadata: {},
|
|
40
|
-
updatedAt: new Date().toISOString(),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
let currentContext = initialContext();
|
|
45
|
-
|
|
46
|
-
export function getCurrentContext(): InspectorCurrentContext {
|
|
47
|
-
return currentContext;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function setCurrentContext(patch: InspectorCurrentContextPatch): InspectorCurrentContext {
|
|
51
|
-
currentContext = {
|
|
52
|
-
...currentContext,
|
|
53
|
-
...patch,
|
|
54
|
-
metadata:
|
|
55
|
-
patch.metadata === undefined
|
|
56
|
-
? currentContext.metadata
|
|
57
|
-
: { ...currentContext.metadata, ...patch.metadata },
|
|
58
|
-
updatedAt: new Date().toISOString(),
|
|
59
|
-
};
|
|
60
|
-
return currentContext;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function _resetCurrentContextForTests(): void {
|
|
64
|
-
currentContext = initialContext();
|
|
65
|
-
}
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
InstanceConnectionOutputSchema,
|
|
4
|
-
InstanceEmptyRequestSchema,
|
|
5
|
-
InstanceErrorOutputSchema,
|
|
6
|
-
InstanceListOutputSchema,
|
|
7
|
-
InstanceOperationOutputSchema,
|
|
8
|
-
InstanceStartRequestSchema,
|
|
9
|
-
InstanceStatusOutputSchema,
|
|
10
|
-
type InstanceStartRequest,
|
|
11
|
-
} from "../lib/instanceContract";
|
|
12
|
-
import type { CallApiOptions } from "./loopback";
|
|
13
|
-
import type { ToolResult } from "./toolHandlers";
|
|
14
|
-
|
|
15
|
-
export const INSTANCE_LIFECYCLE_TIMEOUT_MS = 60_000;
|
|
16
|
-
|
|
17
|
-
export const InstanceToolNameSchema = z.string().trim().min(1).max(64);
|
|
18
|
-
|
|
19
|
-
export const InstanceLifecycleToolInputSchema = InstanceStartRequestSchema.extend({
|
|
20
|
-
name: InstanceToolNameSchema,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
export const InstanceNameToolInputSchema = z
|
|
24
|
-
.object({
|
|
25
|
-
name: InstanceToolNameSchema,
|
|
26
|
-
})
|
|
27
|
-
.strict();
|
|
28
|
-
|
|
29
|
-
export type InstanceCallApiFn = (path: string, options?: CallApiOptions) => Promise<Response>;
|
|
30
|
-
|
|
31
|
-
export type InstanceLifecycleToolInput = InstanceStartRequest & { name: string };
|
|
32
|
-
|
|
33
|
-
function textJson(data: unknown): ToolResult {
|
|
34
|
-
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function toolError(message: string): ToolResult {
|
|
38
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function responseJson(response: Response): Promise<unknown | null> {
|
|
42
|
-
try {
|
|
43
|
-
const value: unknown = await response.json();
|
|
44
|
-
return value;
|
|
45
|
-
} catch {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function validatedInstanceResponse(
|
|
51
|
-
response: Response,
|
|
52
|
-
schema: z.ZodType,
|
|
53
|
-
operation: string,
|
|
54
|
-
): Promise<ToolResult> {
|
|
55
|
-
const value = await responseJson(response);
|
|
56
|
-
if (!response.ok) {
|
|
57
|
-
const error = InstanceErrorOutputSchema.safeParse(value);
|
|
58
|
-
return error.success
|
|
59
|
-
? { ...textJson(error.data), isError: true }
|
|
60
|
-
: toolError(
|
|
61
|
-
`${operation} returned HTTP ${String(response.status)} with an invalid error body`,
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const parsed = schema.safeParse(value);
|
|
66
|
-
return parsed.success
|
|
67
|
-
? textJson(parsed.data)
|
|
68
|
-
: toolError(`${operation} returned an invalid public instance document`);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function instancePath(name: string, suffix = ""): string {
|
|
72
|
-
return `/api/instances/${encodeURIComponent(name)}${suffix}`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function jsonPost(body: unknown): CallApiOptions {
|
|
76
|
-
return {
|
|
77
|
-
method: "POST",
|
|
78
|
-
headers: {
|
|
79
|
-
accept: "application/json",
|
|
80
|
-
"content-type": "application/json",
|
|
81
|
-
},
|
|
82
|
-
body: JSON.stringify(body),
|
|
83
|
-
timeoutMs: INSTANCE_LIFECYCLE_TIMEOUT_MS,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function lifecycleRequest(input: InstanceLifecycleToolInput): InstanceStartRequest {
|
|
88
|
-
return {
|
|
89
|
-
port: input.port,
|
|
90
|
-
basePath: input.basePath,
|
|
91
|
-
host: input.host,
|
|
92
|
-
captureMode: input.captureMode,
|
|
93
|
-
backend: input.backend,
|
|
94
|
-
uiEnabled: input.uiEnabled,
|
|
95
|
-
dataDir: input.dataDir,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function listInstancesImpl(callApi: InstanceCallApiFn): Promise<ToolResult> {
|
|
100
|
-
const response = await callApi("/api/instances", {
|
|
101
|
-
headers: { accept: "application/json" },
|
|
102
|
-
});
|
|
103
|
-
return validatedInstanceResponse(response, InstanceListOutputSchema, "GET /api/instances");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export async function getInstanceImpl(
|
|
107
|
-
callApi: InstanceCallApiFn,
|
|
108
|
-
name: string,
|
|
109
|
-
): Promise<ToolResult> {
|
|
110
|
-
const path = instancePath(name);
|
|
111
|
-
const response = await callApi(path, { headers: { accept: "application/json" } });
|
|
112
|
-
return validatedInstanceResponse(response, InstanceStatusOutputSchema, `GET ${path}`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export async function getInstanceConnectionImpl(
|
|
116
|
-
callApi: InstanceCallApiFn,
|
|
117
|
-
name: string,
|
|
118
|
-
): Promise<ToolResult> {
|
|
119
|
-
const path = instancePath(name, "/connection");
|
|
120
|
-
const response = await callApi(path, { headers: { accept: "application/json" } });
|
|
121
|
-
return validatedInstanceResponse(response, InstanceConnectionOutputSchema, `GET ${path}`);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export async function startInstanceImpl(
|
|
125
|
-
callApi: InstanceCallApiFn,
|
|
126
|
-
input: InstanceLifecycleToolInput,
|
|
127
|
-
): Promise<ToolResult> {
|
|
128
|
-
const path = instancePath(input.name, "/start");
|
|
129
|
-
const request = lifecycleRequest(input);
|
|
130
|
-
const response = await callApi(path, jsonPost(InstanceStartRequestSchema.parse(request)));
|
|
131
|
-
return validatedInstanceResponse(response, InstanceOperationOutputSchema, `POST ${path}`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export async function stopInstanceImpl(
|
|
135
|
-
callApi: InstanceCallApiFn,
|
|
136
|
-
name: string,
|
|
137
|
-
): Promise<ToolResult> {
|
|
138
|
-
const path = instancePath(name, "/stop");
|
|
139
|
-
const response = await callApi(path, jsonPost(InstanceEmptyRequestSchema.parse({})));
|
|
140
|
-
return validatedInstanceResponse(response, InstanceOperationOutputSchema, `POST ${path}`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export async function restartInstanceImpl(
|
|
144
|
-
callApi: InstanceCallApiFn,
|
|
145
|
-
input: InstanceLifecycleToolInput,
|
|
146
|
-
): Promise<ToolResult> {
|
|
147
|
-
const path = instancePath(input.name, "/restart");
|
|
148
|
-
const request = lifecycleRequest(input);
|
|
149
|
-
const response = await callApi(path, jsonPost(InstanceStartRequestSchema.parse(request)));
|
|
150
|
-
return validatedInstanceResponse(response, InstanceOperationOutputSchema, `POST ${path}`);
|
|
151
|
-
}
|
package/src/mcp/loopback.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/* eslint-disable functional/no-throw-statements */
|
|
2
|
-
/**
|
|
3
|
-
* HTTP loopback helper for MCP tool handlers.
|
|
4
|
-
*
|
|
5
|
-
* Why HTTP loopback (not direct function calls): see
|
|
6
|
-
* `openspec/changes/add-mcp-server/design.md` decision D2. All MCP tools
|
|
7
|
-
* delegate to existing `/api/*` endpoints so any future cross-cutting
|
|
8
|
-
* middleware (auth, rate-limit, audit, metrics) added to `/api` is
|
|
9
|
-
* automatically inherited by MCP without duplicate plumbing.
|
|
10
|
-
*
|
|
11
|
-
* NOTE: TanStack Start / Nitro may expose an in-process route invocation
|
|
12
|
-
* API (e.g. Nitro's `$fetch` helper) that would let us skip the real HTTP
|
|
13
|
-
* round-trip while preserving the routing contract. As of this writing
|
|
14
|
-
* that investigation is open (tasks.md 2.3). If/when adopted, the public
|
|
15
|
-
* surface of this module — `callApi(path, init?)` returning a `Response`
|
|
16
|
-
* — should stay identical so callers don't change.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import {
|
|
20
|
-
AGENT_INSPECTOR_PUBLIC_BASE_PATH_HEADER,
|
|
21
|
-
AGENT_INSPECTOR_PUBLIC_PORT_HEADER,
|
|
22
|
-
withBasePath,
|
|
23
|
-
} from "../lib/basePath";
|
|
24
|
-
import { getPublicBasePath, getPublicPort } from "../lib/publicBasePathContext";
|
|
25
|
-
|
|
26
|
-
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
27
|
-
|
|
28
|
-
export type CallApiOptions = RequestInit & {
|
|
29
|
-
/** Override default 30s timeout. */
|
|
30
|
-
timeoutMs?: number;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export class LoopbackTimeoutError extends Error {
|
|
34
|
-
constructor(
|
|
35
|
-
public readonly path: string,
|
|
36
|
-
public readonly timeoutMs: number,
|
|
37
|
-
) {
|
|
38
|
-
super(`Loopback call to ${path} timed out after ${timeoutMs}ms`);
|
|
39
|
-
this.name = "LoopbackTimeoutError";
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Make an HTTP request to one of the inspector's own /api/* endpoints
|
|
45
|
-
* via 127.0.0.1 loopback. The returned Response is a standard Web
|
|
46
|
-
* Response; callers decide whether to call .json(), .text(), .arrayBuffer().
|
|
47
|
-
*
|
|
48
|
-
* `path` MUST start with `/` (e.g. `/api/logs`).
|
|
49
|
-
*/
|
|
50
|
-
export async function callApi(path: string, options: CallApiOptions = {}): Promise<Response> {
|
|
51
|
-
if (!path.startsWith("/")) {
|
|
52
|
-
throw new Error(`callApi: path must start with '/', got: ${path}`);
|
|
53
|
-
}
|
|
54
|
-
const port = getPublicPort();
|
|
55
|
-
const publicBasePath = getPublicBasePath();
|
|
56
|
-
const url = `http://127.0.0.1:${port}${withBasePath(path, publicBasePath)}`;
|
|
57
|
-
|
|
58
|
-
const { timeoutMs = DEFAULT_TIMEOUT_MS, signal: userSignal, ...rest } = options;
|
|
59
|
-
const headers = new Headers(rest.headers);
|
|
60
|
-
headers.set(
|
|
61
|
-
AGENT_INSPECTOR_PUBLIC_BASE_PATH_HEADER,
|
|
62
|
-
publicBasePath.length === 0 ? "/" : publicBasePath,
|
|
63
|
-
);
|
|
64
|
-
headers.set(AGENT_INSPECTOR_PUBLIC_PORT_HEADER, String(port));
|
|
65
|
-
|
|
66
|
-
const controller = new AbortController();
|
|
67
|
-
const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
|
|
68
|
-
|
|
69
|
-
// If caller passed their own signal, chain it.
|
|
70
|
-
if (userSignal !== undefined && userSignal !== null) {
|
|
71
|
-
if (userSignal.aborted) {
|
|
72
|
-
controller.abort();
|
|
73
|
-
} else {
|
|
74
|
-
userSignal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
return await fetch(url, { ...rest, headers, signal: controller.signal });
|
|
80
|
-
} catch (err) {
|
|
81
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
82
|
-
throw new LoopbackTimeoutError(path, timeoutMs);
|
|
83
|
-
}
|
|
84
|
-
throw err;
|
|
85
|
-
} finally {
|
|
86
|
-
clearTimeout(timeoutHandle);
|
|
87
|
-
}
|
|
88
|
-
}
|