@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.
Files changed (482) hide show
  1. package/LICENSE +67 -0
  2. package/dist/acp/AcpAgentRegistryService.d.ts +77 -0
  3. package/dist/acp/AcpAgentRegistryService.d.ts.map +1 -0
  4. package/dist/acp/AcpAgentRegistryService.js +754 -0
  5. package/dist/acp/AcpAgentRegistryService.js.map +1 -0
  6. package/dist/acp/AcpAgentTurnExecutionAdapter.d.ts +56 -0
  7. package/dist/acp/AcpAgentTurnExecutionAdapter.d.ts.map +1 -0
  8. package/dist/acp/AcpAgentTurnExecutionAdapter.js +323 -0
  9. package/dist/acp/AcpAgentTurnExecutionAdapter.js.map +1 -0
  10. package/dist/acp/AcpApprovalPortAdapter.d.ts +41 -0
  11. package/dist/acp/AcpApprovalPortAdapter.d.ts.map +1 -0
  12. package/dist/acp/AcpApprovalPortAdapter.js +82 -0
  13. package/dist/acp/AcpApprovalPortAdapter.js.map +1 -0
  14. package/dist/acp/AcpCoordinationBridge.d.ts +13 -0
  15. package/dist/acp/AcpCoordinationBridge.d.ts.map +1 -0
  16. package/dist/acp/AcpCoordinationBridge.js +13 -0
  17. package/dist/acp/AcpCoordinationBridge.js.map +1 -0
  18. package/dist/acp/AcpDiagnosticsService.d.ts +61 -0
  19. package/dist/acp/AcpDiagnosticsService.d.ts.map +1 -0
  20. package/dist/acp/AcpDiagnosticsService.js +203 -0
  21. package/dist/acp/AcpDiagnosticsService.js.map +1 -0
  22. package/dist/acp/AcpExternalCertificationHarness.d.ts +47 -0
  23. package/dist/acp/AcpExternalCertificationHarness.d.ts.map +1 -0
  24. package/dist/acp/AcpExternalCertificationHarness.js +176 -0
  25. package/dist/acp/AcpExternalCertificationHarness.js.map +1 -0
  26. package/dist/acp/AcpHostBridge.d.ts +81 -0
  27. package/dist/acp/AcpHostBridge.d.ts.map +1 -0
  28. package/dist/acp/AcpHostBridge.js +101 -0
  29. package/dist/acp/AcpHostBridge.js.map +1 -0
  30. package/dist/acp/AcpInteractivePermissionBridge.d.ts +77 -0
  31. package/dist/acp/AcpInteractivePermissionBridge.d.ts.map +1 -0
  32. package/dist/acp/AcpInteractivePermissionBridge.js +127 -0
  33. package/dist/acp/AcpInteractivePermissionBridge.js.map +1 -0
  34. package/dist/acp/AcpPermissionBridge.d.ts +19 -0
  35. package/dist/acp/AcpPermissionBridge.d.ts.map +1 -0
  36. package/dist/acp/AcpPermissionBridge.js +110 -0
  37. package/dist/acp/AcpPermissionBridge.js.map +1 -0
  38. package/dist/acp/AcpPermissionPolicy.d.ts +111 -0
  39. package/dist/acp/AcpPermissionPolicy.d.ts.map +1 -0
  40. package/dist/acp/AcpPermissionPolicy.js +167 -0
  41. package/dist/acp/AcpPermissionPolicy.js.map +1 -0
  42. package/dist/acp/AcpProcessSupervisor.d.ts +134 -0
  43. package/dist/acp/AcpProcessSupervisor.d.ts.map +1 -0
  44. package/dist/acp/AcpProcessSupervisor.js +674 -0
  45. package/dist/acp/AcpProcessSupervisor.js.map +1 -0
  46. package/dist/acp/AcpProviderApprovalService.d.ts +27 -0
  47. package/dist/acp/AcpProviderApprovalService.d.ts.map +1 -0
  48. package/dist/acp/AcpProviderApprovalService.js +128 -0
  49. package/dist/acp/AcpProviderApprovalService.js.map +1 -0
  50. package/dist/acp/AcpProviderCatalogService.d.ts +69 -0
  51. package/dist/acp/AcpProviderCatalogService.d.ts.map +1 -0
  52. package/dist/acp/AcpProviderCatalogService.js +707 -0
  53. package/dist/acp/AcpProviderCatalogService.js.map +1 -0
  54. package/dist/acp/AcpProviderModelService.d.ts +6 -0
  55. package/dist/acp/AcpProviderModelService.d.ts.map +1 -0
  56. package/dist/acp/AcpProviderModelService.js +274 -0
  57. package/dist/acp/AcpProviderModelService.js.map +1 -0
  58. package/dist/acp/AcpProviderVersionReadiness.d.ts +6 -0
  59. package/dist/acp/AcpProviderVersionReadiness.d.ts.map +1 -0
  60. package/dist/acp/AcpProviderVersionReadiness.js +100 -0
  61. package/dist/acp/AcpProviderVersionReadiness.js.map +1 -0
  62. package/dist/acp/AcpRuntimeEventMapper.d.ts +16 -0
  63. package/dist/acp/AcpRuntimeEventMapper.d.ts.map +1 -0
  64. package/dist/acp/AcpRuntimeEventMapper.js +326 -0
  65. package/dist/acp/AcpRuntimeEventMapper.js.map +1 -0
  66. package/dist/acp/AcpSessionService.d.ts +65 -0
  67. package/dist/acp/AcpSessionService.d.ts.map +1 -0
  68. package/dist/acp/AcpSessionService.js +931 -0
  69. package/dist/acp/AcpSessionService.js.map +1 -0
  70. package/dist/acp/DurableAcpPermissionPolicyStore.d.ts +25 -0
  71. package/dist/acp/DurableAcpPermissionPolicyStore.d.ts.map +1 -0
  72. package/dist/acp/DurableAcpPermissionPolicyStore.js +100 -0
  73. package/dist/acp/DurableAcpPermissionPolicyStore.js.map +1 -0
  74. package/dist/acp/acpCommandSafety.d.ts +63 -0
  75. package/dist/acp/acpCommandSafety.d.ts.map +1 -0
  76. package/dist/acp/acpCommandSafety.js +90 -0
  77. package/dist/acp/acpCommandSafety.js.map +1 -0
  78. package/dist/acp/acpErrors.d.ts +47 -0
  79. package/dist/acp/acpErrors.d.ts.map +1 -0
  80. package/dist/acp/acpErrors.js +93 -0
  81. package/dist/acp/acpErrors.js.map +1 -0
  82. package/dist/acp/acpRedaction.d.ts +9 -0
  83. package/dist/acp/acpRedaction.d.ts.map +1 -0
  84. package/dist/acp/acpRedaction.js +69 -0
  85. package/dist/acp/acpRedaction.js.map +1 -0
  86. package/dist/acp/acpSessionResume.d.ts +8 -0
  87. package/dist/acp/acpSessionResume.d.ts.map +1 -0
  88. package/dist/acp/acpSessionResume.js +31 -0
  89. package/dist/acp/acpSessionResume.js.map +1 -0
  90. package/dist/acp/acpTypes.d.ts +467 -0
  91. package/dist/acp/acpTypes.d.ts.map +1 -0
  92. package/dist/acp/acpTypes.js +2 -0
  93. package/dist/acp/acpTypes.js.map +1 -0
  94. package/dist/agent/chooseDirectoryBridge.d.ts +29 -0
  95. package/dist/agent/chooseDirectoryBridge.d.ts.map +1 -0
  96. package/dist/agent/chooseDirectoryBridge.js +116 -0
  97. package/dist/agent/chooseDirectoryBridge.js.map +1 -0
  98. package/dist/agent/permissionProfiles.d.ts +29 -0
  99. package/dist/agent/permissionProfiles.d.ts.map +1 -0
  100. package/dist/agent/permissionProfiles.js +107 -0
  101. package/dist/agent/permissionProfiles.js.map +1 -0
  102. package/dist/agent/runtimeAuthorityPrompt.d.ts +13 -0
  103. package/dist/agent/runtimeAuthorityPrompt.d.ts.map +1 -0
  104. package/dist/agent/runtimeAuthorityPrompt.js +45 -0
  105. package/dist/agent/runtimeAuthorityPrompt.js.map +1 -0
  106. package/dist/agent/runtimeModeOutputGuard.d.ts +6 -0
  107. package/dist/agent/runtimeModeOutputGuard.d.ts.map +1 -0
  108. package/dist/agent/runtimeModeOutputGuard.js +40 -0
  109. package/dist/agent/runtimeModeOutputGuard.js.map +1 -0
  110. package/dist/agent/workspacePlacementBridge.d.ts +29 -0
  111. package/dist/agent/workspacePlacementBridge.d.ts.map +1 -0
  112. package/dist/agent/workspacePlacementBridge.js +143 -0
  113. package/dist/agent/workspacePlacementBridge.js.map +1 -0
  114. package/dist/agentSearch/AgentSearchService.d.ts +81 -0
  115. package/dist/agentSearch/AgentSearchService.d.ts.map +1 -0
  116. package/dist/agentSearch/AgentSearchService.js +1038 -0
  117. package/dist/agentSearch/AgentSearchService.js.map +1 -0
  118. package/dist/agentSearch/JsonInvertedIndexAdapter.d.ts +44 -0
  119. package/dist/agentSearch/JsonInvertedIndexAdapter.d.ts.map +1 -0
  120. package/dist/agentSearch/JsonInvertedIndexAdapter.js +307 -0
  121. package/dist/agentSearch/JsonInvertedIndexAdapter.js.map +1 -0
  122. package/dist/agentSearch/SearchIndexAdapter.d.ts +33 -0
  123. package/dist/agentSearch/SearchIndexAdapter.d.ts.map +1 -0
  124. package/dist/agentSearch/SearchIndexAdapter.js +2 -0
  125. package/dist/agentSearch/SearchIndexAdapter.js.map +1 -0
  126. package/dist/agentSearch/SearchSourceWatcher.d.ts +29 -0
  127. package/dist/agentSearch/SearchSourceWatcher.d.ts.map +1 -0
  128. package/dist/agentSearch/SearchSourceWatcher.js +150 -0
  129. package/dist/agentSearch/SearchSourceWatcher.js.map +1 -0
  130. package/dist/agentSearch/SqliteFtsIndexAdapter.d.ts +58 -0
  131. package/dist/agentSearch/SqliteFtsIndexAdapter.d.ts.map +1 -0
  132. package/dist/agentSearch/SqliteFtsIndexAdapter.js +420 -0
  133. package/dist/agentSearch/SqliteFtsIndexAdapter.js.map +1 -0
  134. package/dist/agentSearch/conversationIndexer.d.ts +69 -0
  135. package/dist/agentSearch/conversationIndexer.d.ts.map +1 -0
  136. package/dist/agentSearch/conversationIndexer.js +313 -0
  137. package/dist/agentSearch/conversationIndexer.js.map +1 -0
  138. package/dist/agentSearch/searchTypes.d.ts +264 -0
  139. package/dist/agentSearch/searchTypes.d.ts.map +1 -0
  140. package/dist/agentSearch/searchTypes.js +2 -0
  141. package/dist/agentSearch/searchTypes.js.map +1 -0
  142. package/dist/agentSearch/searchUtils.d.ts +12 -0
  143. package/dist/agentSearch/searchUtils.d.ts.map +1 -0
  144. package/dist/agentSearch/searchUtils.js +125 -0
  145. package/dist/agentSearch/searchUtils.js.map +1 -0
  146. package/dist/agentSearch/workspaceMetadataIndexer.d.ts +3 -0
  147. package/dist/agentSearch/workspaceMetadataIndexer.d.ts.map +1 -0
  148. package/dist/agentSearch/workspaceMetadataIndexer.js +125 -0
  149. package/dist/agentSearch/workspaceMetadataIndexer.js.map +1 -0
  150. package/dist/cli/CliControlPlaneService.d.ts +269 -0
  151. package/dist/cli/CliControlPlaneService.d.ts.map +1 -0
  152. package/dist/cli/CliControlPlaneService.js +1874 -0
  153. package/dist/cli/CliControlPlaneService.js.map +1 -0
  154. package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.d.ts +91 -0
  155. package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.d.ts.map +1 -0
  156. package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.js +379 -0
  157. package/dist/cloud/XenoCloudAgentTurnExecutionAdapter.js.map +1 -0
  158. package/dist/codebase/CodebaseIntelligenceService.d.ts +68 -0
  159. package/dist/codebase/CodebaseIntelligenceService.d.ts.map +1 -0
  160. package/dist/codebase/CodebaseIntelligenceService.js +1717 -0
  161. package/dist/codebase/CodebaseIntelligenceService.js.map +1 -0
  162. package/dist/codebase/LanguageServerProcessManager.d.ts +85 -0
  163. package/dist/codebase/LanguageServerProcessManager.d.ts.map +1 -0
  164. package/dist/codebase/LanguageServerProcessManager.js +607 -0
  165. package/dist/codebase/LanguageServerProcessManager.js.map +1 -0
  166. package/dist/codebase/codeTypes.d.ts +485 -0
  167. package/dist/codebase/codeTypes.d.ts.map +1 -0
  168. package/dist/codebase/codeTypes.js +2 -0
  169. package/dist/codebase/codeTypes.js.map +1 -0
  170. package/dist/codebase/codeUtils.d.ts +24 -0
  171. package/dist/codebase/codeUtils.d.ts.map +1 -0
  172. package/dist/codebase/codeUtils.js +177 -0
  173. package/dist/codebase/codeUtils.js.map +1 -0
  174. package/dist/codebase/contextPacks.d.ts +18 -0
  175. package/dist/codebase/contextPacks.d.ts.map +1 -0
  176. package/dist/codebase/contextPacks.js +180 -0
  177. package/dist/codebase/contextPacks.js.map +1 -0
  178. package/dist/codebase/dependencyGraph.d.ts +3 -0
  179. package/dist/codebase/dependencyGraph.d.ts.map +1 -0
  180. package/dist/codebase/dependencyGraph.js +209 -0
  181. package/dist/codebase/dependencyGraph.js.map +1 -0
  182. package/dist/codebase/fileIndexer.d.ts +27 -0
  183. package/dist/codebase/fileIndexer.d.ts.map +1 -0
  184. package/dist/codebase/fileIndexer.js +167 -0
  185. package/dist/codebase/fileIndexer.js.map +1 -0
  186. package/dist/codebase/symbolIndexer.d.ts +3 -0
  187. package/dist/codebase/symbolIndexer.d.ts.map +1 -0
  188. package/dist/codebase/symbolIndexer.js +184 -0
  189. package/dist/codebase/symbolIndexer.js.map +1 -0
  190. package/dist/codebase/whatChanged.d.ts +4 -0
  191. package/dist/codebase/whatChanged.d.ts.map +1 -0
  192. package/dist/codebase/whatChanged.js +138 -0
  193. package/dist/codebase/whatChanged.js.map +1 -0
  194. package/dist/coordination/CoordinationService.d.ts +166 -0
  195. package/dist/coordination/CoordinationService.d.ts.map +1 -0
  196. package/dist/coordination/CoordinationService.js +247 -0
  197. package/dist/coordination/CoordinationService.js.map +1 -0
  198. package/dist/coordination/claims.d.ts +122 -0
  199. package/dist/coordination/claims.d.ts.map +1 -0
  200. package/dist/coordination/claims.js +196 -0
  201. package/dist/coordination/claims.js.map +1 -0
  202. package/dist/coordination/coordinationTools.d.ts +40 -0
  203. package/dist/coordination/coordinationTools.d.ts.map +1 -0
  204. package/dist/coordination/coordinationTools.js +92 -0
  205. package/dist/coordination/coordinationTools.js.map +1 -0
  206. package/dist/coordination/laneBridge.d.ts +84 -0
  207. package/dist/coordination/laneBridge.d.ts.map +1 -0
  208. package/dist/coordination/laneBridge.js +86 -0
  209. package/dist/coordination/laneBridge.js.map +1 -0
  210. package/dist/coordination/messages.d.ts +225 -0
  211. package/dist/coordination/messages.d.ts.map +1 -0
  212. package/dist/coordination/messages.js +335 -0
  213. package/dist/coordination/messages.js.map +1 -0
  214. package/dist/coordination/permissionWaitRegistry.d.ts +32 -0
  215. package/dist/coordination/permissionWaitRegistry.d.ts.map +1 -0
  216. package/dist/coordination/permissionWaitRegistry.js +59 -0
  217. package/dist/coordination/permissionWaitRegistry.js.map +1 -0
  218. package/dist/coordination/query.d.ts +187 -0
  219. package/dist/coordination/query.d.ts.map +1 -0
  220. package/dist/coordination/query.js +138 -0
  221. package/dist/coordination/query.js.map +1 -0
  222. package/dist/coordination/renderInbox.d.ts +15 -0
  223. package/dist/coordination/renderInbox.d.ts.map +1 -0
  224. package/dist/coordination/renderInbox.js +19 -0
  225. package/dist/coordination/renderInbox.js.map +1 -0
  226. package/dist/coordination/runtimeEvents.d.ts +53 -0
  227. package/dist/coordination/runtimeEvents.d.ts.map +1 -0
  228. package/dist/coordination/runtimeEvents.js +112 -0
  229. package/dist/coordination/runtimeEvents.js.map +1 -0
  230. package/dist/detachedHostService.d.ts +77 -0
  231. package/dist/detachedHostService.d.ts.map +1 -0
  232. package/dist/detachedHostService.js +66 -0
  233. package/dist/detachedHostService.js.map +1 -0
  234. package/dist/detachedHostSupervisor.d.ts +102 -0
  235. package/dist/detachedHostSupervisor.d.ts.map +1 -0
  236. package/dist/detachedHostSupervisor.js +168 -0
  237. package/dist/detachedHostSupervisor.js.map +1 -0
  238. package/dist/durableRuntimeEventStore.d.ts +49 -0
  239. package/dist/durableRuntimeEventStore.d.ts.map +1 -0
  240. package/dist/durableRuntimeEventStore.js +364 -0
  241. package/dist/durableRuntimeEventStore.js.map +1 -0
  242. package/dist/engineering/EngineeringWorkbenchService.d.ts +142 -0
  243. package/dist/engineering/EngineeringWorkbenchService.d.ts.map +1 -0
  244. package/dist/engineering/EngineeringWorkbenchService.js +2301 -0
  245. package/dist/engineering/EngineeringWorkbenchService.js.map +1 -0
  246. package/dist/engineering/LandingService.d.ts +112 -0
  247. package/dist/engineering/LandingService.d.ts.map +1 -0
  248. package/dist/engineering/LandingService.js +239 -0
  249. package/dist/engineering/LandingService.js.map +1 -0
  250. package/dist/engineering/engineeringTypes.d.ts +2 -0
  251. package/dist/engineering/engineeringTypes.d.ts.map +1 -0
  252. package/dist/engineering/engineeringTypes.js +2 -0
  253. package/dist/engineering/engineeringTypes.js.map +1 -0
  254. package/dist/engineering/patchReview.d.ts +11 -0
  255. package/dist/engineering/patchReview.d.ts.map +1 -0
  256. package/dist/engineering/patchReview.js +174 -0
  257. package/dist/engineering/patchReview.js.map +1 -0
  258. package/dist/index.d.ts +834 -0
  259. package/dist/index.d.ts.map +1 -0
  260. package/dist/index.js +3242 -0
  261. package/dist/index.js.map +1 -0
  262. package/dist/intake/IntakeService.d.ts +84 -0
  263. package/dist/intake/IntakeService.d.ts.map +1 -0
  264. package/dist/intake/IntakeService.js +117 -0
  265. package/dist/intake/IntakeService.js.map +1 -0
  266. package/dist/intake/RepositoryTodoIntakeSource.d.ts +72 -0
  267. package/dist/intake/RepositoryTodoIntakeSource.d.ts.map +1 -0
  268. package/dist/intake/RepositoryTodoIntakeSource.js +168 -0
  269. package/dist/intake/RepositoryTodoIntakeSource.js.map +1 -0
  270. package/dist/intake/WorkspaceTodoIntakeSource.d.ts +53 -0
  271. package/dist/intake/WorkspaceTodoIntakeSource.d.ts.map +1 -0
  272. package/dist/intake/WorkspaceTodoIntakeSource.js +81 -0
  273. package/dist/intake/WorkspaceTodoIntakeSource.js.map +1 -0
  274. package/dist/isolation/CommandExecution.d.ts +132 -0
  275. package/dist/isolation/CommandExecution.d.ts.map +1 -0
  276. package/dist/isolation/CommandExecution.js +48 -0
  277. package/dist/isolation/CommandExecution.js.map +1 -0
  278. package/dist/isolation/LocalCommandExecutor.d.ts +27 -0
  279. package/dist/isolation/LocalCommandExecutor.d.ts.map +1 -0
  280. package/dist/isolation/LocalCommandExecutor.js +97 -0
  281. package/dist/isolation/LocalCommandExecutor.js.map +1 -0
  282. package/dist/isolation/RunExecutionEnvironment.d.ts +135 -0
  283. package/dist/isolation/RunExecutionEnvironment.d.ts.map +1 -0
  284. package/dist/isolation/RunExecutionEnvironment.js +206 -0
  285. package/dist/isolation/RunExecutionEnvironment.js.map +1 -0
  286. package/dist/isolation/RunIsolationService.d.ts +90 -0
  287. package/dist/isolation/RunIsolationService.d.ts.map +1 -0
  288. package/dist/isolation/RunIsolationService.js +86 -0
  289. package/dist/isolation/RunIsolationService.js.map +1 -0
  290. package/dist/isolation/SandboxCommandExecutor.d.ts +93 -0
  291. package/dist/isolation/SandboxCommandExecutor.d.ts.map +1 -0
  292. package/dist/isolation/SandboxCommandExecutor.js +189 -0
  293. package/dist/isolation/SandboxCommandExecutor.js.map +1 -0
  294. package/dist/knowledge/WorkspaceKnowledgeService.d.ts +71 -0
  295. package/dist/knowledge/WorkspaceKnowledgeService.d.ts.map +1 -0
  296. package/dist/knowledge/WorkspaceKnowledgeService.js +103 -0
  297. package/dist/knowledge/WorkspaceKnowledgeService.js.map +1 -0
  298. package/dist/localHostAuthority.d.ts +24 -0
  299. package/dist/localHostAuthority.d.ts.map +1 -0
  300. package/dist/localHostAuthority.js +87 -0
  301. package/dist/localHostAuthority.js.map +1 -0
  302. package/dist/localHostLease.d.ts +51 -0
  303. package/dist/localHostLease.d.ts.map +1 -0
  304. package/dist/localHostLease.js +167 -0
  305. package/dist/localHostLease.js.map +1 -0
  306. package/dist/localHostPaths.d.ts +30 -0
  307. package/dist/localHostPaths.d.ts.map +1 -0
  308. package/dist/localHostPaths.js +60 -0
  309. package/dist/localHostPaths.js.map +1 -0
  310. package/dist/localRpcTransport.d.ts +21 -0
  311. package/dist/localRpcTransport.d.ts.map +1 -0
  312. package/dist/localRpcTransport.js +423 -0
  313. package/dist/localRpcTransport.js.map +1 -0
  314. package/dist/node.d.ts +104 -0
  315. package/dist/node.d.ts.map +1 -0
  316. package/dist/node.js +103 -0
  317. package/dist/node.js.map +1 -0
  318. package/dist/observation/DirectoryBaselineScanner.d.ts +44 -0
  319. package/dist/observation/DirectoryBaselineScanner.d.ts.map +1 -0
  320. package/dist/observation/DirectoryBaselineScanner.js +112 -0
  321. package/dist/observation/DirectoryBaselineScanner.js.map +1 -0
  322. package/dist/observation/MountContentReader.d.ts +63 -0
  323. package/dist/observation/MountContentReader.d.ts.map +1 -0
  324. package/dist/observation/MountContentReader.js +158 -0
  325. package/dist/observation/MountContentReader.js.map +1 -0
  326. package/dist/observation/RunObservationService.d.ts +229 -0
  327. package/dist/observation/RunObservationService.d.ts.map +1 -0
  328. package/dist/observation/RunObservationService.js +248 -0
  329. package/dist/observation/RunObservationService.js.map +1 -0
  330. package/dist/observation/XenoUseObservationSource.d.ts +42 -0
  331. package/dist/observation/XenoUseObservationSource.d.ts.map +1 -0
  332. package/dist/observation/XenoUseObservationSource.js +104 -0
  333. package/dist/observation/XenoUseObservationSource.js.map +1 -0
  334. package/dist/observation/XenoUseRunObserver.d.ts +140 -0
  335. package/dist/observation/XenoUseRunObserver.d.ts.map +1 -0
  336. package/dist/observation/XenoUseRunObserver.js +256 -0
  337. package/dist/observation/XenoUseRunObserver.js.map +1 -0
  338. package/dist/pluginMcp/PluginMcpManagerService.d.ts +141 -0
  339. package/dist/pluginMcp/PluginMcpManagerService.d.ts.map +1 -0
  340. package/dist/pluginMcp/PluginMcpManagerService.js +1821 -0
  341. package/dist/pluginMcp/PluginMcpManagerService.js.map +1 -0
  342. package/dist/pluginMcp/pluginMcpTypes.d.ts +349 -0
  343. package/dist/pluginMcp/pluginMcpTypes.d.ts.map +1 -0
  344. package/dist/pluginMcp/pluginMcpTypes.js +2 -0
  345. package/dist/pluginMcp/pluginMcpTypes.js.map +1 -0
  346. package/dist/policy/WorkspacePolicyService.d.ts +83 -0
  347. package/dist/policy/WorkspacePolicyService.d.ts.map +1 -0
  348. package/dist/policy/WorkspacePolicyService.js +809 -0
  349. package/dist/policy/WorkspacePolicyService.js.map +1 -0
  350. package/dist/policy/policyGuard.d.ts +27 -0
  351. package/dist/policy/policyGuard.d.ts.map +1 -0
  352. package/dist/policy/policyGuard.js +143 -0
  353. package/dist/policy/policyGuard.js.map +1 -0
  354. package/dist/policy/policyTypes.d.ts +190 -0
  355. package/dist/policy/policyTypes.d.ts.map +1 -0
  356. package/dist/policy/policyTypes.js +2 -0
  357. package/dist/policy/policyTypes.js.map +1 -0
  358. package/dist/runtime/RuntimeEventStore.d.ts +42 -0
  359. package/dist/runtime/RuntimeEventStore.d.ts.map +1 -0
  360. package/dist/runtime/RuntimeEventStore.js +412 -0
  361. package/dist/runtime/RuntimeEventStore.js.map +1 -0
  362. package/dist/runtime/RuntimeEventStoreRepositoryAdapter.d.ts +21 -0
  363. package/dist/runtime/RuntimeEventStoreRepositoryAdapter.d.ts.map +1 -0
  364. package/dist/runtime/RuntimeEventStoreRepositoryAdapter.js +41 -0
  365. package/dist/runtime/RuntimeEventStoreRepositoryAdapter.js.map +1 -0
  366. package/dist/runtime/RuntimeTimelineProjection.d.ts +5 -0
  367. package/dist/runtime/RuntimeTimelineProjection.d.ts.map +1 -0
  368. package/dist/runtime/RuntimeTimelineProjection.js +705 -0
  369. package/dist/runtime/RuntimeTimelineProjection.js.map +1 -0
  370. package/dist/runtime/runtimeEventTypes.d.ts +73 -0
  371. package/dist/runtime/runtimeEventTypes.d.ts.map +1 -0
  372. package/dist/runtime/runtimeEventTypes.js +2 -0
  373. package/dist/runtime/runtimeEventTypes.js.map +1 -0
  374. package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.d.ts +117 -0
  375. package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.d.ts.map +1 -0
  376. package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.js +214 -0
  377. package/dist/sdk/SdkNativeAgentTurnExecutionAdapter.js.map +1 -0
  378. package/dist/session/AgentSessionService.d.ts +285 -0
  379. package/dist/session/AgentSessionService.d.ts.map +1 -0
  380. package/dist/session/AgentSessionService.js +444 -0
  381. package/dist/session/AgentSessionService.js.map +1 -0
  382. package/dist/session/bufferedSessionPty.d.ts +27 -0
  383. package/dist/session/bufferedSessionPty.d.ts.map +1 -0
  384. package/dist/session/bufferedSessionPty.js +49 -0
  385. package/dist/session/bufferedSessionPty.js.map +1 -0
  386. package/dist/session/renderSupport.d.ts +53 -0
  387. package/dist/session/renderSupport.d.ts.map +1 -0
  388. package/dist/session/renderSupport.js +41 -0
  389. package/dist/session/renderSupport.js.map +1 -0
  390. package/dist/session/runtimeEventChannel.d.ts +56 -0
  391. package/dist/session/runtimeEventChannel.d.ts.map +1 -0
  392. package/dist/session/runtimeEventChannel.js +53 -0
  393. package/dist/session/runtimeEventChannel.js.map +1 -0
  394. package/dist/state/JsonAgentStateRepository.d.ts +29 -0
  395. package/dist/state/JsonAgentStateRepository.d.ts.map +1 -0
  396. package/dist/state/JsonAgentStateRepository.js +165 -0
  397. package/dist/state/JsonAgentStateRepository.js.map +1 -0
  398. package/dist/state/SqliteAgentStateRepository.d.ts +58 -0
  399. package/dist/state/SqliteAgentStateRepository.d.ts.map +1 -0
  400. package/dist/state/SqliteAgentStateRepository.js +777 -0
  401. package/dist/state/SqliteAgentStateRepository.js.map +1 -0
  402. package/dist/state/createAgentStateRepository.d.ts +4 -0
  403. package/dist/state/createAgentStateRepository.d.ts.map +1 -0
  404. package/dist/state/createAgentStateRepository.js +12 -0
  405. package/dist/state/createAgentStateRepository.js.map +1 -0
  406. package/dist/state/stateSanitizers.d.ts +7 -0
  407. package/dist/state/stateSanitizers.d.ts.map +1 -0
  408. package/dist/state/stateSanitizers.js +87 -0
  409. package/dist/state/stateSanitizers.js.map +1 -0
  410. package/dist/subagents/AcpSubagentExecutionAdapter.d.ts +12 -0
  411. package/dist/subagents/AcpSubagentExecutionAdapter.d.ts.map +1 -0
  412. package/dist/subagents/AcpSubagentExecutionAdapter.js +119 -0
  413. package/dist/subagents/AcpSubagentExecutionAdapter.js.map +1 -0
  414. package/dist/subagents/CliSubagentExecutionAdapter.d.ts +13 -0
  415. package/dist/subagents/CliSubagentExecutionAdapter.d.ts.map +1 -0
  416. package/dist/subagents/CliSubagentExecutionAdapter.js +217 -0
  417. package/dist/subagents/CliSubagentExecutionAdapter.js.map +1 -0
  418. package/dist/subagents/HostTurnSubagentExecutionAdapter.d.ts +78 -0
  419. package/dist/subagents/HostTurnSubagentExecutionAdapter.d.ts.map +1 -0
  420. package/dist/subagents/HostTurnSubagentExecutionAdapter.js +160 -0
  421. package/dist/subagents/HostTurnSubagentExecutionAdapter.js.map +1 -0
  422. package/dist/subagents/SubagentRunService.d.ts +103 -0
  423. package/dist/subagents/SubagentRunService.d.ts.map +1 -0
  424. package/dist/subagents/SubagentRunService.js +1183 -0
  425. package/dist/subagents/SubagentRunService.js.map +1 -0
  426. package/dist/subagents/SubagentScheduler.d.ts +167 -0
  427. package/dist/subagents/SubagentScheduler.d.ts.map +1 -0
  428. package/dist/subagents/SubagentScheduler.js +530 -0
  429. package/dist/subagents/SubagentScheduler.js.map +1 -0
  430. package/dist/subagents/TeamAgentRouter.d.ts +104 -0
  431. package/dist/subagents/TeamAgentRouter.d.ts.map +1 -0
  432. package/dist/subagents/TeamAgentRouter.js +435 -0
  433. package/dist/subagents/TeamAgentRouter.js.map +1 -0
  434. package/dist/subagents/capabilityMatcher.d.ts +3 -0
  435. package/dist/subagents/capabilityMatcher.d.ts.map +1 -0
  436. package/dist/subagents/capabilityMatcher.js +127 -0
  437. package/dist/subagents/capabilityMatcher.js.map +1 -0
  438. package/dist/subagents/subagentRunPort.d.ts +43 -0
  439. package/dist/subagents/subagentRunPort.d.ts.map +1 -0
  440. package/dist/subagents/subagentRunPort.js +24 -0
  441. package/dist/subagents/subagentRunPort.js.map +1 -0
  442. package/dist/subagents/subagentTypes.d.ts +330 -0
  443. package/dist/subagents/subagentTypes.d.ts.map +1 -0
  444. package/dist/subagents/subagentTypes.js +2 -0
  445. package/dist/subagents/subagentTypes.js.map +1 -0
  446. package/dist/subagents/subagentWorkspaceAuthority.d.ts +29 -0
  447. package/dist/subagents/subagentWorkspaceAuthority.d.ts.map +1 -0
  448. package/dist/subagents/subagentWorkspaceAuthority.js +173 -0
  449. package/dist/subagents/subagentWorkspaceAuthority.js.map +1 -0
  450. package/dist/support/SupportDiagnosticsService.d.ts +87 -0
  451. package/dist/support/SupportDiagnosticsService.d.ts.map +1 -0
  452. package/dist/support/SupportDiagnosticsService.js +1199 -0
  453. package/dist/support/SupportDiagnosticsService.js.map +1 -0
  454. package/dist/turns/DurableInterruptedTurnStore.d.ts +14 -0
  455. package/dist/turns/DurableInterruptedTurnStore.d.ts.map +1 -0
  456. package/dist/turns/DurableInterruptedTurnStore.js +63 -0
  457. package/dist/turns/DurableInterruptedTurnStore.js.map +1 -0
  458. package/dist/turns/interruptedTurns.d.ts +50 -0
  459. package/dist/turns/interruptedTurns.d.ts.map +1 -0
  460. package/dist/turns/interruptedTurns.js +54 -0
  461. package/dist/turns/interruptedTurns.js.map +1 -0
  462. package/dist/turns/turnAdmission.d.ts +113 -0
  463. package/dist/turns/turnAdmission.d.ts.map +1 -0
  464. package/dist/turns/turnAdmission.js +136 -0
  465. package/dist/turns/turnAdmission.js.map +1 -0
  466. package/dist/workspace/WorkspaceHostService.d.ts +126 -0
  467. package/dist/workspace/WorkspaceHostService.d.ts.map +1 -0
  468. package/dist/workspace/WorkspaceHostService.js +841 -0
  469. package/dist/workspace/WorkspaceHostService.js.map +1 -0
  470. package/dist/workspace/WorkspaceShellService.d.ts +71 -0
  471. package/dist/workspace/WorkspaceShellService.d.ts.map +1 -0
  472. package/dist/workspace/WorkspaceShellService.js +273 -0
  473. package/dist/workspace/WorkspaceShellService.js.map +1 -0
  474. package/dist/workspace/fileAssociations.d.ts +12 -0
  475. package/dist/workspace/fileAssociations.d.ts.map +1 -0
  476. package/dist/workspace/fileAssociations.js +202 -0
  477. package/dist/workspace/fileAssociations.js.map +1 -0
  478. package/dist/workspace/scrollbackBuffer.d.ts +48 -0
  479. package/dist/workspace/scrollbackBuffer.d.ts.map +1 -0
  480. package/dist/workspace/scrollbackBuffer.js +94 -0
  481. package/dist/workspace/scrollbackBuffer.js.map +1 -0
  482. package/package.json +42 -0
