@moorline/core 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/dist/app/bootstrap/apiAdapterPackageLoader.d.ts +0 -10
  2. package/dist/app/bootstrap/apiAdapterPackageLoader.js +1 -1
  3. package/dist/app/bootstrap/apiAdapterPackageLoader.js.map +1 -1
  4. package/dist/app/bootstrap/operatorPackageService.d.ts +11 -4
  5. package/dist/app/bootstrap/operatorPackageService.js +231 -59
  6. package/dist/app/bootstrap/operatorPackageService.js.map +1 -1
  7. package/dist/app/bootstrap/runtimeBootstrap.d.ts +2 -1
  8. package/dist/app/bootstrap/runtimeBootstrap.js +14 -3
  9. package/dist/app/bootstrap/runtimeBootstrap.js.map +1 -1
  10. package/dist/app/control-api/services/actions.d.ts +12 -16
  11. package/dist/app/control-api/services/actions.js +89 -68
  12. package/dist/app/control-api/services/actions.js.map +1 -1
  13. package/dist/app/control-api/services/controlPlane.d.ts +17 -21
  14. package/dist/app/control-api/services/controlPlane.js +69 -74
  15. package/dist/app/control-api/services/controlPlane.js.map +1 -1
  16. package/dist/app/control-api/services/state.js +5 -9
  17. package/dist/app/control-api/services/state.js.map +1 -1
  18. package/dist/core/domain/memory/retrieval/indexTargets.js +6 -6
  19. package/dist/core/domain/memory/retrieval/indexTargets.js.map +1 -1
  20. package/dist/core/domain/memory/retrieval/schema.js +10 -6
  21. package/dist/core/domain/memory/retrieval/schema.js.map +1 -1
  22. package/dist/core/domain/memory/retrieval/scope.d.ts +2 -2
  23. package/dist/core/domain/memory/retrieval/scope.js +7 -7
  24. package/dist/core/domain/memory/retrieval/scope.js.map +1 -1
  25. package/dist/core/domain/memory/retrieval/types.d.ts +2 -7
  26. package/dist/core/domain/memory/retrieval/types.js.map +1 -1
  27. package/dist/core/domain/memory/retrieval.d.ts +1 -2
  28. package/dist/core/domain/memory/retrieval.js +9 -16
  29. package/dist/core/domain/memory/retrieval.js.map +1 -1
  30. package/dist/core/domain/memory/store.d.ts +1 -1
  31. package/dist/core/domain/memory/store.js +2 -2
  32. package/dist/core/domain/memory/store.js.map +1 -1
  33. package/dist/core/domain/sessions/managedWorkerSessions.d.ts +0 -1
  34. package/dist/core/domain/sessions/managedWorkerSessions.js.map +1 -1
  35. package/dist/core/domain/sessions/runtimeWorkManagementService.d.ts +17 -62
  36. package/dist/core/domain/sessions/runtimeWorkManagementService.js +97 -341
  37. package/dist/core/domain/sessions/runtimeWorkManagementService.js.map +1 -1
  38. package/dist/core/domain/sessions/sessionLifecycleService.d.ts +1 -1
  39. package/dist/core/domain/sessions/sessionLifecycleService.js +4 -4
  40. package/dist/core/domain/sessions/sessionLifecycleService.js.map +1 -1
  41. package/dist/core/domain/sessions/sessionState.d.ts +10 -8
  42. package/dist/core/domain/sessions/sessionState.js +38 -28
  43. package/dist/core/domain/sessions/sessionState.js.map +1 -1
  44. package/dist/core/domain/sessions/workManagement/transportResourceNames.d.ts +2 -0
  45. package/dist/core/domain/sessions/workManagement/{spaceNames.js → transportResourceNames.js} +2 -2
  46. package/dist/core/domain/sessions/workManagement/transportResourceNames.js.map +1 -0
  47. package/dist/core/extension/capabilities/capabilities.d.ts +1 -1
  48. package/dist/core/extension/capabilities/capabilities.js +8 -8
  49. package/dist/core/extension/capabilities/capabilities.js.map +1 -1
  50. package/dist/core/extension/packages/bundledArchiveResolver.d.ts +2 -0
  51. package/dist/core/extension/packages/{officialArchiveResolver.js → bundledArchiveResolver.js} +4 -4
  52. package/dist/core/extension/packages/bundledArchiveResolver.js.map +1 -0
  53. package/dist/core/extension/packages/npmRegistryClient.d.ts +3 -2
  54. package/dist/core/extension/packages/npmRegistryClient.js +9 -22
  55. package/dist/core/extension/packages/npmRegistryClient.js.map +1 -1
  56. package/dist/core/extension/packages/packageActivation.d.ts +0 -4
  57. package/dist/core/extension/packages/packageActivation.js +2 -12
  58. package/dist/core/extension/packages/packageActivation.js.map +1 -1
  59. package/dist/core/extension/packages/packageApplyPlanner.js +1 -4
  60. package/dist/core/extension/packages/packageApplyPlanner.js.map +1 -1
  61. package/dist/core/extension/packages/packageConfigSchema.js +0 -33
  62. package/dist/core/extension/packages/packageConfigSchema.js.map +1 -1
  63. package/dist/core/extension/packages/packageDependencyResolver.js +2 -20
  64. package/dist/core/extension/packages/packageDependencyResolver.js.map +1 -1
  65. package/dist/core/extension/packages/packageInstaller.js +3 -0
  66. package/dist/core/extension/packages/packageInstaller.js.map +1 -1
  67. package/dist/core/extension/packages/packageInventoryStore.js +20 -4
  68. package/dist/core/extension/packages/packageInventoryStore.js.map +1 -1
  69. package/dist/core/extension/packages/packageRegistryBlocklist.d.ts +2 -2
  70. package/dist/core/extension/packages/packageRegistryBlocklist.js +1 -1
  71. package/dist/core/extension/packages/packageRegistryBlocklist.js.map +1 -1
  72. package/dist/core/extension/packages/packageRegistryService.d.ts +8 -3
  73. package/dist/core/extension/packages/packageRegistryService.js +109 -49
  74. package/dist/core/extension/packages/packageRegistryService.js.map +1 -1
  75. package/dist/core/extension/packages/packageRegistryTypes.d.ts +14 -6
  76. package/dist/core/extension/packages/packageSource.js +120 -5
  77. package/dist/core/extension/packages/packageSource.js.map +1 -1
  78. package/dist/core/extension/packages/packageValidation.js +1 -1
  79. package/dist/core/extension/packages/packageValidation.js.map +1 -1
  80. package/dist/core/extension/packages/packageVersionResolver.d.ts +6 -11
  81. package/dist/core/extension/packages/packageVersionResolver.js +5 -5
  82. package/dist/core/extension/packages/packageVersionResolver.js.map +1 -1
  83. package/dist/core/extension/packages/runtimeStartability.d.ts +2 -2
  84. package/dist/core/extension/packages/runtimeStartability.js +26 -23
  85. package/dist/core/extension/packages/runtimeStartability.js.map +1 -1
  86. package/dist/core/extension/plugins/pluginHost.d.ts +9 -4
  87. package/dist/core/extension/plugins/pluginHost.js +33 -7
  88. package/dist/core/extension/plugins/pluginHost.js.map +1 -1
  89. package/dist/core/extension/plugins/pluginId.d.ts +0 -1
  90. package/dist/core/extension/plugins/pluginId.js +0 -3
  91. package/dist/core/extension/plugins/pluginId.js.map +1 -1
  92. package/dist/core/extension/plugins/runtimePluginLoader.d.ts +0 -1
  93. package/dist/core/extension/plugins/runtimePluginLoader.js +0 -7
  94. package/dist/core/extension/plugins/runtimePluginLoader.js.map +1 -1
  95. package/dist/core/extension/skills/skillRegistry.d.ts +3 -2
  96. package/dist/core/extension/skills/skillWriter.d.ts +1 -1
  97. package/dist/core/extension/skills/skillWriter.js +2 -2
  98. package/dist/core/runtime/execution/commandReactor.d.ts +5 -5
  99. package/dist/core/runtime/execution/commandReactor.js +10 -7
  100. package/dist/core/runtime/execution/commandReactor.js.map +1 -1
  101. package/dist/core/runtime/execution/defaultModelSelection.js +1 -1
  102. package/dist/core/runtime/execution/orchestrationEngine.js +10 -10
  103. package/dist/core/runtime/execution/orchestrationEngine.js.map +1 -1
  104. package/dist/core/runtime/execution/orchestrationHealth.d.ts +0 -7
  105. package/dist/core/runtime/execution/orchestrationHealth.js +1 -1
  106. package/dist/core/runtime/execution/orchestrationHealth.js.map +1 -1
  107. package/dist/core/runtime/execution/pluginContext/defaultSessionOwner.js +3 -5
  108. package/dist/core/runtime/execution/pluginContext/defaultSessionOwner.js.map +1 -1
  109. package/dist/core/runtime/execution/pluginContext/pluginCapabilities.d.ts +0 -2
  110. package/dist/core/runtime/execution/pluginContext/pluginCapabilities.js +0 -2
  111. package/dist/core/runtime/execution/pluginContext/pluginCapabilities.js.map +1 -1
  112. package/dist/core/runtime/execution/pluginContext/pluginContextFactory.d.ts +1 -2
  113. package/dist/core/runtime/execution/pluginContext/pluginContextFactory.js +1 -2
  114. package/dist/core/runtime/execution/pluginContext/pluginContextFactory.js.map +1 -1
  115. package/dist/core/runtime/execution/providerCoordination/providerSessionCoordinator.js +3 -3
  116. package/dist/core/runtime/execution/providerCoordination/providerSessionCoordinator.js.map +1 -1
  117. package/dist/core/runtime/execution/providerOrchestration/ports.d.ts +3 -13
  118. package/dist/core/runtime/execution/providerOrchestration/providerAttachmentResolver.d.ts +3 -3
  119. package/dist/core/runtime/execution/providerOrchestration/providerAttachmentResolver.js +4 -5
  120. package/dist/core/runtime/execution/providerOrchestration/providerAttachmentResolver.js.map +1 -1
  121. package/dist/core/runtime/execution/providerOrchestration/providerCompactionPolicy.d.ts +2 -1
  122. package/dist/core/runtime/execution/providerOrchestration/providerCompactionPolicy.js +5 -5
  123. package/dist/core/runtime/execution/providerOrchestration/providerCompactionPolicy.js.map +1 -1
  124. package/dist/core/runtime/execution/providerOrchestration/providerEventPipeline.d.ts +3 -5
  125. package/dist/core/runtime/execution/providerOrchestration/providerEventPipeline.js +10 -8
  126. package/dist/core/runtime/execution/providerOrchestration/providerEventPipeline.js.map +1 -1
  127. package/dist/core/runtime/execution/providerOrchestration/providerOrchestrator.d.ts +3 -3
  128. package/dist/core/runtime/execution/providerOrchestration/providerOrchestrator.js +0 -3
  129. package/dist/core/runtime/execution/providerOrchestration/providerOrchestrator.js.map +1 -1
  130. package/dist/core/runtime/execution/providerOrchestration/providerRequestProjector.d.ts +3 -2
  131. package/dist/core/runtime/execution/providerOrchestration/providerRequestProjector.js +6 -6
  132. package/dist/core/runtime/execution/providerOrchestration/providerRequestProjector.js.map +1 -1
  133. package/dist/core/runtime/execution/providerOrchestration/providerSessionOrchestrator.d.ts +9 -6
  134. package/dist/core/runtime/execution/providerOrchestration/providerSessionOrchestrator.js +36 -15
  135. package/dist/core/runtime/execution/providerOrchestration/providerSessionOrchestrator.js.map +1 -1
  136. package/dist/core/runtime/execution/providerOrchestration/providerTurnBroker.d.ts +9 -3
  137. package/dist/core/runtime/execution/providerOrchestration/providerTurnBroker.js +19 -7
  138. package/dist/core/runtime/execution/providerOrchestration/providerTurnBroker.js.map +1 -1
  139. package/dist/core/runtime/execution/providerProjectionTypes.d.ts +4 -2
  140. package/dist/core/runtime/execution/providerProjectionTypes.js +2 -0
  141. package/dist/core/runtime/execution/providerProjectionTypes.js.map +1 -1
  142. package/dist/core/runtime/execution/providerSessionDirectory.js +12 -4
  143. package/dist/core/runtime/execution/providerSessionDirectory.js.map +1 -1
  144. package/dist/core/runtime/execution/runtimeDomain.d.ts +11 -9
  145. package/dist/core/runtime/execution/runtimeDomain.js +10 -3
  146. package/dist/core/runtime/execution/runtimeDomain.js.map +1 -1
  147. package/dist/core/runtime/execution/runtimeIngestion.js +15 -13
  148. package/dist/core/runtime/execution/runtimeIngestion.js.map +1 -1
  149. package/dist/core/runtime/execution/runtimeInteractionService.d.ts +4 -18
  150. package/dist/core/runtime/execution/runtimeInteractionService.js +15 -93
  151. package/dist/core/runtime/execution/runtimeInteractionService.js.map +1 -1
  152. package/dist/core/runtime/execution/runtimeOrchestrationRequestService.d.ts +1 -1
  153. package/dist/core/runtime/execution/runtimeOrchestrationRequestService.js +8 -28
  154. package/dist/core/runtime/execution/runtimeOrchestrationRequestService.js.map +1 -1
  155. package/dist/core/runtime/execution/runtimeOrchestrationRequests.d.ts +7 -29
  156. package/dist/core/runtime/execution/runtimeOrchestrationRequests.js +21 -67
  157. package/dist/core/runtime/execution/runtimeOrchestrationRequests.js.map +1 -1
  158. package/dist/core/runtime/execution/runtimeOrchestrationResult.js +5 -0
  159. package/dist/core/runtime/execution/runtimeOrchestrationResult.js.map +1 -1
  160. package/dist/core/runtime/execution/runtimePendingRequestService.d.ts +2 -2
  161. package/dist/core/runtime/execution/runtimePendingRequestService.js +10 -10
  162. package/dist/core/runtime/execution/runtimePendingRequestService.js.map +1 -1
  163. package/dist/core/runtime/execution/runtimePluginContextService.d.ts +28 -15
  164. package/dist/core/runtime/execution/runtimePluginContextService.js +989 -166
  165. package/dist/core/runtime/execution/runtimePluginContextService.js.map +1 -1
  166. package/dist/core/runtime/execution/runtimeWorkerQueues.js +1 -1
  167. package/dist/core/runtime/execution/runtimeWorkerQueues.js.map +1 -1
  168. package/dist/core/runtime/hosting/managedTransportResourceMetadata.d.ts +6 -0
  169. package/dist/core/runtime/hosting/managedTransportResourceMetadata.js +8 -0
  170. package/dist/core/runtime/hosting/managedTransportResourceMetadata.js.map +1 -0
  171. package/dist/core/runtime/hosting/runtimeHostingService.d.ts +1 -1
  172. package/dist/core/runtime/hosting/runtimeHostingService.js +16 -20
  173. package/dist/core/runtime/hosting/runtimeHostingService.js.map +1 -1
  174. package/dist/core/runtime/hosting/runtimeLayout.js +1 -1
  175. package/dist/core/runtime/hosting/runtimeLayout.js.map +1 -1
  176. package/dist/core/runtime/hosting/runtimeTransportSurfaceService.d.ts +4 -4
  177. package/dist/core/runtime/hosting/runtimeTransportSurfaceService.js +17 -17
  178. package/dist/core/runtime/hosting/runtimeTransportSurfaceService.js.map +1 -1
  179. package/dist/core/runtime/hosting/systemEmbeds.d.ts +0 -1
  180. package/dist/core/runtime/hosting/systemEmbeds.js +0 -9
  181. package/dist/core/runtime/hosting/systemEmbeds.js.map +1 -1
  182. package/dist/core/runtime/lifecycle/{managedChannelLifecycleService.d.ts → managedTransportResourceLifecycleService.d.ts} +6 -9
  183. package/dist/core/runtime/lifecycle/managedTransportResourceLifecycleService.js +158 -0
  184. package/dist/core/runtime/lifecycle/managedTransportResourceLifecycleService.js.map +1 -0
  185. package/dist/core/runtime/lifecycle/packageJobSchedulerService.d.ts +21 -0
  186. package/dist/core/runtime/lifecycle/packageJobSchedulerService.js +84 -0
  187. package/dist/core/runtime/lifecycle/packageJobSchedulerService.js.map +1 -0
  188. package/dist/core/runtime/lifecycle/runtimeLifecycleService.d.ts +2 -13
  189. package/dist/core/runtime/lifecycle/runtimeLifecycleService.js +19 -250
  190. package/dist/core/runtime/lifecycle/runtimeLifecycleService.js.map +1 -1
  191. package/dist/core/runtime/moorlineRuntime.d.ts +7 -8
  192. package/dist/core/runtime/moorlineRuntime.js +71 -47
  193. package/dist/core/runtime/moorlineRuntime.js.map +1 -1
  194. package/dist/core/runtime/moorlineRuntimeBuilder.d.ts +17 -18
  195. package/dist/core/runtime/moorlineRuntimeBuilder.js +53 -93
  196. package/dist/core/runtime/moorlineRuntimeBuilder.js.map +1 -1
  197. package/dist/core/runtime/runtimeBootstrapRegistry.d.ts +0 -2
  198. package/dist/core/runtime/runtimeBootstrapRegistry.js +0 -6
  199. package/dist/core/runtime/runtimeBootstrapRegistry.js.map +1 -1
  200. package/dist/core/runtime/runtimeStatus.js +2 -2
  201. package/dist/core/runtime/runtimeStatus.js.map +1 -1
  202. package/dist/core/runtime/supervision/runtimeControlService.js +4 -1
  203. package/dist/core/runtime/supervision/runtimeControlService.js.map +1 -1
  204. package/dist/core/shared/errors/statusError.d.ts +5 -0
  205. package/dist/core/shared/errors/statusError.js +18 -0
  206. package/dist/core/shared/errors/statusError.js.map +1 -0
  207. package/dist/core/shared/fs/canonicalPathContainment.d.ts +0 -2
  208. package/dist/core/shared/fs/canonicalPathContainment.js +1 -6
  209. package/dist/core/shared/fs/canonicalPathContainment.js.map +1 -1
  210. package/dist/core/shared/fs/runtimeOwnedPath.d.ts +1 -1
  211. package/dist/core/shared/fs/runtimeOwnedPath.js +3 -3
  212. package/dist/core/shared/fs/runtimeOwnedPath.js.map +1 -1
  213. package/dist/core/shared/scheduling/packageSchedule.d.ts +22 -0
  214. package/dist/core/{domain/missions/missionSchedule.js → shared/scheduling/packageSchedule.js} +15 -18
  215. package/dist/core/shared/scheduling/packageSchedule.js.map +1 -0
  216. package/dist/core/shared/utils/childProcessEnv.js +1 -1
  217. package/dist/core/shared/utils/childProcessEnv.js.map +1 -1
  218. package/dist/core/shared/utils/payloadRedaction.d.ts +0 -12
  219. package/dist/core/shared/utils/payloadRedaction.js +0 -77
  220. package/dist/core/shared/utils/payloadRedaction.js.map +1 -1
  221. package/dist/core/shared/utils/remoteNetworkPolicy.d.ts +0 -4
  222. package/dist/core/shared/utils/remoteNetworkPolicy.js +1 -7
  223. package/dist/core/shared/utils/remoteNetworkPolicy.js.map +1 -1
  224. package/dist/core/shared/utils/runtimeMessageUtils.d.ts +0 -1
  225. package/dist/core/shared/utils/runtimeMessageUtils.js +0 -19
  226. package/dist/core/shared/utils/runtimeMessageUtils.js.map +1 -1
  227. package/dist/core/system/backup/runtimeBackupService.d.ts +0 -2
  228. package/dist/core/system/backup/runtimeBackupService.js +71 -2
  229. package/dist/core/system/backup/runtimeBackupService.js.map +1 -1
  230. package/dist/core/system/config/configStore.d.ts +3 -3
  231. package/dist/core/system/config/configStore.js +19 -20
  232. package/dist/core/system/config/configStore.js.map +1 -1
  233. package/dist/core/system/projection/managementReadModel/deps.d.ts +4 -5
  234. package/dist/core/system/projection/managementReadModel/objects/serviceObjects.d.ts +2 -1
  235. package/dist/core/system/projection/managementReadModel/objects/serviceObjects.js +13 -7
  236. package/dist/core/system/projection/managementReadModel/objects/serviceObjects.js.map +1 -1
  237. package/dist/core/system/projection/managementReadModel/packageTrust.d.ts +5 -0
  238. package/dist/core/system/projection/managementReadModel/packageTrust.js +40 -0
  239. package/dist/core/system/projection/managementReadModel/packageTrust.js.map +1 -0
  240. package/dist/core/system/projection/managementReadModel/pluginDiskRecords.d.ts +0 -1
  241. package/dist/core/system/projection/managementReadModel/pluginDiskRecords.js +1 -10
  242. package/dist/core/system/projection/managementReadModel/pluginDiskRecords.js.map +1 -1
  243. package/dist/core/system/projection/managementReadModelService.d.ts +3 -1
  244. package/dist/core/system/projection/managementReadModelService.js +133 -117
  245. package/dist/core/system/projection/managementReadModelService.js.map +1 -1
  246. package/dist/core/system/projection/pendingRequestProjectionStore.d.ts +1 -1
  247. package/dist/core/system/projection/pendingRequestProjectionStore.js +9 -9
  248. package/dist/core/system/projection/pendingRequestProjectionStore.js.map +1 -1
  249. package/dist/core/system/projection/runtimeActivityStore.d.ts +1 -1
  250. package/dist/core/system/projection/runtimeActivityStore.js +7 -7
  251. package/dist/core/system/projection/runtimeActivityStore.js.map +1 -1
  252. package/dist/core/system/projection/runtimeProjectionService.d.ts +1 -1
  253. package/dist/core/system/projection/runtimeProjectionService.js +3 -3
  254. package/dist/core/system/projection/runtimeProjectionService.js.map +1 -1
  255. package/dist/core/system/projection/runtimeReceiptStore.js +5 -5
  256. package/dist/core/system/projection/runtimeReceiptStore.js.map +1 -1
  257. package/dist/core/system/projection/runtimeReconciler.js +2 -2
  258. package/dist/core/system/projection/runtimeReconciler.js.map +1 -1
  259. package/dist/core/system/projection/runtimeSnapshotQuery.d.ts +6 -5
  260. package/dist/core/system/projection/runtimeSnapshotQuery.js +6 -6
  261. package/dist/core/system/projection/runtimeSnapshotQuery.js.map +1 -1
  262. package/dist/core/system/release/releaseArtifacts.d.ts +0 -2
  263. package/dist/core/system/release/releaseArtifacts.js +1 -12
  264. package/dist/core/system/release/releaseArtifacts.js.map +1 -1
  265. package/dist/core/system/release/runtimePackageLoadReport.d.ts +0 -1
  266. package/dist/core/system/release/runtimePackageLoadReport.js +0 -7
  267. package/dist/core/system/release/runtimePackageLoadReport.js.map +1 -1
  268. package/dist/core/system/state/canonicalEventLogStore.d.ts +1 -1
  269. package/dist/core/system/state/canonicalEventLogStore.js +7 -7
  270. package/dist/core/system/state/canonicalEventLogStore.js.map +1 -1
  271. package/dist/core/system/state/safeJson.d.ts +2 -1
  272. package/dist/core/system/state/sqlite/domainEventLogRepository.js +5 -5
  273. package/dist/core/system/state/sqlite/domainEventLogRepository.js.map +1 -1
  274. package/dist/core/system/state/sqlite/externalResourceRepository.d.ts +25 -0
  275. package/dist/core/system/state/sqlite/externalResourceRepository.js +105 -0
  276. package/dist/core/system/state/sqlite/externalResourceRepository.js.map +1 -0
  277. package/dist/core/system/state/sqlite/gateRunRepository.d.ts +13 -0
  278. package/dist/core/system/state/sqlite/gateRunRepository.js +66 -0
  279. package/dist/core/system/state/sqlite/gateRunRepository.js.map +1 -0
  280. package/dist/core/system/state/sqlite/orchestrationRepository.js +6 -6
  281. package/dist/core/system/state/sqlite/orchestrationRepository.js.map +1 -1
  282. package/dist/core/system/state/sqlite/packageJobRepository.d.ts +11 -0
  283. package/dist/core/system/state/sqlite/packageJobRepository.js +60 -0
  284. package/dist/core/system/state/sqlite/packageJobRepository.js.map +1 -0
  285. package/dist/core/system/state/sqlite/packageStateRepository.d.ts +10 -0
  286. package/dist/core/system/state/sqlite/packageStateRepository.js +45 -0
  287. package/dist/core/system/state/sqlite/packageStateRepository.js.map +1 -0
  288. package/dist/core/system/state/sqlite/pendingRequestRepository.d.ts +2 -2
  289. package/dist/core/system/state/sqlite/pendingRequestRepository.js +10 -10
  290. package/dist/core/system/state/sqlite/pendingRequestRepository.js.map +1 -1
  291. package/dist/core/system/state/sqlite/providerEventLogRepository.d.ts +1 -1
  292. package/dist/core/system/state/sqlite/providerEventLogRepository.js +6 -6
  293. package/dist/core/system/state/sqlite/providerEventLogRepository.js.map +1 -1
  294. package/dist/core/system/state/sqlite/rowMappers.d.ts +0 -1
  295. package/dist/core/system/state/sqlite/rowMappers.js +0 -3
  296. package/dist/core/system/state/sqlite/rowMappers.js.map +1 -1
  297. package/dist/core/system/state/sqlite/runtimeReceiptRepository.js +4 -4
  298. package/dist/core/system/state/sqlite/runtimeReceiptRepository.js.map +1 -1
  299. package/dist/core/system/state/sqlite/sessionRepository.d.ts +1 -1
  300. package/dist/core/system/state/sqlite/sessionRepository.js +13 -10
  301. package/dist/core/system/state/sqlite/sessionRepository.js.map +1 -1
  302. package/dist/core/system/state/sqlite/types.d.ts +91 -48
  303. package/dist/core/system/state/sqlite/types.js +86 -31
  304. package/dist/core/system/state/sqlite/types.js.map +1 -1
  305. package/dist/core/system/state/sqlite/workItemRepository.d.ts +25 -0
  306. package/dist/core/system/state/sqlite/workItemRepository.js +200 -0
  307. package/dist/core/system/state/sqlite/workItemRepository.js.map +1 -0
  308. package/dist/core/system/state/sqliteSessionStore.d.ts +62 -24
  309. package/dist/core/system/state/sqliteSessionStore.js +77 -41
  310. package/dist/core/system/state/sqliteSessionStore.js.map +1 -1
  311. package/dist/core/system/vcs/gitIgnoreTemplate.js +1 -1
  312. package/dist/core/system/vcs/gitIgnoreTemplate.js.map +1 -1
  313. package/dist/core/system/vcs/gitTrackedPaths.js +1 -1
  314. package/dist/core/system/vcs/gitTrackedPaths.js.map +1 -1
  315. package/dist/types/app.d.ts +35 -36
  316. package/dist/types/config.d.ts +14 -19
  317. package/dist/types/config.js +16 -22
  318. package/dist/types/config.js.map +1 -1
  319. package/dist/types/distro.d.ts +1 -1
  320. package/dist/types/distro.js.map +1 -1
  321. package/dist/types/external.d.ts +1 -0
  322. package/dist/types/external.js +2 -0
  323. package/dist/types/external.js.map +1 -0
  324. package/dist/types/package.d.ts +4 -4
  325. package/dist/types/provider.d.ts +2 -2
  326. package/dist/types/provider.js +1 -1
  327. package/dist/types/provider.js.map +1 -1
  328. package/dist/types/runtime.d.ts +2 -2
  329. package/dist/types/runtime.js +1 -1
  330. package/dist/types/runtime.js.map +1 -1
  331. package/dist/types/transport.d.ts +1 -1
  332. package/dist/types/transport.js.map +1 -1
  333. package/package.json +2 -2
  334. package/resources/migrations/001_sessions.sql +8 -9
  335. package/resources/migrations/003_provider_projections.sql +2 -2
  336. package/resources/migrations/004_runtime_projection_state.sql +1 -1
  337. package/resources/migrations/007_package_state_jobs.sql +28 -0
  338. package/resources/migrations/{009_session_orchestration.sql → 008_session_orchestration.sql} +1 -1
  339. package/resources/migrations/010_scope_space_terminology.sql +2 -0
  340. package/resources/migrations/015_external_work_spine.sql +92 -0
  341. package/resources/migrations/016_provider_profiles.sql +4 -0
  342. package/resources/migrations/017_nullable_session_workspace.sql +49 -0
  343. package/resources/policies/default-secure.json +13 -95
  344. package/dist/app/bootstrap/officialCatalog.d.ts +0 -1
  345. package/dist/app/bootstrap/officialCatalog.js +0 -2
  346. package/dist/app/bootstrap/officialCatalog.js.map +0 -1
  347. package/dist/core/domain/memory/operatorMemoryService.d.ts +0 -36
  348. package/dist/core/domain/memory/operatorMemoryService.js +0 -81
  349. package/dist/core/domain/memory/operatorMemoryService.js.map +0 -1
  350. package/dist/core/domain/missions/missionDraftSetup.d.ts +0 -12
  351. package/dist/core/domain/missions/missionDraftSetup.js +0 -92
  352. package/dist/core/domain/missions/missionDraftSetup.js.map +0 -1
  353. package/dist/core/domain/missions/missionHookService.d.ts +0 -41
  354. package/dist/core/domain/missions/missionHookService.js +0 -161
  355. package/dist/core/domain/missions/missionHookService.js.map +0 -1
  356. package/dist/core/domain/missions/missionHookValidation.d.ts +0 -8
  357. package/dist/core/domain/missions/missionHookValidation.js +0 -59
  358. package/dist/core/domain/missions/missionHookValidation.js.map +0 -1
  359. package/dist/core/domain/missions/missionRegistry.d.ts +0 -55
  360. package/dist/core/domain/missions/missionRegistry.js +0 -204
  361. package/dist/core/domain/missions/missionRegistry.js.map +0 -1
  362. package/dist/core/domain/missions/missionSchedule.d.ts +0 -24
  363. package/dist/core/domain/missions/missionSchedule.js.map +0 -1
  364. package/dist/core/domain/sessions/workManagement/spaceNames.d.ts +0 -2
  365. package/dist/core/domain/sessions/workManagement/spaceNames.js.map +0 -1
  366. package/dist/core/extension/packages/officialArchiveResolver.d.ts +0 -2
  367. package/dist/core/extension/packages/officialArchiveResolver.js.map +0 -1
  368. package/dist/core/extension/packages/officialCatalog.d.ts +0 -9
  369. package/dist/core/extension/packages/officialCatalog.js +0 -198
  370. package/dist/core/extension/packages/officialCatalog.js.map +0 -1
  371. package/dist/core/extension/packages/packageDistroMetadata.d.ts +0 -14
  372. package/dist/core/extension/packages/packageDistroMetadata.js +0 -153
  373. package/dist/core/extension/packages/packageDistroMetadata.js.map +0 -1
  374. package/dist/core/runtime/execution/providerCoordination/providerCompactionCoordinator.d.ts +0 -7
  375. package/dist/core/runtime/execution/providerCoordination/providerCompactionCoordinator.js +0 -25
  376. package/dist/core/runtime/execution/providerCoordination/providerCompactionCoordinator.js.map +0 -1
  377. package/dist/core/runtime/execution/providerCoordination/providerRecoveryService.d.ts +0 -7
  378. package/dist/core/runtime/execution/providerCoordination/providerRecoveryService.js +0 -6
  379. package/dist/core/runtime/execution/providerCoordination/providerRecoveryService.js.map +0 -1
  380. package/dist/core/runtime/execution/providerCoordination/providerTurnCoordinator.d.ts +0 -3
  381. package/dist/core/runtime/execution/providerCoordination/providerTurnCoordinator.js +0 -6
  382. package/dist/core/runtime/execution/providerCoordination/providerTurnCoordinator.js.map +0 -1
  383. package/dist/core/runtime/execution/providerOrchestration/providerMissionEventProjector.d.ts +0 -12
  384. package/dist/core/runtime/execution/providerOrchestration/providerMissionEventProjector.js +0 -71
  385. package/dist/core/runtime/execution/providerOrchestration/providerMissionEventProjector.js.map +0 -1
  386. package/dist/core/runtime/hosting/managedSpaceMetadata.d.ts +0 -7
  387. package/dist/core/runtime/hosting/managedSpaceMetadata.js +0 -14
  388. package/dist/core/runtime/hosting/managedSpaceMetadata.js.map +0 -1
  389. package/dist/core/runtime/lifecycle/managedChannelLifecycleService.js +0 -256
  390. package/dist/core/runtime/lifecycle/managedChannelLifecycleService.js.map +0 -1
  391. package/dist/core/system/state/sqlite/missionRepository.d.ts +0 -24
  392. package/dist/core/system/state/sqlite/missionRepository.js +0 -252
  393. package/dist/core/system/state/sqlite/missionRepository.js.map +0 -1
  394. package/resources/migrations/007_missions.sql +0 -41
  395. package/resources/migrations/008_mission_schedule_anchor.sql +0 -5
  396. package/resources/migrations/010_mission_archival.sql +0 -1
  397. package/resources/migrations/012_scope_space_terminology.sql +0 -19
  398. package/resources/migrations/015_mission_schedule_meta.sql +0 -9
  399. package/resources/migrations/016_mission_hook_bindings.sql +0 -16
  400. package/resources/official-catalog.json +0 -444
  401. /package/resources/migrations/{011_managed_sidecars.sql → 009_managed_sidecars.sql} +0 -0
  402. /package/resources/migrations/{013_orchestration_dedupe.sql → 011_orchestration_dedupe.sql} +0 -0
  403. /package/resources/migrations/{014_orchestration_execution_claims.sql → 012_orchestration_execution_claims.sql} +0 -0
  404. /package/resources/migrations/{017_domain_event_provenance.sql → 013_domain_event_provenance.sql} +0 -0
  405. /package/resources/migrations/{018_provider_event_processing.sql → 014_provider_event_processing.sql} +0 -0
