@tonyclaw/agent-inspector 3.1.32 → 4.0.2
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 +241 -120
- package/.output/server/_ssr/index.mjs +1 -1
- package/.output/server/_ssr/{router-oXUk3MBR.mjs → router-BBY_zWRK.mjs} +91 -3
- package/.output/server/index.mjs +1 -1
- package/.output/ui/assets/{CompareDrawer-BtfPSpkV.js → CompareDrawer-rtNElN-B.js} +1 -1
- package/.output/ui/assets/{InspectorPet-D9DPPQ3n.js → InspectorPet-QaAiuF3d.js} +1 -1
- package/.output/ui/assets/{ProxyViewerContainer-Buu8vkCK.js → ProxyViewerContainer-6twNZHwl.js} +4 -4
- package/.output/ui/assets/{ReplayDialog-BER-QzpD.js → ReplayDialog-B7KlziO2.js} +1 -1
- package/.output/ui/assets/{RequestAnatomy-C8Zwxrr7.js → RequestAnatomy-2XVFBrW4.js} +1 -1
- package/.output/ui/assets/{ResponseView-DDpKdYk6.js → ResponseView-BULgzLVB.js} +1 -1
- package/.output/ui/assets/{StreamingChunkSequence-sMPGG7Sw.js → StreamingChunkSequence-DSkvkbns.js} +1 -1
- package/.output/ui/assets/{_sessionId-e4IheHnP.js → _sessionId-D2dmJi3G.js} +1 -1
- package/.output/ui/assets/{_sessionId-C5Uv72Fx.js → _sessionId-DcS0s1Mr.js} +1 -1
- package/.output/ui/assets/{index-B__qT0Yd.js → index-B0TN1KKO.js} +2 -2
- package/.output/ui/assets/{index-Be3bTCzi.js → index-Bva1zHEs.js} +1 -1
- package/.output/ui/assets/{index-C9q__p8J.js → index-BzBExOxu.js} +1 -1
- package/.output/ui/assets/{index-CtB0deSZ.js → index-k6sRQz55.js} +1 -1
- package/.output/ui/assets/{json-viewer-Db0AFp-7.js → json-viewer-CWM4tY-j.js} +1 -1
- package/.output/ui/assets/{jszip.min-DkY0Ym_q.js → jszip.min-BkWvRFlo.js} +1 -1
- package/.output/ui/index.html +1 -1
- package/package.json +8 -13
- 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 -1397
- 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 -253
- 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
package/src/cli/instanceApi.ts
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { type z } from "zod";
|
|
2
|
-
import {
|
|
3
|
-
getNamedInstance,
|
|
4
|
-
getNamedInstanceConnection,
|
|
5
|
-
type InstanceLifecycleError,
|
|
6
|
-
type InstanceLifecycleResult,
|
|
7
|
-
listNamedInstances,
|
|
8
|
-
restartNamedInstance,
|
|
9
|
-
startNamedInstance,
|
|
10
|
-
stopNamedInstance,
|
|
11
|
-
} from "./instance";
|
|
12
|
-
import {
|
|
13
|
-
type InstancePublicErrorCode,
|
|
14
|
-
INSTANCE_API_SCHEMA_VERSION,
|
|
15
|
-
InstanceEmptyRequestSchema,
|
|
16
|
-
InstanceStartRequestSchema,
|
|
17
|
-
instanceErrorOutput,
|
|
18
|
-
} from "../lib/instanceContract";
|
|
19
|
-
import { readManagedInstanceLaunch } from "../lib/managedInstance";
|
|
20
|
-
|
|
21
|
-
const NO_STORE_HEADERS = { "cache-control": "no-store" };
|
|
22
|
-
|
|
23
|
-
type ParsedBody<T> = { ok: true; value: T } | { ok: false; response: Response };
|
|
24
|
-
|
|
25
|
-
function errorStatus(code: InstancePublicErrorCode): number {
|
|
26
|
-
switch (code) {
|
|
27
|
-
case "argument_invalid":
|
|
28
|
-
case "data_dir_invalid":
|
|
29
|
-
case "name_invalid":
|
|
30
|
-
case "port_invalid":
|
|
31
|
-
case "record_invalid":
|
|
32
|
-
return 400;
|
|
33
|
-
case "instance_not_found":
|
|
34
|
-
return 404;
|
|
35
|
-
case "config_mismatch":
|
|
36
|
-
case "data_dir_conflict":
|
|
37
|
-
case "identity_mismatch":
|
|
38
|
-
case "port_conflict":
|
|
39
|
-
case "self_lifecycle_unsupported":
|
|
40
|
-
return 409;
|
|
41
|
-
case "lock_not_owned":
|
|
42
|
-
case "lock_timeout":
|
|
43
|
-
return 423;
|
|
44
|
-
case "launch_failed":
|
|
45
|
-
case "launch_unavailable":
|
|
46
|
-
case "port_exhausted":
|
|
47
|
-
case "registry_io":
|
|
48
|
-
case "restart_failed_degraded":
|
|
49
|
-
case "restart_failed_rolled_back":
|
|
50
|
-
case "shutdown_failed":
|
|
51
|
-
return 503;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function instanceErrorResponse(error: InstanceLifecycleError): Response {
|
|
56
|
-
return Response.json(instanceErrorOutput(error), {
|
|
57
|
-
status: errorStatus(error.code),
|
|
58
|
-
headers: NO_STORE_HEADERS,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function instanceResultResponse<T>(
|
|
63
|
-
result: InstanceLifecycleResult<T>,
|
|
64
|
-
successStatus = 200,
|
|
65
|
-
): Response {
|
|
66
|
-
return result.kind === "error"
|
|
67
|
-
? instanceErrorResponse(result.error)
|
|
68
|
-
: Response.json(result.value, { status: successStatus, headers: NO_STORE_HEADERS });
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export async function parseInstanceBody<T extends z.ZodType>(
|
|
72
|
-
request: Request,
|
|
73
|
-
schema: T,
|
|
74
|
-
): Promise<ParsedBody<z.output<T>>> {
|
|
75
|
-
let value: unknown;
|
|
76
|
-
try {
|
|
77
|
-
const text = await request.text();
|
|
78
|
-
value = text.trim().length === 0 ? {} : JSON.parse(text);
|
|
79
|
-
} catch {
|
|
80
|
-
return {
|
|
81
|
-
ok: false,
|
|
82
|
-
response: instanceErrorResponse({
|
|
83
|
-
code: "argument_invalid",
|
|
84
|
-
message: "Request body must be valid JSON.",
|
|
85
|
-
retryable: false,
|
|
86
|
-
}),
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
const parsed = schema.safeParse(value);
|
|
90
|
-
if (!parsed.success) {
|
|
91
|
-
return {
|
|
92
|
-
ok: false,
|
|
93
|
-
response: instanceErrorResponse({
|
|
94
|
-
code: "argument_invalid",
|
|
95
|
-
message: `Invalid instance request: ${parsed.error.issues[0]?.message ?? "invalid body"}`,
|
|
96
|
-
retryable: false,
|
|
97
|
-
}),
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
return { ok: true, value: parsed.data };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function selfLifecycleError(rawName: string): InstanceLifecycleError | null {
|
|
104
|
-
const current = readManagedInstanceLaunch(process.env);
|
|
105
|
-
return current.kind === "managed" && current.launch.name.toLowerCase() === rawName.toLowerCase()
|
|
106
|
-
? {
|
|
107
|
-
code: "self_lifecycle_unsupported",
|
|
108
|
-
message:
|
|
109
|
-
"A managed runtime cannot stop or restart itself through its own REST/MCP transport; use the CLI or a different controller instance.",
|
|
110
|
-
retryable: false,
|
|
111
|
-
}
|
|
112
|
-
: null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function instanceListResponse(instances: readonly unknown[]): Response {
|
|
116
|
-
return Response.json(
|
|
117
|
-
{ schemaVersion: INSTANCE_API_SCHEMA_VERSION, instances },
|
|
118
|
-
{ headers: NO_STORE_HEADERS },
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function methodNotAllowed(allow: string): Response {
|
|
123
|
-
return Response.json(
|
|
124
|
-
{ error: "Method not allowed" },
|
|
125
|
-
{ status: 405, headers: { ...NO_STORE_HEADERS, allow } },
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function endpointNotFound(): Response {
|
|
130
|
-
return Response.json(
|
|
131
|
-
{ error: "Instance endpoint not found" },
|
|
132
|
-
{ status: 404, headers: NO_STORE_HEADERS },
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function decodedName(value: string): string | null {
|
|
137
|
-
try {
|
|
138
|
-
return decodeURIComponent(value);
|
|
139
|
-
} catch {
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Framework-neutral named-instance API owned by the Node supervisor plane.
|
|
146
|
-
*
|
|
147
|
-
* The protected ingress uses this when a Rust backend is selected, keeping process lifecycle and
|
|
148
|
-
* OS-specific background behavior in the existing CLI instead of reimplementing it in Rust.
|
|
149
|
-
*/
|
|
150
|
-
export async function handleNamedInstanceApi(request: Request): Promise<Response> {
|
|
151
|
-
const url = new URL(request.url);
|
|
152
|
-
const segments = url.pathname.split("/").filter((segment) => segment.length > 0);
|
|
153
|
-
if (segments.length === 2 && segments[0] === "api" && segments[1] === "instances") {
|
|
154
|
-
if (request.method !== "GET") return methodNotAllowed("GET");
|
|
155
|
-
const result = await listNamedInstances();
|
|
156
|
-
return result.kind === "error"
|
|
157
|
-
? instanceResultResponse(result)
|
|
158
|
-
: instanceListResponse(result.value);
|
|
159
|
-
}
|
|
160
|
-
if (segments.length < 3 || segments[0] !== "api" || segments[1] !== "instances") {
|
|
161
|
-
return endpointNotFound();
|
|
162
|
-
}
|
|
163
|
-
const name = decodedName(segments[2] ?? "");
|
|
164
|
-
if (name === null) {
|
|
165
|
-
return instanceErrorResponse({
|
|
166
|
-
code: "name_invalid",
|
|
167
|
-
message: "Instance name is not valid URL encoding.",
|
|
168
|
-
retryable: false,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
if (segments.length === 3) {
|
|
172
|
-
return request.method === "GET"
|
|
173
|
-
? instanceResultResponse(await getNamedInstance(name))
|
|
174
|
-
: methodNotAllowed("GET");
|
|
175
|
-
}
|
|
176
|
-
if (segments.length !== 4) return endpointNotFound();
|
|
177
|
-
const action = segments[3];
|
|
178
|
-
if (action === undefined) return endpointNotFound();
|
|
179
|
-
switch (action) {
|
|
180
|
-
case "connection":
|
|
181
|
-
return request.method === "GET"
|
|
182
|
-
? instanceResultResponse(await getNamedInstanceConnection(name))
|
|
183
|
-
: methodNotAllowed("GET");
|
|
184
|
-
case "start": {
|
|
185
|
-
if (request.method !== "POST") return methodNotAllowed("POST");
|
|
186
|
-
const body = await parseInstanceBody(request, InstanceStartRequestSchema);
|
|
187
|
-
if (!body.ok) return body.response;
|
|
188
|
-
const result = await startNamedInstance(name, body.value);
|
|
189
|
-
const status = result.kind === "success" && result.value.outcome === "created" ? 201 : 200;
|
|
190
|
-
return instanceResultResponse(result, status);
|
|
191
|
-
}
|
|
192
|
-
case "stop": {
|
|
193
|
-
if (request.method !== "POST") return methodNotAllowed("POST");
|
|
194
|
-
const body = await parseInstanceBody(request, InstanceEmptyRequestSchema);
|
|
195
|
-
if (!body.ok) return body.response;
|
|
196
|
-
const selfError = selfLifecycleError(name);
|
|
197
|
-
return selfError === null
|
|
198
|
-
? instanceResultResponse(await stopNamedInstance(name))
|
|
199
|
-
: instanceErrorResponse(selfError);
|
|
200
|
-
}
|
|
201
|
-
case "restart": {
|
|
202
|
-
if (request.method !== "POST") return methodNotAllowed("POST");
|
|
203
|
-
const body = await parseInstanceBody(request, InstanceStartRequestSchema);
|
|
204
|
-
if (!body.ok) return body.response;
|
|
205
|
-
const selfError = selfLifecycleError(name);
|
|
206
|
-
return selfError === null
|
|
207
|
-
? instanceResultResponse(await restartNamedInstance(name, body.value))
|
|
208
|
-
: instanceErrorResponse(selfError);
|
|
209
|
-
}
|
|
210
|
-
default:
|
|
211
|
-
return endpointNotFound();
|
|
212
|
-
}
|
|
213
|
-
}
|
package/src/cli/instanceArgs.ts
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
import { normalizePublicBasePath } from "../lib/basePath";
|
|
2
|
-
import {
|
|
3
|
-
BackendImplementationSchema,
|
|
4
|
-
type BackendImplementation,
|
|
5
|
-
} from "../lib/backendImplementation";
|
|
6
|
-
import { isValidBindHost } from "./networkHints";
|
|
7
|
-
|
|
8
|
-
export type InstanceCaptureMode = "simple" | "full";
|
|
9
|
-
|
|
10
|
-
export type InstanceStartOverrides = {
|
|
11
|
-
backend: BackendImplementation | null;
|
|
12
|
-
port: number | null;
|
|
13
|
-
basePath: string | null;
|
|
14
|
-
host: string | null;
|
|
15
|
-
captureMode: InstanceCaptureMode | null;
|
|
16
|
-
dataDir: string | null;
|
|
17
|
-
uiEnabled: boolean | null;
|
|
18
|
-
open: boolean;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type InstanceAction =
|
|
22
|
-
| { kind: "start"; name: string; overrides: InstanceStartOverrides; json: boolean }
|
|
23
|
-
| { kind: "list"; json: boolean }
|
|
24
|
-
| { kind: "status"; name: string; json: boolean }
|
|
25
|
-
| { kind: "connect"; name: string; json: boolean }
|
|
26
|
-
| { kind: "stop"; name: string; json: boolean }
|
|
27
|
-
| { kind: "restart"; name: string; overrides: InstanceStartOverrides; json: boolean };
|
|
28
|
-
|
|
29
|
-
export type InstanceArgsResult =
|
|
30
|
-
| { kind: "help" }
|
|
31
|
-
| { kind: "error"; message: string }
|
|
32
|
-
| { kind: "ok"; action: InstanceAction };
|
|
33
|
-
|
|
34
|
-
function parsePort(value: string | undefined): number | null {
|
|
35
|
-
if (value === undefined || value.trim().length === 0) return null;
|
|
36
|
-
const parsed = Number(value);
|
|
37
|
-
return Number.isInteger(parsed) && parsed >= 1 && parsed <= 65_535 ? parsed : null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function parseMode(value: string | undefined): InstanceCaptureMode | null {
|
|
41
|
-
return value === "simple" || value === "full" ? value : null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function parseBasePath(value: string | undefined): string | null {
|
|
45
|
-
if (value === undefined) return null;
|
|
46
|
-
return normalizePublicBasePath(value);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function optionWithEquals(arg: string): { name: string; value: string } | null {
|
|
50
|
-
if (!arg.startsWith("--") || !arg.includes("=")) return null;
|
|
51
|
-
const separator = arg.indexOf("=");
|
|
52
|
-
return { name: arg.slice(0, separator), value: arg.slice(separator + 1) };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function emptyOverrides(): InstanceStartOverrides {
|
|
56
|
-
return {
|
|
57
|
-
backend: null,
|
|
58
|
-
port: null,
|
|
59
|
-
basePath: null,
|
|
60
|
-
host: null,
|
|
61
|
-
captureMode: null,
|
|
62
|
-
dataDir: null,
|
|
63
|
-
uiEnabled: null,
|
|
64
|
-
open: false,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type MutableOptions = {
|
|
69
|
-
json: boolean;
|
|
70
|
-
help: boolean;
|
|
71
|
-
overrides: InstanceStartOverrides;
|
|
72
|
-
positional: string[];
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
function setValueOption(
|
|
76
|
-
options: MutableOptions,
|
|
77
|
-
name: string,
|
|
78
|
-
value: string | undefined,
|
|
79
|
-
): string | null {
|
|
80
|
-
switch (name) {
|
|
81
|
-
case "--backend": {
|
|
82
|
-
const backend = BackendImplementationSchema.safeParse(value?.trim().toLowerCase());
|
|
83
|
-
if (!backend.success) return "instance: --backend must be typescript or rust";
|
|
84
|
-
options.overrides.backend = backend.data;
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
case "--port":
|
|
88
|
-
case "-p": {
|
|
89
|
-
const port = parsePort(value);
|
|
90
|
-
if (port === null) return "instance: --port must be an integer from 1 to 65535";
|
|
91
|
-
options.overrides.port = port;
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
case "--base-path": {
|
|
95
|
-
const basePath = parseBasePath(value);
|
|
96
|
-
if (basePath === null) {
|
|
97
|
-
return "instance: --base-path must be an absolute URL path without a query or hash";
|
|
98
|
-
}
|
|
99
|
-
options.overrides.basePath = basePath;
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
case "--host":
|
|
103
|
-
case "-H": {
|
|
104
|
-
const host = value?.trim() ?? "";
|
|
105
|
-
if (!isValidBindHost(host)) {
|
|
106
|
-
return "instance: --host requires a hostname or IP address without a protocol or path";
|
|
107
|
-
}
|
|
108
|
-
options.overrides.host = host;
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
case "--mode":
|
|
112
|
-
case "--capture-mode": {
|
|
113
|
-
const captureMode = parseMode(value);
|
|
114
|
-
if (captureMode === null) return "instance: --mode must be simple or full";
|
|
115
|
-
options.overrides.captureMode = captureMode;
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
case "--data-dir": {
|
|
119
|
-
const dataDir = value?.trim() ?? "";
|
|
120
|
-
if (dataDir.length === 0) return "instance: --data-dir requires a directory path";
|
|
121
|
-
options.overrides.dataDir = dataDir;
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
default:
|
|
125
|
-
return `instance: unknown option ${name}`;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export function parseInstanceArgs(argv: readonly string[]): InstanceArgsResult {
|
|
130
|
-
const options: MutableOptions = {
|
|
131
|
-
json: false,
|
|
132
|
-
help: false,
|
|
133
|
-
overrides: emptyOverrides(),
|
|
134
|
-
positional: [],
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
for (let index = 0; index < argv.length; index++) {
|
|
138
|
-
const arg = argv[index];
|
|
139
|
-
if (arg === undefined) continue;
|
|
140
|
-
const equalsOption = optionWithEquals(arg);
|
|
141
|
-
if (equalsOption !== null) {
|
|
142
|
-
const error = setValueOption(options, equalsOption.name, equalsOption.value);
|
|
143
|
-
if (error !== null) return { kind: "error", message: error };
|
|
144
|
-
continue;
|
|
145
|
-
}
|
|
146
|
-
switch (arg) {
|
|
147
|
-
case "--help":
|
|
148
|
-
case "-h":
|
|
149
|
-
options.help = true;
|
|
150
|
-
break;
|
|
151
|
-
case "--json":
|
|
152
|
-
options.json = true;
|
|
153
|
-
break;
|
|
154
|
-
case "--open":
|
|
155
|
-
options.overrides.open = true;
|
|
156
|
-
break;
|
|
157
|
-
case "--backend-only":
|
|
158
|
-
if (options.overrides.uiEnabled === true) {
|
|
159
|
-
return {
|
|
160
|
-
kind: "error",
|
|
161
|
-
message: "instance: --backend-only and --with-ui are mutually exclusive",
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
options.overrides.uiEnabled = false;
|
|
165
|
-
break;
|
|
166
|
-
case "--with-ui":
|
|
167
|
-
if (options.overrides.uiEnabled === false) {
|
|
168
|
-
return {
|
|
169
|
-
kind: "error",
|
|
170
|
-
message: "instance: --backend-only and --with-ui are mutually exclusive",
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
options.overrides.uiEnabled = true;
|
|
174
|
-
break;
|
|
175
|
-
case "--port":
|
|
176
|
-
case "-p":
|
|
177
|
-
case "--backend":
|
|
178
|
-
case "--base-path":
|
|
179
|
-
case "--host":
|
|
180
|
-
case "-H":
|
|
181
|
-
case "--mode":
|
|
182
|
-
case "--capture-mode":
|
|
183
|
-
case "--data-dir": {
|
|
184
|
-
const error = setValueOption(options, arg, argv[index + 1]);
|
|
185
|
-
if (error !== null) return { kind: "error", message: error };
|
|
186
|
-
index++;
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
default:
|
|
190
|
-
if (arg.startsWith("-")) {
|
|
191
|
-
return { kind: "error", message: `instance: unknown option ${arg}` };
|
|
192
|
-
}
|
|
193
|
-
options.positional.push(arg);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (options.help) return { kind: "help" };
|
|
198
|
-
const command = options.positional[0];
|
|
199
|
-
if (command === "list") {
|
|
200
|
-
if (options.positional.length !== 1) {
|
|
201
|
-
return { kind: "error", message: "instance: list does not accept an instance name" };
|
|
202
|
-
}
|
|
203
|
-
if (
|
|
204
|
-
options.overrides.backend !== null ||
|
|
205
|
-
options.overrides.port !== null ||
|
|
206
|
-
options.overrides.basePath !== null ||
|
|
207
|
-
options.overrides.host !== null ||
|
|
208
|
-
options.overrides.captureMode !== null ||
|
|
209
|
-
options.overrides.dataDir !== null ||
|
|
210
|
-
options.overrides.uiEnabled !== null ||
|
|
211
|
-
options.overrides.open
|
|
212
|
-
) {
|
|
213
|
-
return { kind: "error", message: "instance: list accepts only --json" };
|
|
214
|
-
}
|
|
215
|
-
return { kind: "ok", action: { kind: "list", json: options.json } };
|
|
216
|
-
}
|
|
217
|
-
if (
|
|
218
|
-
command === "status" ||
|
|
219
|
-
command === "stop" ||
|
|
220
|
-
command === "connect" ||
|
|
221
|
-
command === "connection"
|
|
222
|
-
) {
|
|
223
|
-
const name = options.positional[1];
|
|
224
|
-
if (name === undefined || options.positional.length !== 2) {
|
|
225
|
-
return { kind: "error", message: `instance: ${command} requires exactly one instance name` };
|
|
226
|
-
}
|
|
227
|
-
if (
|
|
228
|
-
options.overrides.backend !== null ||
|
|
229
|
-
options.overrides.port !== null ||
|
|
230
|
-
options.overrides.basePath !== null ||
|
|
231
|
-
options.overrides.host !== null ||
|
|
232
|
-
options.overrides.captureMode !== null ||
|
|
233
|
-
options.overrides.dataDir !== null ||
|
|
234
|
-
options.overrides.uiEnabled !== null ||
|
|
235
|
-
options.overrides.open
|
|
236
|
-
) {
|
|
237
|
-
return {
|
|
238
|
-
kind: "error",
|
|
239
|
-
message: `instance: ${command} accepts only an instance name and --json`,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
return {
|
|
243
|
-
kind: "ok",
|
|
244
|
-
action: { kind: command === "connection" ? "connect" : command, name, json: options.json },
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
if (command === "start" || command === "restart") {
|
|
248
|
-
const name = options.positional[1];
|
|
249
|
-
if (name === undefined || options.positional.length !== 2) {
|
|
250
|
-
return { kind: "error", message: `instance: ${command} requires exactly one instance name` };
|
|
251
|
-
}
|
|
252
|
-
if (options.overrides.uiEnabled === false && options.overrides.open) {
|
|
253
|
-
return { kind: "error", message: "instance: --open cannot be used with --backend-only" };
|
|
254
|
-
}
|
|
255
|
-
return {
|
|
256
|
-
kind: "ok",
|
|
257
|
-
action: { kind: command, name, overrides: options.overrides, json: options.json },
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
if (command === undefined) {
|
|
261
|
-
return {
|
|
262
|
-
kind: "error",
|
|
263
|
-
message: "instance: expected start, list, status, connect, stop, or restart",
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
return { kind: "error", message: `instance: unknown command ${command}` };
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export function instanceHelp(): string {
|
|
270
|
-
return `agent-inspector instance - manage isolated named runtimes
|
|
271
|
-
|
|
272
|
-
Usage:
|
|
273
|
-
agent-inspector instance start <name> [options]
|
|
274
|
-
agent-inspector instance list [--json]
|
|
275
|
-
agent-inspector instance status <name> [--json]
|
|
276
|
-
agent-inspector instance connect <name> [--json]
|
|
277
|
-
agent-inspector instance stop <name> [--json]
|
|
278
|
-
agent-inspector instance restart <name> [options]
|
|
279
|
-
|
|
280
|
-
Start/restart options:
|
|
281
|
-
--backend <typescript|rust> Persist the backend implementation (default: rust when native package is available)
|
|
282
|
-
--port, -p <port> Public ingress port (auto-allocated on first start)
|
|
283
|
-
--base-path <path> Public Base Path (default: /inspector; use / for root)
|
|
284
|
-
--host, -H <host> Bind host (default: 127.0.0.1)
|
|
285
|
-
--mode <simple|full> Capture mode (default: simple)
|
|
286
|
-
--data-dir <path> Isolated data/config directory
|
|
287
|
-
--backend-only Persist a headless backend without serving the UI
|
|
288
|
-
--with-ui Persist composed UI serving (the default for new instances)
|
|
289
|
-
--open Open the UI after readiness
|
|
290
|
-
--json Emit machine-readable output
|
|
291
|
-
--help, -h Show this help
|
|
292
|
-
|
|
293
|
-
Named instances run as hidden background supervisors and persist their configuration. Each one
|
|
294
|
-
uses separate Provider, config, capture, and index storage. The existing \`agent-inspector\` command
|
|
295
|
-
remains the unmanaged default instance. Base Path aliases mount another URL on one runtime; named
|
|
296
|
-
instances start separate runtimes.
|
|
297
|
-
|
|
298
|
-
The connect command prints protocol-correct Anthropic, OpenAI /v1, MCP, health, and UI settings
|
|
299
|
-
without exposing lifecycle or Provider credentials. \`connection\` is accepted as an alias.
|
|
300
|
-
`;
|
|
301
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MANAGED_INSTANCE_CONTROL_PATH,
|
|
3
|
-
MANAGED_INSTANCE_SHUTDOWN_PATH,
|
|
4
|
-
MANAGED_INSTANCE_TOKEN_HEADER,
|
|
5
|
-
} from "../lib/managedInstance";
|
|
6
|
-
import {
|
|
7
|
-
BackendImplementationSchema,
|
|
8
|
-
type BackendImplementation,
|
|
9
|
-
} from "../lib/backendImplementation";
|
|
10
|
-
|
|
11
|
-
const DEFAULT_CONTROL_TIMEOUT_MS = 2_000;
|
|
12
|
-
|
|
13
|
-
export type InstanceControlFetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
14
|
-
|
|
15
|
-
export type ExpectedInstanceControlIdentity = {
|
|
16
|
-
backend?: BackendImplementation;
|
|
17
|
-
instanceId: string;
|
|
18
|
-
launchId: string;
|
|
19
|
-
controlToken: string;
|
|
20
|
-
host: string;
|
|
21
|
-
publicPort: number;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type InstanceControlIdentity = {
|
|
25
|
-
schemaVersion: 1;
|
|
26
|
-
backend: BackendImplementation;
|
|
27
|
-
instanceId: string;
|
|
28
|
-
launchId: string;
|
|
29
|
-
supervisorPid: number;
|
|
30
|
-
startedAt: string;
|
|
31
|
-
publicPort: number;
|
|
32
|
-
upstreamPort: number;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export type InstanceControlProbe =
|
|
36
|
-
| { kind: "running"; identity: InstanceControlIdentity }
|
|
37
|
-
| { kind: "unreachable"; timedOut: boolean }
|
|
38
|
-
| { kind: "identity-mismatch" }
|
|
39
|
-
| { kind: "invalid-response" };
|
|
40
|
-
|
|
41
|
-
export type InstanceShutdownResult =
|
|
42
|
-
| { kind: "accepted" }
|
|
43
|
-
| { kind: "unreachable"; timedOut: boolean }
|
|
44
|
-
| { kind: "identity-mismatch" }
|
|
45
|
-
| { kind: "rejected" };
|
|
46
|
-
|
|
47
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
48
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function parseIdentity(value: unknown): InstanceControlIdentity | null {
|
|
52
|
-
if (!isRecord(value)) return null;
|
|
53
|
-
const schemaVersion = value["schemaVersion"];
|
|
54
|
-
const backend = BackendImplementationSchema.safeParse(value["backend"] ?? "typescript");
|
|
55
|
-
const instanceId = value["instanceId"];
|
|
56
|
-
const launchId = value["launchId"];
|
|
57
|
-
const supervisorPid = value["supervisorPid"];
|
|
58
|
-
const startedAt = value["startedAt"];
|
|
59
|
-
const publicPort = value["publicPort"];
|
|
60
|
-
const upstreamPort = value["upstreamPort"];
|
|
61
|
-
if (
|
|
62
|
-
schemaVersion !== 1 ||
|
|
63
|
-
!backend.success ||
|
|
64
|
-
typeof instanceId !== "string" ||
|
|
65
|
-
instanceId.length === 0 ||
|
|
66
|
-
typeof launchId !== "string" ||
|
|
67
|
-
launchId.length === 0 ||
|
|
68
|
-
typeof supervisorPid !== "number" ||
|
|
69
|
-
!Number.isInteger(supervisorPid) ||
|
|
70
|
-
supervisorPid < 1 ||
|
|
71
|
-
typeof startedAt !== "string" ||
|
|
72
|
-
!Number.isFinite(Date.parse(startedAt)) ||
|
|
73
|
-
typeof publicPort !== "number" ||
|
|
74
|
-
!Number.isInteger(publicPort) ||
|
|
75
|
-
publicPort < 1 ||
|
|
76
|
-
publicPort > 65_535 ||
|
|
77
|
-
typeof upstreamPort !== "number" ||
|
|
78
|
-
!Number.isInteger(upstreamPort) ||
|
|
79
|
-
upstreamPort < 1 ||
|
|
80
|
-
upstreamPort > 65_535
|
|
81
|
-
) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
schemaVersion: 1,
|
|
86
|
-
backend: backend.data,
|
|
87
|
-
instanceId,
|
|
88
|
-
launchId,
|
|
89
|
-
supervisorPid,
|
|
90
|
-
startedAt,
|
|
91
|
-
publicPort,
|
|
92
|
-
upstreamPort,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function hostForUrl(host: string): string {
|
|
97
|
-
if (host.startsWith("[") && host.endsWith("]")) return host;
|
|
98
|
-
return host.includes(":") ? `[${host}]` : host;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function endpoint(identity: ExpectedInstanceControlIdentity, path: string): string {
|
|
102
|
-
return `http://${hostForUrl(identity.host)}:${String(identity.publicPort)}${path}`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function requestInit(
|
|
106
|
-
identity: ExpectedInstanceControlIdentity,
|
|
107
|
-
controller: AbortController,
|
|
108
|
-
method: "GET" | "POST",
|
|
109
|
-
): RequestInit {
|
|
110
|
-
return {
|
|
111
|
-
method,
|
|
112
|
-
headers: {
|
|
113
|
-
accept: "application/json",
|
|
114
|
-
[MANAGED_INSTANCE_TOKEN_HEADER]: identity.controlToken,
|
|
115
|
-
},
|
|
116
|
-
cache: "no-store",
|
|
117
|
-
signal: controller.signal,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async function responseJson(response: Response): Promise<unknown | null> {
|
|
122
|
-
try {
|
|
123
|
-
const value: unknown = await response.json();
|
|
124
|
-
return value;
|
|
125
|
-
} catch {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export async function probeInstanceControl(
|
|
131
|
-
expected: ExpectedInstanceControlIdentity,
|
|
132
|
-
fetchImpl: InstanceControlFetch = fetch,
|
|
133
|
-
timeoutMs = DEFAULT_CONTROL_TIMEOUT_MS,
|
|
134
|
-
): Promise<InstanceControlProbe> {
|
|
135
|
-
const controller = new AbortController();
|
|
136
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
137
|
-
try {
|
|
138
|
-
const response = await fetchImpl(
|
|
139
|
-
endpoint(expected, MANAGED_INSTANCE_CONTROL_PATH),
|
|
140
|
-
requestInit(expected, controller, "GET"),
|
|
141
|
-
);
|
|
142
|
-
if (!response.ok) return { kind: "identity-mismatch" };
|
|
143
|
-
const identity = parseIdentity(await responseJson(response));
|
|
144
|
-
if (identity === null) return { kind: "invalid-response" };
|
|
145
|
-
if (
|
|
146
|
-
identity.instanceId !== expected.instanceId ||
|
|
147
|
-
identity.launchId !== expected.launchId ||
|
|
148
|
-
identity.backend !== (expected.backend ?? "typescript") ||
|
|
149
|
-
identity.publicPort !== expected.publicPort
|
|
150
|
-
) {
|
|
151
|
-
return { kind: "identity-mismatch" };
|
|
152
|
-
}
|
|
153
|
-
return { kind: "running", identity };
|
|
154
|
-
} catch (error) {
|
|
155
|
-
return {
|
|
156
|
-
kind: "unreachable",
|
|
157
|
-
timedOut:
|
|
158
|
-
controller.signal.aborted || (error instanceof Error && error.name === "AbortError"),
|
|
159
|
-
};
|
|
160
|
-
} finally {
|
|
161
|
-
clearTimeout(timeout);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export async function requestInstanceShutdown(
|
|
166
|
-
expected: ExpectedInstanceControlIdentity,
|
|
167
|
-
fetchImpl: InstanceControlFetch = fetch,
|
|
168
|
-
timeoutMs = DEFAULT_CONTROL_TIMEOUT_MS,
|
|
169
|
-
): Promise<InstanceShutdownResult> {
|
|
170
|
-
const controller = new AbortController();
|
|
171
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
172
|
-
try {
|
|
173
|
-
const response = await fetchImpl(
|
|
174
|
-
endpoint(expected, MANAGED_INSTANCE_SHUTDOWN_PATH),
|
|
175
|
-
requestInit(expected, controller, "POST"),
|
|
176
|
-
);
|
|
177
|
-
if (response.status === 202) return { kind: "accepted" };
|
|
178
|
-
if (response.status === 401 || response.status === 403 || response.status === 404) {
|
|
179
|
-
return { kind: "identity-mismatch" };
|
|
180
|
-
}
|
|
181
|
-
return { kind: "rejected" };
|
|
182
|
-
} catch (error) {
|
|
183
|
-
return {
|
|
184
|
-
kind: "unreachable",
|
|
185
|
-
timedOut:
|
|
186
|
-
controller.signal.aborted || (error instanceof Error && error.name === "AbortError"),
|
|
187
|
-
};
|
|
188
|
-
} finally {
|
|
189
|
-
clearTimeout(timeout);
|
|
190
|
-
}
|
|
191
|
-
}
|