@@ -0,0 +1,841 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { commandSucceeded } from '../isolation/CommandExecution.js';
3
+ import { LocalCommandExecutor } from '../isolation/LocalCommandExecutor.js';
4
+ /**
5
+ * ⚠️ This file has THREE process starts. Only ONE is adopted, and naming all
6
+ * three matters — an earlier version of this note said "the PTY is not part of
7
+ * this adoption", which was true and skipped `startTerminal` entirely. Naming
8
+ * one of several paths is the same mistake as naming the wrong one.
9
+ *
10
+ * 1. `runCommand` — ADOPTED. Runs through `CommandExecutionPort`.
11
+ * 2. `startTerminal` — still spawns directly. A fire-and-forget session that
12
+ * outlives its request and is reaped by its own timer, so it is not the
13
+ * port's one-call-one-result shape either.
14
+ * 3. `startPty` — a streaming, interactive session: stdin, resize, continuous
15
+ * output. `xeno-use`'s exec surface has the SAME gap — `Command::output()`
16
+ * buffers to completion — so streaming exec is recorded there as a new
17
+ * capability rather than a defect. Forcing either through this port would
18
+ * mean inventing a shape neither side has.
19
+ */
20
+ const commandExecutor = new LocalCommandExecutor();
21
+ import { closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync, } from 'node:fs';
22
+ import { dirname, extname, isAbsolute, join, relative, resolve } from 'node:path';
23
+ import { evaluateIpcPolicy } from '../policy/policyGuard.js';
24
+ import { ScrollbackBuffer } from './scrollbackBuffer.js';
25
+ const MAX_FILE_BYTES = 1024 * 1024;
26
+ const MAX_COMMAND_OUTPUT_BYTES = 200_000;
27
+ const MAX_PTY_SCROLLBACK_BYTES = 500_000;
28
+ const MAX_GRANTS = 1_000;
29
+ /**
30
+ * Host-owned workspace authority, migrated from XENO Hub's workspace IPC
31
+ * implementation. The renderer can narrow trusted grants but cannot mint new
32
+ * roots; only the desktop/Hub composition calls grantDirectory after a native
33
+ * user picker or an audited migration.
34
+ */
35
+ export class WorkspaceHostService {
36
+ grantStorePath;
37
+ applicationGrantStorePath;
38
+ managedConversationRoot;
39
+ terminalSessions = new Map();
40
+ ptySessions = new Map();
41
+ grants = new Map();
42
+ applicationGrants = new Map();
43
+ eventSink = () => { };
44
+ nodePtyLoadPromise = null;
45
+ nodePtyLoadError = null;
46
+ executionEnvironment;
47
+ constructor(options) {
48
+ this.executionEnvironment = options.executionEnvironment;
49
+ const rootDirectory = resolve(options.rootDirectory);
50
+ mkdirSync(rootDirectory, { recursive: true });
51
+ this.grantStorePath = join(rootDirectory, 'workspace-grants.json');
52
+ this.applicationGrantStorePath = join(rootDirectory, 'application-grants.json');
53
+ this.managedConversationRoot = options.managedConversationRoot
54
+ ? resolve(options.managedConversationRoot)
55
+ : null;
56
+ this.loadGrants();
57
+ this.loadApplicationGrants();
58
+ }
59
+ setEventSink(sink) {
60
+ this.eventSink = sink;
61
+ }
62
+ grantDirectory(request) {
63
+ try {
64
+ const requested = cleanPath(request.path);
65
+ if (!requested)
66
+ return { success: false, path: null, error: 'Directory path is empty.' };
67
+ if (!existsSync(requested) || !statSync(requested).isDirectory()) {
68
+ return { success: false, path: null, error: 'Selected directory does not exist.' };
69
+ }
70
+ const canonical = canonicalExistingPath(requested);
71
+ const key = pathKey(canonical);
72
+ this.grants.set(key, {
73
+ path: canonical,
74
+ source: request.source,
75
+ createdAt: this.grants.get(key)?.createdAt || Date.now(),
76
+ });
77
+ this.persistGrants();
78
+ return { success: true, path: canonical, error: null };
79
+ }
80
+ catch (error) {
81
+ return { success: false, path: null, error: safeError(error, 'Failed to grant workspace access.') };
82
+ }
83
+ }
84
+ /**
85
+ * The directories the user has explicitly granted, canonicalised.
86
+ *
87
+ * 🔴 Read-only, and it mints nothing. The comment above `grantDirectory`
88
+ * states the rule this preserves: the renderer can narrow trusted grants but
89
+ * cannot create roots, and only the desktop/Hub composition grants one after a
90
+ * native dialog. Exposing the SET is not exposing the ability to add to it.
91
+ *
92
+ * It exists because a host-side feature that needs "the user's project" has
93
+ * exactly one honest answer: what they authorised. Anything else — the home
94
+ * directory, a guess from the process cwd — would read a tree nobody
95
+ * permitted, which is the failure the workspace authority exists to prevent.
96
+ */
97
+ grantedDirectories() {
98
+ return [...this.grants.values()].map((grant) => grant.path);
99
+ }
100
+ grantApplication(request) {
101
+ try {
102
+ const requested = cleanPath(request.path);
103
+ if (!requested)
104
+ return { success: false, appPath: null, error: 'Application path is empty.' };
105
+ if (!existsSync(requested) || !statSync(requested).isFile()) {
106
+ return { success: false, appPath: null, error: 'Selected application does not exist.' };
107
+ }
108
+ const canonical = canonicalExistingPath(requested);
109
+ const key = pathKey(canonical);
110
+ this.applicationGrants.set(key, {
111
+ path: canonical,
112
+ source: request.source,
113
+ createdAt: this.applicationGrants.get(key)?.createdAt || Date.now(),
114
+ });
115
+ this.persistApplicationGrants();
116
+ return { success: true, appPath: canonical, error: null };
117
+ }
118
+ catch (error) {
119
+ return { success: false, appPath: null, error: safeError(error, 'Failed to grant application access.') };
120
+ }
121
+ }
122
+ authorizeExistingFile(request, action, id = 'workspace.file.authorize') {
123
+ const authorized = this.authorizePath(request, request.path, action, id);
124
+ if (authorized.error)
125
+ return { success: false, path: null, error: authorized.error };
126
+ const filePath = authorized.path;
127
+ try {
128
+ if (!existsSync(filePath))
129
+ return { success: false, path: null, error: 'File not found.' };
130
+ if (!statSync(filePath).isFile()) {
131
+ return { success: false, path: null, error: 'Target path is not a file.' };
132
+ }
133
+ return { success: true, path: canonicalExistingPath(filePath), error: null };
134
+ }
135
+ catch (error) {
136
+ return { success: false, path: null, error: safeError(error, 'Failed to inspect file path.') };
137
+ }
138
+ }
139
+ authorizeApplication(request) {
140
+ const requestedPath = cleanPath(request.appPath);
141
+ if (!requestedPath)
142
+ return { success: false, appPath: null, error: 'Application path is empty.' };
143
+ try {
144
+ if (!existsSync(requestedPath) || !statSync(requestedPath).isFile()) {
145
+ return { success: false, appPath: null, error: 'Executable file not found.' };
146
+ }
147
+ const canonical = canonicalExistingPath(requestedPath);
148
+ const key = pathKey(canonical);
149
+ const allowed = normalizeExistingFiles(request.allowedApplications);
150
+ if (!this.applicationGrants.has(key) || !allowed.some((candidate) => pathKey(candidate) === key)) {
151
+ return { success: false, appPath: canonical, error: 'Application is not allowlisted by the host.' };
152
+ }
153
+ const evaluation = evaluateIpcPolicy({
154
+ caller: {
155
+ workspaceId: request.workspaceId,
156
+ teamId: request.teamId,
157
+ agentId: request.agentId,
158
+ allowedDirectories: [dirname(canonical)],
159
+ },
160
+ workspaceId: request.workspaceId,
161
+ teamId: request.teamId,
162
+ agentId: request.agentId,
163
+ allowedDirectories: [dirname(canonical)],
164
+ rootDirectory: dirname(canonical),
165
+ }, { action: 'execute', kind: 'app', id: 'workspace.app.open', path: canonical });
166
+ if (!evaluation.allowed) {
167
+ return { success: false, appPath: canonical, error: `Policy denied: ${evaluation.decision.reason}` };
168
+ }
169
+ return { success: true, appPath: canonical, error: null };
170
+ }
171
+ catch (error) {
172
+ return { success: false, appPath: null, error: safeError(error, 'Failed to inspect application path.') };
173
+ }
174
+ }
175
+ listDirectory(request) {
176
+ const denied = this.authorizePath(request, request.dirPath, 'read', 'workspace.directory.list');
177
+ if (denied.error)
178
+ return { success: false, entries: [], error: denied.error };
179
+ const directory = denied.path;
180
+ try {
181
+ if (!existsSync(directory))
182
+ return { success: false, entries: [], error: 'Directory not found.' };
183
+ if (!statSync(directory).isDirectory()) {
184
+ return { success: false, entries: [], error: 'Target path is not a directory.' };
185
+ }
186
+ const entries = [];
187
+ for (const entry of readdirSync(directory, { withFileTypes: true })) {
188
+ const fullPath = resolve(directory, entry.name);
189
+ try {
190
+ if (entry.isSymbolicLink() || lstatSync(fullPath).isSymbolicLink())
191
+ continue;
192
+ if (!isCanonicalPathInside(fullPath, denied.allowedRoots))
193
+ continue;
194
+ const stats = statSync(fullPath);
195
+ const isDirectory = stats.isDirectory();
196
+ if (!isDirectory && !stats.isFile())
197
+ continue;
198
+ entries.push({
199
+ name: entry.name,
200
+ path: fullPath,
201
+ size: isDirectory ? 0 : stats.size,
202
+ modified: stats.mtime.toISOString(),
203
+ type: isDirectory ? 'directory' : 'file',
204
+ extension: isDirectory ? '' : extname(entry.name).slice(1).toLowerCase(),
205
+ });
206
+ }
207
+ catch {
208
+ // Match the mature Hub behavior: one unreadable entry does not fail a listing.
209
+ }
210
+ }
211
+ entries.sort((left, right) => {
212
+ if (left.type !== right.type)
213
+ return left.type === 'directory' ? -1 : 1;
214
+ return left.name.localeCompare(right.name, undefined, { numeric: true, sensitivity: 'base' });
215
+ });
216
+ return { success: true, entries, error: null };
217
+ }
218
+ catch (error) {
219
+ return { success: false, entries: [], error: safeError(error, 'Failed to list directory.') };
220
+ }
221
+ }
222
+ readFile(request) {
223
+ const denied = this.authorizePath(request, request.path, 'read', 'workspace.file.read');
224
+ if (denied.error)
225
+ return { success: false, path: null, content: '', bytes: 0, error: denied.error };
226
+ const filePath = denied.path;
227
+ try {
228
+ if (!existsSync(filePath)) {
229
+ return { success: false, path: null, content: '', bytes: 0, error: 'File not found.' };
230
+ }
231
+ const stats = statSync(filePath);
232
+ if (!stats.isFile()) {
233
+ return { success: false, path: null, content: '', bytes: 0, error: 'Target path is not a file.' };
234
+ }
235
+ if (stats.size > MAX_FILE_BYTES) {
236
+ return { success: false, path: filePath, content: '', bytes: stats.size, error: 'File exceeds 1MB limit.' };
237
+ }
238
+ const content = readFileSync(filePath);
239
+ if (content.includes(0)) {
240
+ return { success: false, path: filePath, content: '', bytes: stats.size, error: 'Binary files are not supported yet.' };
241
+ }
242
+ return { success: true, path: filePath, content: content.toString('utf8'), bytes: stats.size, error: null };
243
+ }
244
+ catch (error) {
245
+ return { success: false, path: filePath, content: '', bytes: 0, error: safeError(error, 'Failed to read file.') };
246
+ }
247
+ }
248
+ writeFile(request) {
249
+ if (Buffer.byteLength(request.content || '', 'utf8') > MAX_FILE_BYTES) {
250
+ return { success: false, path: null, bytes: 0, error: 'File content exceeds 1MB limit.' };
251
+ }
252
+ const denied = this.authorizePath(request, request.path, 'write', 'workspace.file.write', true);
253
+ if (denied.error)
254
+ return { success: false, path: null, bytes: 0, error: denied.error };
255
+ const filePath = denied.path;
256
+ try {
257
+ mkdirSync(dirname(filePath), { recursive: true });
258
+ if (!isCanonicalPathInside(filePath, denied.allowedRoots, true)) {
259
+ return { success: false, path: null, bytes: 0, error: 'Target path resolves outside trusted workspace grants.' };
260
+ }
261
+ writeFileSync(filePath, request.content || '', { encoding: 'utf8' });
262
+ return {
263
+ success: true,
264
+ path: filePath,
265
+ bytes: Buffer.byteLength(request.content || '', 'utf8'),
266
+ error: null,
267
+ };
268
+ }
269
+ catch (error) {
270
+ return { success: false, path: filePath, bytes: 0, error: safeError(error, 'Failed to write file.') };
271
+ }
272
+ }
273
+ async runCommand(request) {
274
+ const command = String(request.command || '').trim();
275
+ if (!command)
276
+ return commandFailure('Command is empty.');
277
+ if (containsForbiddenSyntax(command))
278
+ return commandFailure('Command contains forbidden shell syntax.');
279
+ if (containsDangerousAction(command))
280
+ return commandFailure('Command blocked for safety.');
281
+ const denied = this.authorizePath(request, request.cwd || request.allowedDirectories[0] || '', 'execute', 'workspace.command.run');
282
+ if (denied.error)
283
+ return commandFailure(denied.error);
284
+ const cwd = denied.path;
285
+ if (!existsSync(cwd) || !statSync(cwd).isDirectory())
286
+ return commandFailure('Working directory not found.');
287
+ const timeoutMs = clampInteger(request.timeoutMs, 20_000, 1_000, 120_000);
288
+ /**
289
+ * The SECOND adopter of `CommandExecutionPort` — ADE §5.3.
290
+ *
291
+ * 🔴 The guards above stay here, deliberately. `containsForbiddenSyntax`,
292
+ * `containsDangerousAction` and `authorizePath` are CALLER-side policy: they
293
+ * decide whether this host is willing to ask for the command at all, which
294
+ * is a different question from where it then runs. Pushing them into the
295
+ * executor would apply them to every future caller — including a sandboxed
296
+ * one, where a path allowlist is the wrong instrument — and would put a
297
+ * rule inside the shared callee that only one caller means.
298
+ *
299
+ * ⚠️ None of them is containment. §5.3 is explicit that a rule inside the
300
+ * shell it runs in does not confine anything; these reduce what gets asked
301
+ * for, and the substrate is what will refuse.
302
+ *
303
+ * `shellInvocation` already returns `{command, args}`, so this site needed
304
+ * no argv change at all — it was already spelling a shell AS argv, which is
305
+ * the pattern the port's rule generalises rather than imposes.
306
+ */
307
+ const invocation = shellInvocation(command, true);
308
+ // 🔴 Resolved PER CALL, from the conversation this request belongs to.
309
+ // Caching an executor on the service would outlive the run that justified
310
+ // it and keep sending commands to a torn-down container — or, worse, keep
311
+ // reporting containment after it ended. With no environment injected this
312
+ // is the module's local executor, exactly as before.
313
+ const executor = this.executionEnvironment?.executorFor(request.conversationId)
314
+ ?? commandExecutor;
315
+ const result = await executor.execute({
316
+ argv: [invocation.command, ...invocation.args],
317
+ cwd,
318
+ timeoutMs,
319
+ maxOutputBytes: MAX_COMMAND_OUTPUT_BYTES,
320
+ });
321
+ return {
322
+ success: commandSucceeded(result),
323
+ stdout: result.stdout,
324
+ stderr: result.stderr,
325
+ exitCode: result.exitCode,
326
+ cwd,
327
+ // The contract uses `null` for absence here; the port omits the key.
328
+ error: result.error ?? null,
329
+ // 🔴 Newly REPORTED rather than newly happening. This method has always
330
+ // trimmed at 200 KB; it just never said so, and a caller reading a short
331
+ // output concluded that was all the command printed.
332
+ truncated: result.truncated,
333
+ };
334
+ }
335
+ startTerminal(request) {
336
+ const command = String(request.command || '').trim();
337
+ if (!command)
338
+ return terminalStartFailure('Command is empty.');
339
+ if (containsDangerousAction(command))
340
+ return terminalStartFailure('Command blocked for safety.');
341
+ const denied = this.authorizePath(request, request.cwd || request.allowedDirectories[0] || '', 'execute', 'workspace.terminal.start');
342
+ if (denied.error)
343
+ return terminalStartFailure(denied.error);
344
+ const cwd = denied.path;
345
+ const timeoutMs = clampInteger(request.timeoutMs, 300_000, 1_000, 900_000);
346
+ const terminalId = uniqueId('terminal');
347
+ const invocation = shellInvocation(command, false);
348
+ try {
349
+ const child = spawn(invocation.command, invocation.args, {
350
+ cwd,
351
+ windowsHide: true,
352
+ shell: false,
353
+ env: process.env,
354
+ });
355
+ const session = {
356
+ id: terminalId,
357
+ ownerInstanceId: request.client.instanceId,
358
+ command,
359
+ cwd,
360
+ process: child,
361
+ timer: null,
362
+ timedOut: false,
363
+ };
364
+ this.terminalSessions.set(terminalId, session);
365
+ session.timer = setTimeout(() => {
366
+ const active = this.terminalSessions.get(terminalId);
367
+ if (!active)
368
+ return;
369
+ active.timedOut = true;
370
+ active.process.kill();
371
+ }, timeoutMs);
372
+ child.stdout.on('data', (chunk) => {
373
+ this.eventSink('workspace.terminal.data', { terminalId, stream: 'stdout', chunk: chunk.toString() });
374
+ });
375
+ child.stderr.on('data', (chunk) => {
376
+ this.eventSink('workspace.terminal.data', { terminalId, stream: 'stderr', chunk: chunk.toString() });
377
+ });
378
+ child.once('error', (error) => {
379
+ const active = this.cleanupTerminal(terminalId);
380
+ if (!active)
381
+ return;
382
+ this.eventSink('workspace.terminal.exit', {
383
+ terminalId,
384
+ command,
385
+ cwd,
386
+ success: false,
387
+ exitCode: null,
388
+ error: error.message || 'Failed to start terminal command.',
389
+ ownerInstanceId: active?.ownerInstanceId || request.client.instanceId,
390
+ });
391
+ });
392
+ child.once('close', (exitCode) => {
393
+ const active = this.cleanupTerminal(terminalId);
394
+ if (!active)
395
+ return;
396
+ this.eventSink('workspace.terminal.exit', {
397
+ terminalId,
398
+ command,
399
+ cwd,
400
+ success: !active.timedOut && exitCode === 0,
401
+ exitCode,
402
+ error: active.timedOut ? `Command timed out after ${timeoutMs}ms.` : null,
403
+ ownerInstanceId: active.ownerInstanceId,
404
+ });
405
+ });
406
+ return { success: true, terminalId, cwd, error: null };
407
+ }
408
+ catch (error) {
409
+ return { success: false, terminalId: null, cwd, error: safeError(error, 'Failed to start terminal command.') };
410
+ }
411
+ }
412
+ stopTerminal(request) {
413
+ const session = this.terminalSessions.get(String(request.terminalId || '').trim());
414
+ const denied = this.authorizeSession(request, session);
415
+ if (denied)
416
+ return { success: false, error: denied };
417
+ session.process.kill();
418
+ return { success: true, error: null };
419
+ }
420
+ async startPty(request) {
421
+ const denied = this.authorizePath(request, request.cwd || request.allowedDirectories[0] || '', 'execute', 'workspace.pty.start');
422
+ if (denied.error)
423
+ return ptyStartFailure(denied.error);
424
+ const cwd = denied.path;
425
+ const terminalId = uniqueId('pty');
426
+ const cols = clampInteger(request.cols, 80, 20, 240);
427
+ const rows = clampInteger(request.rows, 24, 6, 120);
428
+ try {
429
+ const nodePty = await this.loadNodePty();
430
+ if (!nodePty) {
431
+ return ptyStartFailure(`PTY terminal is unavailable${this.nodePtyLoadError ? `: ${this.nodePtyLoadError}` : '.'}`, cwd);
432
+ }
433
+ const shell = process.platform === 'win32' ? 'powershell.exe' : (process.env.SHELL || '/bin/bash');
434
+ const args = process.platform === 'win32' ? ['-NoLogo'] : [];
435
+ const processHandle = nodePty.spawn(shell, args, {
436
+ name: 'xterm-256color',
437
+ cols,
438
+ rows,
439
+ cwd,
440
+ env: { ...process.env, TERM: 'xterm-256color', COLORTERM: 'truecolor' },
441
+ ...(process.platform === 'win32' ? { useConpty: true, useConptyDll: true } : {}),
442
+ });
443
+ const session = {
444
+ id: terminalId,
445
+ ownerInstanceId: request.client.instanceId,
446
+ cwd,
447
+ process: processHandle,
448
+ output: new ScrollbackBuffer(MAX_PTY_SCROLLBACK_BYTES),
449
+ };
450
+ this.ptySessions.set(terminalId, session);
451
+ processHandle.onData((data) => {
452
+ const active = this.ptySessions.get(terminalId);
453
+ if (!active)
454
+ return;
455
+ active.output.append(data);
456
+ this.eventSink('workspace.pty.data', { terminalId, data, ownerInstanceId: active.ownerInstanceId });
457
+ });
458
+ processHandle.onExit(({ exitCode, signal }) => {
459
+ const active = this.ptySessions.get(terminalId);
460
+ this.ptySessions.delete(terminalId);
461
+ this.eventSink('workspace.pty.exit', {
462
+ terminalId,
463
+ exitCode,
464
+ signal,
465
+ ownerInstanceId: active?.ownerInstanceId || request.client.instanceId,
466
+ });
467
+ });
468
+ return { success: true, terminalId, cwd, error: null };
469
+ }
470
+ catch (error) {
471
+ return { success: false, terminalId: null, cwd, error: safeError(error, 'Failed to start PTY terminal.') };
472
+ }
473
+ }
474
+ snapshotPty(request) {
475
+ const terminalId = String(request.terminalId || '').trim();
476
+ const session = this.ptySessions.get(terminalId);
477
+ const denied = this.authorizeSession(request, session);
478
+ if (denied) {
479
+ return { success: false, exists: !!session, terminalId, cwd: null, output: '', error: denied };
480
+ }
481
+ return { success: true, exists: true, terminalId, cwd: session.cwd, output: session.output.read(), error: null };
482
+ }
483
+ inputPty(request) {
484
+ const session = this.ptySessions.get(String(request.terminalId || '').trim());
485
+ const denied = this.authorizeSession(request, session);
486
+ if (denied)
487
+ return { success: false, error: denied };
488
+ session.process.write(String(request.data || '').slice(0, 100_000));
489
+ return { success: true, error: null };
490
+ }
491
+ resizePty(request) {
492
+ const session = this.ptySessions.get(String(request.terminalId || '').trim());
493
+ const denied = this.authorizeSession(request, session);
494
+ if (denied)
495
+ return { success: false, error: denied };
496
+ session.process.resize(clampInteger(request.cols, 80, 20, 240), clampInteger(request.rows, 24, 6, 120));
497
+ return { success: true, error: null };
498
+ }
499
+ clearPty(request) {
500
+ const session = this.ptySessions.get(String(request.terminalId || '').trim());
501
+ const denied = this.authorizeSession(request, session);
502
+ if (denied)
503
+ return { success: false, error: denied };
504
+ session.output.clear();
505
+ return { success: true, error: null };
506
+ }
507
+ stopPty(request) {
508
+ const session = this.ptySessions.get(String(request.terminalId || '').trim());
509
+ const denied = this.authorizeSession(request, session);
510
+ if (denied)
511
+ return { success: false, error: denied };
512
+ this.ptySessions.delete(session.id);
513
+ session.process.kill();
514
+ return { success: true, error: null };
515
+ }
516
+ close() {
517
+ for (const session of this.terminalSessions.values()) {
518
+ if (session.timer)
519
+ clearTimeout(session.timer);
520
+ try {
521
+ session.process.kill();
522
+ }
523
+ catch { /* process already exited */ }
524
+ }
525
+ this.terminalSessions.clear();
526
+ for (const session of this.ptySessions.values()) {
527
+ try {
528
+ session.process.kill();
529
+ }
530
+ catch { /* process already exited */ }
531
+ }
532
+ this.ptySessions.clear();
533
+ }
534
+ authorizePath(request, rawPath, action, id, allowMissing = false) {
535
+ const path = cleanPath(rawPath);
536
+ if (!path)
537
+ return { path: null, allowedRoots: [], error: 'Path is empty.' };
538
+ const allowedRoots = this.effectiveAllowedRoots(request.allowedDirectories, request.conversationId);
539
+ if (allowedRoots.length === 0) {
540
+ return { path: null, allowedRoots, error: 'No trusted workspace directories are granted.' };
541
+ }
542
+ if (!isCanonicalPathInside(path, allowedRoots, allowMissing)) {
543
+ return { path: null, allowedRoots, error: 'Path is outside trusted workspace grants.' };
544
+ }
545
+ const evaluation = evaluateIpcPolicy({
546
+ caller: {
547
+ workspaceId: request.workspaceId,
548
+ teamId: request.teamId,
549
+ agentId: request.agentId,
550
+ allowedDirectories: allowedRoots,
551
+ },
552
+ workspaceId: request.workspaceId,
553
+ teamId: request.teamId,
554
+ agentId: request.agentId,
555
+ conversationId: request.conversationId,
556
+ allowedDirectories: allowedRoots,
557
+ rootDirectory: path,
558
+ }, { action, kind: action === 'execute' ? 'tool' : 'file', id, path });
559
+ if (!evaluation.allowed) {
560
+ return { path: null, allowedRoots, error: `Policy denied: ${evaluation.decision.reason}` };
561
+ }
562
+ return { path, allowedRoots, error: null };
563
+ }
564
+ authorizeSession(request, session) {
565
+ if (!session)
566
+ return 'Terminal session not found.';
567
+ if (session.ownerInstanceId !== request.client.instanceId)
568
+ return 'Terminal session belongs to another surface.';
569
+ return null;
570
+ }
571
+ effectiveAllowedRoots(requestedDirectories, conversationId) {
572
+ const requested = normalizeExistingDirectories(requestedDirectories);
573
+ const trusted = [...this.grants.values()].map((grant) => grant.path);
574
+ const effective = requested.filter((candidate) => trusted.some((root) => isSubPath(candidate, root)));
575
+ const conversationRoot = this.resolveManagedConversationRoot(conversationId);
576
+ if (conversationRoot && !effective.some((candidate) => pathKey(candidate) === pathKey(conversationRoot))) {
577
+ effective.push(conversationRoot);
578
+ }
579
+ return effective;
580
+ }
581
+ resolveManagedConversationRoot(conversationId) {
582
+ if (!this.managedConversationRoot || typeof conversationId !== 'string' || !conversationId.trim())
583
+ return null;
584
+ const safeConversationId = conversationId
585
+ .replace(/[^A-Za-z0-9._-]/g, '_')
586
+ .slice(0, 120) || 'conversation';
587
+ const candidate = resolve(this.managedConversationRoot, safeConversationId);
588
+ try {
589
+ if (!existsSync(candidate) || !statSync(candidate).isDirectory())
590
+ return null;
591
+ const canonicalManagedRoot = canonicalExistingPath(this.managedConversationRoot);
592
+ const canonicalConversationRoot = canonicalExistingPath(candidate);
593
+ return isSubPath(canonicalConversationRoot, canonicalManagedRoot) ? canonicalConversationRoot : null;
594
+ }
595
+ catch {
596
+ return null;
597
+ }
598
+ }
599
+ cleanupTerminal(terminalId) {
600
+ const session = this.terminalSessions.get(terminalId);
601
+ if (!session)
602
+ return undefined;
603
+ if (session.timer)
604
+ clearTimeout(session.timer);
605
+ session.timer = null;
606
+ this.terminalSessions.delete(terminalId);
607
+ return session;
608
+ }
609
+ async loadNodePty() {
610
+ if (!this.nodePtyLoadPromise) {
611
+ this.nodePtyLoadPromise = import('node-pty')
612
+ .then((loaded) => {
613
+ const namespace = loaded;
614
+ const module = (namespace.default || namespace);
615
+ if (typeof module.spawn !== 'function')
616
+ throw new Error('node-pty did not expose a spawn function.');
617
+ this.nodePtyLoadError = null;
618
+ return module;
619
+ })
620
+ .catch((error) => {
621
+ this.nodePtyLoadError = safeError(error, 'Failed to load node-pty.');
622
+ return null;
623
+ });
624
+ }
625
+ return this.nodePtyLoadPromise;
626
+ }
627
+ loadGrants() {
628
+ try {
629
+ if (!existsSync(this.grantStorePath))
630
+ return;
631
+ const parsed = JSON.parse(readFileSync(this.grantStorePath, 'utf8'));
632
+ if (parsed.version !== 1 || !Array.isArray(parsed.grants))
633
+ return;
634
+ for (const grant of parsed.grants.slice(0, MAX_GRANTS)) {
635
+ if (!grant || typeof grant.path !== 'string' || !existsSync(grant.path))
636
+ continue;
637
+ if (!statSync(grant.path).isDirectory())
638
+ continue;
639
+ const canonical = canonicalExistingPath(grant.path);
640
+ this.grants.set(pathKey(canonical), {
641
+ path: canonical,
642
+ source: grant.source === 'legacy-migration' || grant.source === 'host-managed'
643
+ ? grant.source
644
+ : 'user-picker',
645
+ createdAt: typeof grant.createdAt === 'number' ? grant.createdAt : Date.now(),
646
+ });
647
+ }
648
+ }
649
+ catch {
650
+ // A corrupt grant file fails closed. The user can select the directory again.
651
+ this.grants.clear();
652
+ }
653
+ }
654
+ loadApplicationGrants() {
655
+ try {
656
+ if (!existsSync(this.applicationGrantStorePath))
657
+ return;
658
+ const parsed = JSON.parse(readFileSync(this.applicationGrantStorePath, 'utf8'));
659
+ if (parsed.version !== 1 || !Array.isArray(parsed.applications))
660
+ return;
661
+ for (const grant of parsed.applications.slice(0, MAX_GRANTS)) {
662
+ if (!grant || typeof grant.path !== 'string' || !existsSync(grant.path))
663
+ continue;
664
+ if (!statSync(grant.path).isFile())
665
+ continue;
666
+ const canonical = canonicalExistingPath(grant.path);
667
+ this.applicationGrants.set(pathKey(canonical), {
668
+ path: canonical,
669
+ source: grant.source === 'legacy-migration' || grant.source === 'host-managed'
670
+ ? grant.source
671
+ : 'user-picker',
672
+ createdAt: typeof grant.createdAt === 'number' ? grant.createdAt : Date.now(),
673
+ });
674
+ }
675
+ }
676
+ catch {
677
+ // A corrupt executable grant file fails closed.
678
+ this.applicationGrants.clear();
679
+ }
680
+ }
681
+ persistGrants() {
682
+ const payload = {
683
+ version: 1,
684
+ grants: [...this.grants.values()]
685
+ .sort((left, right) => left.createdAt - right.createdAt || left.path.localeCompare(right.path))
686
+ .slice(-MAX_GRANTS),
687
+ };
688
+ const temporary = `${this.grantStorePath}.tmp-${process.pid}-${Date.now()}`;
689
+ writeFileSync(temporary, JSON.stringify(payload, null, 2), 'utf8');
690
+ const descriptor = openSync(temporary, 'r+');
691
+ try {
692
+ fsyncSync(descriptor);
693
+ }
694
+ finally {
695
+ closeSync(descriptor);
696
+ }
697
+ renameSync(temporary, this.grantStorePath);
698
+ }
699
+ persistApplicationGrants() {
700
+ const payload = {
701
+ version: 1,
702
+ applications: [...this.applicationGrants.values()]
703
+ .sort((left, right) => left.createdAt - right.createdAt || left.path.localeCompare(right.path))
704
+ .slice(-MAX_GRANTS),
705
+ };
706
+ persistJsonAtomically(this.applicationGrantStorePath, payload);
707
+ }
708
+ }
709
+ function normalizeExistingDirectories(values) {
710
+ const result = [];
711
+ const seen = new Set();
712
+ for (const value of Array.isArray(values) ? values.slice(0, 100) : []) {
713
+ try {
714
+ const path = canonicalExistingPath(String(value || ''));
715
+ if (!statSync(path).isDirectory())
716
+ continue;
717
+ const key = pathKey(path);
718
+ if (seen.has(key))
719
+ continue;
720
+ seen.add(key);
721
+ result.push(path);
722
+ }
723
+ catch {
724
+ // Invalid/unavailable roots are ignored and therefore fail closed.
725
+ }
726
+ }
727
+ return result;
728
+ }
729
+ function normalizeExistingFiles(values) {
730
+ const result = [];
731
+ const seen = new Set();
732
+ for (const value of Array.isArray(values) ? values.slice(0, 100) : []) {
733
+ try {
734
+ const path = canonicalExistingPath(String(value || ''));
735
+ if (!statSync(path).isFile())
736
+ continue;
737
+ const key = pathKey(path);
738
+ if (seen.has(key))
739
+ continue;
740
+ seen.add(key);
741
+ result.push(path);
742
+ }
743
+ catch {
744
+ // Invalid/unavailable application paths are ignored and therefore fail closed.
745
+ }
746
+ }
747
+ return result;
748
+ }
749
+ function persistJsonAtomically(path, payload) {
750
+ const temporary = `${path}.tmp-${process.pid}-${Date.now()}`;
751
+ writeFileSync(temporary, JSON.stringify(payload, null, 2), 'utf8');
752
+ const descriptor = openSync(temporary, 'r+');
753
+ try {
754
+ fsyncSync(descriptor);
755
+ }
756
+ finally {
757
+ closeSync(descriptor);
758
+ }
759
+ renameSync(temporary, path);
760
+ }
761
+ function canonicalExistingPath(path) {
762
+ return realpathSync.native(resolve(path));
763
+ }
764
+ function canonicalForContainment(path, allowMissing) {
765
+ const absolute = resolve(path);
766
+ if (existsSync(absolute))
767
+ return canonicalExistingPath(absolute);
768
+ if (!allowMissing)
769
+ return null;
770
+ let ancestor = dirname(absolute);
771
+ while (!existsSync(ancestor)) {
772
+ const parent = dirname(ancestor);
773
+ if (parent === ancestor)
774
+ return null;
775
+ ancestor = parent;
776
+ }
777
+ const canonicalAncestor = canonicalExistingPath(ancestor);
778
+ const remainder = relative(ancestor, absolute);
779
+ if (!remainder || remainder.startsWith('..') || isAbsolute(remainder))
780
+ return null;
781
+ return resolve(canonicalAncestor, remainder);
782
+ }
783
+ function isCanonicalPathInside(path, roots, allowMissing = false) {
784
+ const canonical = canonicalForContainment(path, allowMissing);
785
+ return !!canonical && roots.some((root) => isSubPath(canonical, root));
786
+ }
787
+ function isSubPath(childPath, parentPath) {
788
+ const child = pathKey(resolve(childPath));
789
+ const parent = pathKey(resolve(parentPath));
790
+ if (child === parent)
791
+ return true;
792
+ const separator = process.platform === 'win32' ? '\\' : '/';
793
+ return child.startsWith(parent.endsWith(separator) ? parent : `${parent}${separator}`);
794
+ }
795
+ function pathKey(path) {
796
+ const normalized = resolve(path);
797
+ return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
798
+ }
799
+ function cleanPath(value) {
800
+ if (typeof value !== 'string' || !value.trim() || value.includes('\0'))
801
+ return '';
802
+ return resolve(value.trim());
803
+ }
804
+ function containsForbiddenSyntax(command) {
805
+ return /(\r|\n|&&|\|\||;|`|>|<|\$\()/.test(command);
806
+ }
807
+ function containsDangerousAction(command) {
808
+ return /\b(remove-item|rm|rmdir|del|erase|format|diskpart|shutdown|reboot|restart-computer|stop-computer)\b/i.test(command);
809
+ }
810
+ function shellInvocation(command, nonInteractive) {
811
+ if (process.platform === 'win32') {
812
+ return {
813
+ command: 'powershell.exe',
814
+ args: ['-NoLogo', '-NoProfile', ...(nonInteractive ? ['-NonInteractive'] : []), '-Command', command],
815
+ };
816
+ }
817
+ return { command: '/bin/bash', args: ['-lc', command] };
818
+ }
819
+ function clampInteger(value, fallback, minimum, maximum) {
820
+ return typeof value === 'number' && Number.isFinite(value)
821
+ ? Math.max(minimum, Math.min(maximum, Math.floor(value)))
822
+ : fallback;
823
+ }
824
+ function uniqueId(prefix) {
825
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
826
+ }
827
+ function commandFailure(error) {
828
+ // `truncated: false` is a FACT here, not a filler: the command was refused
829
+ // before it ran, so there is no output and nothing was trimmed.
830
+ return { success: false, stdout: '', stderr: '', exitCode: null, cwd: null, error, truncated: false };
831
+ }
832
+ function terminalStartFailure(error) {
833
+ return { success: false, terminalId: null, cwd: null, error };
834
+ }
835
+ function ptyStartFailure(error, cwd = null) {
836
+ return { success: false, terminalId: null, cwd, error };
837
+ }
838
+ function safeError(error, fallback) {
839
+ return error instanceof Error && error.message.trim() ? error.message.slice(0, 1_000) : fallback;
840
+ }
841
+ //# sourceMappingURL=WorkspaceHostService.js.map