@@ -1,5 +1,8 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { join } from 'node:path';
1
3
  import { usesProviderDefaultModel } from '../../../types/config.js';
2
4
  import { saveMoorlineConfig } from '../../system/config/configStore.js';
5
+ import { writeSkill } from '../../extension/skills/skillWriter.js';
3
6
  import { parseRuntimeModeName } from '../../../types/runtime.js';
4
7
  import { refreshMemoryIndex, retrieveFromMemoryWithSQLite } from '../../domain/memory/retrieval.js';
5
8
  import { recordHistoryCheckpoint } from '../../system/vcs/gitCheckpointService.js';
@@ -7,6 +10,7 @@ import { createPluginContextCapabilities } from './pluginContext/pluginContextFa
7
10
  import { describeTransportAuthor } from './pluginContext/transportAuthor.js';
8
11
  import { toPluginPackageId } from '../../extension/plugins/pluginId.js';
9
12
  import { normalizeAndValidateDefaultModel } from './defaultModelSelection.js';
13
+ import { computePackageJobRunAtOrAfterWithMeta, packageScheduleMetaToJson, parsePackageSchedule, parsePackageScheduleStartTime } from '../../shared/scheduling/packageSchedule.js';
10
14
  export { defaultSessionOwner } from './pluginContext/defaultSessionOwner.js';
