@xenosystem/agent-interface-host 0.1.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/LICENSE +67 -0
- package/dist/acp/AcpAgentRegistryService.d.ts +77 -0
- package/dist/acp/AcpAgentRegistryService.d.ts.map +1 -0
- package/dist/acp/AcpAgentRegistryService.js +754 -0
- package/dist/acp/AcpAgentRegistryService.js.map +1 -0
- package/dist/acp/AcpAgentTurnExecutionAdapter.d.ts +56 -0
- package/dist/acp/AcpAgentTurnExecutionAdapter.d.ts.map +1 -0
- package/dist/acp/AcpAgentTurnExecutionAdapter.js +323 -0
- package/dist/acp/AcpAgentTurnExecutionAdapter.js.map +1 -0
- package/dist/acp/AcpApprovalPortAdapter.d.ts +41 -0
- package/dist/acp/AcpApprovalPortAdapter.d.ts.map +1 -0
- package/dist/acp/AcpApprovalPortAdapter.js +82 -0
- package/dist/acp/AcpApprovalPortAdapter.js.map +1 -0
- package/dist/acp/AcpCoordinationBridge.d.ts +13 -0
- package/dist/acp/AcpCoordinationBridge.d.ts.map +1 -0
- package/dist/acp/AcpCoordinationBridge.js +13 -0
- package/dist/acp/AcpCoordinationBridge.js.map +1 -0
- package/dist/acp/AcpDiagnosticsService.d.ts +61 -0
- package/dist/acp/AcpDiagnosticsService.d.ts.map +1 -0
- package/dist/acp/AcpDiagnosticsService.js +203 -0
- package/dist/acp/AcpDiagnosticsService.js.map +1 -0
- package/dist/acp/AcpExternalCertificationHarness.d.ts +47 -0
- package/dist/acp/AcpExternalCertificationHarness.d.ts.map +1 -0
- package/dist/acp/AcpExternalCertificationHarness.js +176 -0
- package/dist/acp/AcpExternalCertificationHarness.js.map +1 -0
- package/dist/acp/AcpHostBridge.d.ts +81 -0
- package/dist/acp/AcpHostBridge.d.ts.map +1 -0
- package/dist/acp/AcpHostBridge.js +101 -0
- package/dist/acp/AcpHostBridge.js.map +1 -0
- package/dist/acp/AcpInteractivePermissionBridge.d.ts +77 -0
- package/dist/acp/AcpInteractivePermissionBridge.d.ts.map +1 -0
- package/dist/acp/AcpInteractivePermissionBridge.js +127 -0
- package/dist/acp/AcpInteractivePermissionBridge.js.map +1 -0
- package/dist/acp/AcpPermissionBridge.d.ts +19 -0
- package/dist/acp/AcpPermissionBridge.d.ts.map +1 -0
- package/dist/acp/AcpPermissionBridge.js +110 -0
- package/dist/acp/AcpPermissionBridge.js.map +1 -0
- package/dist/acp/AcpPermissionPolicy.d.ts +111 -0
- package/dist/acp/AcpPermissionPolicy.d.ts.map +1 -0
- package/dist/acp/AcpPermissionPolicy.js +167 -0
- package/dist/acp/AcpPermissionPolicy.js.map +1 -0
- package/dist/acp/AcpProcessSupervisor.d.ts +134 -0
- package/dist/acp/AcpProcessSupervisor.d.ts.map +1 -0
- package/dist/acp/AcpProcessSupervisor.js +674 -0
- package/dist/acp/AcpProcessSupervisor.js.map +1 -0
- package/dist/acp/AcpProviderApprovalService.d.ts +27 -0
- package/dist/acp/AcpProviderApprovalService.d.ts.map +1 -0
- package/dist/acp/AcpProviderApprovalService.js +128 -0
- package/dist/acp/AcpProviderApprovalService.js.map +1 -0
- package/dist/acp/AcpProviderCatalogService.d.ts +69 -0
- package/dist/acp/AcpProviderCatalogService.d.ts.map +1 -0
- package/dist/acp/AcpProviderCatalogService.js +707 -0
- package/dist/acp/AcpProviderCatalogService.js.map +1 -0
- package/dist/acp/AcpProviderModelService.d.ts +6 -0
- package/dist/acp/AcpProviderModelService.d.ts.map +1 -0
- package/dist/acp/AcpProviderModelService.js +274 -0
- package/dist/acp/AcpProviderModelService.js.map +1 -0
- package/dist/acp/AcpProviderVersionReadiness.d.ts +6 -0
- package/dist/acp/AcpProviderVersionReadiness.d.ts.map +1 -0
- package/dist/acp/AcpProviderVersionReadiness.js +100 -0
- package/dist/acp/AcpProviderVersionReadiness.js.map +1 -0
- package/dist/acp/AcpRuntimeEventMapper.d.ts +16 -0
- package/dist/acp/AcpRuntimeEventMapper.d.ts.map +1 -0
- package/dist/acp/AcpRuntimeEventMapper.js +326 -0
- package/dist/acp/AcpRuntimeEventMapper.js.map +1 -0
- package/dist/acp/AcpSessionService.d.ts +65 -0
- package/dist/acp/AcpSessionService.d.ts.map +1 -0
- package/dist/acp/AcpSessionService.js +931 -0
- package/dist/acp/AcpSessionService.js.map +1 -0
- package/dist/acp/DurableAcpPermissionPolicyStore.d.ts +25 -0
- package/dist/acp/DurableAcpPermissionPolicyStore.d.ts.map +1 -0
- package/dist/acp/DurableAcpPermissionPolicyStore.js +100 -0
- package/dist/acp/DurableAcpPermissionPolicyStore.js.map +1 -0
- package/dist/acp/acpCommandSafety.d.ts +63 -0
- package/dist/acp/acpCommandSafety.d.ts.map +1 -0
- package/dist/acp/acpCommandSafety.js +90 -0
- package/dist/acp/acpCommandSafety.js.map +1 -0
- package/dist/acp/acpErrors.d.ts +47 -0
- package/dist/acp/acpErrors.d.ts.map +1 -0
- package/dist/acp/acpErrors.js +93 -0
- package/dist/acp/acpErrors.js.map +1 -0
- package/dist/acp/acpRedaction.d.ts +9 -0
- package/dist/acp/acpRedaction.d.ts.map +1 -0
- package/dist/acp/acpRedaction.js +69 -0
- package/dist/acp/acpRedaction.js.map +1 -0
- package/dist/acp/acpSessionResume.d.ts +8 -0
- package/dist/acp/acpSessionResume.d.ts.map +1 -0
- package/dist/acp/acpSessionResume.js +31 -0
- package/dist/acp/acpSessionResume.js.map +1 -0
- package/dist/acp/acpTypes.d.ts +467 -0
- package/dist/acp/acpTypes.d.ts.map +1 -0
- package/dist/acp/acpTypes.js +2 -0
- package/dist/acp/acpTypes.js.map +1 -0
- package/dist/agent/chooseDirectoryBridge.d.ts +29 -0
- package/dist/agent/chooseDirectoryBridge.d.ts.map +1 -0
- package/dist/agent/chooseDirectoryBridge.js +116 -0
- package/dist/agent/chooseDirectoryBridge.js.map +1 -0
- package/dist/agent/permissionProfiles.d.ts +29 -0
- package/dist/agent/permissionProfiles.d.ts.map +1 -0
- package/dist/agent/permissionProfiles.js +107 -0
- package/dist/agent/permissionProfiles.js.map +1 -0
- package/dist/agent/runtimeAuthorityPrompt.d.ts +13 -0
- package/dist/agent/runtimeAuthorityPrompt.d.ts.map +1 -0
- package/dist/agent/runtimeAuthorityPrompt.js +45 -0
- package/dist/agent/runtimeAuthorityPrompt.js.map +1 -0
- package/dist/agent/runtimeModeOutputGuard.d.ts +6 -0
- package/dist/agent/runtimeModeOutputGuard.d.ts.map +1 -0
- package/dist/agent/runtimeModeOutputGuard.js +40 -0
- package/dist/agent/runtimeModeOutputGuard.js.map +1 -0
- package/dist/agent/workspacePlacementBridge.d.ts +29 -0
- package/dist/agent/workspacePlacementBridge.d.ts.map +1 -0
- package/dist/agent/workspacePlacementBridge.js +143 -0
- package/dist/agent/workspacePlacementBridge.js.map +1 -0
- package/dist/agentSearch/AgentSearchService.d.ts +81 -0
- package/dist/agentSearch/AgentSearchService.d.ts.map +1 -0
- package/dist/agentSearch/AgentSearchService.js +1038 -0
- package/dist/agentSearch/AgentSearchService.js.map +1 -0
- package/dist/agentSearch/JsonInvertedIndexAdapter.d.ts +44 -0
- package/dist/agentSearch/JsonInvertedIndexAdapter.d.ts.map +1 -0
- package/dist/agentSearch/JsonInvertedIndexAdapter.js +307 -0
- package/dist/agentSearch/JsonInvertedIndexAdapter.js.map +1 -0
- package/dist/agentSearch/SearchIndexAdapter.d.ts +33 -0
- package/dist/agentSearch/SearchIndexAdapter.d.ts.map +1 -0
- package/dist/agentSearch/SearchIndexAdapter.js +2 -0
- package/dist/agentSearch/SearchIndexAdapter.js.map +1 -0
- package/dist/agentSearch/SearchSourceWatcher.d.ts +29 -0
- package/dist/agentSearch/SearchSourceWatcher.d.ts.map +1 -0
- package/dist/agentSearch/SearchSourceWatcher.js +150 -0
- package/dist/agentSearch/SearchSourceWatcher.js.map +1 -0
- package/dist/agentSearch/SqliteFtsIndexAdapter.d.ts +58 -0
- package/dist/agentSearch/SqliteFtsIndexAdapter.d.ts.map +1 -0
- package/dist/agentSearch/SqliteFtsIndexAdapter.js +420 -0
- package/dist/agentSearch/SqliteFtsIndexAdapter.js.map +1 -0
- package/dist/agentSearch/conversationIndexer.d.ts +69 -0
- package/dist/agentSearch/conversationIndexer.d.ts.map +1 -0
- package/dist/agentSearch/conversationIndexer.js +313 -0
- package/dist/agentSearch/conversationIndexer.js.map +1 -0
- package/dist/agentSearch/searchTypes.d.ts +264 -0
- package/dist/agentSearch/searchTypes.d.ts.map +1 -0
- package/dist/agentSearch/searchTypes.js +2 -0
- package/dist/agentSearch/searchTypes.js.map +1 -0
- package/dist/agentSearch/searchUtils.d.ts +12 -0
- package/dist/agentSearch/searchUtils.d.ts.map +1 -0
- package/dist/agentSearch/searchUtils.js +125 -0
- package/dist/agentSearch/searchUtils.js.map +1 -0
- package/dist/agentSearch/workspaceMetadataIndexer.d.ts +3 -0
- package/dist/agentSearch/workspaceMetadataIndexer.d.ts.map +1 -0
- package/dist/agentSearch/workspaceMetadataIndexer.js +125 -0
- package/dist/agentSearch/workspaceMetadataIndexer.js.map +1 -0
- package/dist/cli/CliControlPlaneService.d.ts +269 -0
- package/dist/cli/CliControlPlaneService.d.ts.map +1 -0
- package/dist/cli/CliControlPlaneService.js +1874 -0
- package/dist/cli/CliControlPlaneService.js.map +1 -0
- package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.d.ts +91 -0
- package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.d.ts.map +1 -0
- package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.js +379 -0
- package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.js.map +1 -0
- package/dist/codebase/CodebaseIntelligenceService.d.ts +68 -0
- package/dist/codebase/CodebaseIntelligenceService.d.ts.map +1 -0
- package/dist/codebase/CodebaseIntelligenceService.js +1717 -0
- package/dist/codebase/CodebaseIntelligenceService.js.map +1 -0
- package/dist/codebase/LanguageServerProcessManager.d.ts +85 -0
- package/dist/codebase/LanguageServerProcessManager.d.ts.map +1 -0
- package/dist/codebase/LanguageServerProcessManager.js +607 -0
- package/dist/codebase/LanguageServerProcessManager.js.map +1 -0
- package/dist/codebase/codeTypes.d.ts +485 -0
- package/dist/codebase/codeTypes.d.ts.map +1 -0
- package/dist/codebase/codeTypes.js +2 -0
- package/dist/codebase/codeTypes.js.map +1 -0
- package/dist/codebase/codeUtils.d.ts +24 -0
- package/dist/codebase/codeUtils.d.ts.map +1 -0
- package/dist/codebase/codeUtils.js +177 -0
- package/dist/codebase/codeUtils.js.map +1 -0
- package/dist/codebase/contextPacks.d.ts +18 -0
- package/dist/codebase/contextPacks.d.ts.map +1 -0
- package/dist/codebase/contextPacks.js +180 -0
- package/dist/codebase/contextPacks.js.map +1 -0
- package/dist/codebase/dependencyGraph.d.ts +3 -0
- package/dist/codebase/dependencyGraph.d.ts.map +1 -0
- package/dist/codebase/dependencyGraph.js +209 -0
- package/dist/codebase/dependencyGraph.js.map +1 -0
- package/dist/codebase/fileIndexer.d.ts +27 -0
- package/dist/codebase/fileIndexer.d.ts.map +1 -0
- package/dist/codebase/fileIndexer.js +167 -0
- package/dist/codebase/fileIndexer.js.map +1 -0
- package/dist/codebase/symbolIndexer.d.ts +3 -0
- package/dist/codebase/symbolIndexer.d.ts.map +1 -0
- package/dist/codebase/symbolIndexer.js +184 -0
- package/dist/codebase/symbolIndexer.js.map +1 -0
- package/dist/codebase/whatChanged.d.ts +4 -0
- package/dist/codebase/whatChanged.d.ts.map +1 -0
- package/dist/codebase/whatChanged.js +138 -0
- package/dist/codebase/whatChanged.js.map +1 -0
- package/dist/coordination/CoordinationService.d.ts +166 -0
- package/dist/coordination/CoordinationService.d.ts.map +1 -0
- package/dist/coordination/CoordinationService.js +247 -0
- package/dist/coordination/CoordinationService.js.map +1 -0
- package/dist/coordination/claims.d.ts +122 -0
- package/dist/coordination/claims.d.ts.map +1 -0
- package/dist/coordination/claims.js +196 -0
- package/dist/coordination/claims.js.map +1 -0
- package/dist/coordination/coordinationTools.d.ts +40 -0
- package/dist/coordination/coordinationTools.d.ts.map +1 -0
- package/dist/coordination/coordinationTools.js +92 -0
- package/dist/coordination/coordinationTools.js.map +1 -0
- package/dist/coordination/laneBridge.d.ts +84 -0
- package/dist/coordination/laneBridge.d.ts.map +1 -0
- package/dist/coordination/laneBridge.js +86 -0
- package/dist/coordination/laneBridge.js.map +1 -0
- package/dist/coordination/messages.d.ts +225 -0
- package/dist/coordination/messages.d.ts.map +1 -0
- package/dist/coordination/messages.js +335 -0
- package/dist/coordination/messages.js.map +1 -0
- package/dist/coordination/permissionWaitRegistry.d.ts +32 -0
- package/dist/coordination/permissionWaitRegistry.d.ts.map +1 -0
- package/dist/coordination/permissionWaitRegistry.js +59 -0
- package/dist/coordination/permissionWaitRegistry.js.map +1 -0
- package/dist/coordination/query.d.ts +187 -0
- package/dist/coordination/query.d.ts.map +1 -0
- package/dist/coordination/query.js +138 -0
- package/dist/coordination/query.js.map +1 -0
- package/dist/coordination/renderInbox.d.ts +15 -0
- package/dist/coordination/renderInbox.d.ts.map +1 -0
- package/dist/coordination/renderInbox.js +19 -0
- package/dist/coordination/renderInbox.js.map +1 -0
- package/dist/coordination/runtimeEvents.d.ts +53 -0
- package/dist/coordination/runtimeEvents.d.ts.map +1 -0
- package/dist/coordination/runtimeEvents.js +112 -0
- package/dist/coordination/runtimeEvents.js.map +1 -0
- package/dist/detachedHostService.d.ts +77 -0
- package/dist/detachedHostService.d.ts.map +1 -0
- package/dist/detachedHostService.js +66 -0
- package/dist/detachedHostService.js.map +1 -0
- package/dist/detachedHostSupervisor.d.ts +102 -0
- package/dist/detachedHostSupervisor.d.ts.map +1 -0
- package/dist/detachedHostSupervisor.js +168 -0
- package/dist/detachedHostSupervisor.js.map +1 -0
- package/dist/durableRuntimeEventStore.d.ts +49 -0
- package/dist/durableRuntimeEventStore.d.ts.map +1 -0
- package/dist/durableRuntimeEventStore.js +364 -0
- package/dist/durableRuntimeEventStore.js.map +1 -0
- package/dist/engineering/EngineeringWorkbenchService.d.ts +142 -0
- package/dist/engineering/EngineeringWorkbenchService.d.ts.map +1 -0
- package/dist/engineering/EngineeringWorkbenchService.js +2301 -0
- package/dist/engineering/EngineeringWorkbenchService.js.map +1 -0
- package/dist/engineering/LandingService.d.ts +112 -0
- package/dist/engineering/LandingService.d.ts.map +1 -0
- package/dist/engineering/LandingService.js +239 -0
- package/dist/engineering/LandingService.js.map +1 -0
- package/dist/engineering/engineeringTypes.d.ts +2 -0
- package/dist/engineering/engineeringTypes.d.ts.map +1 -0
- package/dist/engineering/engineeringTypes.js +2 -0
- package/dist/engineering/engineeringTypes.js.map +1 -0
- package/dist/engineering/patchReview.d.ts +11 -0
- package/dist/engineering/patchReview.d.ts.map +1 -0
- package/dist/engineering/patchReview.js +174 -0
- package/dist/engineering/patchReview.js.map +1 -0
- package/dist/index.d.ts +834 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3242 -0
- package/dist/index.js.map +1 -0
- package/dist/intake/IntakeService.d.ts +84 -0
- package/dist/intake/IntakeService.d.ts.map +1 -0
- package/dist/intake/IntakeService.js +117 -0
- package/dist/intake/IntakeService.js.map +1 -0
- package/dist/intake/RepositoryTodoIntakeSource.d.ts +72 -0
- package/dist/intake/RepositoryTodoIntakeSource.d.ts.map +1 -0
- package/dist/intake/RepositoryTodoIntakeSource.js +168 -0
- package/dist/intake/RepositoryTodoIntakeSource.js.map +1 -0
- package/dist/intake/WorkspaceTodoIntakeSource.d.ts +53 -0
- package/dist/intake/WorkspaceTodoIntakeSource.d.ts.map +1 -0
- package/dist/intake/WorkspaceTodoIntakeSource.js +81 -0
- package/dist/intake/WorkspaceTodoIntakeSource.js.map +1 -0
- package/dist/isolation/CommandExecution.d.ts +132 -0
- package/dist/isolation/CommandExecution.d.ts.map +1 -0
- package/dist/isolation/CommandExecution.js +48 -0
- package/dist/isolation/CommandExecution.js.map +1 -0
- package/dist/isolation/LocalCommandExecutor.d.ts +27 -0
- package/dist/isolation/LocalCommandExecutor.d.ts.map +1 -0
- package/dist/isolation/LocalCommandExecutor.js +97 -0
- package/dist/isolation/LocalCommandExecutor.js.map +1 -0
- package/dist/isolation/RunExecutionEnvironment.d.ts +135 -0
- package/dist/isolation/RunExecutionEnvironment.d.ts.map +1 -0
- package/dist/isolation/RunExecutionEnvironment.js +206 -0
- package/dist/isolation/RunExecutionEnvironment.js.map +1 -0
- package/dist/isolation/RunIsolationService.d.ts +90 -0
- package/dist/isolation/RunIsolationService.d.ts.map +1 -0
- package/dist/isolation/RunIsolationService.js +86 -0
- package/dist/isolation/RunIsolationService.js.map +1 -0
- package/dist/isolation/SandboxCommandExecutor.d.ts +93 -0
- package/dist/isolation/SandboxCommandExecutor.d.ts.map +1 -0
- package/dist/isolation/SandboxCommandExecutor.js +189 -0
- package/dist/isolation/SandboxCommandExecutor.js.map +1 -0
- package/dist/knowledge/WorkspaceKnowledgeService.d.ts +71 -0
- package/dist/knowledge/WorkspaceKnowledgeService.d.ts.map +1 -0
- package/dist/knowledge/WorkspaceKnowledgeService.js +103 -0
- package/dist/knowledge/WorkspaceKnowledgeService.js.map +1 -0
- package/dist/localHostAuthority.d.ts +24 -0
- package/dist/localHostAuthority.d.ts.map +1 -0
- package/dist/localHostAuthority.js +87 -0
- package/dist/localHostAuthority.js.map +1 -0
- package/dist/localHostLease.d.ts +51 -0
- package/dist/localHostLease.d.ts.map +1 -0
- package/dist/localHostLease.js +167 -0
- package/dist/localHostLease.js.map +1 -0
- package/dist/localHostPaths.d.ts +30 -0
- package/dist/localHostPaths.d.ts.map +1 -0
- package/dist/localHostPaths.js +60 -0
- package/dist/localHostPaths.js.map +1 -0
- package/dist/localRpcTransport.d.ts +21 -0
- package/dist/localRpcTransport.d.ts.map +1 -0
- package/dist/localRpcTransport.js +423 -0
- package/dist/localRpcTransport.js.map +1 -0
- package/dist/node.d.ts +104 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +103 -0
- package/dist/node.js.map +1 -0
- package/dist/observation/DirectoryBaselineScanner.d.ts +44 -0
- package/dist/observation/DirectoryBaselineScanner.d.ts.map +1 -0
- package/dist/observation/DirectoryBaselineScanner.js +112 -0
- package/dist/observation/DirectoryBaselineScanner.js.map +1 -0
- package/dist/observation/MountContentReader.d.ts +63 -0
- package/dist/observation/MountContentReader.d.ts.map +1 -0
- package/dist/observation/MountContentReader.js +158 -0
- package/dist/observation/MountContentReader.js.map +1 -0
- package/dist/observation/RunObservationService.d.ts +229 -0
- package/dist/observation/RunObservationService.d.ts.map +1 -0
- package/dist/observation/RunObservationService.js +248 -0
- package/dist/observation/RunObservationService.js.map +1 -0
- package/dist/observation/XenoUseObservationSource.d.ts +42 -0
- package/dist/observation/XenoUseObservationSource.d.ts.map +1 -0
- package/dist/observation/XenoUseObservationSource.js +104 -0
- package/dist/observation/XenoUseObservationSource.js.map +1 -0
- package/dist/observation/XenoUseRunObserver.d.ts +140 -0
- package/dist/observation/XenoUseRunObserver.d.ts.map +1 -0
- package/dist/observation/XenoUseRunObserver.js +256 -0
- package/dist/observation/XenoUseRunObserver.js.map +1 -0
- package/dist/pluginMcp/PluginMcpManagerService.d.ts +141 -0
- package/dist/pluginMcp/PluginMcpManagerService.d.ts.map +1 -0
- package/dist/pluginMcp/PluginMcpManagerService.js +1821 -0
- package/dist/pluginMcp/PluginMcpManagerService.js.map +1 -0
- package/dist/pluginMcp/pluginMcpTypes.d.ts +349 -0
- package/dist/pluginMcp/pluginMcpTypes.d.ts.map +1 -0
- package/dist/pluginMcp/pluginMcpTypes.js +2 -0
- package/dist/pluginMcp/pluginMcpTypes.js.map +1 -0
- package/dist/policy/WorkspacePolicyService.d.ts +83 -0
- package/dist/policy/WorkspacePolicyService.d.ts.map +1 -0
- package/dist/policy/WorkspacePolicyService.js +809 -0
- package/dist/policy/WorkspacePolicyService.js.map +1 -0
- package/dist/policy/policyGuard.d.ts +27 -0
- package/dist/policy/policyGuard.d.ts.map +1 -0
- package/dist/policy/policyGuard.js +143 -0
- package/dist/policy/policyGuard.js.map +1 -0
- package/dist/policy/policyTypes.d.ts +190 -0
- package/dist/policy/policyTypes.d.ts.map +1 -0
- package/dist/policy/policyTypes.js +2 -0
- package/dist/policy/policyTypes.js.map +1 -0
- package/dist/runtime/RuntimeEventStore.d.ts +42 -0
- package/dist/runtime/RuntimeEventStore.d.ts.map +1 -0
- package/dist/runtime/RuntimeEventStore.js +412 -0
- package/dist/runtime/RuntimeEventStore.js.map +1 -0
- package/dist/runtime/RuntimeEventStoreRepositoryAdapter.d.ts +21 -0
- package/dist/runtime/RuntimeEventStoreRepositoryAdapter.d.ts.map +1 -0
- package/dist/runtime/RuntimeEventStoreRepositoryAdapter.js +41 -0
- package/dist/runtime/RuntimeEventStoreRepositoryAdapter.js.map +1 -0
- package/dist/runtime/RuntimeTimelineProjection.d.ts +5 -0
- package/dist/runtime/RuntimeTimelineProjection.d.ts.map +1 -0
- package/dist/runtime/RuntimeTimelineProjection.js +705 -0
- package/dist/runtime/RuntimeTimelineProjection.js.map +1 -0
- package/dist/runtime/runtimeEventTypes.d.ts +73 -0
- package/dist/runtime/runtimeEventTypes.d.ts.map +1 -0
- package/dist/runtime/runtimeEventTypes.js +2 -0
- package/dist/runtime/runtimeEventTypes.js.map +1 -0
- package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.d.ts +117 -0
- package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.d.ts.map +1 -0
- package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.js +214 -0
- package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.js.map +1 -0
- package/dist/session/AgentSessionService.d.ts +285 -0
- package/dist/session/AgentSessionService.d.ts.map +1 -0
- package/dist/session/AgentSessionService.js +444 -0
- package/dist/session/AgentSessionService.js.map +1 -0
- package/dist/session/bufferedSessionPty.d.ts +27 -0
- package/dist/session/bufferedSessionPty.d.ts.map +1 -0
- package/dist/session/bufferedSessionPty.js +49 -0
- package/dist/session/bufferedSessionPty.js.map +1 -0
- package/dist/session/renderSupport.d.ts +53 -0
- package/dist/session/renderSupport.d.ts.map +1 -0
- package/dist/session/renderSupport.js +41 -0
- package/dist/session/renderSupport.js.map +1 -0
- package/dist/session/runtimeEventChannel.d.ts +56 -0
- package/dist/session/runtimeEventChannel.d.ts.map +1 -0
- package/dist/session/runtimeEventChannel.js +53 -0
- package/dist/session/runtimeEventChannel.js.map +1 -0
- package/dist/state/JsonAgentStateRepository.d.ts +29 -0
- package/dist/state/JsonAgentStateRepository.d.ts.map +1 -0
- package/dist/state/JsonAgentStateRepository.js +165 -0
- package/dist/state/JsonAgentStateRepository.js.map +1 -0
- package/dist/state/SqliteAgentStateRepository.d.ts +58 -0
- package/dist/state/SqliteAgentStateRepository.d.ts.map +1 -0
- package/dist/state/SqliteAgentStateRepository.js +777 -0
- package/dist/state/SqliteAgentStateRepository.js.map +1 -0
- package/dist/state/createAgentStateRepository.d.ts +4 -0
- package/dist/state/createAgentStateRepository.d.ts.map +1 -0
- package/dist/state/createAgentStateRepository.js +12 -0
- package/dist/state/createAgentStateRepository.js.map +1 -0
- package/dist/state/stateSanitizers.d.ts +7 -0
- package/dist/state/stateSanitizers.d.ts.map +1 -0
- package/dist/state/stateSanitizers.js +87 -0
- package/dist/state/stateSanitizers.js.map +1 -0
- package/dist/subagents/AcpSubagentExecutionAdapter.d.ts +12 -0
- package/dist/subagents/AcpSubagentExecutionAdapter.d.ts.map +1 -0
- package/dist/subagents/AcpSubagentExecutionAdapter.js +119 -0
- package/dist/subagents/AcpSubagentExecutionAdapter.js.map +1 -0
- package/dist/subagents/CliSubagentExecutionAdapter.d.ts +13 -0
- package/dist/subagents/CliSubagentExecutionAdapter.d.ts.map +1 -0
- package/dist/subagents/CliSubagentExecutionAdapter.js +217 -0
- package/dist/subagents/CliSubagentExecutionAdapter.js.map +1 -0
- package/dist/subagents/HostTurnSubagentExecutionAdapter.d.ts +78 -0
- package/dist/subagents/HostTurnSubagentExecutionAdapter.d.ts.map +1 -0
- package/dist/subagents/HostTurnSubagentExecutionAdapter.js +160 -0
- package/dist/subagents/HostTurnSubagentExecutionAdapter.js.map +1 -0
- package/dist/subagents/SubagentRunService.d.ts +103 -0
- package/dist/subagents/SubagentRunService.d.ts.map +1 -0
- package/dist/subagents/SubagentRunService.js +1183 -0
- package/dist/subagents/SubagentRunService.js.map +1 -0
- package/dist/subagents/SubagentScheduler.d.ts +167 -0
- package/dist/subagents/SubagentScheduler.d.ts.map +1 -0
- package/dist/subagents/SubagentScheduler.js +530 -0
- package/dist/subagents/SubagentScheduler.js.map +1 -0
- package/dist/subagents/TeamAgentRouter.d.ts +104 -0
- package/dist/subagents/TeamAgentRouter.d.ts.map +1 -0
- package/dist/subagents/TeamAgentRouter.js +435 -0
- package/dist/subagents/TeamAgentRouter.js.map +1 -0
- package/dist/subagents/capabilityMatcher.d.ts +3 -0
- package/dist/subagents/capabilityMatcher.d.ts.map +1 -0
- package/dist/subagents/capabilityMatcher.js +127 -0
- package/dist/subagents/capabilityMatcher.js.map +1 -0
- package/dist/subagents/subagentRunPort.d.ts +43 -0
- package/dist/subagents/subagentRunPort.d.ts.map +1 -0
- package/dist/subagents/subagentRunPort.js +24 -0
- package/dist/subagents/subagentRunPort.js.map +1 -0
- package/dist/subagents/subagentTypes.d.ts +330 -0
- package/dist/subagents/subagentTypes.d.ts.map +1 -0
- package/dist/subagents/subagentTypes.js +2 -0
- package/dist/subagents/subagentTypes.js.map +1 -0
- package/dist/subagents/subagentWorkspaceAuthority.d.ts +29 -0
- package/dist/subagents/subagentWorkspaceAuthority.d.ts.map +1 -0
- package/dist/subagents/subagentWorkspaceAuthority.js +173 -0
- package/dist/subagents/subagentWorkspaceAuthority.js.map +1 -0
- package/dist/support/SupportDiagnosticsService.d.ts +87 -0
- package/dist/support/SupportDiagnosticsService.d.ts.map +1 -0
- package/dist/support/SupportDiagnosticsService.js +1199 -0
- package/dist/support/SupportDiagnosticsService.js.map +1 -0
- package/dist/turns/DurableInterruptedTurnStore.d.ts +14 -0
- package/dist/turns/DurableInterruptedTurnStore.d.ts.map +1 -0
- package/dist/turns/DurableInterruptedTurnStore.js +63 -0
- package/dist/turns/DurableInterruptedTurnStore.js.map +1 -0
- package/dist/turns/interruptedTurns.d.ts +50 -0
- package/dist/turns/interruptedTurns.d.ts.map +1 -0
- package/dist/turns/interruptedTurns.js +54 -0
- package/dist/turns/interruptedTurns.js.map +1 -0
- package/dist/turns/turnAdmission.d.ts +113 -0
- package/dist/turns/turnAdmission.d.ts.map +1 -0
- package/dist/turns/turnAdmission.js +136 -0
- package/dist/turns/turnAdmission.js.map +1 -0
- package/dist/workspace/WorkspaceHostService.d.ts +126 -0
- package/dist/workspace/WorkspaceHostService.d.ts.map +1 -0
- package/dist/workspace/WorkspaceHostService.js +841 -0
- package/dist/workspace/WorkspaceHostService.js.map +1 -0
- package/dist/workspace/WorkspaceShellService.d.ts +71 -0
- package/dist/workspace/WorkspaceShellService.d.ts.map +1 -0
- package/dist/workspace/WorkspaceShellService.js +273 -0
- package/dist/workspace/WorkspaceShellService.js.map +1 -0
- package/dist/workspace/fileAssociations.d.ts +12 -0
- package/dist/workspace/fileAssociations.d.ts.map +1 -0
- package/dist/workspace/fileAssociations.js +202 -0
- package/dist/workspace/fileAssociations.js.map +1 -0
- package/dist/workspace/scrollbackBuffer.d.ts +48 -0
- package/dist/workspace/scrollbackBuffer.d.ts.map +1 -0
- package/dist/workspace/scrollbackBuffer.js +94 -0
- package/dist/workspace/scrollbackBuffer.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a run's commands execute, and what that means for containment — ADE §5.3.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 **The two answers come from ONE lookup, and that is the whole point.**
|
|
5
|
+
*
|
|
6
|
+
* The reporting half (`RunIsolationService`) and the enforcing half
|
|
7
|
+
* (`SandboxCommandExecutor`) were built separately and could trivially disagree:
|
|
8
|
+
* a composition could install the sandbox executor and forget to flip the
|
|
9
|
+
* report, and the product would confine correctly while telling the user it does
|
|
10
|
+
* not — or, far worse, the reverse. Two facts that must always agree, written in
|
|
11
|
+
* two places, is the shape this ecosystem has shipped repeatedly.
|
|
12
|
+
*
|
|
13
|
+
* So neither is stored. `resolve()` produces BOTH from the same record, and
|
|
14
|
+
* `executorFor`/`isolationFor` are thin readers of it. A mismatch is not
|
|
15
|
+
* "prevented by a test"; there is no code path that can express one.
|
|
16
|
+
*
|
|
17
|
+
* ## Which sites this serves — and which it deliberately does not
|
|
18
|
+
*
|
|
19
|
+
* §5.3 is about confining the AGENT. It is not about confining our own
|
|
20
|
+
* plumbing, and the distinction is load-bearing:
|
|
21
|
+
*
|
|
22
|
+
* - **Agent-reachable** — `workspace.command.run` and the agent's terminal tool.
|
|
23
|
+
* The agent chooses what runs. These are what a sandbox exists to contain.
|
|
24
|
+
* - **Host plumbing** — `EngineeringWorkbenchService`'s `git`/`gh` checks. We
|
|
25
|
+
* choose what runs, and it needs the user's git credentials, their `gh` auth
|
|
26
|
+
* and network access. Routing it into a `--network none`, `--read-only`
|
|
27
|
+
* container would break every check while confining nothing that was ever a
|
|
28
|
+
* threat. It stays LOCAL, deliberately, and this class is not offered to it.
|
|
29
|
+
*
|
|
30
|
+
* Stated here because "we sandboxed some of it" is exactly the kind of partial
|
|
31
|
+
* truth that gets remembered as "it's sandboxed".
|
|
32
|
+
*
|
|
33
|
+
* ## The identity mismatch, and why it is resolved here
|
|
34
|
+
*
|
|
35
|
+
* Isolation is a property of a RUN. The call sites know a CONVERSATION —
|
|
36
|
+
* `AgentWorkspaceAccessContext` carries `conversationId`, not `runId`. Rather
|
|
37
|
+
* than push that mismatch onto every caller, the binding records both and this
|
|
38
|
+
* class indexes by each. The host already has both at the one moment that
|
|
39
|
+
* matters: `runObservationBinder.begin` is handed `{ runId, conversationId }`.
|
|
40
|
+
*/
|
|
41
|
+
import type { CommandExecutionPort } from './CommandExecution.js';
|
|
42
|
+
import type { RunIsolation, RunIsolationReport, RunIsolationSource } from './RunIsolationService.js';
|
|
43
|
+
import { type SandboxCommandMount } from './SandboxCommandExecutor.js';
|
|
44
|
+
/** What confines a run, when something does. Supplied by the composition. */
|
|
45
|
+
export interface RunSandboxBinding {
|
|
46
|
+
sandboxId: string;
|
|
47
|
+
mount: SandboxCommandMount;
|
|
48
|
+
/** Base URL of the `xeno-use` service. */
|
|
49
|
+
baseUrl: string;
|
|
50
|
+
token: string;
|
|
51
|
+
/**
|
|
52
|
+
* What is doing the confining, in the substrate's own words — surfaced to the
|
|
53
|
+
* user beside `sandboxed`. Free-form because this host does not own that
|
|
54
|
+
* vocabulary.
|
|
55
|
+
*/
|
|
56
|
+
mechanism: string;
|
|
57
|
+
}
|
|
58
|
+
/** Everything a run's execution site needs, produced together. */
|
|
59
|
+
export interface RunExecutionResolution {
|
|
60
|
+
executor: CommandExecutionPort;
|
|
61
|
+
isolation: RunIsolationReport;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A sandbox that is still being created.
|
|
65
|
+
*
|
|
66
|
+
* 🔴 This exists to close a RACE, and the race produces exactly the lie every
|
|
67
|
+
* gate in this directory exists to prevent. Spawning a container takes seconds
|
|
68
|
+
* and the composition deliberately does not block a turn on it. So a run can
|
|
69
|
+
* begin, execute its first command, and only then acquire a sandbox — with the
|
|
70
|
+
* command having run on the HOST while the run goes on to report `sandboxed`.
|
|
71
|
+
*
|
|
72
|
+
* The fix is not to make the spawn synchronous (that stalls every turn) and not
|
|
73
|
+
* to upgrade the report mid-run (isolation is a property of a RUN; a value that
|
|
74
|
+
* changes halfway describes neither half). It is to make the EXECUTOR wait:
|
|
75
|
+
* `execute()` is already async, so a command issued before the container is
|
|
76
|
+
* ready simply waits for it. No command runs unconfined, no turn is blocked for
|
|
77
|
+
* a run that never executes anything, and the report is true from the start.
|
|
78
|
+
*
|
|
79
|
+
* If the spawn FAILS the run reports `unknown` — not `none`. Nothing executed
|
|
80
|
+
* unconfined (the executor refuses rather than falling back), so "unconfined" is
|
|
81
|
+
* the wrong word; what is true is that the host cannot say what confined it.
|
|
82
|
+
*/
|
|
83
|
+
export type PendingSandbox = Promise<RunSandboxBinding | undefined>;
|
|
84
|
+
export interface RunExecutionEnvironmentOptions {
|
|
85
|
+
/**
|
|
86
|
+
* Used for every run that has no sandbox. Injectable so a test can observe
|
|
87
|
+
* which implementation a resolution actually chose, rather than inferring it.
|
|
88
|
+
*/
|
|
89
|
+
localExecutor?: CommandExecutionPort;
|
|
90
|
+
createSandboxExecutor?: (binding: RunSandboxBinding) => CommandExecutionPort;
|
|
91
|
+
}
|
|
92
|
+
export declare class RunExecutionEnvironment implements RunIsolationSource {
|
|
93
|
+
#private;
|
|
94
|
+
constructor(options?: RunExecutionEnvironmentOptions);
|
|
95
|
+
/**
|
|
96
|
+
* Records where a run executes.
|
|
97
|
+
*
|
|
98
|
+
* 🔴 Called for EVERY run, with or without a sandbox — the same discipline
|
|
99
|
+
* `runObservationBinder.begin` follows. A run that is bound without one is
|
|
100
|
+
* positively known to be unconfined; a run that was never bound is a run this
|
|
101
|
+
* host has no record of, and those are different answers.
|
|
102
|
+
*/
|
|
103
|
+
bind(context: {
|
|
104
|
+
runId: string;
|
|
105
|
+
conversationId: string;
|
|
106
|
+
sandbox?: RunSandboxBinding;
|
|
107
|
+
/**
|
|
108
|
+
* A sandbox still being created. Commands WAIT for it rather than running
|
|
109
|
+
* on the host — see `PendingSandbox`.
|
|
110
|
+
*
|
|
111
|
+
* Resolving to `undefined` means the spawn failed, and the run then reports
|
|
112
|
+
* `unknown`: nothing ran unconfined, so `none` would be the wrong word.
|
|
113
|
+
*/
|
|
114
|
+
pendingSandbox?: PendingSandbox;
|
|
115
|
+
}): void;
|
|
116
|
+
release(runId: string): void;
|
|
117
|
+
/**
|
|
118
|
+
* The single lookup. Everything else on this class reads it.
|
|
119
|
+
*
|
|
120
|
+
* An unknown run resolves to the LOCAL executor and `unknown` — not `none`.
|
|
121
|
+
* The two are genuinely different and the distinction is the one that matters
|
|
122
|
+
* for a user's next action: `none` says nothing confines this, `unknown` says
|
|
123
|
+
* this host cannot account for the run at all, and the second is the one where
|
|
124
|
+
* they should not proceed. Reporting `none` here would turn "I have no record"
|
|
125
|
+
* into a confident all-clear.
|
|
126
|
+
*/
|
|
127
|
+
resolve(runId: string | undefined): RunExecutionResolution;
|
|
128
|
+
/** The executor for a CONVERSATION's current run — the identity call sites have. */
|
|
129
|
+
executorFor(conversationId: string | undefined): CommandExecutionPort;
|
|
130
|
+
/** `RunIsolationSource`. Same lookup, so it cannot disagree with the executor. */
|
|
131
|
+
isolationFor(runId: string): RunIsolationReport | undefined;
|
|
132
|
+
/** Whether a run is confined — for tests and diagnostics that want the bare fact. */
|
|
133
|
+
isolationKindFor(runId: string): RunIsolation;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=RunExecutionEnvironment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunExecutionEnvironment.d.ts","sourceRoot":"","sources":["../../src/isolation/RunExecutionEnvironment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AACpG,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAA;AAEpC,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,mBAAmB,CAAA;IAC1B,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,oBAAoB,CAAA;IAC9B,SAAS,EAAE,kBAAkB,CAAA;CAC9B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAA;AAWnE,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,aAAa,CAAC,EAAE,oBAAoB,CAAA;IACpC,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,oBAAoB,CAAA;CAC7E;AAED,qBAAa,uBAAwB,YAAW,kBAAkB;;gBAOpD,OAAO,GAAE,8BAAmC;IAaxD;;;;;;;OAOG;IACH,IAAI,CAAC,OAAO,EAAE;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,cAAc,EAAE,MAAM,CAAA;QACtB,OAAO,CAAC,EAAE,iBAAiB,CAAA;QAC3B;;;;;;WAMG;QACH,cAAc,CAAC,EAAE,cAAc,CAAA;KAChC,GAAG,IAAI;IAiER,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAW5B;;;;;;;;;OASG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,sBAAsB;IA0C1D,oFAAoF;IACpF,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,oBAAoB;IAKrE,kFAAkF;IAClF,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI3D,qFAAqF;IACrF,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY;CAG9C"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a run's commands execute, and what that means for containment — ADE §5.3.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 **The two answers come from ONE lookup, and that is the whole point.**
|
|
5
|
+
*
|
|
6
|
+
* The reporting half (`RunIsolationService`) and the enforcing half
|
|
7
|
+
* (`SandboxCommandExecutor`) were built separately and could trivially disagree:
|
|
8
|
+
* a composition could install the sandbox executor and forget to flip the
|
|
9
|
+
* report, and the product would confine correctly while telling the user it does
|
|
10
|
+
* not — or, far worse, the reverse. Two facts that must always agree, written in
|
|
11
|
+
* two places, is the shape this ecosystem has shipped repeatedly.
|
|
12
|
+
*
|
|
13
|
+
* So neither is stored. `resolve()` produces BOTH from the same record, and
|
|
14
|
+
* `executorFor`/`isolationFor` are thin readers of it. A mismatch is not
|
|
15
|
+
* "prevented by a test"; there is no code path that can express one.
|
|
16
|
+
*
|
|
17
|
+
* ## Which sites this serves — and which it deliberately does not
|
|
18
|
+
*
|
|
19
|
+
* §5.3 is about confining the AGENT. It is not about confining our own
|
|
20
|
+
* plumbing, and the distinction is load-bearing:
|
|
21
|
+
*
|
|
22
|
+
* - **Agent-reachable** — `workspace.command.run` and the agent's terminal tool.
|
|
23
|
+
* The agent chooses what runs. These are what a sandbox exists to contain.
|
|
24
|
+
* - **Host plumbing** — `EngineeringWorkbenchService`'s `git`/`gh` checks. We
|
|
25
|
+
* choose what runs, and it needs the user's git credentials, their `gh` auth
|
|
26
|
+
* and network access. Routing it into a `--network none`, `--read-only`
|
|
27
|
+
* container would break every check while confining nothing that was ever a
|
|
28
|
+
* threat. It stays LOCAL, deliberately, and this class is not offered to it.
|
|
29
|
+
*
|
|
30
|
+
* Stated here because "we sandboxed some of it" is exactly the kind of partial
|
|
31
|
+
* truth that gets remembered as "it's sandboxed".
|
|
32
|
+
*
|
|
33
|
+
* ## The identity mismatch, and why it is resolved here
|
|
34
|
+
*
|
|
35
|
+
* Isolation is a property of a RUN. The call sites know a CONVERSATION —
|
|
36
|
+
* `AgentWorkspaceAccessContext` carries `conversationId`, not `runId`. Rather
|
|
37
|
+
* than push that mismatch onto every caller, the binding records both and this
|
|
38
|
+
* class indexes by each. The host already has both at the one moment that
|
|
39
|
+
* matters: `runObservationBinder.begin` is handed `{ runId, conversationId }`.
|
|
40
|
+
*/
|
|
41
|
+
import { LocalCommandExecutor } from './LocalCommandExecutor.js';
|
|
42
|
+
import { SandboxCommandExecutor, } from './SandboxCommandExecutor.js';
|
|
43
|
+
export class RunExecutionEnvironment {
|
|
44
|
+
#runs = new Map();
|
|
45
|
+
/** conversationId → runId. Rebuilt on bind/release so it cannot outlive its run. */
|
|
46
|
+
#byConversation = new Map();
|
|
47
|
+
#localExecutor;
|
|
48
|
+
#createSandboxExecutor;
|
|
49
|
+
constructor(options = {}) {
|
|
50
|
+
this.#localExecutor = options.localExecutor ?? new LocalCommandExecutor();
|
|
51
|
+
this.#createSandboxExecutor =
|
|
52
|
+
options.createSandboxExecutor ??
|
|
53
|
+
((binding) => new SandboxCommandExecutor({
|
|
54
|
+
baseUrl: binding.baseUrl,
|
|
55
|
+
token: binding.token,
|
|
56
|
+
sandboxId: binding.sandboxId,
|
|
57
|
+
mount: binding.mount,
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Records where a run executes.
|
|
62
|
+
*
|
|
63
|
+
* 🔴 Called for EVERY run, with or without a sandbox — the same discipline
|
|
64
|
+
* `runObservationBinder.begin` follows. A run that is bound without one is
|
|
65
|
+
* positively known to be unconfined; a run that was never bound is a run this
|
|
66
|
+
* host has no record of, and those are different answers.
|
|
67
|
+
*/
|
|
68
|
+
bind(context) {
|
|
69
|
+
const record = { conversationId: context.conversationId };
|
|
70
|
+
if (context.sandbox) {
|
|
71
|
+
record.sandbox = {
|
|
72
|
+
executor: this.#createSandboxExecutor(context.sandbox),
|
|
73
|
+
mechanism: context.sandbox.mechanism,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
else if (context.pendingSandbox) {
|
|
77
|
+
const pending = { executor: undefined, failed: false };
|
|
78
|
+
const ready = context.pendingSandbox.then((binding) => {
|
|
79
|
+
if (!binding) {
|
|
80
|
+
pending.failed = true;
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
pending.executor = this.#createSandboxExecutor(binding);
|
|
84
|
+
const current = this.#runs.get(context.runId);
|
|
85
|
+
// Only if this record is still the live one: a second run on the same
|
|
86
|
+
// conversation, or a release, must not be overwritten by a container
|
|
87
|
+
// that finished spawning for a run nobody is watching any more.
|
|
88
|
+
if (current === record) {
|
|
89
|
+
current.sandbox = { executor: pending.executor, mechanism: binding.mechanism };
|
|
90
|
+
delete current.pending;
|
|
91
|
+
}
|
|
92
|
+
return pending.executor;
|
|
93
|
+
}, () => {
|
|
94
|
+
pending.failed = true;
|
|
95
|
+
return undefined;
|
|
96
|
+
});
|
|
97
|
+
record.pending = {
|
|
98
|
+
failed: false,
|
|
99
|
+
// Every call waits on the SAME promise, so N commands issued during the
|
|
100
|
+
// spawn do not each try to create a container.
|
|
101
|
+
executor: {
|
|
102
|
+
execute: async (request) => {
|
|
103
|
+
const executor = await ready;
|
|
104
|
+
if (!executor) {
|
|
105
|
+
// Refused, never run locally. The whole point of waiting is that
|
|
106
|
+
// no command escapes to the host; falling back here would undo it
|
|
107
|
+
// at the one moment it matters.
|
|
108
|
+
return {
|
|
109
|
+
stdout: '',
|
|
110
|
+
stderr: '',
|
|
111
|
+
exitCode: null,
|
|
112
|
+
timedOut: false,
|
|
113
|
+
truncated: false,
|
|
114
|
+
error: 'The sandbox for this run could not be created, so the command was not run.',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return await executor.execute(request);
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
// `failed` is read through the closure below rather than copied.
|
|
122
|
+
Object.defineProperty(record.pending, 'failed', {
|
|
123
|
+
get: () => pending.failed,
|
|
124
|
+
enumerable: true,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
this.#runs.set(context.runId, record);
|
|
128
|
+
this.#byConversation.set(context.conversationId, context.runId);
|
|
129
|
+
}
|
|
130
|
+
release(runId) {
|
|
131
|
+
const record = this.#runs.get(runId);
|
|
132
|
+
if (!record)
|
|
133
|
+
return;
|
|
134
|
+
this.#runs.delete(runId);
|
|
135
|
+
// Only if it still points here: a conversation can start a second run, and
|
|
136
|
+
// releasing the first must not orphan the second's index entry.
|
|
137
|
+
if (this.#byConversation.get(record.conversationId) === runId) {
|
|
138
|
+
this.#byConversation.delete(record.conversationId);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The single lookup. Everything else on this class reads it.
|
|
143
|
+
*
|
|
144
|
+
* An unknown run resolves to the LOCAL executor and `unknown` — not `none`.
|
|
145
|
+
* The two are genuinely different and the distinction is the one that matters
|
|
146
|
+
* for a user's next action: `none` says nothing confines this, `unknown` says
|
|
147
|
+
* this host cannot account for the run at all, and the second is the one where
|
|
148
|
+
* they should not proceed. Reporting `none` here would turn "I have no record"
|
|
149
|
+
* into a confident all-clear.
|
|
150
|
+
*/
|
|
151
|
+
resolve(runId) {
|
|
152
|
+
const record = runId === undefined ? undefined : this.#runs.get(runId);
|
|
153
|
+
if (!record) {
|
|
154
|
+
return {
|
|
155
|
+
executor: this.#localExecutor,
|
|
156
|
+
isolation: {
|
|
157
|
+
isolation: 'unknown',
|
|
158
|
+
reason: 'This host has no record of the run these commands belong to.',
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (record.sandbox) {
|
|
163
|
+
return {
|
|
164
|
+
executor: record.sandbox.executor,
|
|
165
|
+
isolation: { isolation: 'sandboxed', mechanism: record.sandbox.mechanism },
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (record.pending) {
|
|
169
|
+
// A spawn that FAILED. `unknown`, not `none`: nothing ran unconfined —
|
|
170
|
+
// the waiting executor refuses rather than falling back — so "nothing
|
|
171
|
+
// confines this" is the wrong sentence. What is true is that the host
|
|
172
|
+
// cannot say what confined it.
|
|
173
|
+
if (record.pending.failed) {
|
|
174
|
+
return {
|
|
175
|
+
executor: record.pending.executor,
|
|
176
|
+
isolation: {
|
|
177
|
+
isolation: 'unknown',
|
|
178
|
+
reason: 'The sandbox for this run could not be created.',
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Still spawning. Reported `sandboxed` because it is the answer that will
|
|
183
|
+
// be true for every command this run executes: the executor waits, so no
|
|
184
|
+
// command can reach the host in the meantime.
|
|
185
|
+
return {
|
|
186
|
+
executor: record.pending.executor,
|
|
187
|
+
isolation: { isolation: 'sandboxed', mechanism: 'container (starting)' },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return { executor: this.#localExecutor, isolation: { isolation: 'none' } };
|
|
191
|
+
}
|
|
192
|
+
/** The executor for a CONVERSATION's current run — the identity call sites have. */
|
|
193
|
+
executorFor(conversationId) {
|
|
194
|
+
const runId = conversationId === undefined ? undefined : this.#byConversation.get(conversationId);
|
|
195
|
+
return this.resolve(runId).executor;
|
|
196
|
+
}
|
|
197
|
+
/** `RunIsolationSource`. Same lookup, so it cannot disagree with the executor. */
|
|
198
|
+
isolationFor(runId) {
|
|
199
|
+
return this.resolve(runId).isolation;
|
|
200
|
+
}
|
|
201
|
+
/** Whether a run is confined — for tests and diagnostics that want the bare fact. */
|
|
202
|
+
isolationKindFor(runId) {
|
|
203
|
+
return this.resolve(runId).isolation.isolation;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=RunExecutionEnvironment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunExecutionEnvironment.js","sourceRoot":"","sources":["../../src/isolation/RunExecutionEnvironment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a run is CONTAINED — ADE §5.3's reporting half.
|
|
3
|
+
*
|
|
4
|
+
* §5.3: *"Isolation strength is surfaced in the UI — the user always knows
|
|
5
|
+
* whether the thing running is contained or not."* Nothing reported it. The
|
|
6
|
+
* settings surface went further and asserted the opposite, calling host
|
|
7
|
+
* execution "Sandboxed" until `181c251`; correcting that stopped the product
|
|
8
|
+
* lying, and left it silent. Silence is better than a lie and is still not what
|
|
9
|
+
* §5.3 asks for.
|
|
10
|
+
*
|
|
11
|
+
* ## This is the REPORTING half, deliberately not the enforcing half
|
|
12
|
+
*
|
|
13
|
+
* §5.3 puts implementing containers, VMs and worktrees explicitly out of scope
|
|
14
|
+
* for this repo, and its gate requires an out-of-mount write to be refused **by
|
|
15
|
+
* the substrate, not by a rule inside the shell it runs in**. So nothing here
|
|
16
|
+
* confines anything. It answers one question — *is this run contained?* — and
|
|
17
|
+
* answers it honestly while the answer is still "no".
|
|
18
|
+
*
|
|
19
|
+
* That ordering is not a compromise. A surface that can display containment is
|
|
20
|
+
* the thing that makes adopting a sandbox observable: land the adapter and the
|
|
21
|
+
* badge changes by itself. Building enforcement first would mean shipping
|
|
22
|
+
* containment nobody could see, which is how "sandboxed" got written in the UI
|
|
23
|
+
* in the first place.
|
|
24
|
+
*
|
|
25
|
+
* ## The source is a PORT — a licensing boundary before a design preference
|
|
26
|
+
*
|
|
27
|
+
* 🔴 **`xeno-use` is AGPL-3.0** and XENO Agent is proprietary, so this package
|
|
28
|
+
* must not import `@xeno-use/*`, link its N-API binding, or depend on it in any
|
|
29
|
+
* direction. `RunIsolationSource` is declared HERE, provider-neutral, and an
|
|
30
|
+
* adapter is supplied from outside — talking to `xeno-use` out of process over
|
|
31
|
+
* its own `/v1/use/*` surface. Exactly the shape `RunObservationSource` already
|
|
32
|
+
* uses one directory over, and for exactly the same reason.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* What confines a run, as a SHAPE rather than an import.
|
|
36
|
+
*
|
|
37
|
+
* `unknown` is a first-class member and the reason this is a three-member union
|
|
38
|
+
* rather than a boolean. The three are genuinely different facts:
|
|
39
|
+
*
|
|
40
|
+
* - `none` — POSITIVE knowledge that nothing confines this run. When no source
|
|
41
|
+
* is configured at all, this is what the host knows: execution goes through
|
|
42
|
+
* `WorkspaceHostService.runCommand` to a host process as the signed-in user.
|
|
43
|
+
* "No sandbox is installed" is not ignorance about containment; it is
|
|
44
|
+
* containment's absence, and the user is entitled to be told so plainly.
|
|
45
|
+
* - `sandboxed` — a source answered that this run is confined.
|
|
46
|
+
* - `unknown` — a source EXISTS and could not answer for this run. Never
|
|
47
|
+
* collapse this into `none`: "nothing confines it" and "I could not find out"
|
|
48
|
+
* lead a person to different actions, and the second one is the one where
|
|
49
|
+
* they should not proceed.
|
|
50
|
+
*/
|
|
51
|
+
export type RunIsolation = 'none' | 'sandboxed' | 'unknown';
|
|
52
|
+
export interface RunIsolationReport {
|
|
53
|
+
isolation: RunIsolation;
|
|
54
|
+
/**
|
|
55
|
+
* What is doing the confining, when something is — e.g. a container runtime.
|
|
56
|
+
*
|
|
57
|
+
* Free-form because this host does not own the vocabulary; the substrate does.
|
|
58
|
+
* Present ONLY alongside `sandboxed`: a mechanism named beside `none` would
|
|
59
|
+
* read as a confinement that exists and merely failed this time.
|
|
60
|
+
*/
|
|
61
|
+
mechanism?: string;
|
|
62
|
+
/** Why the answer is `unknown`, when it is. Never a bare unknown. */
|
|
63
|
+
reason?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A provider of containment facts. Supplied by the composition, never imported.
|
|
67
|
+
*
|
|
68
|
+
* Returning `undefined` for a run means the source has no opinion about it,
|
|
69
|
+
* which resolves to `unknown` — not to `none`. A source that knows a run is
|
|
70
|
+
* unconfined must say so by answering `none` explicitly.
|
|
71
|
+
*/
|
|
72
|
+
export interface RunIsolationSource {
|
|
73
|
+
isolationFor(runId: string): RunIsolationReport | undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Answers "is this run contained?" for every run, with or without a source.
|
|
77
|
+
*
|
|
78
|
+
* 🔴 Constructed with NO source in the shipped composition today, and that path
|
|
79
|
+
* is the one that must be right: it reports `none`, because that is true.
|
|
80
|
+
*/
|
|
81
|
+
export declare class RunIsolationService {
|
|
82
|
+
#private;
|
|
83
|
+
constructor(options?: {
|
|
84
|
+
source?: RunIsolationSource;
|
|
85
|
+
});
|
|
86
|
+
/** Whether a containment substrate is configured at all. */
|
|
87
|
+
get hasSource(): boolean;
|
|
88
|
+
report(runId: string): RunIsolationReport;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=RunIsolationService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunIsolationService.d.ts","sourceRoot":"","sources":["../../src/isolation/RunIsolationService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAA;AAE3D,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,YAAY,CAAA;IACvB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAA;CAC5D;AAED;;;;;GAKG;AACH,qBAAa,mBAAmB;;gBAGlB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,kBAAkB,CAAA;KAAO;IAIzD,4DAA4D;IAC5D,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB;CAkC1C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a run is CONTAINED — ADE §5.3's reporting half.
|
|
3
|
+
*
|
|
4
|
+
* §5.3: *"Isolation strength is surfaced in the UI — the user always knows
|
|
5
|
+
* whether the thing running is contained or not."* Nothing reported it. The
|
|
6
|
+
* settings surface went further and asserted the opposite, calling host
|
|
7
|
+
* execution "Sandboxed" until `181c251`; correcting that stopped the product
|
|
8
|
+
* lying, and left it silent. Silence is better than a lie and is still not what
|
|
9
|
+
* §5.3 asks for.
|
|
10
|
+
*
|
|
11
|
+
* ## This is the REPORTING half, deliberately not the enforcing half
|
|
12
|
+
*
|
|
13
|
+
* §5.3 puts implementing containers, VMs and worktrees explicitly out of scope
|
|
14
|
+
* for this repo, and its gate requires an out-of-mount write to be refused **by
|
|
15
|
+
* the substrate, not by a rule inside the shell it runs in**. So nothing here
|
|
16
|
+
* confines anything. It answers one question — *is this run contained?* — and
|
|
17
|
+
* answers it honestly while the answer is still "no".
|
|
18
|
+
*
|
|
19
|
+
* That ordering is not a compromise. A surface that can display containment is
|
|
20
|
+
* the thing that makes adopting a sandbox observable: land the adapter and the
|
|
21
|
+
* badge changes by itself. Building enforcement first would mean shipping
|
|
22
|
+
* containment nobody could see, which is how "sandboxed" got written in the UI
|
|
23
|
+
* in the first place.
|
|
24
|
+
*
|
|
25
|
+
* ## The source is a PORT — a licensing boundary before a design preference
|
|
26
|
+
*
|
|
27
|
+
* 🔴 **`xeno-use` is AGPL-3.0** and XENO Agent is proprietary, so this package
|
|
28
|
+
* must not import `@xeno-use/*`, link its N-API binding, or depend on it in any
|
|
29
|
+
* direction. `RunIsolationSource` is declared HERE, provider-neutral, and an
|
|
30
|
+
* adapter is supplied from outside — talking to `xeno-use` out of process over
|
|
31
|
+
* its own `/v1/use/*` surface. Exactly the shape `RunObservationSource` already
|
|
32
|
+
* uses one directory over, and for exactly the same reason.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Answers "is this run contained?" for every run, with or without a source.
|
|
36
|
+
*
|
|
37
|
+
* 🔴 Constructed with NO source in the shipped composition today, and that path
|
|
38
|
+
* is the one that must be right: it reports `none`, because that is true.
|
|
39
|
+
*/
|
|
40
|
+
export class RunIsolationService {
|
|
41
|
+
#source;
|
|
42
|
+
constructor(options = {}) {
|
|
43
|
+
this.#source = options.source;
|
|
44
|
+
}
|
|
45
|
+
/** Whether a containment substrate is configured at all. */
|
|
46
|
+
get hasSource() {
|
|
47
|
+
return this.#source !== undefined;
|
|
48
|
+
}
|
|
49
|
+
report(runId) {
|
|
50
|
+
const source = this.#source;
|
|
51
|
+
if (!source) {
|
|
52
|
+
// No substrate is installed, so nothing confines anything. Stated as a
|
|
53
|
+
// fact rather than as an absence of information.
|
|
54
|
+
return { isolation: 'none' };
|
|
55
|
+
}
|
|
56
|
+
let answer;
|
|
57
|
+
try {
|
|
58
|
+
answer = source.isolationFor(runId);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// A source that throws has not told us the run is unconfined; it has
|
|
62
|
+
// failed to tell us anything. Reporting `none` here would turn a broken
|
|
63
|
+
// sensor into a confident all-clear.
|
|
64
|
+
return {
|
|
65
|
+
isolation: 'unknown',
|
|
66
|
+
reason: `The isolation source failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (!answer) {
|
|
70
|
+
return { isolation: 'unknown', reason: 'The isolation source has no record of this run.' };
|
|
71
|
+
}
|
|
72
|
+
if (answer.isolation === 'sandboxed') {
|
|
73
|
+
return {
|
|
74
|
+
isolation: 'sandboxed',
|
|
75
|
+
...(answer.mechanism === undefined ? {} : { mechanism: answer.mechanism }),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (answer.isolation === 'none')
|
|
79
|
+
return { isolation: 'none' };
|
|
80
|
+
return {
|
|
81
|
+
isolation: 'unknown',
|
|
82
|
+
...(answer.reason === undefined ? {} : { reason: answer.reason }),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=RunIsolationService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunIsolationService.js","sourceRoot":"","sources":["../../src/isolation/RunIsolationService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA8CH;;;;;GAKG;AACH,MAAM,OAAO,mBAAmB;IACrB,OAAO,CAAgC;IAEhD,YAAY,UAA2C,EAAE;QACvD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAA;IAC/B,CAAC;IAED,4DAA4D;IAC5D,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAA;IACnC,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,uEAAuE;YACvE,iDAAiD;YACjD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAA;QAC9B,CAAC;QACD,IAAI,MAAsC,CAAA;QAC1C,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QACrC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qEAAqE;YACrE,wEAAwE;YACxE,qCAAqC;YACrC,OAAO;gBACL,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aACjG,CAAA;QACH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,iDAAiD,EAAE,CAAA;QAC5F,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;YACrC,OAAO;gBACL,SAAS,EAAE,WAAW;gBACtB,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;aAC3E,CAAA;QACH,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,MAAM;YAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAA;QAC7D,OAAO;YACL,SAAS,EAAE,SAAS;YACpB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;SAClE,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CommandExecutionPort` over a `xeno-use` sandbox — the CONFINING implementation.
|
|
3
|
+
*
|
|
4
|
+
* Reached through `RunExecutionEnvironment`, which is what a composition wires
|
|
5
|
+
* and what decides — in ONE lookup — both that this executor serves a run and
|
|
6
|
+
* that the run reports `sandboxed`. Nothing constructs this directly.
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ What remains before a run is actually confined is the BINDING: no
|
|
9
|
+
* composition yet spawns a sandbox the agent RUNS in. `XenoUseRunObserver`
|
|
10
|
+
* spawns an OBSERVATION sandbox, and binding execution to that one is exactly
|
|
11
|
+
* the convenient wrong turn `isolationIsNotObservation.test.ts` exists to pin —
|
|
12
|
+
* a sandbox that is watched is not a sandbox that confines. Everything
|
|
13
|
+
* downstream of the binding is now live, so that step is a spawn plus a
|
|
14
|
+
* `bind({ sandbox })`, not a rewrite.
|
|
15
|
+
*
|
|
16
|
+
* This is the other half of the port `LocalCommandExecutor` exists beside, and
|
|
17
|
+
* the reason the port was built at all: adopting a sandbox becomes a composition
|
|
18
|
+
* change rather than a rewrite at each call site. Where the local executor
|
|
19
|
+
* starts a real process on the user's machine as the signed-in user, this one
|
|
20
|
+
* runs the command inside a container with `--network none`, `--read-only`,
|
|
21
|
+
* `--cap-drop ALL`, a non-root uid, and only the mounts it was given.
|
|
22
|
+
*
|
|
23
|
+
* ## 🔒 Out of process, always — a licensing boundary before a design preference
|
|
24
|
+
*
|
|
25
|
+
* `xeno-use` is AGPL-3.0 and this package is proprietary, so nothing here
|
|
26
|
+
* imports `@xeno-use/*` or links its N-API binding. The request and response
|
|
27
|
+
* shapes are written out by hand and reached over `/v1/use/*` — exactly what
|
|
28
|
+
* `RunObservationSource` and `XenoUseRunObserver` already do, for exactly the
|
|
29
|
+
* same reason. It looks like duplication and is the boundary.
|
|
30
|
+
*
|
|
31
|
+
* ## 🔴 It NEVER falls back to local execution
|
|
32
|
+
*
|
|
33
|
+
* The single most important property in this file, and the one most likely to
|
|
34
|
+
* be "fixed" in later. If the sandbox is unreachable, this returns a FAILED
|
|
35
|
+
* result — it does not quietly run the command on the host instead. A fallback
|
|
36
|
+
* would mean a run reporting itself contained while executing with the user's
|
|
37
|
+
* full privileges, which is strictly worse than having no sandbox at all:
|
|
38
|
+
* without one the report says `none` and the user knows where they stand.
|
|
39
|
+
*
|
|
40
|
+
* Same shape as the convenient wrong turn `isolationIsNotObservation.test.ts`
|
|
41
|
+
* pins one directory over. A sandbox that is watched is not a sandbox that
|
|
42
|
+
* confines; a sandbox that silently degrades to the host does not confine
|
|
43
|
+
* either, and lies about it.
|
|
44
|
+
*
|
|
45
|
+
* ## Why the executor is bound to ONE sandbox
|
|
46
|
+
*
|
|
47
|
+
* `CommandExecutionRequest` carries no run id, deliberately — a call site asks
|
|
48
|
+
* to run a command, not to route one. So the binding happens at construction:
|
|
49
|
+
* the composition makes an executor per run, against that run's sandbox. A
|
|
50
|
+
* resolver taking a run id would put routing in the hot path and make "which
|
|
51
|
+
* sandbox did this actually run in?" a question with a computed answer.
|
|
52
|
+
*/
|
|
53
|
+
import type { CommandExecutionPort, CommandExecutionRequest, CommandExecutionResult } from './CommandExecution.js';
|
|
54
|
+
/** Where the run's directory sits on each side of the mount. */
|
|
55
|
+
export interface SandboxCommandMount {
|
|
56
|
+
/** Host directory holding the run's work, e.g. `D:\work\repo`. */
|
|
57
|
+
hostDirectory: string;
|
|
58
|
+
/** Where it appears inside the sandbox, e.g. `/mnt/xeno/work`. */
|
|
59
|
+
containerDirectory: string;
|
|
60
|
+
}
|
|
61
|
+
export interface SandboxCommandExecutorOptions {
|
|
62
|
+
/** Base URL of the `xeno-use` service, e.g. `http://127.0.0.1:8787`. */
|
|
63
|
+
baseUrl: string;
|
|
64
|
+
/** Bearer token. Its workspace is what authorizes the call. */
|
|
65
|
+
token: string;
|
|
66
|
+
/** The sandbox this executor runs in. One executor, one sandbox. */
|
|
67
|
+
sandboxId: string;
|
|
68
|
+
mount: SandboxCommandMount;
|
|
69
|
+
fetch?: typeof globalThis.fetch;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Maps a host path into container terms.
|
|
73
|
+
*
|
|
74
|
+
* Returns `undefined` when the path is not under the mount — which is not a
|
|
75
|
+
* security check. Confinement comes from the sandbox's filesystem namespace,
|
|
76
|
+
* not from a rule applied at the call: a process can `chdir` after it starts,
|
|
77
|
+
* so a path rule enforced on entry decides nothing. This is a REPRESENTABILITY
|
|
78
|
+
* question — a host directory outside the mount has no name inside the
|
|
79
|
+
* container, so the request cannot be expressed and must be refused rather than
|
|
80
|
+
* silently rewritten to the mount root.
|
|
81
|
+
*
|
|
82
|
+
* Case-insensitive on the host segment because Windows paths are, and the run
|
|
83
|
+
* directory reaching us from a UI and from a config may differ only in case.
|
|
84
|
+
* The CONTAINER half preserves case exactly — Linux paths are case-sensitive
|
|
85
|
+
* and folding them would produce a path that does not exist.
|
|
86
|
+
*/
|
|
87
|
+
export declare function toContainerPath(mount: SandboxCommandMount, hostPath: string): string | undefined;
|
|
88
|
+
export declare class SandboxCommandExecutor implements CommandExecutionPort {
|
|
89
|
+
#private;
|
|
90
|
+
constructor(options: SandboxCommandExecutorOptions);
|
|
91
|
+
execute(request: CommandExecutionRequest): Promise<CommandExecutionResult>;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=SandboxCommandExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SandboxCommandExecutor.d.ts","sourceRoot":"","sources":["../../src/isolation/SandboxCommandExecutor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,uBAAuB,CAAA;AAE9B,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAA;IACrB,kEAAkE;IAClE,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,6BAA6B;IAC5C,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,mBAAmB,CAAA;IAC1B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC;AAiBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAapB;AAED,qBAAa,sBAAuB,YAAW,oBAAoB;;gBAOrD,OAAO,EAAE,6BAA6B;IAQ5C,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC;CA2FjF"}
|