@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,1874 @@
1
+ import { spawn } from 'child_process';
2
+ import { asRecord, denyWithPolicy, evaluateIpcPolicy } from '../policy/policyGuard.js';
3
+ import { getRuntimeEventStore, RuntimeEventStore } from '../runtime/RuntimeEventStore.js';
4
+ const SECRET_KEY_PATTERN = /(authorization|bearer|token|secret|password|credential|cookie|api[-_]?key|access[-_]?key|refresh[-_]?token|private[-_]?key)/i;
5
+ const LOCAL_HOSTS = new Set(['localhost', '127.0.0.1', '::1', '[::1]']);
6
+ const HTTP_OPENAPI_METHOD_PATTERN = /^(get|put|post|delete|patch|options|head|trace)$/i;
7
+ const READ_ONLY_OPERATION_METHODS = new Set(['GET', 'HEAD']);
8
+ const activeCliThreadRuns = new Map();
9
+ const activeCliRemoteRuns = new Map();
10
+ const CLI_WORKFLOW_DEFINITIONS = [
11
+ {
12
+ id: 'runs',
13
+ label: 'Runs',
14
+ keywords: ['run', 'runs', 'session', 'sessions', 'attach', 'stop', 'cancel', 'event', 'events', 'stream'],
15
+ excludeKeywords: ['remote'],
16
+ expected: [
17
+ { id: 'run-lifecycle', label: 'run lifecycle', keywords: ['run', 'runs', 'session', 'sessions'] },
18
+ { id: 'stream-attach', label: 'stream or attach', keywords: ['attach', 'event', 'events', 'stream'] },
19
+ { id: 'stop-cancel', label: 'stop or cancel', keywords: ['stop', 'cancel'] },
20
+ ],
21
+ },
22
+ {
23
+ id: 'evals',
24
+ label: 'Evals',
25
+ keywords: ['eval', 'evals', 'evaluation', 'evaluations', 'compare', 'report', 'reports', 'artifact', 'artifacts', 'score'],
26
+ expected: [
27
+ { id: 'evaluation-runs', label: 'evaluation runs', keywords: ['eval', 'evals', 'evaluation', 'evaluations'] },
28
+ { id: 'reports-compare', label: 'reports or compare', keywords: ['report', 'reports', 'compare'] },
29
+ { id: 'artifacts', label: 'artifacts', keywords: ['artifact', 'artifacts'] },
30
+ ],
31
+ },
32
+ {
33
+ id: 'shareReplay',
34
+ label: 'Share/replay',
35
+ keywords: ['share', 'replay', 'bundle', 'bundles', 'snapshot', 'export', 'import'],
36
+ expected: [
37
+ { id: 'share-export', label: 'share or export', keywords: ['share', 'export'] },
38
+ { id: 'replay-import', label: 'replay or import', keywords: ['replay', 'import'] },
39
+ { id: 'bundle', label: 'bundle', keywords: ['bundle', 'bundles'] },
40
+ ],
41
+ },
42
+ {
43
+ id: 'remoteRuns',
44
+ label: 'Remote runs',
45
+ keywords: ['remote', 'probe', 'probes', 'validate', 'attach', 'event', 'events'],
46
+ expected: [
47
+ { id: 'remote-targets', label: 'remote targets', keywords: ['remote'] },
48
+ { id: 'probe-validate', label: 'probe or validate', keywords: ['probe', 'probes', 'validate'] },
49
+ { id: 'attach-events', label: 'attach or events', keywords: ['attach', 'event', 'events'] },
50
+ ],
51
+ },
52
+ {
53
+ id: 'mcpAuth',
54
+ label: 'MCP auth',
55
+ keywords: ['mcp', 'auth', 'login', 'logout', 'device', 'status'],
56
+ expected: [
57
+ { id: 'mcp-surface', label: 'mcp surface', keywords: ['mcp'] },
58
+ { id: 'auth-lifecycle', label: 'auth lifecycle', keywords: ['auth', 'login', 'logout', 'device'] },
59
+ { id: 'status', label: 'status', keywords: ['status'] },
60
+ ],
61
+ },
62
+ {
63
+ id: 'orgMetadata',
64
+ label: 'Org metadata',
65
+ keywords: ['org', 'organization', 'knowledge', 'playbook', 'playbooks', 'serviceuser', 'serviceusers', 'secret', 'secrets'],
66
+ expected: [
67
+ { id: 'org-surface', label: 'org surface', keywords: ['org', 'organization'] },
68
+ { id: 'knowledge-playbooks', label: 'knowledge or playbooks', keywords: ['knowledge', 'playbook', 'playbooks'] },
69
+ { id: 'service-users-metadata', label: 'service users or protected metadata', keywords: ['serviceuser', 'serviceusers', 'secret', 'secrets'] },
70
+ ],
71
+ },
72
+ {
73
+ id: 'githubApp',
74
+ label: 'GitHub app',
75
+ keywords: ['github', 'webhook', 'webhooks', 'plan', 'verify', 'installation', 'installations'],
76
+ expected: [
77
+ { id: 'github-surface', label: 'github surface', keywords: ['github'] },
78
+ { id: 'webhooks', label: 'webhooks', keywords: ['webhook', 'webhooks'] },
79
+ { id: 'plan-verify', label: 'plan or verify', keywords: ['plan', 'verify'] },
80
+ ],
81
+ },
82
+ ];
83
+ const CLI_PRODUCT_DASHBOARD_DETAILS = {
84
+ runs: {
85
+ label: 'Run control dashboard',
86
+ description: 'Local CLI run list, start, attach, stop, and event contracts.',
87
+ nextStep: 'Inspect run list/events first; mutation actions stay guarded until typed run-control calls are approved.',
88
+ },
89
+ evals: {
90
+ label: 'Eval dashboard',
91
+ description: 'Eval list, inspect, run, compare, reports, and artifact contracts.',
92
+ nextStep: 'Probe report/artifact reads before enabling eval run or compare actions.',
93
+ },
94
+ shareReplay: {
95
+ label: 'Share/replay dashboard',
96
+ description: 'Share export, replay bundle inspection, and redacted bundle contracts.',
97
+ nextStep: 'Use read-only bundle inspection before enabling export/import mutations.',
98
+ },
99
+ remoteRuns: {
100
+ label: 'Remote run dashboard',
101
+ description: 'Remote readiness, probe, validate, start, attach, events, and stop contracts.',
102
+ nextStep: 'Verify remote readiness/probe metadata before showing attach/start/stop actions.',
103
+ },
104
+ mcpAuth: {
105
+ label: 'MCP auth dashboard',
106
+ description: 'MCP auth status, login, no-browser/device flow, and logout contracts.',
107
+ nextStep: 'Show auth status and device-flow instructions before exposing login/logout actions.',
108
+ },
109
+ orgMetadata: {
110
+ label: 'Org metadata dashboard',
111
+ description: 'Knowledge, playbooks, secrets metadata, and service-user list contracts.',
112
+ nextStep: 'List metadata only; never render token, key, secret, or credential values.',
113
+ },
114
+ githubApp: {
115
+ label: 'GitHub app dashboard',
116
+ description: 'GitHub app plan, verify, and webhook fixture inspection contracts.',
117
+ nextStep: 'Inspect plan/verify output before enabling webhook or installation mutations.',
118
+ },
119
+ };
120
+ export function normalizeLocalCliAppServerEndpoint(value) {
121
+ if (typeof value !== 'string')
122
+ return null;
123
+ const trimmed = value.trim();
124
+ if (!trimmed)
125
+ return null;
126
+ try {
127
+ const url = new URL(trimmed);
128
+ if (url.protocol !== 'http:' && url.protocol !== 'https:')
129
+ return null;
130
+ const host = url.hostname.toLowerCase();
131
+ if (!LOCAL_HOSTS.has(host) && !host.endsWith('.localhost'))
132
+ return null;
133
+ return `${url.protocol}//${url.host}`;
134
+ }
135
+ catch {
136
+ return null;
137
+ }
138
+ }
139
+ export function normalizeCliAppServerTokenEnvKey(value) {
140
+ if (typeof value !== 'string')
141
+ return null;
142
+ const key = value.trim().slice(0, 128);
143
+ if (/^(sk|xox[baprs]|gh[pousr])_[A-Za-z0-9_=-]{8,}$/i.test(key))
144
+ return null;
145
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key) ? key : null;
146
+ }
147
+ export function redactCliControlPlaneText(value, maxLength = 220) {
148
+ if (typeof value !== 'string')
149
+ return '';
150
+ const redacted = value
151
+ .replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/gi, 'Bearer [redacted]')
152
+ .replace(/(sk|xox[baprs]|gh[pousr])_[A-Za-z0-9_=-]{8,}/gi, '$1_[redacted]')
153
+ .replace(/([?&#](?:token|key|secret|password|bearer|api_key|access_token)=)[^&#\s]+/gi, '$1[redacted]')
154
+ .replace(/\/\/([^:/\s]+):([^@/\s]+)@/g, '//[redacted]@[redacted]@');
155
+ return redacted.slice(0, maxLength);
156
+ }
157
+ export function emptyManifestSummary(error) {
158
+ return { ok: false, status: 0, capabilities: [], ...(error ? { error: redactCliControlPlaneText(error) } : {}) };
159
+ }
160
+ export function emptyOpenApiSummary(error) {
161
+ return { ok: false, status: 0, operationCount: 0, paths: [], ...(error ? { error: redactCliControlPlaneText(error) } : {}) };
162
+ }
163
+ export function emptyOperationResponseSummary(error) {
164
+ return {
165
+ ok: false,
166
+ status: 0,
167
+ bodyType: 'null',
168
+ keys: [],
169
+ ...(error ? { error: redactCliControlPlaneText(error) } : {}),
170
+ };
171
+ }
172
+ function isSafeOpenApiPath(path) {
173
+ return path.startsWith('/') && !SECRET_KEY_PATTERN.test(path);
174
+ }
175
+ export function normalizeCliWorkflowOperationPath(value) {
176
+ if (typeof value !== 'string')
177
+ return null;
178
+ const trimmed = value.trim();
179
+ if (!trimmed || trimmed.length > 400)
180
+ return null;
181
+ if (!trimmed.startsWith('/') || trimmed.startsWith('//'))
182
+ return null;
183
+ if (/[\\\r\n\t]/.test(trimmed) || SECRET_KEY_PATTERN.test(trimmed))
184
+ return null;
185
+ try {
186
+ const normalized = new URL(trimmed, 'http://localhost').pathname;
187
+ return normalized === trimmed.split(/[?#]/, 1)[0] ? trimmed : null;
188
+ }
189
+ catch {
190
+ return null;
191
+ }
192
+ }
193
+ function readString(record, keys, maxLength = 120) {
194
+ for (const key of keys) {
195
+ if (SECRET_KEY_PATTERN.test(key))
196
+ continue;
197
+ const value = record[key];
198
+ if (typeof value === 'string' && value.trim())
199
+ return redactCliControlPlaneText(value.trim(), maxLength);
200
+ }
201
+ return undefined;
202
+ }
203
+ function readSafeDescriptor(record, keys, maxLength = 120) {
204
+ const value = readString(record, keys, maxLength);
205
+ if (!value || SECRET_KEY_PATTERN.test(value))
206
+ return undefined;
207
+ return value;
208
+ }
209
+ function readSafeHttpUrlArgument(record, keys, maxLength = 500) {
210
+ let provided = false;
211
+ for (const key of keys) {
212
+ const value = record[key];
213
+ if (typeof value === 'string' && value.trim())
214
+ provided = true;
215
+ }
216
+ if (!provided)
217
+ return {};
218
+ const value = readSafeDescriptor(record, keys, maxLength);
219
+ if (!value)
220
+ return { error: 'GitHub app backend URL must be a safe http(s) URL.' };
221
+ try {
222
+ const parsed = new URL(value);
223
+ if ((parsed.protocol !== 'http:' && parsed.protocol !== 'https:') || parsed.username || parsed.password || SECRET_KEY_PATTERN.test(parsed.search)) {
224
+ return { error: 'GitHub app backend URL must be a safe http(s) URL.' };
225
+ }
226
+ return { value };
227
+ }
228
+ catch {
229
+ return { error: 'GitHub app backend URL must be a safe http(s) URL.' };
230
+ }
231
+ }
232
+ function readSafePathArgument(record, keys, maxLength = 2000) {
233
+ for (const key of keys) {
234
+ const value = record[key];
235
+ if (typeof value !== 'string')
236
+ continue;
237
+ const trimmed = value.trim().slice(0, maxLength);
238
+ if (!trimmed || /[\0\r\n]/.test(trimmed) || SECRET_KEY_PATTERN.test(trimmed))
239
+ continue;
240
+ return trimmed;
241
+ }
242
+ return undefined;
243
+ }
244
+ function safePathLabel(value) {
245
+ if (!value)
246
+ return undefined;
247
+ const parts = value.split(/[\\/]+/).filter(Boolean);
248
+ return redactCliControlPlaneText(parts.at(-1) || value, 160);
249
+ }
250
+ function readRecord(value) {
251
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
252
+ }
253
+ function readThreadRunText(messages, bodyRecord) {
254
+ for (const message of messages) {
255
+ const messageRecord = readRecord(message);
256
+ const resultRecord = readRecord(messageRecord.result);
257
+ const text = readString(resultRecord, ['text', 'content', 'output', 'message', 'summary'], 4000)
258
+ || readString(messageRecord, ['text', 'content', 'output', 'message', 'summary'], 4000);
259
+ if (text)
260
+ return text;
261
+ }
262
+ return readString(bodyRecord, ['text', 'content', 'output', 'message', 'summary'], 4000);
263
+ }
264
+ function appendCliThreadRuntimeEvent(store, record, event) {
265
+ const conversationId = readSafeDescriptor(record, ['conversationId', 'targetConversationId'], 200);
266
+ const requestId = readSafeDescriptor(record, ['requestId'], 100);
267
+ if (!conversationId || !requestId)
268
+ return;
269
+ const callerRecord = asRecord(record.caller);
270
+ store.append({
271
+ conversationId,
272
+ requestId,
273
+ caller: {
274
+ workspaceId: readSafeDescriptor(callerRecord, ['workspaceId'], 200),
275
+ teamId: readSafeDescriptor(callerRecord, ['teamId'], 200),
276
+ agentId: readSafeDescriptor(callerRecord, ['agentId'], 200),
277
+ },
278
+ source: 'cli',
279
+ redactionState: 'redacted',
280
+ event,
281
+ });
282
+ }
283
+ function appendCliRemoteRuntimeEvent(store, record, event) {
284
+ const conversationId = readSafeDescriptor(record, ['conversationId', 'targetConversationId'], 200);
285
+ const requestId = readSafeDescriptor(record, ['requestId'], 100);
286
+ if (!conversationId || !requestId)
287
+ return;
288
+ const callerRecord = asRecord(record.caller);
289
+ store.append({
290
+ conversationId,
291
+ requestId,
292
+ caller: {
293
+ workspaceId: readSafeDescriptor(callerRecord, ['workspaceId'], 200),
294
+ teamId: readSafeDescriptor(callerRecord, ['teamId'], 200),
295
+ agentId: readSafeDescriptor(callerRecord, ['agentId'], 200),
296
+ },
297
+ source: 'remote',
298
+ redactionState: 'redacted',
299
+ event,
300
+ });
301
+ }
302
+ function readCliRemoteCwd(record) {
303
+ const direct = typeof record.cwd === 'string' && record.cwd.trim()
304
+ ? record.cwd.trim().slice(0, 2000)
305
+ : undefined;
306
+ if (direct)
307
+ return direct;
308
+ const caller = asRecord(record.caller);
309
+ if (!Array.isArray(caller.allowedDirectories))
310
+ return undefined;
311
+ const first = caller.allowedDirectories.find((entry) => typeof entry === 'string' && !!entry.trim());
312
+ return first?.trim().slice(0, 2000);
313
+ }
314
+ const MAX_CLI_REMOTE_OUTPUT_CHARS = 2_000_000;
315
+ function appendBoundedOutput(current, chunk) {
316
+ if (current.length >= MAX_CLI_REMOTE_OUTPUT_CHARS)
317
+ return current;
318
+ return (current + chunk.toString('utf8')).slice(0, MAX_CLI_REMOTE_OUTPUT_CHARS);
319
+ }
320
+ function runXenoCliCommand(args, options) {
321
+ return new Promise((resolve, reject) => {
322
+ const child = spawn(process.platform === 'win32' ? 'xeno.cmd' : 'xeno', args, {
323
+ cwd: options.cwd,
324
+ env: process.env,
325
+ stdio: ['ignore', 'pipe', 'pipe'],
326
+ windowsHide: true,
327
+ });
328
+ options.activeRun.child = child;
329
+ let stdout = '';
330
+ let stderr = '';
331
+ const timeout = setTimeout(() => {
332
+ options.activeRun.cancelled = true;
333
+ child.kill();
334
+ }, options.timeoutMs);
335
+ child.stdout.on('data', (chunk) => { stdout = appendBoundedOutput(stdout, chunk); });
336
+ child.stderr.on('data', (chunk) => { stderr = appendBoundedOutput(stderr, chunk); });
337
+ child.on('error', (error) => {
338
+ clearTimeout(timeout);
339
+ reject(error);
340
+ });
341
+ child.on('close', (exitCode) => {
342
+ clearTimeout(timeout);
343
+ resolve({ exitCode, stdout, stderr });
344
+ });
345
+ });
346
+ }
347
+ function parseCliRemoteReport(stdout) {
348
+ try {
349
+ const parsed = JSON.parse(stdout.trim());
350
+ return readRecord(parsed);
351
+ }
352
+ catch {
353
+ return null;
354
+ }
355
+ }
356
+ function summarizeCliJsonCommandResult(result) {
357
+ const body = parseCliRemoteReport(result.stdout);
358
+ const ok = result.exitCode === 0 && Boolean(body);
359
+ return {
360
+ body,
361
+ response: summarizeOperationResponse({
362
+ ok,
363
+ status: ok ? 200 : result.exitCode ?? 0,
364
+ contentType: body ? 'application/json' : undefined,
365
+ body: body || null,
366
+ error: ok ? undefined : redactCliControlPlaneText(result.stderr || 'CLI command did not return JSON.', 400),
367
+ }),
368
+ };
369
+ }
370
+ function cliRemoteStatus(report, exitCode, cancelled) {
371
+ if (cancelled)
372
+ return 'cancelled';
373
+ if (report?.ok === true)
374
+ return 'available';
375
+ const code = readSafeDescriptor(report || {}, ['code'], 120) || '';
376
+ if (/not_ready|capability|budget|denied|unauthorized/i.test(code))
377
+ return 'blocked';
378
+ return exitCode === null ? 'offline' : 'degraded';
379
+ }
380
+ function remoteRunStartedText(runId) {
381
+ return runId ? `Remote run started: ${runId}` : 'Remote run started.';
382
+ }
383
+ function readCapabilities(value) {
384
+ const out = [];
385
+ const seen = new Set();
386
+ const push = (entry) => {
387
+ if (typeof entry !== 'string')
388
+ return;
389
+ const cleaned = redactCliControlPlaneText(entry.trim(), 80);
390
+ if (!cleaned || SECRET_KEY_PATTERN.test(cleaned) || seen.has(cleaned))
391
+ return;
392
+ seen.add(cleaned);
393
+ out.push(cleaned);
394
+ };
395
+ if (Array.isArray(value)) {
396
+ for (const item of value)
397
+ push(item);
398
+ }
399
+ else if (value && typeof value === 'object' && !Array.isArray(value)) {
400
+ for (const [key, enabled] of Object.entries(value)) {
401
+ if (enabled === false || SECRET_KEY_PATTERN.test(key))
402
+ continue;
403
+ push(key);
404
+ }
405
+ }
406
+ return out.slice(0, 40);
407
+ }
408
+ function countOpenApiOperations(paths) {
409
+ let count = 0;
410
+ for (const [path, value] of Object.entries(paths)) {
411
+ if (!isSafeOpenApiPath(path))
412
+ continue;
413
+ const pathItem = readRecord(value);
414
+ for (const method of Object.keys(pathItem)) {
415
+ if (HTTP_OPENAPI_METHOD_PATTERN.test(method))
416
+ count += 1;
417
+ }
418
+ }
419
+ return count;
420
+ }
421
+ function addWorkflowTokens(target, value) {
422
+ if (typeof value !== 'string' || SECRET_KEY_PATTERN.test(value))
423
+ return;
424
+ const expanded = value.replace(/([a-z0-9])([A-Z])/g, '$1 $2').toLowerCase();
425
+ for (const segment of expanded.split(/[/?#&=]+/)) {
426
+ const compact = segment.replace(/[^a-z0-9]+/g, '');
427
+ if (compact)
428
+ target.add(compact);
429
+ for (const token of segment.split(/[^a-z0-9]+/)) {
430
+ if (token)
431
+ target.add(token);
432
+ }
433
+ }
434
+ }
435
+ function workflowTokensMatch(tokens, keywords) {
436
+ return keywords.some((keyword) => tokens.has(keyword.toLowerCase().replace(/[^a-z0-9]+/g, '')));
437
+ }
438
+ function readOperationTokens(path, method, operation) {
439
+ const tokens = new Set();
440
+ addWorkflowTokens(tokens, path);
441
+ addWorkflowTokens(tokens, method);
442
+ addWorkflowTokens(tokens, operation.operationId);
443
+ addWorkflowTokens(tokens, operation.summary);
444
+ addWorkflowTokens(tokens, operation.description);
445
+ if (Array.isArray(operation.tags)) {
446
+ for (const tag of operation.tags)
447
+ addWorkflowTokens(tokens, tag);
448
+ }
449
+ return tokens;
450
+ }
451
+ export function deriveCliWorkflowReadiness(pathsValue) {
452
+ const paths = readRecord(pathsValue);
453
+ const summaries = CLI_WORKFLOW_DEFINITIONS.map((definition) => ({
454
+ id: definition.id,
455
+ label: definition.label,
456
+ available: false,
457
+ operationCount: 0,
458
+ pathSet: new Set(),
459
+ operations: [],
460
+ actions: definition.expected.map((action) => ({
461
+ id: action.id,
462
+ label: action.label,
463
+ available: false,
464
+ operationCount: 0,
465
+ methodSet: new Set(),
466
+ pathSet: new Set(),
467
+ inspectableOperationIds: new Set(),
468
+ })),
469
+ matchedKeywords: new Set(),
470
+ }));
471
+ for (const [path, value] of Object.entries(paths)) {
472
+ if (!isSafeOpenApiPath(path))
473
+ continue;
474
+ const pathItem = readRecord(value);
475
+ for (const [method, operationValue] of Object.entries(pathItem)) {
476
+ if (!HTTP_OPENAPI_METHOD_PATTERN.test(method))
477
+ continue;
478
+ const operation = readRecord(operationValue);
479
+ const tokens = readOperationTokens(path, method, operation);
480
+ for (const [index, definition] of CLI_WORKFLOW_DEFINITIONS.entries()) {
481
+ const excludeKeywords = 'excludeKeywords' in definition ? definition.excludeKeywords : [];
482
+ if (excludeKeywords.length && workflowTokensMatch(tokens, excludeKeywords))
483
+ continue;
484
+ if (!workflowTokensMatch(tokens, definition.keywords))
485
+ continue;
486
+ const methodUpper = method.toUpperCase();
487
+ const operationSummary = {
488
+ id: `${methodUpper} ${path}`,
489
+ method: methodUpper,
490
+ path,
491
+ operationId: readSafeDescriptor(operation, ['operationId'], 100),
492
+ summary: readSafeDescriptor(operation, ['summary'], 140),
493
+ tags: readCapabilities(operation.tags).slice(0, 8),
494
+ inspectable: READ_ONLY_OPERATION_METHODS.has(methodUpper) && !/[{}]/.test(path),
495
+ };
496
+ const summary = summaries[index];
497
+ summary.available = true;
498
+ summary.operationCount += 1;
499
+ summary.pathSet.add(path);
500
+ if (!summary.operations.some((existing) => existing.id === operationSummary.id)) {
501
+ summary.operations.push(operationSummary);
502
+ }
503
+ for (const [actionIndex, action] of definition.expected.entries()) {
504
+ if (!workflowTokensMatch(tokens, action.keywords))
505
+ continue;
506
+ const actionSummary = summary.actions[actionIndex];
507
+ actionSummary.available = true;
508
+ actionSummary.operationCount += 1;
509
+ actionSummary.methodSet.add(operationSummary.method);
510
+ actionSummary.pathSet.add(operationSummary.path);
511
+ if (operationSummary.inspectable)
512
+ actionSummary.inspectableOperationIds.add(operationSummary.id);
513
+ }
514
+ for (const keyword of definition.keywords) {
515
+ if (workflowTokensMatch(tokens, [keyword]))
516
+ summary.matchedKeywords.add(keyword);
517
+ }
518
+ }
519
+ }
520
+ }
521
+ return summaries.map((summary, index) => {
522
+ const definition = CLI_WORKFLOW_DEFINITIONS[index];
523
+ return {
524
+ id: summary.id,
525
+ label: summary.label,
526
+ available: summary.available,
527
+ operationCount: summary.operationCount,
528
+ paths: Array.from(summary.pathSet).slice(0, 12),
529
+ operations: summary.operations.slice(0, 12),
530
+ actions: summary.actions.map((action) => ({
531
+ id: action.id,
532
+ label: action.label,
533
+ available: action.available,
534
+ operationCount: action.operationCount,
535
+ methods: Array.from(action.methodSet).slice(0, 8),
536
+ paths: Array.from(action.pathSet).slice(0, 8),
537
+ inspectableOperationIds: Array.from(action.inspectableOperationIds).slice(0, 8),
538
+ })),
539
+ missing: definition.expected
540
+ .filter((expectation) => !workflowTokensMatch(summary.matchedKeywords, expectation.keywords))
541
+ .map((expectation) => expectation.label),
542
+ };
543
+ });
544
+ }
545
+ export function deriveCliProductDashboards(workflows) {
546
+ return workflows.map((workflow) => {
547
+ const details = CLI_PRODUCT_DASHBOARD_DETAILS[workflow.id] || {
548
+ label: `${workflow.label} dashboard`,
549
+ description: `${workflow.label} CLI workflow contract.`,
550
+ nextStep: 'Inspect safe read-only operations before enabling mutations.',
551
+ };
552
+ const readOnlyProbeCount = workflow.operations.filter((operation) => operation.inspectable).length;
553
+ const mutatingOperationCount = workflow.operations.filter((operation) => !READ_ONLY_OPERATION_METHODS.has(operation.method)).length;
554
+ const availableActionCount = workflow.actions.filter((action) => action.available).length;
555
+ const requiredActionCount = workflow.actions.length;
556
+ const status = !workflow.available
557
+ ? 'missing'
558
+ : workflow.missing.length > 0
559
+ ? 'partial'
560
+ : 'ready';
561
+ return {
562
+ id: workflow.id,
563
+ label: details.label,
564
+ description: details.description,
565
+ nextStep: details.nextStep,
566
+ status,
567
+ operationCount: workflow.operationCount,
568
+ availableActionCount,
569
+ requiredActionCount,
570
+ readOnlyProbeCount,
571
+ mutatingOperationCount,
572
+ paths: workflow.paths,
573
+ missing: workflow.missing,
574
+ actions: workflow.actions.map((action) => ({
575
+ id: action.id,
576
+ label: action.label,
577
+ available: action.available,
578
+ operationCount: action.operationCount,
579
+ methods: action.methods,
580
+ paths: action.paths,
581
+ probeablePathCount: action.inspectableOperationIds.length,
582
+ mutatingOperationCount: action.methods.filter((method) => !READ_ONLY_OPERATION_METHODS.has(method)).length,
583
+ })),
584
+ };
585
+ });
586
+ }
587
+ async function fetchJson(endpoint, path, timeoutMs, method = 'GET', token) {
588
+ try {
589
+ const headers = { Accept: 'application/json' };
590
+ if (token)
591
+ headers.Authorization = `Bearer ${token}`;
592
+ const response = await fetch(`${endpoint}${path}`, {
593
+ method,
594
+ headers,
595
+ signal: AbortSignal.timeout(timeoutMs),
596
+ });
597
+ const contentType = response.headers.get('content-type') || undefined;
598
+ const text = method === 'HEAD' ? '' : await response.text();
599
+ let body = null;
600
+ try {
601
+ body = text ? JSON.parse(text) : null;
602
+ }
603
+ catch {
604
+ return { ok: false, status: response.status, contentType, body: null, error: 'Invalid JSON response.' };
605
+ }
606
+ return { ok: response.ok, status: response.status, contentType, body, error: response.ok ? undefined : `HTTP ${response.status}` };
607
+ }
608
+ catch (error) {
609
+ return { ok: false, status: 0, body: null, error: error instanceof Error ? error.message : 'Network request failed.' };
610
+ }
611
+ }
612
+ function summarizeOperationResponse(result) {
613
+ const body = result.body;
614
+ const base = {
615
+ ok: result.ok,
616
+ status: result.status,
617
+ contentType: result.contentType,
618
+ error: result.error ? redactCliControlPlaneText(result.error) : undefined,
619
+ };
620
+ if (Array.isArray(body)) {
621
+ const first = readRecord(body[0]);
622
+ return {
623
+ ...base,
624
+ bodyType: 'array',
625
+ itemCount: body.length,
626
+ keys: Object.keys(first).filter((key) => !SECRET_KEY_PATTERN.test(key)).slice(0, 24),
627
+ };
628
+ }
629
+ if (body && typeof body === 'object') {
630
+ return {
631
+ ...base,
632
+ bodyType: 'object',
633
+ keys: Object.keys(readRecord(body)).filter((key) => !SECRET_KEY_PATTERN.test(key)).slice(0, 24),
634
+ };
635
+ }
636
+ if (typeof body === 'string') {
637
+ return {
638
+ ...base,
639
+ bodyType: 'string',
640
+ keys: [],
641
+ preview: redactCliControlPlaneText(body, 160),
642
+ };
643
+ }
644
+ if (typeof body === 'number')
645
+ return { ...base, bodyType: 'number', keys: [], preview: String(body).slice(0, 80) };
646
+ if (typeof body === 'boolean')
647
+ return { ...base, bodyType: 'boolean', keys: [], preview: String(body) };
648
+ return { ...base, bodyType: 'null', keys: [] };
649
+ }
650
+ function normalizeReadOnlyOperationMethod(value) {
651
+ if (typeof value !== 'string')
652
+ return null;
653
+ const method = value.trim().toUpperCase();
654
+ return method === 'GET' || method === 'HEAD' ? method : null;
655
+ }
656
+ function normalizeRemoteRunOperationAction(value) {
657
+ if (value === 'list' || value === 'get' || value === 'events' || value === 'stop')
658
+ return value;
659
+ return null;
660
+ }
661
+ function defaultRemoteRunOperationPath(action, runId) {
662
+ if (action === 'list')
663
+ return '/v1/remote-runs';
664
+ if (!runId)
665
+ return null;
666
+ const encoded = encodeURIComponent(runId);
667
+ if (action === 'get')
668
+ return `/v1/remote-runs/${encoded}`;
669
+ if (action === 'events')
670
+ return `/v1/remote-runs/${encoded}/events`;
671
+ return `/v1/remote-runs/${encoded}/stop`;
672
+ }
673
+ function remoteRunOperationPath(record, action, runId) {
674
+ const override = normalizeCliWorkflowOperationPath(record.path);
675
+ if (!override)
676
+ return defaultRemoteRunOperationPath(action, runId);
677
+ const encoded = runId ? encodeURIComponent(runId) : '';
678
+ const resolved = override
679
+ .replace(/\{runId\}/g, encoded)
680
+ .replace(/\{run_id\}/g, encoded);
681
+ return resolved.includes('{') || resolved.includes('}') ? null : normalizeCliWorkflowOperationPath(resolved);
682
+ }
683
+ function summarizeManifest(result) {
684
+ const body = readRecord(result.body);
685
+ const client = readRecord(body.client);
686
+ const metadata = readRecord(body.metadata);
687
+ return {
688
+ ok: result.ok,
689
+ status: result.status,
690
+ contentType: result.contentType,
691
+ error: result.error ? redactCliControlPlaneText(result.error) : undefined,
692
+ name: readString(body, ['name', 'app', 'serviceName']),
693
+ service: readString(body, ['service', 'id']),
694
+ version: readString(body, ['version']),
695
+ cliVersion: readString(body, ['cliVersion', 'cli_version']),
696
+ appVersion: readString(body, ['appVersion', 'app_version']),
697
+ clientName: readString(client, ['name']) || readString(metadata, ['clientName', 'client']),
698
+ capabilities: readCapabilities(body.capabilities || metadata.capabilities),
699
+ };
700
+ }
701
+ function summarizeOpenApi(result) {
702
+ const body = readRecord(result.body);
703
+ const info = readRecord(body.info);
704
+ const paths = readRecord(body.paths);
705
+ return {
706
+ ok: result.ok,
707
+ status: result.status,
708
+ contentType: result.contentType,
709
+ error: result.error ? redactCliControlPlaneText(result.error) : undefined,
710
+ title: readString(info, ['title']),
711
+ version: readString(info, ['version']),
712
+ operationCount: countOpenApiOperations(paths),
713
+ paths: Object.keys(paths)
714
+ .filter(isSafeOpenApiPath)
715
+ .slice(0, 40),
716
+ };
717
+ }
718
+ function versionSkewWarning(manifest, openapi) {
719
+ const manifestVersion = manifest.cliVersion || manifest.appVersion || manifest.version;
720
+ if (!manifestVersion || !openapi.version || manifestVersion === openapi.version)
721
+ return undefined;
722
+ return `CLI manifest version ${manifestVersion} differs from OpenAPI version ${openapi.version}.`;
723
+ }
724
+ export async function inspectCliAppServer(params) {
725
+ const record = asRecord(params);
726
+ const endpoint = normalizeLocalCliAppServerEndpoint(record.endpoint);
727
+ const checkedAt = Date.now();
728
+ if (!endpoint) {
729
+ return {
730
+ success: false,
731
+ endpoint: null,
732
+ checkedAt,
733
+ status: 'blocked',
734
+ manifest: emptyManifestSummary('CLI app-server endpoint must be a local http(s) origin.'),
735
+ openapi: emptyOpenApiSummary('CLI app-server endpoint must be a local http(s) origin.'),
736
+ workflows: deriveCliWorkflowReadiness({}),
737
+ dashboards: deriveCliProductDashboards(deriveCliWorkflowReadiness({})),
738
+ error: 'CLI app-server endpoint must be a local http(s) origin.',
739
+ };
740
+ }
741
+ const policy = evaluateIpcPolicy({ ...record, endpoint }, {
742
+ action: 'read',
743
+ kind: 'tool',
744
+ id: 'cliControlPlane:inspectAppServer',
745
+ });
746
+ if (!policy.allowed) {
747
+ return denyWithPolicy(policy, {
748
+ endpoint,
749
+ checkedAt,
750
+ status: 'blocked',
751
+ manifest: emptyManifestSummary('Policy denied.'),
752
+ openapi: emptyOpenApiSummary('Policy denied.'),
753
+ workflows: deriveCliWorkflowReadiness({}),
754
+ dashboards: deriveCliProductDashboards(deriveCliWorkflowReadiness({})),
755
+ });
756
+ }
757
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
758
+ ? Math.max(1000, Math.min(15000, Math.floor(record.timeoutMs)))
759
+ : 5000;
760
+ const [manifestResult, openapiResult] = await Promise.all([
761
+ fetchJson(endpoint, '/manifest', timeoutMs),
762
+ fetchJson(endpoint, '/openapi.json', timeoutMs),
763
+ ]);
764
+ const manifest = summarizeManifest(manifestResult);
765
+ const openapi = summarizeOpenApi(openapiResult);
766
+ const workflows = deriveCliWorkflowReadiness(readRecord(readRecord(openapiResult.body).paths));
767
+ const dashboards = deriveCliProductDashboards(workflows);
768
+ const warning = versionSkewWarning(manifest, openapi);
769
+ const success = manifest.ok && openapi.ok;
770
+ const status = success
771
+ ? (warning ? 'degraded' : 'available')
772
+ : (manifest.status === 0 && openapi.status === 0 ? 'offline' : 'degraded');
773
+ return {
774
+ success,
775
+ endpoint,
776
+ checkedAt,
777
+ status,
778
+ manifest,
779
+ openapi,
780
+ workflows,
781
+ dashboards,
782
+ versionSkewWarning: warning,
783
+ error: success ? undefined : [manifest.error, openapi.error].filter(Boolean).join(' / ') || 'CLI app-server inspection failed.',
784
+ };
785
+ }
786
+ export async function inspectCliWorkflowOperation(params) {
787
+ const record = asRecord(params);
788
+ const endpoint = normalizeLocalCliAppServerEndpoint(record.endpoint);
789
+ const method = normalizeReadOnlyOperationMethod(record.method);
790
+ const path = normalizeCliWorkflowOperationPath(record.path);
791
+ const operationId = readSafeDescriptor(record, ['operationId'], 100);
792
+ const checkedAt = Date.now();
793
+ if (!endpoint) {
794
+ return {
795
+ success: false,
796
+ endpoint: null,
797
+ checkedAt,
798
+ status: 'blocked',
799
+ method: method || 'GET',
800
+ path,
801
+ operationId,
802
+ response: emptyOperationResponseSummary('CLI app-server endpoint must be a local http(s) origin.'),
803
+ error: 'CLI app-server endpoint must be a local http(s) origin.',
804
+ };
805
+ }
806
+ if (!method) {
807
+ return {
808
+ success: false,
809
+ endpoint,
810
+ checkedAt,
811
+ status: 'blocked',
812
+ method: 'GET',
813
+ path,
814
+ operationId,
815
+ response: emptyOperationResponseSummary('Only read-only GET/HEAD CLI workflow operations can be inspected.'),
816
+ error: 'Only read-only GET/HEAD CLI workflow operations can be inspected.',
817
+ };
818
+ }
819
+ if (!path || /[{}]/.test(path)) {
820
+ return {
821
+ success: false,
822
+ endpoint,
823
+ checkedAt,
824
+ status: 'blocked',
825
+ method,
826
+ path: path || null,
827
+ operationId,
828
+ response: emptyOperationResponseSummary('CLI workflow operation path must be a safe resolved app-server path.'),
829
+ error: 'CLI workflow operation path must be a safe resolved app-server path.',
830
+ };
831
+ }
832
+ const policyRecord = { ...record };
833
+ delete policyRecord.path;
834
+ const policy = evaluateIpcPolicy({ ...policyRecord, endpoint, operationPath: path, method }, {
835
+ action: 'read',
836
+ kind: 'tool',
837
+ id: `cliControlPlane:inspectWorkflowOperation:${method}:${path.slice(0, 160)}`,
838
+ });
839
+ if (!policy.allowed) {
840
+ return denyWithPolicy(policy, {
841
+ endpoint,
842
+ checkedAt,
843
+ status: 'blocked',
844
+ method,
845
+ path,
846
+ operationId,
847
+ response: emptyOperationResponseSummary('Policy denied.'),
848
+ });
849
+ }
850
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
851
+ ? Math.max(1000, Math.min(15000, Math.floor(record.timeoutMs)))
852
+ : 5000;
853
+ const responseResult = await fetchJson(endpoint, path, timeoutMs, method);
854
+ const response = summarizeOperationResponse(responseResult);
855
+ const success = response.ok;
856
+ const status = success ? 'available' : (response.status === 0 ? 'offline' : 'degraded');
857
+ return {
858
+ success,
859
+ endpoint,
860
+ checkedAt,
861
+ status,
862
+ method,
863
+ path,
864
+ operationId,
865
+ response,
866
+ error: success ? undefined : response.error || 'CLI workflow operation inspection failed.',
867
+ };
868
+ }
869
+ export async function runCliRemoteRunOperation(params) {
870
+ const record = asRecord(params);
871
+ const endpoint = normalizeLocalCliAppServerEndpoint(record.endpoint);
872
+ const action = normalizeRemoteRunOperationAction(record.action) || 'list';
873
+ const runId = readSafeDescriptor(record, ['runId', 'id'], 160);
874
+ const method = action === 'stop' ? 'POST' : 'GET';
875
+ const path = remoteRunOperationPath(record, action, runId);
876
+ const checkedAt = Date.now();
877
+ if (!endpoint) {
878
+ return {
879
+ success: false,
880
+ endpoint: null,
881
+ checkedAt,
882
+ status: 'blocked',
883
+ action,
884
+ method,
885
+ path,
886
+ runId,
887
+ response: emptyOperationResponseSummary('CLI app-server endpoint must be a local http(s) origin.'),
888
+ error: 'CLI app-server endpoint must be a local http(s) origin.',
889
+ };
890
+ }
891
+ if (!path || (action !== 'list' && !runId)) {
892
+ return {
893
+ success: false,
894
+ endpoint,
895
+ checkedAt,
896
+ status: 'blocked',
897
+ action,
898
+ method,
899
+ path,
900
+ runId,
901
+ response: emptyOperationResponseSummary('Remote run operation requires a safe resolved path and runId.'),
902
+ error: 'Remote run operation requires a safe resolved path and runId.',
903
+ };
904
+ }
905
+ const tokenEnvKey = normalizeCliAppServerTokenEnvKey(record.tokenEnvKey || record.cliAppServerTokenEnvKey);
906
+ const token = tokenEnvKey ? process.env[tokenEnvKey]?.trim() : undefined;
907
+ if (action === 'stop' && !token) {
908
+ return {
909
+ success: false,
910
+ endpoint,
911
+ checkedAt,
912
+ status: 'blocked',
913
+ action,
914
+ method,
915
+ path,
916
+ runId,
917
+ response: emptyOperationResponseSummary('CLI app-server token env reference is required before remote stop.'),
918
+ error: 'CLI app-server token env reference is required before remote stop.',
919
+ };
920
+ }
921
+ const policyRecord = { ...record };
922
+ delete policyRecord.path;
923
+ const policy = evaluateIpcPolicy({ ...policyRecord, endpoint, operationPath: path, method, tokenEnvKey }, {
924
+ action: action === 'stop' ? 'execute' : 'read',
925
+ kind: 'tool',
926
+ id: `cliControlPlane:remoteRun.${action}`,
927
+ });
928
+ if (!policy.allowed) {
929
+ return denyWithPolicy(policy, {
930
+ endpoint,
931
+ checkedAt,
932
+ status: 'blocked',
933
+ action,
934
+ method,
935
+ path,
936
+ runId,
937
+ response: emptyOperationResponseSummary('Policy denied.'),
938
+ });
939
+ }
940
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
941
+ ? Math.max(1000, Math.min(15000, Math.floor(record.timeoutMs)))
942
+ : 5000;
943
+ const response = summarizeOperationResponse(await fetchJson(endpoint, path, timeoutMs, method, token));
944
+ const success = response.ok;
945
+ const status = success ? 'available' : (response.status === 0 ? 'offline' : response.status === 401 || response.status === 403 ? 'blocked' : 'degraded');
946
+ if (action === 'events' && runId) {
947
+ appendCliRemoteRuntimeEvent(getRuntimeEventStore(), record, {
948
+ id: `${runId}:remote-events-attached`,
949
+ type: 'remote.run.events.attached',
950
+ method: 'remoteRun.events',
951
+ status,
952
+ runId,
953
+ ...(typeof response.itemCount === 'number' ? { eventCount: response.itemCount } : {}),
954
+ });
955
+ }
956
+ if (action === 'stop' && runId) {
957
+ appendCliRemoteRuntimeEvent(getRuntimeEventStore(), record, {
958
+ id: `${runId}:remote-stop`,
959
+ type: success ? 'turn.cancelled' : 'turn.failed',
960
+ method: 'remoteRun.stop',
961
+ status,
962
+ runId,
963
+ ...(response.error ? { error: response.error } : {}),
964
+ });
965
+ }
966
+ return {
967
+ success,
968
+ endpoint,
969
+ checkedAt,
970
+ status,
971
+ action,
972
+ method,
973
+ path,
974
+ runId,
975
+ response,
976
+ error: success ? undefined : response.error || 'CLI remote run operation failed.',
977
+ };
978
+ }
979
+ function normalizeShareReplayOperationAction(value) {
980
+ return value === 'export' || value === 'inspect' ? value : null;
981
+ }
982
+ function normalizeEvalOperationAction(value) {
983
+ return value === 'list' || value === 'inspect' || value === 'run' || value === 'compare' ? value : null;
984
+ }
985
+ function normalizeOrgMetadataOperationAction(value) {
986
+ if (value === 'knowledge' || value === 'playbooks' || value === 'secrets' || value === 'serviceUsers')
987
+ return value;
988
+ if (value === 'service-users' || value === 'service_users')
989
+ return 'serviceUsers';
990
+ return null;
991
+ }
992
+ function normalizeMcpAuthOperationAction(value) {
993
+ if (value === 'status' || value === 'login' || value === 'logout')
994
+ return value;
995
+ return null;
996
+ }
997
+ function normalizeGithubAppOperationAction(value) {
998
+ if (value === 'plan' || value === 'verify' || value === 'mapWebhook')
999
+ return value;
1000
+ if (value === 'map-webhook' || value === 'map_webhook')
1001
+ return 'mapWebhook';
1002
+ return null;
1003
+ }
1004
+ function orgMetadataOperationMethod(action) {
1005
+ if (action === 'playbooks')
1006
+ return 'xeno org playbooks list';
1007
+ if (action === 'secrets')
1008
+ return 'xeno org secrets list';
1009
+ if (action === 'serviceUsers')
1010
+ return 'xeno org service-users list';
1011
+ return 'xeno org knowledge list';
1012
+ }
1013
+ function githubAppOperationMethod(action) {
1014
+ if (action === 'verify')
1015
+ return 'xeno github app verify';
1016
+ if (action === 'mapWebhook')
1017
+ return 'xeno github app map-webhook';
1018
+ return 'xeno github app plan';
1019
+ }
1020
+ function mcpAuthOperationMethod(action) {
1021
+ if (action === 'login')
1022
+ return 'xeno mcp login';
1023
+ if (action === 'logout')
1024
+ return 'xeno mcp logout';
1025
+ return 'xeno mcp auth status';
1026
+ }
1027
+ function orgMetadataOperationArgs(action) {
1028
+ if (action === 'playbooks')
1029
+ return ['org', 'playbooks', 'list', '--json'];
1030
+ if (action === 'secrets')
1031
+ return ['org', 'secrets', 'list', '--json'];
1032
+ if (action === 'serviceUsers')
1033
+ return ['org', 'service-users', 'list', '--json'];
1034
+ return ['org', 'knowledge', 'list', '--json'];
1035
+ }
1036
+ function evalOperationMethod(action) {
1037
+ if (action === 'inspect')
1038
+ return 'xeno eval inspect';
1039
+ if (action === 'run')
1040
+ return 'xeno eval run';
1041
+ if (action === 'compare')
1042
+ return 'xeno eval compare';
1043
+ return 'xeno eval list';
1044
+ }
1045
+ function buildEvalOperationArgs(record, action) {
1046
+ const suite = readSafePathArgument(record, ['suite', 'suiteId', 'id'], 400);
1047
+ const reportPath = readSafePathArgument(record, ['reportPath', 'report']);
1048
+ const before = readSafePathArgument(record, ['before', 'runA', 'baseline']);
1049
+ const after = readSafePathArgument(record, ['after', 'runB', 'candidate']);
1050
+ if (action === 'list')
1051
+ return { args: ['eval', 'list', '--json'] };
1052
+ if (action === 'inspect') {
1053
+ return suite
1054
+ ? { args: ['eval', 'inspect', suite, '--json'], suite, targetPath: suite }
1055
+ : { args: null, error: 'Eval inspect requires a suite reference.' };
1056
+ }
1057
+ if (action === 'run') {
1058
+ if (!suite)
1059
+ return { args: null, error: 'Eval run requires a suite reference.' };
1060
+ const args = ['eval', 'run', suite, '--json'];
1061
+ if (reportPath)
1062
+ args.push('--report', reportPath);
1063
+ if (record.allowFailures === true)
1064
+ args.push('--allow-failures');
1065
+ return { args, suite, targetPath: reportPath || suite };
1066
+ }
1067
+ if (!before || !after)
1068
+ return { args: null, error: 'Eval compare requires before and after report references.' };
1069
+ return { args: ['eval', 'compare', before, after, '--json'], targetPath: before };
1070
+ }
1071
+ function buildMcpAuthOperationArgs(record, action) {
1072
+ const server = readSafeDescriptor(record, ['server', 'serverName', 'name'], 160);
1073
+ const tokenEnvProvided = ['tokenEnv', 'tokenEnvKey', 'bearerTokenEnv'].some((key) => {
1074
+ const value = record[key];
1075
+ return typeof value === 'string' && Boolean(value.trim());
1076
+ });
1077
+ const tokenEnv = normalizeCliAppServerTokenEnvKey(record.tokenEnv || record.tokenEnvKey || record.bearerTokenEnv);
1078
+ if (tokenEnvProvided && !tokenEnv)
1079
+ return { args: null, server, error: 'MCP token env reference must be a safe environment variable name.' };
1080
+ if (action === 'status')
1081
+ return { args: ['mcp', 'auth', 'status', '--json'] };
1082
+ if (!server)
1083
+ return { args: null, error: `MCP auth ${action} requires a server name.` };
1084
+ if (action === 'logout')
1085
+ return { args: ['mcp', 'logout', server, '--json'], server };
1086
+ const args = ['mcp', 'login', server, '--json'];
1087
+ if (tokenEnv)
1088
+ args.push('--token-env', tokenEnv);
1089
+ if (record.noBrowser !== false)
1090
+ args.push('--no-browser');
1091
+ return { args, server };
1092
+ }
1093
+ function buildGithubAppOperationArgs(record, action) {
1094
+ const fixturePath = readSafePathArgument(record, ['fixturePath', 'fixture', 'path']);
1095
+ const backendUrl = readSafeHttpUrlArgument(record, ['backendUrl', 'backend']);
1096
+ if (backendUrl.error)
1097
+ return { args: null, fixturePath, error: backendUrl.error };
1098
+ const appendBackendUrl = (args) => {
1099
+ if (backendUrl.value)
1100
+ args.push('--backend-url', backendUrl.value);
1101
+ return args;
1102
+ };
1103
+ if (action === 'plan')
1104
+ return { args: appendBackendUrl(['github', 'app', 'plan', '--json']), backendUrl: backendUrl.value };
1105
+ if (action === 'verify') {
1106
+ const args = ['github', 'app', 'verify', '--json'];
1107
+ if (fixturePath)
1108
+ args.push('--fixture', fixturePath);
1109
+ return { args: appendBackendUrl(args), fixturePath, backendUrl: backendUrl.value, targetPath: fixturePath };
1110
+ }
1111
+ if (!fixturePath) {
1112
+ return { args: null, error: 'GitHub app webhook mapping requires a fixture path.' };
1113
+ }
1114
+ return {
1115
+ args: ['github', 'app', 'map-webhook', fixturePath, '--json'],
1116
+ fixturePath,
1117
+ targetPath: fixturePath,
1118
+ };
1119
+ }
1120
+ export async function runCliEvalOperation(params, options = {}) {
1121
+ const record = asRecord(params);
1122
+ const checkedAt = Date.now();
1123
+ const action = normalizeEvalOperationAction(record.action) || 'list';
1124
+ const method = evalOperationMethod(action);
1125
+ const cwd = readCliRemoteCwd(record);
1126
+ const built = buildEvalOperationArgs(record, action);
1127
+ if (!built.args) {
1128
+ return {
1129
+ success: false,
1130
+ checkedAt,
1131
+ status: 'blocked',
1132
+ action,
1133
+ method,
1134
+ suite: built.suite,
1135
+ pathLabel: safePathLabel(built.targetPath),
1136
+ response: emptyOperationResponseSummary(built.error || 'CLI eval operation is incomplete.'),
1137
+ error: built.error || 'CLI eval operation is incomplete.',
1138
+ };
1139
+ }
1140
+ const policy = evaluateIpcPolicy({ ...record, cwd, path: built.targetPath }, {
1141
+ action: action === 'run' ? 'execute' : 'read',
1142
+ kind: 'tool',
1143
+ id: `cliControlPlane:eval.${action}`,
1144
+ path: built.targetPath,
1145
+ });
1146
+ if (!policy.allowed) {
1147
+ return denyWithPolicy(policy, {
1148
+ success: false,
1149
+ checkedAt,
1150
+ status: 'blocked',
1151
+ action,
1152
+ method,
1153
+ suite: built.suite,
1154
+ pathLabel: safePathLabel(built.targetPath),
1155
+ response: emptyOperationResponseSummary('Policy denied.'),
1156
+ });
1157
+ }
1158
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1159
+ ? Math.max(1000, Math.min(300_000, Math.floor(record.timeoutMs)))
1160
+ : 60_000;
1161
+ const activeRun = { cancelled: false };
1162
+ try {
1163
+ const result = await (options.commandRunner || runXenoCliCommand)(built.args, { cwd, timeoutMs, activeRun });
1164
+ const { body, response } = summarizeCliJsonCommandResult(result);
1165
+ const commandError = body ? readSafeDescriptor(body, ['error'], 400) : undefined;
1166
+ const success = result.exitCode === 0 && response.ok;
1167
+ return {
1168
+ success,
1169
+ checkedAt,
1170
+ status: success ? 'available' : (result.exitCode === null ? 'offline' : 'degraded'),
1171
+ action,
1172
+ method,
1173
+ suite: built.suite,
1174
+ pathLabel: safePathLabel(built.targetPath),
1175
+ response,
1176
+ error: success ? undefined : commandError || response.error || 'CLI eval operation failed.',
1177
+ };
1178
+ }
1179
+ catch (error) {
1180
+ const message = redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI eval operation failed.', 400);
1181
+ return {
1182
+ success: false,
1183
+ checkedAt,
1184
+ status: 'offline',
1185
+ action,
1186
+ method,
1187
+ suite: built.suite,
1188
+ pathLabel: safePathLabel(built.targetPath),
1189
+ response: emptyOperationResponseSummary(message),
1190
+ error: message,
1191
+ };
1192
+ }
1193
+ }
1194
+ export async function runCliOrgMetadataOperation(params, options = {}) {
1195
+ const record = asRecord(params);
1196
+ const checkedAt = Date.now();
1197
+ const action = normalizeOrgMetadataOperationAction(record.action) || 'knowledge';
1198
+ const method = orgMetadataOperationMethod(action);
1199
+ const cwd = readCliRemoteCwd(record);
1200
+ const policy = evaluateIpcPolicy({ ...record, cwd, path: cwd }, {
1201
+ action: 'read',
1202
+ kind: 'tool',
1203
+ id: `cliControlPlane:orgMetadata.${action}`,
1204
+ path: cwd,
1205
+ });
1206
+ if (!policy.allowed) {
1207
+ return denyWithPolicy(policy, {
1208
+ success: false,
1209
+ checkedAt,
1210
+ status: 'blocked',
1211
+ action,
1212
+ method,
1213
+ workspaceLabel: safePathLabel(cwd),
1214
+ response: emptyOperationResponseSummary('Policy denied.'),
1215
+ });
1216
+ }
1217
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1218
+ ? Math.max(1000, Math.min(120_000, Math.floor(record.timeoutMs)))
1219
+ : 60_000;
1220
+ const activeRun = { cancelled: false };
1221
+ try {
1222
+ const result = await (options.commandRunner || runXenoCliCommand)(orgMetadataOperationArgs(action), { cwd, timeoutMs, activeRun });
1223
+ const { body, response } = summarizeCliJsonCommandResult(result);
1224
+ const commandError = body ? readSafeDescriptor(body, ['error'], 400) : undefined;
1225
+ const success = result.exitCode === 0 && response.ok;
1226
+ return {
1227
+ success,
1228
+ checkedAt,
1229
+ status: success ? 'available' : (result.exitCode === null ? 'offline' : 'degraded'),
1230
+ action,
1231
+ method,
1232
+ workspaceLabel: safePathLabel(cwd),
1233
+ response,
1234
+ error: success ? undefined : commandError || response.error || 'CLI org metadata operation failed.',
1235
+ };
1236
+ }
1237
+ catch (error) {
1238
+ const message = redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI org metadata operation failed.', 400);
1239
+ return {
1240
+ success: false,
1241
+ checkedAt,
1242
+ status: 'offline',
1243
+ action,
1244
+ method,
1245
+ workspaceLabel: safePathLabel(cwd),
1246
+ response: emptyOperationResponseSummary(message),
1247
+ error: message,
1248
+ };
1249
+ }
1250
+ }
1251
+ export async function runCliMcpAuthOperation(params, options = {}) {
1252
+ const record = asRecord(params);
1253
+ const checkedAt = Date.now();
1254
+ const action = normalizeMcpAuthOperationAction(record.action) || 'status';
1255
+ const method = mcpAuthOperationMethod(action);
1256
+ const cwd = readCliRemoteCwd(record);
1257
+ const built = buildMcpAuthOperationArgs(record, action);
1258
+ if (!built.args) {
1259
+ return {
1260
+ success: false,
1261
+ checkedAt,
1262
+ status: 'blocked',
1263
+ action,
1264
+ method,
1265
+ server: built.server,
1266
+ response: emptyOperationResponseSummary(built.error || 'CLI MCP auth operation is incomplete.'),
1267
+ error: built.error || 'CLI MCP auth operation is incomplete.',
1268
+ };
1269
+ }
1270
+ const policy = evaluateIpcPolicy({ ...record, cwd, path: cwd }, {
1271
+ action: action === 'status' ? 'read' : 'execute',
1272
+ kind: 'tool',
1273
+ id: `cliControlPlane:mcpAuth.${action}`,
1274
+ path: cwd,
1275
+ });
1276
+ if (!policy.allowed) {
1277
+ return denyWithPolicy(policy, {
1278
+ success: false,
1279
+ checkedAt,
1280
+ status: 'blocked',
1281
+ action,
1282
+ method,
1283
+ server: built.server,
1284
+ response: emptyOperationResponseSummary('Policy denied.'),
1285
+ });
1286
+ }
1287
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1288
+ ? Math.max(1000, Math.min(120_000, Math.floor(record.timeoutMs)))
1289
+ : 60_000;
1290
+ const activeRun = { cancelled: false };
1291
+ try {
1292
+ const result = await (options.commandRunner || runXenoCliCommand)(built.args, { cwd, timeoutMs, activeRun });
1293
+ const { body, response } = summarizeCliJsonCommandResult(result);
1294
+ const commandError = body ? readSafeDescriptor(body, ['error'], 400) : undefined;
1295
+ const success = result.exitCode === 0 && response.ok;
1296
+ return {
1297
+ success,
1298
+ checkedAt,
1299
+ status: success ? 'available' : (result.exitCode === null ? 'offline' : 'degraded'),
1300
+ action,
1301
+ method,
1302
+ server: built.server,
1303
+ response,
1304
+ error: success ? undefined : commandError || response.error || 'CLI MCP auth operation failed.',
1305
+ };
1306
+ }
1307
+ catch (error) {
1308
+ const message = redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI MCP auth operation failed.', 400);
1309
+ return {
1310
+ success: false,
1311
+ checkedAt,
1312
+ status: 'offline',
1313
+ action,
1314
+ method,
1315
+ server: built.server,
1316
+ response: emptyOperationResponseSummary(message),
1317
+ error: message,
1318
+ };
1319
+ }
1320
+ }
1321
+ export async function runCliGithubAppOperation(params, options = {}) {
1322
+ const record = asRecord(params);
1323
+ const checkedAt = Date.now();
1324
+ const action = normalizeGithubAppOperationAction(record.action) || 'plan';
1325
+ const method = githubAppOperationMethod(action);
1326
+ const cwd = readCliRemoteCwd(record);
1327
+ const built = buildGithubAppOperationArgs(record, action);
1328
+ const targetPath = built.targetPath || cwd;
1329
+ if (!built.args) {
1330
+ return {
1331
+ success: false,
1332
+ checkedAt,
1333
+ status: 'blocked',
1334
+ action,
1335
+ method,
1336
+ fixtureLabel: safePathLabel(built.fixturePath),
1337
+ backendUrl: built.backendUrl,
1338
+ response: emptyOperationResponseSummary(built.error || 'CLI GitHub app operation is incomplete.'),
1339
+ error: built.error || 'CLI GitHub app operation is incomplete.',
1340
+ };
1341
+ }
1342
+ const policy = evaluateIpcPolicy({ ...record, cwd, path: targetPath }, {
1343
+ action: 'read',
1344
+ kind: 'tool',
1345
+ id: `cliControlPlane:githubApp.${action}`,
1346
+ path: targetPath,
1347
+ });
1348
+ if (!policy.allowed) {
1349
+ return denyWithPolicy(policy, {
1350
+ success: false,
1351
+ checkedAt,
1352
+ status: 'blocked',
1353
+ action,
1354
+ method,
1355
+ fixtureLabel: safePathLabel(built.fixturePath),
1356
+ backendUrl: built.backendUrl,
1357
+ response: emptyOperationResponseSummary('Policy denied.'),
1358
+ });
1359
+ }
1360
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1361
+ ? Math.max(1000, Math.min(120_000, Math.floor(record.timeoutMs)))
1362
+ : 60_000;
1363
+ const activeRun = { cancelled: false };
1364
+ try {
1365
+ const result = await (options.commandRunner || runXenoCliCommand)(built.args, { cwd, timeoutMs, activeRun });
1366
+ const { body, response } = summarizeCliJsonCommandResult(result);
1367
+ const commandError = body ? readSafeDescriptor(body, ['error'], 400) : undefined;
1368
+ const success = result.exitCode === 0 && response.ok;
1369
+ return {
1370
+ success,
1371
+ checkedAt,
1372
+ status: success ? 'available' : (result.exitCode === null ? 'offline' : 'degraded'),
1373
+ action,
1374
+ method,
1375
+ fixtureLabel: safePathLabel(built.fixturePath),
1376
+ backendUrl: built.backendUrl,
1377
+ response,
1378
+ error: success ? undefined : commandError || response.error || 'CLI GitHub app operation failed.',
1379
+ };
1380
+ }
1381
+ catch (error) {
1382
+ const message = redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI GitHub app operation failed.', 400);
1383
+ return {
1384
+ success: false,
1385
+ checkedAt,
1386
+ status: 'offline',
1387
+ action,
1388
+ method,
1389
+ fixtureLabel: safePathLabel(built.fixturePath),
1390
+ backendUrl: built.backendUrl,
1391
+ response: emptyOperationResponseSummary(message),
1392
+ error: message,
1393
+ };
1394
+ }
1395
+ }
1396
+ export async function runCliShareReplayOperation(params, options = {}) {
1397
+ const record = asRecord(params);
1398
+ const checkedAt = Date.now();
1399
+ const action = normalizeShareReplayOperationAction(record.action) || 'inspect';
1400
+ const method = action === 'export' ? 'xeno share export' : 'xeno share inspect';
1401
+ const cwd = readCliRemoteCwd(record);
1402
+ const sourceId = readSafeDescriptor(record, ['sourceId', 'runId', 'sessionId', 'id'], 180);
1403
+ const bundlePath = readSafePathArgument(record, ['bundlePath', 'path']);
1404
+ const outputPath = readSafePathArgument(record, ['outputPath', 'out']);
1405
+ const targetPath = action === 'export' ? outputPath : bundlePath;
1406
+ if (action === 'export' && (!sourceId || !outputPath)) {
1407
+ return {
1408
+ success: false,
1409
+ checkedAt,
1410
+ status: 'blocked',
1411
+ action,
1412
+ method,
1413
+ sourceId,
1414
+ pathLabel: safePathLabel(outputPath),
1415
+ response: emptyOperationResponseSummary('Share export requires a source id and output path.'),
1416
+ error: 'Share export requires a source id and output path.',
1417
+ };
1418
+ }
1419
+ if (action === 'inspect' && !bundlePath) {
1420
+ return {
1421
+ success: false,
1422
+ checkedAt,
1423
+ status: 'blocked',
1424
+ action,
1425
+ method,
1426
+ pathLabel: safePathLabel(bundlePath),
1427
+ response: emptyOperationResponseSummary('Share inspect requires a bundle path.'),
1428
+ error: 'Share inspect requires a bundle path.',
1429
+ };
1430
+ }
1431
+ const policy = evaluateIpcPolicy({ ...record, cwd, path: targetPath }, {
1432
+ action: action === 'export' ? 'execute' : 'read',
1433
+ kind: 'tool',
1434
+ id: `cliControlPlane:shareReplay.${action}`,
1435
+ path: targetPath,
1436
+ });
1437
+ if (!policy.allowed) {
1438
+ return denyWithPolicy(policy, {
1439
+ success: false,
1440
+ checkedAt,
1441
+ status: 'blocked',
1442
+ action,
1443
+ method,
1444
+ sourceId,
1445
+ pathLabel: safePathLabel(targetPath),
1446
+ response: emptyOperationResponseSummary('Policy denied.'),
1447
+ });
1448
+ }
1449
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1450
+ ? Math.max(1000, Math.min(120_000, Math.floor(record.timeoutMs)))
1451
+ : 60_000;
1452
+ const args = action === 'export'
1453
+ ? ['share', 'export', sourceId, '--out', outputPath, '--json']
1454
+ : ['share', 'inspect', bundlePath, '--json'];
1455
+ const activeRun = { cancelled: false };
1456
+ try {
1457
+ const result = await (options.commandRunner || runXenoCliCommand)(args, { cwd, timeoutMs, activeRun });
1458
+ const { body, response } = summarizeCliJsonCommandResult(result);
1459
+ const commandError = body ? readSafeDescriptor(body, ['error'], 400) : undefined;
1460
+ const success = result.exitCode === 0 && response.ok;
1461
+ return {
1462
+ success,
1463
+ checkedAt,
1464
+ status: success ? 'available' : (result.exitCode === null ? 'offline' : 'degraded'),
1465
+ action,
1466
+ method,
1467
+ sourceId,
1468
+ pathLabel: safePathLabel(targetPath),
1469
+ response,
1470
+ error: success ? undefined : commandError || response.error || 'CLI share/replay operation failed.',
1471
+ };
1472
+ }
1473
+ catch (error) {
1474
+ const message = redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI share/replay operation failed.', 400);
1475
+ return {
1476
+ success: false,
1477
+ checkedAt,
1478
+ status: 'offline',
1479
+ action,
1480
+ method,
1481
+ sourceId,
1482
+ pathLabel: safePathLabel(targetPath),
1483
+ response: emptyOperationResponseSummary(message),
1484
+ error: message,
1485
+ };
1486
+ }
1487
+ }
1488
+ /**
1489
+ * The permission modes `xeno run` accepts on its command line. Narrower than the
1490
+ * hosted API's enum (no `plan`, no `dontAsk`) — the CLI exits(1) on anything
1491
+ * else, so an unrecognised value must be rejected here rather than turned into
1492
+ * argv, and must NOT be silently dropped: a dropped permission field is
1493
+ * indistinguishable from a deliberate default.
1494
+ */
1495
+ const CLI_RUN_PERMISSION_MODES = new Set(['default', 'auto', 'acceptEdits', 'bypassPermissions']);
1496
+ export async function runCliRemoteTurn(params, options = {}) {
1497
+ const record = asRecord(params);
1498
+ const checkedAt = Date.now();
1499
+ const requestId = readSafeDescriptor(record, ['requestId'], 100) || `hub-remote-run-${checkedAt}`;
1500
+ const prompt = typeof record.prompt === 'string' ? record.prompt.trim().slice(0, 200_000) : '';
1501
+ const remoteBackendId = readSafeDescriptor(record, ['remoteBackendId', 'providerId'], 200);
1502
+ const cwd = readCliRemoteCwd(record);
1503
+ const runtimeStore = options.runtimeStore || getRuntimeEventStore();
1504
+ if (!remoteBackendId) {
1505
+ return {
1506
+ success: false,
1507
+ checkedAt,
1508
+ status: 'blocked',
1509
+ method: 'xeno run --remote',
1510
+ requestId,
1511
+ error: 'CLI remote backend reference is required.',
1512
+ };
1513
+ }
1514
+ if (!prompt) {
1515
+ return {
1516
+ success: false,
1517
+ checkedAt,
1518
+ status: 'blocked',
1519
+ method: 'xeno run --remote',
1520
+ requestId,
1521
+ error: 'CLI remote prompt is required.',
1522
+ };
1523
+ }
1524
+ const policy = evaluateIpcPolicy({ ...record, cwd }, {
1525
+ action: 'execute',
1526
+ kind: 'tool',
1527
+ id: 'cliControlPlane:xeno.run.remote',
1528
+ });
1529
+ if (!policy.allowed) {
1530
+ return denyWithPolicy(policy, {
1531
+ success: false,
1532
+ checkedAt,
1533
+ status: 'blocked',
1534
+ method: 'xeno run --remote',
1535
+ requestId,
1536
+ });
1537
+ }
1538
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1539
+ ? Math.max(1000, Math.min(300_000, Math.floor(record.timeoutMs)))
1540
+ : 60_000;
1541
+ const args = ['run', prompt, '--remote', '--json'];
1542
+ const model = readSafeDescriptor(record, ['model'], 160);
1543
+ if (model)
1544
+ args.push('--model', model);
1545
+ const title = readSafeDescriptor(record, ['title'], 180);
1546
+ if (title)
1547
+ args.push('--title', title);
1548
+ // This argv list is an ALLOW-LIST: a flag not pushed here cannot reach the
1549
+ // CLI. `--permission-mode` was never pushed, so every remote turn ran under
1550
+ // the CLI's own `default` — and the hosted server now REFUSES Write/Edit
1551
+ // under `default`. Forward the caller's mode so a read-only run is a choice.
1552
+ const permissionMode = readSafeDescriptor(record, ['permissionMode'], 40);
1553
+ if (permissionMode) {
1554
+ if (!CLI_RUN_PERMISSION_MODES.has(permissionMode)) {
1555
+ return {
1556
+ success: false,
1557
+ checkedAt,
1558
+ status: 'blocked',
1559
+ method: 'xeno run --remote',
1560
+ requestId,
1561
+ error: `Unsupported permissionMode for xeno run --remote: ${permissionMode}. Expected one of ${[...CLI_RUN_PERMISSION_MODES].join(', ')}.`,
1562
+ };
1563
+ }
1564
+ args.push('--permission-mode', permissionMode);
1565
+ }
1566
+ const activeRun = { cancelled: false };
1567
+ activeCliRemoteRuns.set(requestId, activeRun);
1568
+ appendCliRemoteRuntimeEvent(runtimeStore, record, {
1569
+ id: `${requestId}:cli-remote-started`,
1570
+ type: 'turn.started',
1571
+ model: model || 'xeno-agent-cli',
1572
+ method: 'xeno run --remote',
1573
+ providerKind: 'cli-remote',
1574
+ providerId: remoteBackendId,
1575
+ });
1576
+ try {
1577
+ const result = await (options.commandRunner || runXenoCliCommand)(args, { cwd, timeoutMs, activeRun });
1578
+ const report = parseCliRemoteReport(result.stdout);
1579
+ const run = readRecord(report?.run);
1580
+ const runId = readSafeDescriptor(run, ['runId', 'id'], 160);
1581
+ const error = report
1582
+ ? readSafeDescriptor(report, ['error'], 400) || (result.exitCode === 0 ? undefined : `xeno run --remote exited with ${result.exitCode}.`)
1583
+ : redactCliControlPlaneText(result.stderr || 'xeno run --remote did not return JSON.', 400);
1584
+ const status = cliRemoteStatus(report, result.exitCode, activeRun.cancelled);
1585
+ const text = report?.ok === true ? remoteRunStartedText(runId) : undefined;
1586
+ if (text) {
1587
+ appendCliRemoteRuntimeEvent(runtimeStore, record, {
1588
+ id: `${requestId}:cli-remote-text`,
1589
+ type: 'model.text.delta',
1590
+ text,
1591
+ delta: text,
1592
+ method: 'xeno run --remote',
1593
+ providerKind: 'cli-remote',
1594
+ providerId: remoteBackendId,
1595
+ ...(runId ? { runId } : {}),
1596
+ });
1597
+ }
1598
+ appendCliRemoteRuntimeEvent(runtimeStore, record, {
1599
+ id: `${requestId}:cli-remote-terminal`,
1600
+ type: status === 'cancelled' ? 'turn.cancelled' : report?.ok === true ? 'turn.completed' : 'turn.failed',
1601
+ method: 'xeno run --remote',
1602
+ status,
1603
+ providerKind: 'cli-remote',
1604
+ providerId: remoteBackendId,
1605
+ ...(runId ? { runId } : {}),
1606
+ ...(error && report?.ok !== true ? { error: redactCliControlPlaneText(error, 400) } : {}),
1607
+ });
1608
+ return {
1609
+ success: report?.ok === true && status === 'available',
1610
+ checkedAt,
1611
+ status,
1612
+ method: 'xeno run --remote',
1613
+ requestId,
1614
+ ...(runId ? { runId } : {}),
1615
+ ...(text ? { text } : {}),
1616
+ ...(status === 'cancelled' ? { cancelled: true } : {}),
1617
+ ...(error && report?.ok !== true ? { error: redactCliControlPlaneText(error, 400) } : {}),
1618
+ };
1619
+ }
1620
+ catch (error) {
1621
+ const wasCancelled = activeRun.cancelled;
1622
+ const redactedError = wasCancelled
1623
+ ? 'CLI remote run cancelled.'
1624
+ : redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI remote run failed.', 400);
1625
+ appendCliRemoteRuntimeEvent(runtimeStore, record, {
1626
+ id: `${requestId}:cli-remote-terminal`,
1627
+ type: wasCancelled ? 'turn.cancelled' : 'turn.failed',
1628
+ method: 'xeno run --remote',
1629
+ status: wasCancelled ? 'cancelled' : 'offline',
1630
+ providerKind: 'cli-remote',
1631
+ providerId: remoteBackendId,
1632
+ ...(wasCancelled ? { reason: redactedError } : { error: redactedError }),
1633
+ });
1634
+ return {
1635
+ success: false,
1636
+ checkedAt,
1637
+ status: wasCancelled ? 'cancelled' : 'offline',
1638
+ method: 'xeno run --remote',
1639
+ requestId,
1640
+ ...(wasCancelled ? { cancelled: true } : {}),
1641
+ error: redactedError,
1642
+ };
1643
+ }
1644
+ finally {
1645
+ if (activeCliRemoteRuns.get(requestId) === activeRun)
1646
+ activeCliRemoteRuns.delete(requestId);
1647
+ }
1648
+ }
1649
+ export async function runCliAppServerThread(params, options = {}) {
1650
+ const record = asRecord(params);
1651
+ const endpoint = normalizeLocalCliAppServerEndpoint(record.endpoint);
1652
+ const tokenEnvKey = normalizeCliAppServerTokenEnvKey(record.tokenEnvKey || record.cliAppServerTokenEnvKey);
1653
+ const prompt = typeof record.prompt === 'string' ? record.prompt.trim().slice(0, 200_000) : '';
1654
+ const checkedAt = Date.now();
1655
+ const requestId = readSafeDescriptor(record, ['requestId'], 100) || `hub-thread-run-${checkedAt}`;
1656
+ const runtimeStore = options.runtimeStore || getRuntimeEventStore();
1657
+ if (!endpoint) {
1658
+ return {
1659
+ success: false,
1660
+ endpoint: null,
1661
+ checkedAt,
1662
+ status: 'blocked',
1663
+ method: 'thread.run',
1664
+ messageCount: 0,
1665
+ error: 'CLI app-server endpoint must be a local http(s) origin.',
1666
+ };
1667
+ }
1668
+ if (!tokenEnvKey) {
1669
+ return {
1670
+ success: false,
1671
+ endpoint,
1672
+ checkedAt,
1673
+ status: 'blocked',
1674
+ method: 'thread.run',
1675
+ messageCount: 0,
1676
+ error: 'CLI app-server token env reference is required before /rpc execution.',
1677
+ };
1678
+ }
1679
+ if (!prompt) {
1680
+ return {
1681
+ success: false,
1682
+ endpoint,
1683
+ checkedAt,
1684
+ status: 'blocked',
1685
+ method: 'thread.run',
1686
+ messageCount: 0,
1687
+ error: 'CLI app-server thread.run prompt is required.',
1688
+ };
1689
+ }
1690
+ const policy = evaluateIpcPolicy({ ...record, endpoint, tokenEnvKey }, {
1691
+ action: 'execute',
1692
+ kind: 'tool',
1693
+ id: 'cliControlPlane:thread.run',
1694
+ });
1695
+ if (!policy.allowed) {
1696
+ return denyWithPolicy(policy, {
1697
+ success: false,
1698
+ endpoint,
1699
+ checkedAt,
1700
+ status: 'blocked',
1701
+ method: 'thread.run',
1702
+ messageCount: 0,
1703
+ });
1704
+ }
1705
+ const token = process.env[tokenEnvKey]?.trim();
1706
+ if (!token) {
1707
+ return {
1708
+ success: false,
1709
+ endpoint,
1710
+ checkedAt,
1711
+ status: 'blocked',
1712
+ method: 'thread.run',
1713
+ messageCount: 0,
1714
+ error: `CLI app-server bearer token is unavailable in env ref ${tokenEnvKey}.`,
1715
+ };
1716
+ }
1717
+ const timeoutMs = typeof record.timeoutMs === 'number' && Number.isFinite(record.timeoutMs)
1718
+ ? Math.max(1000, Math.min(300_000, Math.floor(record.timeoutMs)))
1719
+ : 60_000;
1720
+ const activeRun = { controller: new AbortController(), cancelled: false };
1721
+ activeCliThreadRuns.set(requestId, activeRun);
1722
+ const timeout = setTimeout(() => activeRun.controller.abort(), timeoutMs);
1723
+ appendCliThreadRuntimeEvent(runtimeStore, record, {
1724
+ id: `${requestId}:cli-thread-started`,
1725
+ type: 'turn.started',
1726
+ model: 'xeno-agent-cli',
1727
+ method: 'thread.run',
1728
+ providerKind: 'cli-app-server',
1729
+ endpoint,
1730
+ });
1731
+ try {
1732
+ const response = await fetch(`${endpoint}/rpc`, {
1733
+ method: 'POST',
1734
+ headers: {
1735
+ Authorization: `Bearer ${token}`,
1736
+ 'content-type': 'application/json',
1737
+ Accept: 'application/json',
1738
+ },
1739
+ body: JSON.stringify({
1740
+ jsonrpc: '2.0',
1741
+ id: requestId,
1742
+ method: 'thread.run',
1743
+ params: { prompt },
1744
+ }),
1745
+ signal: activeRun.controller.signal,
1746
+ });
1747
+ const text = await response.text();
1748
+ const body = text ? JSON.parse(text) : {};
1749
+ const bodyRecord = readRecord(body);
1750
+ const messages = Array.isArray(bodyRecord.messages) ? bodyRecord.messages : [];
1751
+ const responseText = readThreadRunText(messages, bodyRecord);
1752
+ const rpcError = messages
1753
+ .map((message) => readRecord(message).error)
1754
+ .find(Boolean);
1755
+ const error = !response.ok
1756
+ ? readString(bodyRecord, ['error'], 220) || `HTTP ${response.status}`
1757
+ : rpcError
1758
+ ? redactCliControlPlaneText(JSON.stringify(rpcError), 220)
1759
+ : undefined;
1760
+ if (responseText) {
1761
+ appendCliThreadRuntimeEvent(runtimeStore, record, {
1762
+ id: `${requestId}:cli-thread-text`,
1763
+ type: 'model.text.delta',
1764
+ text: responseText,
1765
+ delta: responseText,
1766
+ method: 'thread.run',
1767
+ });
1768
+ }
1769
+ appendCliThreadRuntimeEvent(runtimeStore, record, {
1770
+ id: `${requestId}:cli-thread-terminal`,
1771
+ type: error ? 'turn.failed' : 'turn.completed',
1772
+ method: 'thread.run',
1773
+ status: response.ok ? (error ? 'degraded' : 'available') : (response.status === 401 ? 'blocked' : 'degraded'),
1774
+ messageCount: messages.length,
1775
+ ...(error ? { error } : {}),
1776
+ });
1777
+ return {
1778
+ success: response.ok && !error,
1779
+ endpoint,
1780
+ checkedAt,
1781
+ status: response.ok ? (error ? 'degraded' : 'available') : (response.status === 401 ? 'blocked' : 'degraded'),
1782
+ method: 'thread.run',
1783
+ messageCount: messages.length,
1784
+ ...(responseText ? { text: responseText } : {}),
1785
+ messages,
1786
+ ...(error ? { error } : {}),
1787
+ };
1788
+ }
1789
+ catch (error) {
1790
+ const wasCancelled = activeRun.cancelled;
1791
+ const redactedError = wasCancelled
1792
+ ? 'CLI app-server thread.run cancelled.'
1793
+ : redactCliControlPlaneText(error instanceof Error ? error.message : 'CLI app-server thread.run failed.');
1794
+ appendCliThreadRuntimeEvent(runtimeStore, record, {
1795
+ id: `${requestId}:cli-thread-terminal`,
1796
+ type: wasCancelled ? 'turn.cancelled' : 'turn.failed',
1797
+ method: 'thread.run',
1798
+ status: wasCancelled ? 'cancelled' : 'offline',
1799
+ ...(wasCancelled ? { reason: redactedError } : { error: redactedError }),
1800
+ });
1801
+ return {
1802
+ success: false,
1803
+ endpoint,
1804
+ checkedAt,
1805
+ status: wasCancelled ? 'cancelled' : 'offline',
1806
+ method: 'thread.run',
1807
+ messageCount: 0,
1808
+ ...(wasCancelled ? { cancelled: true } : {}),
1809
+ error: redactedError,
1810
+ };
1811
+ }
1812
+ finally {
1813
+ clearTimeout(timeout);
1814
+ if (activeCliThreadRuns.get(requestId) === activeRun)
1815
+ activeCliThreadRuns.delete(requestId);
1816
+ }
1817
+ }
1818
+ export async function cancelCliAppServerThread(params) {
1819
+ const record = asRecord(params);
1820
+ const checkedAt = Date.now();
1821
+ const requestId = readSafeDescriptor(record, ['requestId'], 100);
1822
+ if (!requestId) {
1823
+ return { success: false, checkedAt, requestId: null, cancelled: false, error: 'CLI app-server requestId is required.' };
1824
+ }
1825
+ const policy = evaluateIpcPolicy(record, {
1826
+ action: 'execute',
1827
+ kind: 'tool',
1828
+ id: 'cliControlPlane:thread.cancel',
1829
+ });
1830
+ if (!policy.allowed) {
1831
+ return denyWithPolicy(policy, {
1832
+ success: false,
1833
+ checkedAt,
1834
+ requestId,
1835
+ cancelled: false,
1836
+ });
1837
+ }
1838
+ const activeRun = activeCliThreadRuns.get(requestId);
1839
+ if (!activeRun) {
1840
+ return { success: false, checkedAt, requestId, cancelled: false, error: 'No active CLI app-server thread.run found for requestId.' };
1841
+ }
1842
+ activeRun.cancelled = true;
1843
+ activeRun.controller.abort();
1844
+ return { success: true, checkedAt, requestId, cancelled: true };
1845
+ }
1846
+ export async function cancelCliRemoteTurn(params) {
1847
+ const record = asRecord(params);
1848
+ const checkedAt = Date.now();
1849
+ const requestId = readSafeDescriptor(record, ['requestId'], 100);
1850
+ if (!requestId) {
1851
+ return { success: false, checkedAt, requestId: null, cancelled: false, error: 'CLI remote requestId is required.' };
1852
+ }
1853
+ const policy = evaluateIpcPolicy(record, {
1854
+ action: 'execute',
1855
+ kind: 'tool',
1856
+ id: 'cliControlPlane:remote.cancel',
1857
+ });
1858
+ if (!policy.allowed) {
1859
+ return denyWithPolicy(policy, {
1860
+ success: false,
1861
+ checkedAt,
1862
+ requestId,
1863
+ cancelled: false,
1864
+ });
1865
+ }
1866
+ const activeRun = activeCliRemoteRuns.get(requestId);
1867
+ if (!activeRun) {
1868
+ return { success: false, checkedAt, requestId, cancelled: false, error: 'No active CLI remote run found for requestId.' };
1869
+ }
1870
+ activeRun.cancelled = true;
1871
+ activeRun.child?.kill();
1872
+ return { success: true, checkedAt, requestId, cancelled: true };
1873
+ }
1874
+ //# sourceMappingURL=CliControlPlaneService.js.map