11
15
  export class RuntimePluginContextService {
12
16
  deps;
@@ -43,6 +47,103 @@ export class RuntimePluginContextService {
43
47
  const providerId = this.deps.config.provider.packageId ?? this.deps.config.provider.kind;
44
48
  return `provider:${providerId}:${threadId}:${suffix}`;
45
49
  }
50
+ contextPackageId(actorId) {
51
+ return actorId.startsWith('plugin:') ? actorId.slice('plugin:'.length) : actorId;
52
+ }
53
+ packageState(valueJson) {
54
+ try {
55
+ return JSON.parse(valueJson);
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ validateStructuredOutput(value, schema) {
62
+ if (!schema || typeof schema !== 'object' || Array.isArray(schema)) {
63
+ return;
64
+ }
65
+ const record = schema;
66
+ if (record.type === 'object' && (!value || typeof value !== 'object' || Array.isArray(value))) {
67
+ throw new Error('Headless run output must be a JSON object.');
68
+ }
69
+ const objectValue = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
70
+ if (Array.isArray(record.required)) {
71
+ for (const key of record.required) {
72
+ if (typeof key === 'string' && objectValue[key] === undefined) {
73
+ throw new Error(`Headless run output is missing required field: ${key}.`);
74
+ }
75
+ }
76
+ }
77
+ const properties = record.properties && typeof record.properties === 'object' && !Array.isArray(record.properties)
78
+ ? record.properties
79
+ : {};
80
+ for (const [key, property] of Object.entries(properties)) {
81
+ const expected = property.type;
82
+ const actual = objectValue[key];
83
+ if (actual === undefined || typeof expected !== 'string') {
84
+ continue;
85
+ }
86
+ const ok = expected === 'array'
87
+ ? Array.isArray(actual)
88
+ : expected === 'object'
89
+ ? actual !== null && typeof actual === 'object' && !Array.isArray(actual)
90
+ : typeof actual === expected;
91
+ if (!ok) {
92
+ throw new Error(`Headless run output field ${key} must be ${expected}.`);
93
+ }
94
+ }
95
+ }
96
+ transitionWorkItem(actorId, workItemId, update) {
97
+ const current = this.requireOwnedWorkItem(actorId, workItemId);
98
+ const nowIso = this.deps.now();
99
+ const updated = this.deps.store.updateWorkItem(update(current, nowIso));
100
+ this.deps.appendAuditEvent('work_item.updated', {
101
+ actorId,
102
+ packageId: updated.packageId,
103
+ workItemId: updated.workItemId,
104
+ queue: updated.queue,
105
+ status: updated.status
106
+ });
107
+ this.deps.recordRuntimeActivity({
108
+ ...this.activityTargetForSession(updated.sessionId, 'runtime:work'),
109
+ sourceEventId: randomUUID(),
110
+ kind: `work_item.${updated.status}`,
111
+ severity: updated.status === 'failed' || updated.status === 'dead_lettered' ? 'error' : 'info',
112
+ title: `Work item ${updated.status}`,
113
+ detail: `${updated.packageId}/${updated.queue}/${updated.workItemId}`,
114
+ createdAt: nowIso
115
+ });
116
+ return updated;
117
+ }
118
+ requireOwnedWorkItem(actorId, workItemId) {
119
+ const record = this.deps.store.getWorkItem(workItemId);
120
+ if (!record) {
121
+ throw new Error(`Unknown work item: ${workItemId}`);
122
+ }
123
+ const packageId = this.contextPackageId(actorId);
124
+ if (record.packageId !== packageId) {
125
+ throw new Error(`Work item ${workItemId} is owned by ${record.packageId}, not ${packageId}.`);
126
+ }
127
+ return record;
128
+ }
129
+ requireSession(sessionId) {
130
+ const session = this.deps.store.getSession(sessionId);
131
+ if (!session) {
132
+ throw new Error(`Unknown session: ${sessionId}`);
133
+ }
134
+ return session;
135
+ }
136
+ activityTargetForSession(sessionId, fallbackThreadId) {
137
+ if (!sessionId) {
138
+ return { threadId: fallbackThreadId, sessionId: null, transportResourceId: null };
139
+ }
140
+ const session = this.deps.store.getSession(sessionId);
141
+ return {
142
+ threadId: session?.threadId ?? fallbackThreadId,
143
+ sessionId,
144
+ transportResourceId: session?.transportResourceId ?? null
145
+ };
146
+ }
46
147
  createContext(actorId) {
47
148
  const capabilities = createPluginContextCapabilities({
48
149
  actorId,
@@ -63,66 +164,329 @@ export class RuntimePluginContextService {
63
164
  config: this.deps.config,
64
165
  getAdminConfig: () => capabilities.admin.getAdminConfig(),
65
166
  isAdminActor: (input) => this.deps.isAdminActor(input),
66
- getNamespaceState: () => this.deps.requireNamespaceState(),
67
- getCurrentSpaceId: () => this.deps.getNamespaceState()?.chatChannelId ?? this.deps.config.transport.scopeId,
68
- getCurrentThreadId: () => `chat:${this.deps.getNamespaceState()?.chatChannelId ?? this.deps.config.transport.scopeId}`,
69
- getCurrentWorkspacePath: () => this.deps.chatWorkspacePath,
70
- getChatWorkspacePath: () => this.deps.chatWorkspacePath,
167
+ getSurfaceState: () => this.deps.requireSurfaceState(),
168
+ getCurrentTransportResourceId: () => this.deps.getSurfaceState()?.coordinationResourceId ?? this.deps.config.transport.scopeId,
169
+ getCurrentThreadId: () => `coordination:${this.deps.getSurfaceState()?.coordinationResourceId ?? this.deps.config.transport.scopeId}`,
170
+ getCurrentWorkspacePath: () => this.deps.coordinationWorkspacePath,
171
+ getCoordinationWorkspacePath: () => this.deps.coordinationWorkspacePath,
172
+ getRuntimeRootPath: () => this.deps.runtimeRoot,
71
173
  listSkills: () => capabilities.memory.listSkills(),
72
174
  loadSkill: async (name) => await capabilities.memory.loadSkill(name),
73
175
  writeSkill: async (input) => await capabilities.memory.writeSkill(input),
74
176
  listSessions: () => this.deps.snapshots.listSessions().map((entry) => entry.session),
75
- getSessionBySpaceId: (spaceId) => this.deps.snapshots.getSessionBySpaceId(spaceId)?.session ?? null,
177
+ getSessionByTransportResourceId: (transportResourceId) => this.deps.snapshots.getSessionByTransportResourceId(transportResourceId)?.session ?? null,
76
178
  getSessionById: (sessionId) => this.deps.snapshots.getSessionById(sessionId)?.session ?? null,
77
- listMissions: () => this.deps.missionRegistry.list(),
78
- getMissionBySpaceId: (spaceId) => this.deps.missionRegistry.getBySpaceId(spaceId),
79
- getMissionById: (missionId) => this.deps.missionRegistry.getById(missionId),
80
- listMissionRuns: (missionId, limit) => this.deps.missionRegistry.listRuns(missionId, limit),
81
- listMissionHookBindings: (filter) => this.deps.missionHooks.listBindings({
82
- ...(filter?.missionId ? { missionId: filter.missionId } : {}),
83
- ...(filter?.hookKey ? { hookKey: filter.hookKey } : {})
179
+ getPackageState: (key) => {
180
+ const row = this.deps.store.getPackageState(this.contextPackageId(actorId), key);
181
+ return row ? this.packageState(row.valueJson) : null;
182
+ },
183
+ putPackageState: async (key, value) => await this.deps.runGuardedAction({
184
+ action: 'package.state.write',
185
+ actor: actorId,
186
+ target: `${this.contextPackageId(actorId)}:${key}`,
187
+ title: 'Package state write blocked',
188
+ execute: async () => {
189
+ this.deps.store.putPackageState({
190
+ packageId: this.contextPackageId(actorId),
191
+ key,
192
+ valueJson: JSON.stringify(value),
193
+ updatedAt: this.deps.now()
194
+ });
195
+ }
84
196
  }),
85
- bindMissionHook: ({ missionId, hookKey, condition }) => this.deps.runGuardedAction({
86
- action: 'mission.control',
197
+ deletePackageState: async (key) => await this.deps.runGuardedAction({
198
+ action: 'package.state.write',
87
199
  actor: actorId,
88
- target: missionId,
89
- payload: { hookKey, hasCondition: Boolean(condition) },
90
- title: 'Mission hook binding blocked',
91
- execute: async () => this.deps.missionHooks.bind({
92
- actorId,
93
- missionId,
94
- hookKey,
95
- ...(condition ? { condition } : {})
96
- })
200
+ target: `${this.contextPackageId(actorId)}:${key}`,
201
+ title: 'Package state delete blocked',
202
+ execute: async () => {
203
+ this.deps.store.deletePackageState(this.contextPackageId(actorId), key);
204
+ }
97
205
  }),
98
- unbindMissionHook: ({ bindingId }) => this.deps.runGuardedAction({
99
- action: 'mission.control',
206
+ listPackageState: (prefix) => this.deps.store.listPackageState(this.contextPackageId(actorId), prefix).map((row) => ({
207
+ packageId: row.packageId,
208
+ key: row.key,
209
+ value: this.packageState(row.valueJson),
210
+ updatedAt: row.updatedAt
211
+ })),
212
+ schedulePackageJob: async ({ jobId, actionId, schedule, startTime, payload }) => await this.deps.runGuardedAction({
213
+ action: 'package.job.manage',
100
214
  actor: actorId,
101
- target: bindingId,
102
- title: 'Mission hook binding removal blocked',
103
- execute: async () => this.deps.missionHooks.unbind({
104
- actorId,
105
- bindingId
106
- })
215
+ target: `${this.contextPackageId(actorId)}:${jobId}`,
216
+ payload: { actionId, schedule },
217
+ title: 'Package job schedule blocked',
218
+ execute: async () => {
219
+ const nowIso = this.deps.now();
220
+ const parsed = parsePackageSchedule(schedule);
221
+ const anchor = parsePackageScheduleStartTime(startTime, nowIso);
222
+ const nextRunAt = computePackageJobRunAtOrAfterWithMeta(anchor, parsed.cadenceMinutes, nowIso, parsed.meta);
223
+ const row = {
224
+ packageId: this.contextPackageId(actorId),
225
+ jobId,
226
+ actionId,
227
+ schedule: parsed.normalized,
228
+ scheduleAnchorAt: anchor,
229
+ cadenceMinutes: parsed.cadenceMinutes,
230
+ scheduleMetaJson: packageScheduleMetaToJson(parsed.meta),
231
+ payloadJson: JSON.stringify(payload ?? {}),
232
+ nextRunAt,
233
+ createdAt: this.deps.store.getPackageJob(this.contextPackageId(actorId), jobId)?.createdAt ?? nowIso,
234
+ updatedAt: nowIso
235
+ };
236
+ this.deps.store.upsertPackageJob(row);
237
+ return {
238
+ packageId: row.packageId,
239
+ jobId: row.jobId,
240
+ actionId: row.actionId,
241
+ schedule: row.schedule,
242
+ scheduleAnchorAt: row.scheduleAnchorAt,
243
+ nextRunAt: row.nextRunAt,
244
+ payload: payload ?? {},
245
+ createdAt: row.createdAt,
246
+ updatedAt: row.updatedAt
247
+ };
248
+ }
107
249
  }),
108
- emitMissionHook: ({ hookKey, payload, source }) => this.deps.runGuardedAction({
109
- action: 'mission.control',
250
+ cancelPackageJob: async (jobId) => await this.deps.runGuardedAction({
251
+ action: 'package.job.manage',
110
252
  actor: actorId,
111
- target: hookKey,
112
- payload: { source: source ?? actorId, payloadKeys: Object.keys(payload ?? {}) },
113
- title: 'Mission hook trigger blocked',
114
- execute: async () => await this.deps.missionHooks.emit({
115
- actorId,
116
- hookKey,
117
- ...(payload ? { payload } : {}),
118
- ...(source ? { source } : {})
253
+ target: `${this.contextPackageId(actorId)}:${jobId}`,
254
+ title: 'Package job cancel blocked',
255
+ execute: async () => {
256
+ const row = this.deps.store.deletePackageJob(this.contextPackageId(actorId), jobId);
257
+ return row
258
+ ? {
259
+ packageId: row.packageId,
260
+ jobId: row.jobId,
261
+ actionId: row.actionId,
262
+ schedule: row.schedule,
263
+ scheduleAnchorAt: row.scheduleAnchorAt,
264
+ nextRunAt: row.nextRunAt,
265
+ payload: this.packageState(row.payloadJson) ?? {},
266
+ createdAt: row.createdAt,
267
+ updatedAt: row.updatedAt
268
+ }
269
+ : null;
270
+ }
271
+ }),
272
+ listPackageJobs: () => this.deps.store.listPackageJobs(this.contextPackageId(actorId)).map((row) => ({
273
+ packageId: row.packageId,
274
+ jobId: row.jobId,
275
+ actionId: row.actionId,
276
+ schedule: row.schedule,
277
+ scheduleAnchorAt: row.scheduleAnchorAt,
278
+ nextRunAt: row.nextRunAt,
279
+ payload: this.packageState(row.payloadJson) ?? {},
280
+ createdAt: row.createdAt,
281
+ updatedAt: row.updatedAt
282
+ })),
283
+ enqueueWorkItem: async ({ queue, workItemId, idempotencyKey, externalResource, payload, priority, runAfter, maxAttempts }) => await this.deps.runGuardedAction({
284
+ action: 'package.work.manage',
285
+ actor: actorId,
286
+ target: `${this.contextPackageId(actorId)}:${queue}`,
287
+ payload: { idempotencyKey, externalResource },
288
+ title: 'Package work enqueue blocked',
289
+ execute: async () => {
290
+ const packageId = this.contextPackageId(actorId);
291
+ const normalizedQueue = queue.trim();
292
+ if (!normalizedQueue) {
293
+ throw new Error('Work item queue is required.');
294
+ }
295
+ const nowIso = this.deps.now();
296
+ if (externalResource) {
297
+ this.deps.store.upsertExternalResource({ ...externalResource, nowIso });
298
+ }
299
+ const record = this.deps.store.enqueueWorkItem({
300
+ workItemId: workItemId?.trim() || randomUUID(),
301
+ packageId,
302
+ queue: normalizedQueue,
303
+ status: 'queued',
304
+ priority: Number.isFinite(priority) ? Math.trunc(priority ?? 0) : 0,
305
+ ...(idempotencyKey ? { idempotencyKey } : {}),
306
+ ...(externalResource ? { externalResource } : {}),
307
+ payload: payload ?? {},
308
+ attempts: 0,
309
+ maxAttempts: Math.max(1, Math.trunc(maxAttempts ?? 3)),
310
+ runAfter: runAfter ?? null,
311
+ leaseOwner: null,
312
+ leaseExpiresAt: null,
313
+ lastError: null,
314
+ createdAt: nowIso,
315
+ updatedAt: nowIso,
316
+ completedAt: null
317
+ });
318
+ this.deps.appendAuditEvent('work_item.enqueued', {
319
+ actorId,
320
+ packageId,
321
+ workItemId: record.workItemId,
322
+ queue: record.queue,
323
+ idempotencyKey: record.idempotencyKey
324
+ });
325
+ this.deps.recordRuntimeActivity({
326
+ threadId: 'runtime:work',
327
+ sessionId: null,
328
+ transportResourceId: null,
329
+ sourceEventId: randomUUID(),
330
+ kind: 'work_item.queued',
331
+ severity: 'info',
332
+ title: 'Work item queued',
333
+ detail: `${record.packageId}/${record.queue}/${record.workItemId}`,
334
+ createdAt: nowIso
335
+ });
336
+ return record;
337
+ }
338
+ }),
339
+ claimWorkItem: async ({ queue, leaseSeconds, leaseOwner }) => await this.deps.runGuardedAction({
340
+ action: 'package.work.manage',
341
+ actor: actorId,
342
+ target: `${this.contextPackageId(actorId)}:${queue}`,
343
+ title: 'Package work claim blocked',
344
+ execute: async () => {
345
+ const now = new Date(this.deps.now());
346
+ const leaseMs = Math.max(1, leaseSeconds ?? 300) * 1000;
347
+ const claimed = this.deps.store.claimWorkItem({
348
+ packageId: this.contextPackageId(actorId),
349
+ queue,
350
+ leaseOwner: leaseOwner?.trim() || actorId,
351
+ leaseExpiresAt: new Date(now.getTime() + leaseMs).toISOString(),
352
+ nowIso: now.toISOString()
353
+ });
354
+ if (claimed) {
355
+ this.deps.appendAuditEvent('work_item.claimed', {
356
+ actorId,
357
+ packageId: claimed.packageId,
358
+ workItemId: claimed.workItemId,
359
+ queue: claimed.queue,
360
+ attempts: claimed.attempts
361
+ });
362
+ this.deps.recordRuntimeActivity({
363
+ ...this.activityTargetForSession(claimed.sessionId, 'runtime:work'),
364
+ sourceEventId: randomUUID(),
365
+ kind: 'work_item.claimed',
366
+ severity: 'info',
367
+ title: 'Work item claimed',
368
+ detail: `${claimed.packageId}/${claimed.queue}/${claimed.workItemId}`,
369
+ createdAt: now.toISOString()
370
+ });
371
+ }
372
+ return claimed;
373
+ }
374
+ }),
375
+ completeWorkItem: async ({ workItemId, phase }) => await this.deps.runGuardedAction({
376
+ action: 'package.work.manage',
377
+ actor: actorId,
378
+ target: workItemId,
379
+ title: 'Package work complete blocked',
380
+ execute: async () => this.transitionWorkItem(actorId, workItemId, (current, nowIso) => ({
381
+ ...current,
382
+ status: 'completed',
383
+ ...(phase ? { phase } : {}),
384
+ leaseOwner: null,
385
+ leaseExpiresAt: null,
386
+ lastError: null,
387
+ updatedAt: nowIso,
388
+ completedAt: nowIso
389
+ }))
390
+ }),
391
+ failWorkItem: async ({ workItemId, error, retryAfter, phase }) => await this.deps.runGuardedAction({
392
+ action: 'package.work.manage',
393
+ actor: actorId,
394
+ target: workItemId,
395
+ title: 'Package work fail blocked',
396
+ execute: async () => this.transitionWorkItem(actorId, workItemId, (current, nowIso) => {
397
+ const shouldRetry = retryAfter !== undefined && current.attempts < current.maxAttempts;
398
+ return {
399
+ ...current,
400
+ status: shouldRetry ? 'queued' : 'failed',
401
+ ...(phase ? { phase } : {}),
402
+ runAfter: shouldRetry ? retryAfter : current.runAfter,
403
+ leaseOwner: null,
404
+ leaseExpiresAt: null,
405
+ lastError: error,
406
+ updatedAt: nowIso,
407
+ completedAt: shouldRetry ? null : nowIso
408
+ };
119
409
  })
120
410
  }),
121
- listPendingRequests: (spaceId) => this.deps.store.listPendingRequestsBySpace(spaceId).filter((request) => request.status === 'open'),
411
+ deadLetterWorkItem: async ({ workItemId, reason, phase }) => await this.deps.runGuardedAction({
412
+ action: 'package.work.manage',
413
+ actor: actorId,
414
+ target: workItemId,
415
+ title: 'Package work dead-letter blocked',
416
+ execute: async () => this.transitionWorkItem(actorId, workItemId, (current, nowIso) => ({
417
+ ...current,
418
+ status: 'dead_lettered',
419
+ ...(phase ? { phase } : {}),
420
+ leaseOwner: null,
421
+ leaseExpiresAt: null,
422
+ lastError: reason,
423
+ updatedAt: nowIso,
424
+ completedAt: nowIso
425
+ }))
426
+ }),
427
+ updateWorkItem: async ({ workItemId, payload, phase, externalResource, sessionId }) => await this.deps.runGuardedAction({
428
+ action: 'package.work.manage',
429
+ actor: actorId,
430
+ target: workItemId,
431
+ title: 'Package work update blocked',
432
+ execute: async () => {
433
+ if (sessionId) {
434
+ this.requireSession(sessionId);
435
+ }
436
+ return this.transitionWorkItem(actorId, workItemId, (current, nowIso) => ({
437
+ ...current,
438
+ ...(payload ? { payload } : {}),
439
+ ...(phase ? { phase } : {}),
440
+ ...(externalResource ? { externalResource } : {}),
441
+ ...(sessionId ? { sessionId } : {}),
442
+ updatedAt: nowIso
443
+ }));
444
+ }
445
+ }),
446
+ getWorkItem: (workItemId) => {
447
+ const record = this.deps.store.getWorkItem(workItemId);
448
+ return record?.packageId === this.contextPackageId(actorId) ? record : null;
449
+ },
450
+ listWorkItems: (filter) => this.deps.store.listWorkItems({
451
+ packageId: this.contextPackageId(actorId),
452
+ queue: filter?.queue,
453
+ status: filter?.status,
454
+ externalResource: filter?.externalResource,
455
+ limit: filter?.limit
456
+ }),
457
+ upsertExternalResource: async (input) => await this.deps.runGuardedAction({
458
+ action: 'package.work.manage',
459
+ actor: actorId,
460
+ target: `${input.provider}:${input.kind}:${input.id}`,
461
+ title: 'External resource update blocked',
462
+ execute: async () => this.deps.store.upsertExternalResource({ ...input, nowIso: this.deps.now() })
463
+ }),
464
+ listExternalResources: (filter) => this.deps.store.listExternalResources(filter),
465
+ bindSessionToExternalResource: async ({ sessionId, externalResource, relationship }) => await this.deps.runGuardedAction({
466
+ action: 'package.work.manage',
467
+ actor: actorId,
468
+ target: `${sessionId}:${externalResource.provider}:${externalResource.kind}:${externalResource.id}`,
469
+ title: 'Session resource binding blocked',
470
+ execute: async () => {
471
+ this.requireSession(sessionId);
472
+ this.deps.store.upsertExternalResource({ ...externalResource, nowIso: this.deps.now() });
473
+ this.deps.store.bindSessionToExternalResource({
474
+ sessionId,
475
+ resource: externalResource,
476
+ relationship: relationship?.trim() || 'source',
477
+ nowIso: this.deps.now()
478
+ });
479
+ }
480
+ }),
481
+ listSessionsForExternalResource: (resource) => {
482
+ const ids = new Set(this.deps.store.listSessionIdsForExternalResource(resource));
483
+ return this.deps.snapshots.listSessions().filter((snapshot) => ids.has(snapshot.session.sessionId));
484
+ },
485
+ listPendingRequests: (transportResourceId) => this.deps.store.listPendingRequestsByTransportResource(transportResourceId).filter((request) => request.status === 'open'),
122
486
  listRuntimeReceipts: () => this.deps.snapshots.overview().receipts,
123
487
  listProviderConnections: () => this.deps.snapshots.overview().providers,
124
488
  listRuntimeActivities: (threadId) => threadId ? this.deps.snapshots.getSessionByThreadId(threadId)?.recentActivities ?? [] : this.deps.activities.listRecent(25),
125
- getSessionSnapshotBySpaceId: (spaceId) => this.deps.snapshots.getSessionBySpaceId(spaceId),
489
+ getSessionSnapshotByTransportResourceId: (transportResourceId) => this.deps.snapshots.getSessionByTransportResourceId(transportResourceId),
126
490
  getSessionSnapshotById: (sessionId) => this.deps.snapshots.getSessionById(sessionId),
127
491
  getRuntimeOverview: () => this.deps.snapshots.overview(),
128
492
  querySessions: (filter) => this.deps.snapshots.querySessions(filter),
@@ -167,40 +531,40 @@ export class RuntimePluginContextService {
167
531
  listDomainEvents: (threadId) => this.deps.store.listDomainEvents(threadId).map((row) => ({
168
532
  eventId: row.eventId,
169
533
  threadId: row.threadId,
170
- spaceId: row.spaceId,
534
+ transportResourceId: row.transportResourceId,
171
535
  sessionId: row.sessionId,
172
536
  sourceProviderEventId: row.sourceProviderEventId,
173
537
  createdAt: row.createdAt,
174
538
  type: row.type,
175
539
  payload: JSON.parse(row.payloadJson)
176
540
  })),
177
- updateSessionSummary: async (spaceId, summary, nowIso) => {
178
- this.deps.sessionRegistry.updateSummary(spaceId, summary, nowIso);
541
+ updateSessionSummary: async (transportResourceId, summary, nowIso) => {
542
+ this.deps.sessionRegistry.updateSummary(transportResourceId, summary, nowIso);
179
543
  },
180
- retrieveMemory: async ({ query, scopeId, spaceId, threadId, maxResults, enableRerank }) => this.deps.runGuardedAction({
544
+ retrieveMemory: async ({ query, scopeId, transportResourceId, threadId, maxResults, enableRerank }) => this.deps.runGuardedAction({
181
545
  action: 'memory.read',
182
546
  actor: actorId,
183
- target: spaceId ? `${scopeId}:${spaceId}:${threadId ?? 'root'}` : scopeId,
547
+ target: transportResourceId ? `${scopeId}:${transportResourceId}:${threadId ?? 'root'}` : scopeId,
184
548
  payload: { query, maxResults, enableRerank },
185
549
  title: 'Memory read blocked',
186
- execute: async () => await retrieveFromMemoryWithSQLite(query, this.deps.runtimeRoot, { scopeId: scopeId, spaceId: spaceId, threadId: threadId ?? null, projectKey: 'default' }, this.deps.sqlitePath, { maxResults, enableRerank })
550
+ execute: async () => await retrieveFromMemoryWithSQLite(query, this.deps.runtimeRoot, { scopeId: scopeId, transportResourceId: transportResourceId, threadId: threadId ?? null, projectKey: 'default' }, this.deps.sqlitePath, { maxResults, enableRerank })
187
551
  }),
188
- writeSessionMemory: async ({ scopeId, spaceId, threadId, kind, content, sourceRefs }) => {
552
+ writeSessionMemory: async ({ scopeId, transportResourceId, threadId, kind, content, sourceRefs }) => {
189
553
  await this.deps.runGuardedAction({
190
554
  action: kind === 'summary' ? 'memory.write' : 'fs.write',
191
555
  actor: actorId,
192
- target: `${scopeId}:${spaceId}:${threadId ?? 'root'}:${kind}`,
556
+ target: `${scopeId}:${transportResourceId}:${threadId ?? 'root'}:${kind}`,
193
557
  payload: { sourceRefs },
194
558
  title: 'Session memory write blocked',
195
559
  execute: async () => this.deps.memoryStore.writeSessionRecord({
196
560
  scopeId: scopeId,
197
- spaceId: spaceId,
561
+ transportResourceId: transportResourceId,
198
562
  threadId: threadId ?? null,
199
563
  kind,
200
564
  content,
201
565
  sourceRefs
202
566
  }).then(() => {
203
- void refreshMemoryIndex(this.deps.runtimeRoot, { scopeId: scopeId, spaceId: spaceId, threadId: threadId ?? null, projectKey: 'default' }, this.deps.sqlitePath);
567
+ void refreshMemoryIndex(this.deps.runtimeRoot, { scopeId: scopeId, transportResourceId: transportResourceId, threadId: threadId ?? null, projectKey: 'default' }, this.deps.sqlitePath);
204
568
  })
205
569
  });
206
570
  },
@@ -228,7 +592,7 @@ export class RuntimePluginContextService {
228
592
  })
229
593
  });
230
594
  },
231
- createSession: async ({ requestedName, runtimeMode, initialInstruction, objective, owner, tags }) => {
595
+ createSession: async ({ requestedName, runtimeMode, initialInstruction, objective, owner, tags, externalResource, workItemId }) => {
232
596
  const safeRuntimeMode = parseRuntimeModeName(runtimeMode, 'runtime_mode');
233
597
  const created = await this.deps.workManagement.createManagedSession({
234
598
  actorId,
@@ -239,84 +603,189 @@ export class RuntimePluginContextService {
239
603
  owner,
240
604
  tags
241
605
  });
242
- return { session: created.session, spaceId: created.spaceId };
606
+ if (externalResource) {
607
+ this.deps.store.upsertExternalResource({ ...externalResource, nowIso: this.deps.now() });
608
+ this.deps.store.bindSessionToExternalResource({
609
+ sessionId: created.session.sessionId,
610
+ resource: externalResource,
611
+ relationship: 'source',
612
+ nowIso: this.deps.now()
613
+ });
614
+ }
615
+ if (workItemId) {
616
+ this.transitionWorkItem(actorId, workItemId, (current, nowIso) => ({
617
+ ...current,
618
+ sessionId: created.session.sessionId,
619
+ ...(externalResource ? { externalResource } : {}),
620
+ updatedAt: nowIso
621
+ }));
622
+ }
623
+ return { session: created.session, transportResourceId: created.transportResourceId };
243
624
  },
244
- directSession: async ({ sessionId, spaceId, instruction, reason }) => await this.deps.workManagement.directManagedSession({
625
+ runGate: async ({ gateId, command, args, cwd, required, workItemId, sessionId }) => await this.deps.runGuardedAction({
626
+ action: 'command.exec',
627
+ actor: actorId,
628
+ target: `${gateId}:${command}`,
629
+ payload: { args, cwd, required, workItemId, sessionId },
630
+ threadId: sessionId ? this.deps.store.getSession(sessionId)?.threadId : undefined,
631
+ title: 'Runtime gate blocked',
632
+ execute: async () => {
633
+ if (!this.deps.commandRunner) {
634
+ throw new Error('Runtime gates require a command runner.');
635
+ }
636
+ if (sessionId) {
637
+ this.requireSession(sessionId);
638
+ }
639
+ if (workItemId) {
640
+ this.requireOwnedWorkItem(actorId, workItemId);
641
+ }
642
+ const packageId = this.contextPackageId(actorId);
643
+ const startedAt = this.deps.now();
644
+ let gate = this.deps.store.upsertGateRun({
645
+ gateRunId: randomUUID(),
646
+ gateId,
647
+ packageId,
648
+ ...(workItemId ? { workItemId } : {}),
649
+ ...(sessionId ? { sessionId } : {}),
650
+ command,
651
+ args: args ?? [],
652
+ ...(cwd ? { cwd } : {}),
653
+ required: required === true,
654
+ status: 'running',
655
+ exitCode: null,
656
+ stdout: '',
657
+ stderr: '',
658
+ startedAt,
659
+ completedAt: null
660
+ });
661
+ try {
662
+ const result = await this.deps.commandRunner.run(command, args ?? [], cwd);
663
+ gate = this.deps.store.upsertGateRun({
664
+ ...gate,
665
+ status: result.exitCode === 0 ? 'passed' : 'failed',
666
+ exitCode: result.exitCode,
667
+ stdout: result.stdout,
668
+ stderr: result.stderr,
669
+ completedAt: this.deps.now()
670
+ });
671
+ this.deps.appendAuditEvent(result.exitCode === 0 ? 'runtime.gate.passed' : 'runtime.gate.failed', {
672
+ actorId,
673
+ packageId,
674
+ gateRunId: gate.gateRunId,
675
+ gateId,
676
+ workItemId,
677
+ sessionId,
678
+ exitCode: result.exitCode
679
+ });
680
+ this.deps.recordRuntimeActivity({
681
+ ...this.activityTargetForSession(sessionId, 'runtime:gates'),
682
+ sourceEventId: gate.gateRunId,
683
+ kind: result.exitCode === 0 ? 'runtime.gate.passed' : 'runtime.gate.failed',
684
+ severity: result.exitCode === 0 ? 'info' : 'error',
685
+ title: result.exitCode === 0 ? 'Runtime gate passed' : 'Runtime gate failed',
686
+ detail: `${gate.gateId}: ${gate.command} ${(gate.args ?? []).join(' ')}`.trim(),
687
+ createdAt: gate.completedAt ?? this.deps.now()
688
+ });
689
+ return gate;
690
+ }
691
+ catch (error) {
692
+ this.deps.store.upsertGateRun({
693
+ ...gate,
694
+ status: 'error',
695
+ exitCode: null,
696
+ stderr: error instanceof Error ? error.message : String(error),
697
+ completedAt: this.deps.now()
698
+ });
699
+ this.deps.recordRuntimeActivity({
700
+ ...this.activityTargetForSession(sessionId, 'runtime:gates'),
701
+ sourceEventId: gate.gateRunId,
702
+ kind: 'runtime.gate.error',
703
+ severity: 'error',
704
+ title: 'Runtime gate errored',
705
+ detail: error instanceof Error ? error.message : String(error),
706
+ createdAt: this.deps.now()
707
+ });
708
+ throw error;
709
+ }
710
+ }
711
+ }),
712
+ runHeadless: async ({ requestedName, runtimeMode, prompt, objective, owner, tags, externalResource, workItemId, outputSchema, requireStructuredOutput }) => await this.deps.runGuardedAction({
713
+ action: 'provider.headless.run',
714
+ actor: actorId,
715
+ target: `${this.contextPackageId(actorId)}:${requestedName}`,
716
+ payload: { requestedName, runtimeMode, objective, owner, tags, externalResource, workItemId },
717
+ title: 'Headless provider run blocked',
718
+ execute: async () => {
719
+ const context = this.createContext(actorId);
720
+ // First-pass headless runs are session-backed, so provider execution uses the managed session workspace.
721
+ const created = await context.createSession({
722
+ requestedName,
723
+ runtimeMode,
724
+ objective,
725
+ owner,
726
+ tags,
727
+ externalResource,
728
+ workItemId
729
+ });
730
+ const reply = await context.runAgent({
731
+ surface: 'session',
732
+ transportResourceId: created.transportResourceId,
733
+ actorId,
734
+ actorLabel: this.contextPackageId(actorId),
735
+ message: prompt,
736
+ session: created.session,
737
+ cwd: created.session.workspacePath,
738
+ runtimeMode,
739
+ context: {
740
+ systemPromptSections: await this.loadSessionPromptSections(this.toInternalSessionRow(created.session))
741
+ },
742
+ promptSource: 'headless'
743
+ });
744
+ const text = reply.text ?? '';
745
+ let parsedOutput;
746
+ if (outputSchema || requireStructuredOutput) {
747
+ try {
748
+ parsedOutput = JSON.parse(text);
749
+ this.validateStructuredOutput(parsedOutput, outputSchema);
750
+ }
751
+ catch (error) {
752
+ if (requireStructuredOutput) {
753
+ throw error;
754
+ }
755
+ }
756
+ }
757
+ return {
758
+ session: created.session,
759
+ reply,
760
+ ...(parsedOutput !== undefined ? { parsedOutput } : {})
761
+ };
762
+ }
763
+ }),
764
+ directSession: async ({ sessionId, transportResourceId, instruction, reason }) => await this.deps.workManagement.directManagedSession({
245
765
  actorId,
246
766
  sessionId,
247
- spaceId: spaceId,
767
+ transportResourceId: transportResourceId,
248
768
  instruction,
249
769
  reason
250
770
  }),
251
- archiveSession: async ({ spaceId, sessionId }) => await this.deps.workManagement.archiveManagedSession({
771
+ archiveSession: async ({ transportResourceId, sessionId }) => await this.deps.workManagement.archiveManagedSession({
252
772
  actorId,
253
- spaceId: spaceId,
773
+ transportResourceId: transportResourceId,
254
774
  sessionId
255
775
  }),
256
- deleteArchivedSession: async ({ spaceId, sessionId }) => await this.deps.workManagement.deleteManagedSession({
776
+ deleteArchivedSession: async ({ transportResourceId, sessionId }) => await this.deps.workManagement.deleteManagedSession({
257
777
  actorId,
258
- spaceId: spaceId,
778
+ transportResourceId: transportResourceId,
259
779
  sessionId
260
780
  }),
261
- archiveMission: async ({ spaceId, missionId }) => await this.deps.workManagement.archiveMission({
262
- actorId,
263
- spaceId: spaceId,
264
- missionId
265
- }),
266
- deleteArchivedMission: async ({ spaceId, missionId }) => await this.deps.workManagement.deleteArchivedMission({
267
- actorId,
268
- spaceId: spaceId,
269
- missionId
270
- }),
271
- archiveSpaceTarget: async ({ spaceId }) => await this.deps.workManagement.archiveChannelTarget({
781
+ archiveTransportResourceTarget: async ({ transportResourceId }) => await this.deps.workManagement.archiveResourceTarget({
272
782
  actorId,
273
- spaceId: spaceId
783
+ transportResourceId: transportResourceId
274
784
  }),
275
- deleteArchivedSpaceTarget: async ({ spaceId }) => await this.deps.workManagement.deleteArchivedChannelTarget({
785
+ deleteArchivedTransportResourceTarget: async ({ transportResourceId }) => await this.deps.workManagement.deleteArchivedResourceTarget({
276
786
  actorId,
277
- spaceId: spaceId
787
+ transportResourceId: transportResourceId
278
788
  }),
279
- createMission: async ({ title, goal, schedule, startTime, runtimeMode }) => {
280
- const safeRuntimeMode = parseRuntimeModeName(runtimeMode, 'runtime_mode');
281
- const created = await this.deps.workManagement.createMission({
282
- actorId,
283
- title,
284
- goal,
285
- schedule,
286
- startTime,
287
- runtimeMode: safeRuntimeMode
288
- });
289
- return { mission: created.mission, spaceId: created.spaceId };
290
- },
291
- pauseMission: async ({ spaceId, missionId }) => this.deps.workManagement.updateMissionLifecycle(actorId, { spaceId: spaceId, missionId }, 'pause'),
292
- resumeMission: async ({ spaceId, missionId }) => this.deps.workManagement.updateMissionLifecycle(actorId, { spaceId: spaceId, missionId }, 'resume'),
293
- stopMission: async ({ spaceId, missionId }) => this.deps.workManagement.updateMissionLifecycle(actorId, { spaceId: spaceId, missionId }, 'stop'),
294
- runMissionNow: async ({ spaceId, missionId, requesterActorId }) => {
295
- const mission = this.deps.workManagement.resolveMission({ spaceId, missionId });
296
- if (!mission) {
297
- return null;
298
- }
299
- await this.deps.runGuardedAction({
300
- action: 'mission.control',
301
- actor: actorId,
302
- target: mission.missionId,
303
- title: 'Mission control blocked',
304
- execute: async () => undefined
305
- });
306
- if (mission.lifecycleStatus === 'draft' || mission.lifecycleStatus === 'stopped' || mission.completedAt || mission.archivedAt) {
307
- throw new Error(`Mission ${mission.missionId} cannot be run because it is not fully configured or is stopped.`);
308
- }
309
- void this.deps.lifecycleService
310
- .runMissionTurn(mission.missionId, 'manual', 'runtime:mission/manual', requesterActorId ?? null)
311
- .catch((error) => {
312
- this.deps.appendAuditEvent('mission.trigger.failed', {
313
- missionId: mission.missionId,
314
- actorId,
315
- error: error instanceof Error ? error.message : String(error)
316
- });
317
- });
318
- return this.deps.missionRegistry.getById(mission.missionId) ?? mission;
319
- },
320
789
  respondToRuntimeRequest: async ({ threadId, requestId, decision, requesterActor }) => {
321
790
  await this.deps.resolvePendingRequest({
322
791
  actorId,
@@ -444,69 +913,99 @@ export class RuntimePluginContextService {
444
913
  }
445
914
  return true;
446
915
  }),
447
- sendMessage: async (spaceId, payload) => {
448
- await this.deps.postTransportMessage(actorId, spaceId, payload);
916
+ sendMessage: async (transportResourceId, payload) => {
917
+ await this.deps.postTransportMessage(actorId, transportResourceId, payload);
449
918
  },
450
919
  sendStatusUpdate: async (payload) => {
451
- const namespaceState = this.deps.getNamespaceState();
452
- if (namespaceState) {
453
- await this.deps.postTransportMessage(actorId, namespaceState.statusChannelId, payload);
920
+ const surfaceState = this.deps.getSurfaceState();
921
+ if (surfaceState) {
922
+ await this.deps.postTransportMessage(actorId, surfaceState.statusResourceId, payload);
454
923
  }
455
924
  },
456
925
  appendAuditEvent: (event, payload) => {
457
926
  this.deps.appendAuditEvent(event, payload);
458
927
  },
459
928
  nowIso: () => this.deps.now(),
460
- runAgent: async ({ surface, spaceId, actorId: promptActorId, actorLabel, text, attachments, session, cwd, runtimeMode, basePromptSections, promptSource }) => {
461
- const promptSections = [
462
- ...basePromptSections,
463
- ...(await this.deps.getPluginHost().beforeAgentPrompt({
464
- surface,
465
- spaceId,
466
- actorId: promptActorId,
467
- actorLabel,
468
- text,
469
- attachments,
470
- session
471
- }, (pluginId) => this.createContext(`plugin:${pluginId}`)))
929
+ runAgent: async ({ surface, transportResourceId, actorId: promptActorId, actorLabel, message, attachments, session, cwd, runtimeMode, toolGrantIds, context: agentContext, agentKind, promptSource }) => {
930
+ const activeSession = session
931
+ ? this.toInternalSessionRow(session)
932
+ : await this.deps.ensureCoordinationSession(transportResourceId, cwd ?? this.deps.coordinationWorkspacePath);
933
+ const effectiveAgentKind = agentKind ?? activeSession.agentKind ?? (session ? 'workspace' : 'ephemeral');
934
+ const contributions = await this.deps.getPluginHost().contributeAgentContext({
935
+ surface,
936
+ transportResourceId,
937
+ actorId: promptActorId,
938
+ actorLabel,
939
+ text: message,
940
+ attachments,
941
+ session
942
+ }, (pluginId) => this.createContext(`plugin:${pluginId}`));
943
+ const contributionSystemSections = contributions.flatMap((entry) => entry.systemPromptSections ?? []);
944
+ const contributionContext = contributions.flatMap((entry) => entry.perTurnContext ?? []);
945
+ const contributionGrantIds = contributions.flatMap((entry) => entry.toolGrantIds ?? []);
946
+ const policyGrants = this.deps.providerToolPolicy[effectiveAgentKind].grants ?? [];
947
+ const resources = this.buildProviderResourceBundle([
948
+ ...(agentContext?.systemPromptSections ?? []),
949
+ ...contributionSystemSections
950
+ ]);
951
+ const providerContext = [
952
+ {
953
+ title: promptSource === 'orchestration' ? 'Orchestration instruction source' : 'Transport message source',
954
+ content: promptSource === 'orchestration'
955
+ ? `${actorLabel} (${promptActorId})`
956
+ : describeTransportAuthor({
957
+ authorId: promptActorId,
958
+ authorUsername: actorLabel,
959
+ authorGlobalName: null,
960
+ authorDisplayName: actorLabel,
961
+ authorLabel: actorLabel
962
+ }),
963
+ source: 'moorline/runtime'
964
+ },
965
+ ...((attachments ?? []).length > 0
966
+ ? [{
967
+ title: 'Attachment summary',
968
+ content: `Attached image count: ${(attachments ?? []).length}`,
969
+ source: 'moorline/runtime'
970
+ }]
971
+ : []),
972
+ ...(agentContext?.perTurnContext ?? []),
973
+ ...contributionContext
974
+ ];
975
+ const resolvedGrantIds = [
976
+ ...(activeSession.toolGrantIds ?? []),
977
+ ...policyGrants,
978
+ ...(toolGrantIds ?? []),
979
+ ...contributionGrantIds,
980
+ ...(effectiveAgentKind === 'ephemeral' ? ['core.moorline_session'] : [])
472
981
  ];
473
- const activeSession = session ?? (await this.deps.ensureChatSession(spaceId, cwd));
474
- const prompt = [
475
- ...promptSections,
476
- '',
477
- promptSource === 'orchestration'
478
- ? `Orchestration instruction from ${actorLabel} (${promptActorId}): ${text || '(no text content)'}`
479
- : `Transport message from ${describeTransportAuthor({
480
- authorId: promptActorId,
481
- authorUsername: actorLabel,
482
- authorGlobalName: null,
483
- authorDisplayName: actorLabel,
484
- authorLabel: actorLabel
485
- })}: ${text || '(no text content)'}`,
486
- ...((attachments ?? []).length > 0 ? [`Attached image count: ${(attachments ?? []).length}`] : [])
487
- ].join('\n');
982
+ const providerTools = this.resolveProviderTools(effectiveAgentKind, resolvedGrantIds);
488
983
  const providerImages = await this.deps.prepareProviderImages(activeSession.threadId, attachments);
489
984
  const result = await this.deps.providerOrchestrator.runTurn({
490
985
  actorId,
491
986
  session: activeSession,
492
- spaceId: spaceId,
987
+ transportResourceId: transportResourceId,
493
988
  surface,
494
- promptContent: text,
989
+ promptContent: message,
495
990
  promptSource,
496
991
  authorId: promptActorId,
497
992
  authorLabel: actorLabel,
498
993
  providerInput: {
499
- text: prompt,
500
- ...(providerImages && providerImages.length > 0 ? { images: providerImages } : {})
501
- }
994
+ text: message,
995
+ ...(providerImages && providerImages.length > 0 ? { images: providerImages } : {}),
996
+ ...(providerContext.length > 0 ? { context: providerContext } : {})
997
+ },
998
+ providerResources: resources,
999
+ providerTools,
1000
+ providerToolExecutor: this.createProviderToolExecutor(providerTools)
502
1001
  });
503
1002
  const formattedResult = this.deps.normalizeReply(result.text || (result.attachments?.length ? '' : 'I could not finish that cleanly.'));
504
1003
  await this.deps.getPluginHost().afterAgentResponse({
505
1004
  surface,
506
- spaceId,
1005
+ transportResourceId,
507
1006
  actorId: promptActorId,
508
1007
  actorLabel,
509
- text,
1008
+ text: message,
510
1009
  attachments,
511
1010
  session,
512
1011
  replyMessage: formattedResult
@@ -539,18 +1038,342 @@ export class RuntimePluginContextService {
539
1038
  }
540
1039
  return dynamicSections;
541
1040
  }
542
- async loadMissionPromptSections(mission) {
1041
+ toInternalSessionRow(session) {
1042
+ return session;
1043
+ }
1044
+ buildProviderResourceBundle(systemPromptSections) {
1045
+ const skills = this.deps.skillRegistry.list().map((skill) => ({
1046
+ name: skill.name,
1047
+ description: skill.description,
1048
+ filePath: skill.path,
1049
+ baseDir: skill.path.replace(/[\\/]SKILL\.md$/, ''),
1050
+ metadata: skill.metadata
1051
+ }));
1052
+ return {
1053
+ systemPromptSections: systemPromptSections.map((section) => section.trim()).filter(Boolean),
1054
+ contextFiles: [],
1055
+ skills,
1056
+ promptTemplates: []
1057
+ };
1058
+ }
1059
+ coreSessionTool() {
1060
+ return {
1061
+ name: 'moorline_session',
1062
+ description: 'Inspect, query, create, direct, archive, or delete Moorline managed sessions.',
1063
+ inputSchema: {
1064
+ type: 'object',
1065
+ properties: {
1066
+ action: {
1067
+ type: 'string',
1068
+ enum: ['query', 'inspect', 'create', 'direct', 'archive', 'delete_archived']
1069
+ },
1070
+ session_id: { type: 'string' },
1071
+ transport_resource_id: { type: 'string' },
1072
+ requested_name: { type: 'string' },
1073
+ runtime_mode: { type: 'string' },
1074
+ instruction: { type: 'string' },
1075
+ objective: { type: 'string' },
1076
+ reason: { type: 'string' },
1077
+ include_archived: { type: 'boolean' },
1078
+ limit: { type: 'number' }
1079
+ },
1080
+ required: ['action'],
1081
+ additionalProperties: false
1082
+ },
1083
+ execute: async (input, context) => {
1084
+ const action = typeof input.action === 'string' ? input.action : '';
1085
+ const sessionId = typeof input.session_id === 'string' ? input.session_id.trim() : '';
1086
+ const transportResourceId = typeof input.transport_resource_id === 'string' ? input.transport_resource_id.trim() : '';
1087
+ switch (action) {
1088
+ case 'query': {
1089
+ return await this.deps.runGuardedAction({
1090
+ action: 'session.inspect',
1091
+ actor: context.actorId,
1092
+ target: 'sessions',
1093
+ title: 'Session query blocked',
1094
+ execute: async () => {
1095
+ const sessions = this.deps.snapshots.querySessions({
1096
+ includeArchived: input.include_archived === true,
1097
+ limit: typeof input.limit === 'number' ? input.limit : undefined
1098
+ });
1099
+ return {
1100
+ content: sessions.length === 0
1101
+ ? 'No sessions matched.'
1102
+ : [
1103
+ 'Sessions:',
1104
+ ...sessions.map(({ session }) => [
1105
+ `- ${session.sessionId}`,
1106
+ `kind=${session.agentKind ?? 'workspace'}`,
1107
+ `lifecycle=${session.lifecycleStatus}`,
1108
+ `mode=${session.runtimeMode}`,
1109
+ `provider=${session.providerStatus}`,
1110
+ session.objective ? `objective=${session.objective}` : null
1111
+ ].filter(Boolean).join(' | '))
1112
+ ].join('\n')
1113
+ };
1114
+ }
1115
+ });
1116
+ }
1117
+ case 'inspect': {
1118
+ return await this.deps.runGuardedAction({
1119
+ action: 'session.inspect',
1120
+ actor: context.actorId,
1121
+ target: sessionId || transportResourceId || 'session',
1122
+ title: 'Session inspect blocked',
1123
+ execute: async () => {
1124
+ const snapshot = sessionId
1125
+ ? this.deps.snapshots.getSessionById(sessionId)
1126
+ : transportResourceId
1127
+ ? this.deps.snapshots.getSessionByTransportResourceId(transportResourceId)
1128
+ : null;
1129
+ return { content: snapshot ? JSON.stringify(snapshot, null, 2) : 'No matching session found.' };
1130
+ }
1131
+ });
1132
+ }
1133
+ case 'create': {
1134
+ const requestedName = typeof input.requested_name === 'string' ? input.requested_name.trim() : '';
1135
+ if (!requestedName)
1136
+ return { content: 'create error: requested_name is required.' };
1137
+ const runtimeMode = parseRuntimeModeName(input.runtime_mode, 'runtime_mode');
1138
+ return await this.deps.runGuardedAction({
1139
+ action: 'session.create',
1140
+ actor: context.actorId,
1141
+ target: requestedName,
1142
+ title: 'Session create blocked',
1143
+ execute: async () => {
1144
+ const created = await this.deps.workManagement.createManagedSession({
1145
+ actorId: 'runtime:provider/tool',
1146
+ requestedName,
1147
+ runtimeMode,
1148
+ objective: typeof input.objective === 'string' ? input.objective : undefined
1149
+ });
1150
+ return { content: `Created session ${created.session.sessionId} (${created.transportResourceId}).` };
1151
+ }
1152
+ });
1153
+ }
1154
+ case 'direct': {
1155
+ const instruction = typeof input.instruction === 'string' ? input.instruction.trim() : '';
1156
+ if (!instruction)
1157
+ return { content: 'direct error: instruction is required.' };
1158
+ return await this.deps.runGuardedAction({
1159
+ action: 'session.direct',
1160
+ actor: context.actorId,
1161
+ target: sessionId || transportResourceId || 'session',
1162
+ title: 'Session direct blocked',
1163
+ execute: async () => {
1164
+ const result = await this.deps.workManagement.directManagedSession({
1165
+ actorId: 'runtime:provider/tool',
1166
+ sessionId: sessionId || undefined,
1167
+ transportResourceId: transportResourceId || undefined,
1168
+ instruction,
1169
+ reason: typeof input.reason === 'string' ? input.reason : undefined
1170
+ });
1171
+ return { content: `Directed session ${result.session.sessionId}.\n${result.reply.text ?? ''}`.trim() };
1172
+ }
1173
+ });
1174
+ }
1175
+ case 'archive': {
1176
+ return await this.deps.runGuardedAction({
1177
+ action: 'session.archive',
1178
+ actor: context.actorId,
1179
+ target: sessionId || transportResourceId || 'session',
1180
+ title: 'Session archive blocked',
1181
+ execute: async () => {
1182
+ const archived = await this.deps.workManagement.archiveManagedSession({
1183
+ actorId: 'runtime:provider/tool',
1184
+ sessionId: sessionId || undefined,
1185
+ transportResourceId: transportResourceId || undefined
1186
+ });
1187
+ return { content: archived ? `Archived session ${archived.sessionId}.` : 'No matching session found.' };
1188
+ }
1189
+ });
1190
+ }
1191
+ case 'delete_archived': {
1192
+ return await this.deps.runGuardedAction({
1193
+ action: 'session.delete',
1194
+ actor: context.actorId,
1195
+ target: sessionId || transportResourceId || 'session',
1196
+ title: 'Session delete blocked',
1197
+ execute: async () => {
1198
+ const deleted = await this.deps.workManagement.deleteManagedSession({
1199
+ actorId: 'runtime:provider/tool',
1200
+ sessionId: sessionId || undefined,
1201
+ transportResourceId: transportResourceId || undefined
1202
+ });
1203
+ return { content: deleted ? `Deleted archived session ${deleted.sessionId}.` : 'No matching archived session found.' };
1204
+ }
1205
+ });
1206
+ }
1207
+ default:
1208
+ return { content: 'moorline_session error: unknown action.' };
1209
+ }
1210
+ }
1211
+ };
1212
+ }
1213
+ coreSkillLoadTool() {
1214
+ return {
1215
+ name: 'moorline_skill.load',
1216
+ description: 'Load a Moorline-managed skill by name.',
1217
+ requiredCapability: 'fs.read',
1218
+ inputSchema: {
1219
+ type: 'object',
1220
+ properties: {
1221
+ name: { type: 'string' }
1222
+ },
1223
+ required: ['name'],
1224
+ additionalProperties: false
1225
+ },
1226
+ execute: async (input) => {
1227
+ const name = typeof input.name === 'string' ? input.name.trim() : '';
1228
+ if (!name) {
1229
+ return { content: 'moorline_skill.load error: name is required.' };
1230
+ }
1231
+ const skill = await this.deps.skillRegistry.load(name);
1232
+ return {
1233
+ content: skill ? JSON.stringify(skill, null, 2) : `No matching skill found: ${name}`
1234
+ };
1235
+ }
1236
+ };
1237
+ }
1238
+ coreSkillSaveTool() {
1239
+ return {
1240
+ name: 'moorline_skill.save',
1241
+ description: 'Create or update a Moorline-managed runtime skill.',
1242
+ requiredCapability: 'fs.write',
1243
+ inputSchema: {
1244
+ type: 'object',
1245
+ properties: {
1246
+ name: { type: 'string' },
1247
+ description: { type: 'string' },
1248
+ tags: { type: 'array', items: { type: 'string' } },
1249
+ body: { type: 'string' },
1250
+ directory_name: { type: 'string' },
1251
+ resource_files: {
1252
+ type: 'array',
1253
+ items: {
1254
+ type: 'object',
1255
+ properties: {
1256
+ path: { type: 'string' },
1257
+ content: { type: 'string' }
1258
+ },
1259
+ required: ['path', 'content'],
1260
+ additionalProperties: false
1261
+ }
1262
+ }
1263
+ },
1264
+ required: ['name', 'body'],
1265
+ additionalProperties: false
1266
+ },
1267
+ execute: async (input, context) => {
1268
+ const name = typeof input.name === 'string' ? input.name.trim() : '';
1269
+ const body = typeof input.body === 'string' ? input.body : '';
1270
+ if (!name) {
1271
+ return { content: 'moorline_skill.save error: name is required.' };
1272
+ }
1273
+ if (!body.trim()) {
1274
+ return { content: 'moorline_skill.save error: body is required.' };
1275
+ }
1276
+ const resourceFiles = Array.isArray(input.resource_files)
1277
+ ? input.resource_files
1278
+ .filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry))
1279
+ .map((entry) => ({
1280
+ path: typeof entry.path === 'string' ? entry.path : '',
1281
+ content: typeof entry.content === 'string' ? entry.content : ''
1282
+ }))
1283
+ : [];
1284
+ const written = writeSkill({
1285
+ rootDir: join(this.deps.runtimeRoot, 'packages', 'skills'),
1286
+ name,
1287
+ description: typeof input.description === 'string' ? input.description : undefined,
1288
+ tags: Array.isArray(input.tags) ? input.tags.filter((tag) => typeof tag === 'string') : undefined,
1289
+ body,
1290
+ directoryName: typeof input.directory_name === 'string' ? input.directory_name : undefined,
1291
+ resourceFiles
1292
+ });
1293
+ this.deps.skillRegistry.invalidateCache();
1294
+ recordHistoryCheckpoint({
1295
+ homeRoot: this.deps.homeRoot,
1296
+ actor: context.actorId,
1297
+ reason: `Updated skill ${name}.`,
1298
+ operation: `provider tool write skill ${typeof input.directory_name === 'string' ? input.directory_name : name}`,
1299
+ absoluteTargets: [written.skillDir]
1300
+ });
1301
+ return { content: JSON.stringify(written, null, 2) };
1302
+ }
1303
+ };
1304
+ }
1305
+ allProviderRuntimeTools() {
543
1306
  return [
544
- `Mission ID: ${mission.missionId}`,
545
- `Mission title: ${mission.title}`,
546
- `Mission goal: ${mission.goal}`,
547
- `Mission schedule: ${mission.scheduleText}`,
548
- `Mission workspace: ${mission.workspacePath}`,
549
- `Runtime mode: ${mission.runtimeMode}`,
550
- 'Mission interactions are independent operator messages. Respond directly to the current message while using the persistent mission thread context when helpful.',
551
- 'Manual mission messages must not change or cancel the recurring mission schedule.'
1307
+ { ...this.coreSessionTool(), pluginId: 'core' },
1308
+ { ...this.coreSkillLoadTool(), pluginId: 'core' },
1309
+ { ...this.coreSkillSaveTool(), pluginId: 'core' },
1310
+ ...this.deps.getPluginHost().listTools((pluginId) => this.createContext(`plugin:${pluginId}`))
552
1311
  ];
553
1312
  }
1313
+ toolId(tool) {
1314
+ return tool.pluginId === 'core' ? `core.${tool.name}` : `plugin:${tool.pluginId ?? 'unknown'}.${tool.name}`;
1315
+ }
1316
+ resolveProviderTools(agentKind, grantIds) {
1317
+ const grants = new Set(grantIds);
1318
+ if (agentKind === 'ephemeral') {
1319
+ grants.add('core.moorline_session');
1320
+ }
1321
+ return this.allProviderRuntimeTools()
1322
+ .filter((tool) => grants.has(this.toolId(tool)))
1323
+ .map((tool) => ({
1324
+ id: this.toolId(tool),
1325
+ name: tool.name,
1326
+ description: tool.description ?? tool.name,
1327
+ inputSchema: tool.inputSchema ?? { type: 'object', additionalProperties: true },
1328
+ ...(tool.requiredCapability ? { requiredCapability: tool.requiredCapability } : {}),
1329
+ source: tool.pluginId === 'core' ? 'core' : 'plugin',
1330
+ ...(tool.pluginId && tool.pluginId !== 'core' ? { ownerPackageId: tool.pluginId } : {})
1331
+ }));
1332
+ }
1333
+ createProviderToolExecutor(tools) {
1334
+ const allowed = new Set(tools.map((tool) => tool.id));
1335
+ return {
1336
+ executeProviderTool: async ({ toolId, arguments: args, actor }) => {
1337
+ if (!allowed.has(toolId)) {
1338
+ throw new Error(`Provider tool is not granted for this session: ${toolId}`);
1339
+ }
1340
+ const runtimeTool = this.allProviderRuntimeTools().find((tool) => this.toolId(tool) === toolId);
1341
+ if (!runtimeTool) {
1342
+ throw new Error(`Unknown provider tool: ${toolId}`);
1343
+ }
1344
+ const context = this.createContext(runtimeTool.pluginId && runtimeTool.pluginId !== 'core' ? `plugin:${runtimeTool.pluginId}` : actor);
1345
+ const run = async () => await runtimeTool.execute(args, context);
1346
+ try {
1347
+ const result = runtimeTool.requiredCapability
1348
+ ? await this.deps.runGuardedAction({
1349
+ action: runtimeTool.requiredCapability,
1350
+ actor,
1351
+ target: toolId,
1352
+ title: 'Provider tool blocked',
1353
+ execute: run
1354
+ })
1355
+ : await run();
1356
+ this.deps.appendAuditEvent('provider.tool.executed', {
1357
+ actor,
1358
+ toolId,
1359
+ ownerPackageId: runtimeTool.pluginId ?? 'core',
1360
+ ok: true
1361
+ });
1362
+ return { content: result.content };
1363
+ }
1364
+ catch (error) {
1365
+ this.deps.appendAuditEvent('provider.tool.executed', {
1366
+ actor,
1367
+ toolId,
1368
+ ownerPackageId: runtimeTool.pluginId ?? 'core',
1369
+ ok: false,
1370
+ error: error instanceof Error ? error.message : String(error)
1371
+ });
1372
+ throw error;
1373
+ }
1374
+ }
1375
+ };
1376
+ }
554
1377
  normalizePluginSidecarScope(scope) {
555
1378
  if (scope.kind === 'session') {
556
1379
  return {
@@ -564,7 +1387,7 @@ export class RuntimePluginContextService {
564
1387
  const normalized = candidate.trim();
565
1388
  const sessions = this.deps.sessionRegistry.list();
566
1389
  const session = sessions.find((entry) => entry.sessionId === normalized) ??
567
- sessions.find((entry) => entry.spaceId === normalized) ??
1390
+ sessions.find((entry) => entry.transportResourceId === normalized) ??
568
1391
  sessions.find((entry) => entry.threadId === normalized) ??
569
1392
  null;
570
1393
  if (!session) {