@wildo-ai/saas-backend-lib 1.1.0 → 1.1.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 (265) hide show
  1. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts +14 -3
  2. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
  3. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +115 -22
  4. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
  5. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +3 -1
  6. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
  7. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +8 -3
  8. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
  9. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts +11 -0
  10. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
  11. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js +11 -2
  12. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js.map +1 -1
  13. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +1 -0
  14. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
  15. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +6 -1
  16. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
  17. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js +16 -0
  19. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map +1 -1
  20. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts +20 -6
  21. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
  22. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +88 -32
  23. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
  24. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts +3 -1
  25. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js +32 -7
  27. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js.map +1 -1
  28. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts +8 -5
  29. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
  30. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.js.map +1 -1
  31. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +31 -0
  32. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
  33. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +127 -5
  34. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
  35. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +71 -1
  36. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
  37. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +62 -2
  38. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
  39. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +21 -0
  40. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
  41. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +126 -4
  42. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
  43. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts +3 -26
  44. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
  45. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js +3 -68
  46. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js.map +1 -1
  47. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  48. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +4 -2
  49. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  50. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +6 -6
  51. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
  52. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +38 -0
  53. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
  54. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +40 -0
  55. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
  56. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +20 -0
  57. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
  58. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +28 -0
  59. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
  60. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +12 -0
  61. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -0
  62. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +118 -0
  63. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -0
  64. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
  65. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +8 -5
  66. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
  67. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
  68. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +14 -0
  69. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
  70. package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
  71. package/dist/esm/config/custom/application-config-controller.backend.service.js +7 -1
  72. package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -1
  73. package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -0
  74. package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
  75. package/dist/esm/config/services/app-configuration.backend.utils.d.ts +10 -1
  76. package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
  77. package/dist/esm/config/services/app-configuration.backend.utils.js +13 -2
  78. package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
  79. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts +2 -2
  80. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js +2 -2
  81. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js.map +1 -1
  82. package/dist/esm/databases/models/filter.backend.schemas.js +2 -2
  83. package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -1
  84. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
  85. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +20 -1
  86. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -1
  87. package/dist/esm/databases/services/redis.service.d.ts +27 -0
  88. package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
  89. package/dist/esm/databases/services/redis.service.js +29 -0
  90. package/dist/esm/databases/services/redis.service.js.map +1 -1
  91. package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
  92. package/dist/esm/errors/services/error-handler.backend.service.js +5 -0
  93. package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
  94. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts +41 -0
  95. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -0
  96. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js +40 -0
  97. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js.map +1 -0
  98. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts +64 -0
  99. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -0
  100. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js +193 -0
  101. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js.map +1 -0
  102. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +13 -2
  103. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
  104. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +8 -2
  105. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
  106. package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
  107. package/dist/esm/external-data/external-data-transform.backend.js +7 -1
  108. package/dist/esm/external-data/external-data-transform.backend.js.map +1 -1
  109. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts +2 -0
  110. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
  111. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js +13 -0
  112. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js.map +1 -1
  113. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +14 -0
  114. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  115. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +6 -0
  116. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  117. package/dist/esm/files/controllers/file.controller.d.ts +24 -1
  118. package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
  119. package/dist/esm/files/controllers/file.controller.js +66 -2
  120. package/dist/esm/files/controllers/file.controller.js.map +1 -1
  121. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts +17 -0
  122. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -0
  123. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js +1 -0
  124. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -0
  125. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +5 -1
  126. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
  127. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +42 -3
  128. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
  129. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +18 -0
  130. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
  131. package/dist/esm/files/services/file-operation-handler.backend.service.js +36 -28
  132. package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
  133. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +163 -0
  134. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -0
  135. package/dist/esm/files/services/file-upload-grant.backend.service.js +442 -0
  136. package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -0
  137. package/dist/esm/files/services/files.backend.service.d.ts +19 -0
  138. package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
  139. package/dist/esm/files/services/files.backend.service.js +78 -15
  140. package/dist/esm/files/services/files.backend.service.js.map +1 -1
  141. package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
  142. package/dist/esm/files/utils/file-uploader.utils.js +12 -0
  143. package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
  144. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +5 -5
  145. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
  146. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +79 -0
  147. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  148. package/dist/esm/flows-actors/services/agents.backend.service.js +319 -42
  149. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  150. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +151 -41
  151. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  152. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +300 -139
  153. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  154. package/dist/esm/index.d.ts +4 -1
  155. package/dist/esm/index.d.ts.map +1 -1
  156. package/dist/esm/index.js +14 -1
  157. package/dist/esm/index.js.map +1 -1
  158. package/dist/esm/inject/models/container.d.ts.map +1 -1
  159. package/dist/esm/inject/models/container.js +4 -0
  160. package/dist/esm/inject/models/container.js.map +1 -1
  161. package/dist/esm/inject/models/service-types.d.ts +3 -0
  162. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  163. package/dist/esm/inject/models/service-types.js +2 -0
  164. package/dist/esm/inject/models/service-types.js.map +1 -1
  165. package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
  166. package/dist/esm/mcp/controllers/mcp.controller.js +12 -4
  167. package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
  168. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts +34 -0
  169. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
  170. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js +42 -0
  171. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
  172. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +29 -1
  173. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
  174. package/dist/esm/mcp/services/mcp-server.backend.service.js +131 -3
  175. package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
  176. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts +64 -2
  177. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
  178. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +130 -6
  179. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
  180. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +9 -0
  181. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
  182. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +11 -36
  183. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
  184. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  185. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +9 -7
  186. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
  187. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts +5 -5
  188. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
  189. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js +14 -13
  190. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js.map +1 -1
  191. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts +2 -1
  192. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
  193. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +2 -2
  194. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
  195. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
  196. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +9 -7
  197. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
  198. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
  199. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js +4 -1
  200. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js.map +1 -1
  201. package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
  202. package/dist/esm/requests/service/websocket.service.js +56 -7
  203. package/dist/esm/requests/service/websocket.service.js.map +1 -1
  204. package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
  205. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
  206. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
  207. package/dist/esm/resources/services/resource-id.backend.service.js +3 -3
  208. package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -1
  209. package/dist/esm/resources/services/resources-registry.backend.service.js +1 -1
  210. package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
  211. package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
  212. package/dist/esm/runtime/services/execution-context-creator.backend.service.js +13 -7
  213. package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
  214. package/dist/esm/runtime/services/start-application.backend.service.d.ts +28 -0
  215. package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
  216. package/dist/esm/runtime/services/start-application.backend.service.js +82 -0
  217. package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
  218. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +3 -23
  219. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
  220. package/dist/esm/security/authentications/models/jwt.backend.schemas.js +20 -45
  221. package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -1
  222. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +9 -1
  223. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
  224. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +9 -1
  225. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
  226. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
  227. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +5 -3
  228. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -1
  229. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +25 -1
  230. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
  231. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +55 -4
  232. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
  233. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
  234. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js +24 -1
  235. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js.map +1 -1
  236. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts +117 -0
  237. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -0
  238. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js +104 -0
  239. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js.map +1 -0
  240. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +101 -6
  241. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
  242. package/dist/esm/security/authorizations/services/authorizations.backend.service.js +210 -30
  243. package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
  244. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +18 -1
  245. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
  246. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +110 -74
  247. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -1
  248. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts +22 -0
  249. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -0
  250. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js +22 -0
  251. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js.map +1 -0
  252. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +17 -3
  253. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
  254. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +12 -0
  255. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -1
  256. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +20 -0
  257. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
  258. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +58 -5
  259. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
  260. package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
  261. package/dist/esm/security/jwt/services/jwt.backend.service.js +1 -18
  262. package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -1
  263. package/dist/tsconfig.build.tsbuildinfo +1 -1
  264. package/package.json +15 -9
  265. package/dist/esm/.builder.pid +0 -9
@@ -1,10 +1,17 @@
1
1
  /**
2
2
  * Agent Client Protocol session runner.
3
3
  *
4
- * Drives one coding turn: spawn the agent, negotiate `initialize`, open a
5
- * session against a confined working directory, send one `session/prompt`, and
6
- * settle when the agent reports a stop reason — answering the agent's callbacks
7
- * along the way.
4
+ * Two shapes over one transport:
5
+ *
6
+ * - {@link startACPAgentSession} opens a LIVE session — spawn the agent,
7
+ * negotiate `initialize`, open (or `session/load`-resume) a session against a
8
+ * confined working directory — and returns a handle whose `promptTurn` drives
9
+ * ONE turn at a time. The caller decides whether to send another prompt on
10
+ * the same session, which is what makes the interactive/continuation lane
11
+ * possible: a turn that ended with a question is answered by the next
12
+ * `promptTurn`, on the same `sessionId`, with the agent's context intact.
13
+ * - {@link runACPCodingSession} is the single-turn wrapper kept for every
14
+ * existing caller: start, one turn, close.
8
15
  *
9
16
  * # Why the transport is written here rather than taken from a package
10
17
  *
@@ -86,19 +93,6 @@ const PERMISSION_DECISION_RECORD_LIMIT = 200;
86
93
  * {@link permissionAllowedByCeiling}, where the ceiling means what it says —
87
94
  * and where the caller's mutation scope can still refuse a path.
88
95
  */
89
- const PREFERRED_MODE_IDS = {
90
- [AgentClientProtocol_PermissionCeiling.PROMPT_ALWAYS]: ['default'],
91
- // Same reasoning as every other ceiling: the read-only lane is expressed by ANSWERING the
92
- // permission requests, never by asking the agent to stop raising them. An agent mode that
93
- // pre-approves reads on the agent's side would decide which calls count as reads, which is the
94
- // decision this runner exists to keep.
95
- [AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS]: ['default'],
96
- [AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_EDITS]: ['default'],
97
- // Even here: an ungated ceiling is expressed by ANSWERING yes, not by asking
98
- // the agent to stop reporting. The event stream stays complete, so a run is
99
- // still auditable after the fact.
100
- [AgentClientProtocol_PermissionCeiling.UNRESTRICTED]: ['default'],
101
- };
102
96
  /** Tool kinds that count as an EDIT for the AUTO_ACCEPT_EDITS ceiling. */
103
97
  const EDIT_TOOL_KINDS = new Set(['edit', 'delete', 'move']);
104
98
  /**
@@ -141,6 +135,12 @@ export function permissionAllowedByCeiling(ceiling, toolKind) {
141
135
  // agent's own `acceptEdits` mode made `execute` bypass this branch
142
136
  // entirely, measured live.
143
137
  return toolKind !== undefined && EDIT_TOOL_KINDS.has(toolKind);
138
+ case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS_AND_EDITS:
139
+ // The union of the two sets above, refusing exactly what both refuse:
140
+ // `execute` (a command can mutate anything) and `other` (unclassified,
141
+ // fail-closed). The evidence-persisting research lane's ceiling — the
142
+ // location predicate is what keeps its writes inside the store.
143
+ return toolKind !== undefined && (NON_MUTATING_TOOL_KINDS.has(toolKind) || EDIT_TOOL_KINDS.has(toolKind));
144
144
  case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS:
145
145
  /*
146
146
  * Non-mutating kinds are pre-approved; everything else is denied rather than guessed — the
@@ -233,14 +233,23 @@ export function isPathWithin(root, candidate) {
233
233
  return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
234
234
  });
235
235
  }
236
- export async function runACPCodingSession(options) {
236
+ /**
237
+ * Open a live ACP session and return a handle whose `promptTurn` drives one
238
+ * turn at a time.
239
+ *
240
+ * The caller owns the turn cadence — this is the whole point of the handle. A
241
+ * turn that ends with a question is not the end of the session; the caller
242
+ * inspects it and may `promptTurn` again with the answer.
243
+ */
244
+ export async function startACPAgentSession(options) {
237
245
  const maxRecordedEventBytes = options.maxRecordedEventBytes ?? DEFAULT_MAX_RECORDED_EVENT_BYTES;
238
246
  const child = spawn(options.command, [...(options.args ?? [])], {
239
247
  cwd: options.cwd,
240
248
  env: options.env,
241
249
  stdio: ['pipe', 'pipe', 'pipe'],
242
250
  });
243
- const state = {
251
+ // Cumulative session state. Per-turn slices are taken from these by index.
252
+ const session = {
244
253
  nextId: 1,
245
254
  buffer: '',
246
255
  stderrTail: '',
@@ -248,12 +257,20 @@ export async function runACPCodingSession(options) {
248
257
  events: [],
249
258
  recordedBytes: 0,
250
259
  eventsTruncated: false,
251
- finalMessage: '',
252
- reportedFileLocations: new Set(),
253
- lastUsageUpdate: undefined,
254
- deniedPermissionCount: 0,
260
+ reportedFileLocations: [],
255
261
  permissionDecisions: [],
256
- settled: false,
262
+ deniedPermissionCount: 0,
263
+ // Reset at the start of each turn.
264
+ turnFinalMessage: '',
265
+ turnLastUsageUpdate: undefined,
266
+ // True while `session/load` replay is streaming: replayed history is
267
+ // consumed and discarded (it is already on the durable record).
268
+ replaying: false,
269
+ // Set once the child exits; a later `promptTurn` refuses rather than hanging.
270
+ childExited: false,
271
+ // Set BEFORE a deliberate terminate() so the exit handler does not reject
272
+ // the exit promise for a shutdown the caller asked for.
273
+ closed: false,
257
274
  };
258
275
  const pending = new Map();
259
276
  const write = (payload) => {
@@ -261,7 +278,7 @@ export async function runACPCodingSession(options) {
261
278
  child.stdin.write(`${JSON.stringify(payload)}\n`);
262
279
  };
263
280
  const request = (method, params) => {
264
- const id = state.nextId++;
281
+ const id = session.nextId++;
265
282
  return new Promise((resolvePromise, rejectPromise) => {
266
283
  pending.set(id, { resolve: resolvePromise, reject: rejectPromise });
267
284
  write({ jsonrpc: '2.0', id, method, params });
@@ -270,17 +287,22 @@ export async function runACPCodingSession(options) {
270
287
  const respond = (id, result) => write({ jsonrpc: '2.0', id, result });
271
288
  const respondError = (id, message) => write({ jsonrpc: '2.0', id, error: { code: -32603, message } });
272
289
  const recordEvent = (event) => {
273
- if (!state.eventsTruncated) {
290
+ // Replayed `session/load` history is neither persisted nor forwarded: it is
291
+ // already recorded from the run that produced it, and re-emitting it would
292
+ // double every earlier frame on the resuming run's record.
293
+ if (session.replaying)
294
+ return;
295
+ if (!session.eventsTruncated) {
274
296
  const size = JSON.stringify(event).length;
275
- if (state.recordedBytes + size > maxRecordedEventBytes) {
297
+ if (session.recordedBytes + size > maxRecordedEventBytes) {
276
298
  // Truncate, never reject. Losing the tail of a transcript is a reporting
277
299
  // loss; failing the run here would discard work already written to the
278
300
  // workspace, which is the mistake the transport this replaces made.
279
- state.eventsTruncated = true;
301
+ session.eventsTruncated = true;
280
302
  }
281
303
  else {
282
- state.recordedBytes += size;
283
- state.events.push(event);
304
+ session.recordedBytes += size;
305
+ session.events.push(event);
284
306
  }
285
307
  }
286
308
  try {
@@ -299,9 +321,9 @@ export async function runACPCodingSession(options) {
299
321
  const rawOptions = Array.isArray(params.options) ? params.options : [];
300
322
  const offeredOptionKinds = rawOptions.flatMap((entry) => (isRecord(entry) && typeof entry.kind === 'string' ? [entry.kind] : []));
301
323
  const record = (allowed, reason) => {
302
- if (state.permissionDecisions.length >= PERMISSION_DECISION_RECORD_LIMIT)
324
+ if (session.permissionDecisions.length >= PERMISSION_DECISION_RECORD_LIMIT)
303
325
  return;
304
- state.permissionDecisions.push({
326
+ session.permissionDecisions.push({
305
327
  allowed,
306
328
  reason,
307
329
  ...(toolKind !== undefined ? { toolKind } : {}),
@@ -339,7 +361,7 @@ export async function runACPCodingSession(options) {
339
361
  respond(id, { outcome: { outcome: 'selected', optionId: decision.optionId } });
340
362
  return;
341
363
  }
342
- state.deniedPermissionCount++;
364
+ session.deniedPermissionCount++;
343
365
  const rawOptions = Array.isArray(params.options) ? params.options : [];
344
366
  const reject = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'reject_once');
345
367
  if (isRecord(reject) && typeof reject.optionId === 'string') {
@@ -412,7 +434,7 @@ export async function runACPCodingSession(options) {
412
434
  * frames are excluded by construction: they parse, so they never reach this branch, and the
413
435
  * tail cannot fill with the session's own traffic.
414
436
  */
415
- state.unparsedStdoutTail = `${state.unparsedStdoutTail}${line}\n`.slice(-4_000);
437
+ session.unparsedStdoutTail = `${session.unparsedStdoutTail}${line}\n`.slice(-4_000);
416
438
  return;
417
439
  }
418
440
  if (!isRecord(message))
@@ -420,18 +442,21 @@ export async function runACPCodingSession(options) {
420
442
  if (message.method === 'session/update') {
421
443
  const update = isRecord(message.params) && isRecord(message.params.update) ? message.params.update : {};
422
444
  const kind = typeof update.sessionUpdate === 'string' ? update.sessionUpdate : 'unknown';
423
- if (kind === 'agent_message_chunk') {
424
- const content = isRecord(update.content) ? update.content : {};
425
- if (typeof content.text === 'string')
426
- state.finalMessage += content.text;
427
- }
428
- if (kind === 'usage_update')
429
- state.lastUsageUpdate = update;
430
- if (kind === 'tool_call' || kind === 'tool_call_update') {
431
- if (Array.isArray(update.locations)) {
432
- for (const entry of update.locations) {
433
- if (isRecord(entry) && typeof entry.path === 'string')
434
- state.reportedFileLocations.add(entry.path);
445
+ if (!session.replaying) {
446
+ if (kind === 'agent_message_chunk') {
447
+ const content = isRecord(update.content) ? update.content : {};
448
+ if (typeof content.text === 'string')
449
+ session.turnFinalMessage += content.text;
450
+ }
451
+ if (kind === 'usage_update')
452
+ session.turnLastUsageUpdate = update;
453
+ if (kind === 'tool_call' || kind === 'tool_call_update') {
454
+ if (Array.isArray(update.locations)) {
455
+ for (const entry of update.locations) {
456
+ if (isRecord(entry) && typeof entry.path === 'string' && !session.reportedFileLocations.includes(entry.path)) {
457
+ session.reportedFileLocations.push(entry.path);
458
+ }
459
+ }
435
460
  }
436
461
  }
437
462
  }
@@ -445,28 +470,44 @@ export async function runACPCodingSession(options) {
445
470
  if (typeof message.id === 'number' && pending.has(message.id)) {
446
471
  const waiter = pending.get(message.id);
447
472
  pending.delete(message.id);
448
- if (message.error !== undefined)
449
- waiter.reject(message.error);
473
+ if (message.error !== undefined) {
474
+ /*
475
+ * A JSON-RPC error is an OBJECT ({code, message, data?}), and rejecting with it raw is how a
476
+ * real adapter answer became "[object Object]" at the choreography seam and "Unknown agent
477
+ * invocation error" in the trace — three layers each normalizing for Error-or-string and
478
+ * discarding everything else. The adapter names its failures; carry the name. (Found
479
+ * 2026-09-03: a research turn's session/prompt error cost a full diagnosis cycle because all
480
+ * that survived was the coercion.)
481
+ */
482
+ const rpcError = message.error;
483
+ const detail = typeof rpcError?.message === 'string' ? rpcError.message : JSON.stringify(message.error)?.slice(0, 500);
484
+ const rejection = new Error(`ACP agent error${typeof rpcError?.code === 'number' ? ` ${rpcError.code}` : ''}: ${detail}`);
485
+ rejection.acpError = message.error;
486
+ waiter.reject(rejection);
487
+ }
450
488
  else
451
489
  waiter.resolve(message.result);
452
490
  }
453
491
  };
454
492
  child.stdout.setEncoding('utf8');
455
493
  child.stdout.on('data', (chunk) => {
456
- state.buffer += chunk;
494
+ session.buffer += chunk;
457
495
  let index;
458
- while ((index = state.buffer.indexOf('\n')) >= 0) {
459
- const line = state.buffer.slice(0, index).trim();
460
- state.buffer = state.buffer.slice(index + 1);
496
+ while ((index = session.buffer.indexOf('\n')) >= 0) {
497
+ const line = session.buffer.slice(0, index).trim();
498
+ session.buffer = session.buffer.slice(index + 1);
461
499
  if (line)
462
500
  onLine(line);
463
501
  }
464
502
  });
465
503
  child.stderr.setEncoding('utf8');
466
504
  child.stderr.on('data', (chunk) => {
467
- state.stderrTail = `${state.stderrTail}${chunk}`.slice(-4_000);
505
+ session.stderrTail = `${session.stderrTail}${chunk}`.slice(-4_000);
468
506
  });
469
507
  const terminate = () => {
508
+ // Mark the shutdown as deliberate BEFORE killing so the exit handler does
509
+ // not reject the exit promise for a close the caller asked for.
510
+ session.closed = true;
470
511
  if (!child.killed)
471
512
  child.kill('SIGTERM');
472
513
  setTimeout(() => {
@@ -476,15 +517,24 @@ export async function runACPCodingSession(options) {
476
517
  };
477
518
  const failed = (message, details) => new ACPSessionRunnerError(message, {
478
519
  ...details,
479
- stderrTail: state.stderrTail.trim().slice(-1_000),
480
- stdoutTail: state.unparsedStdoutTail.trim().slice(-1_000),
520
+ stderrTail: session.stderrTail.trim().slice(-1_000),
521
+ stdoutTail: session.unparsedStdoutTail.trim().slice(-1_000),
481
522
  });
482
- const spawnFailure = new Promise((_, rejectPromise) => {
483
- child.on('error', (error) => rejectPromise(failed(`Agent process failed to start: ${error.message}`, {})));
523
+ // ONE persistent "the child died" promise, raced against every awaited
524
+ // request. It rejects at most once, only for an UNDELIBERATE exit — a close()
525
+ // the caller asked for sets `closed` first and leaves it pending. Raced at
526
+ // `initialize`, so it always carries a rejection handler and a later reject
527
+ // (e.g. a crash between turns) never surfaces as an unhandled rejection.
528
+ const exitPromise = new Promise((_, rejectPromise) => {
529
+ child.on('error', (error) => {
530
+ session.childExited = true;
531
+ if (!session.closed)
532
+ rejectPromise(failed(`Agent process failed to start: ${error.message}`, {}));
533
+ });
484
534
  child.on('exit', (code, signal) => {
485
- if (!state.settled) {
535
+ session.childExited = true;
536
+ if (!session.closed)
486
537
  rejectPromise(failed('Agent process exited before the turn completed', { exitCode: code, signal }));
487
- }
488
538
  });
489
539
  });
490
540
  try {
@@ -502,7 +552,7 @@ export async function runACPCodingSession(options) {
502
552
  terminal: false,
503
553
  },
504
554
  }),
505
- spawnFailure,
555
+ exitPromise,
506
556
  ]);
507
557
  if (!isRecord(initializeResult)) {
508
558
  throw failed('Agent returned a malformed initialize result', { initializeResult });
@@ -517,100 +567,211 @@ export async function runACPCodingSession(options) {
517
567
  });
518
568
  }
519
569
  const agentInfo = isRecord(initializeResult.agentInfo) ? initializeResult.agentInfo : {};
520
- // --- session/new --------------------------------------------------------
521
- const sessionResult = await Promise.race([
522
- request('session/new', {
523
- cwd: options.cwd,
524
- mcpServers: [],
525
- ...(options.sessionMetaExtensions ? { _meta: options.sessionMetaExtensions } : {}),
526
- }),
527
- spawnFailure,
528
- ]);
529
- if (!isRecord(sessionResult) || typeof sessionResult.sessionId !== 'string') {
530
- throw failed('Agent returned a malformed session/new result', { sessionResult });
531
- }
532
- const sessionId = sessionResult.sessionId;
533
- // --- best-effort mode selection (an optimisation, never the guarantee) ---
570
+ const agentCapabilities = isRecord(initializeResult.agentCapabilities) ? initializeResult.agentCapabilities : {};
571
+ const loadSessionSupported = agentCapabilities.loadSession === true;
572
+ let sessionId;
534
573
  let sessionModeId;
535
- const modes = isRecord(sessionResult.modes) ? sessionResult.modes : undefined;
536
- const available = modes && Array.isArray(modes.availableModes) ? modes.availableModes : [];
537
- const preferred = PREFERRED_MODE_IDS[options.permissionCeiling] ?? [];
538
- const match = available.find((entry) => isRecord(entry) && typeof entry.id === 'string' && preferred.includes(entry.id));
539
- if (isRecord(match) && typeof match.id === 'string') {
540
- try {
541
- // Raced against the death signal: before this, a `session/set_mode` sent
542
- // to an agent that then died left a promise nobody would ever settle,
543
- // with the turn timeout not yet armed — the run hung forever.
544
- await Promise.race([request('session/set_mode', { sessionId, modeId: match.id }), spawnFailure]);
545
- sessionModeId = match.id;
574
+ if (options.resumeSessionId !== undefined) {
575
+ // --- session/load (resume) -------------------------------------------
576
+ if (!loadSessionSupported) {
577
+ // Refused, not degraded. Starting a fresh session here would present a
578
+ // context-less turn as a continuation of a parked one.
579
+ throw failed('Agent does not advertise the loadSession capability; cannot resume the session', {
580
+ resumeSessionId: options.resumeSessionId,
581
+ });
546
582
  }
547
- catch {
548
- // The ceiling is still enforced by the permission handler, so a mode we
549
- // could not set costs round-trips, not safety.
550
- sessionModeId = undefined;
583
+ session.replaying = true;
584
+ await Promise.race([
585
+ request('session/load', {
586
+ sessionId: options.resumeSessionId,
587
+ cwd: options.cwd,
588
+ mcpServers: [],
589
+ }),
590
+ exitPromise,
591
+ ]);
592
+ session.replaying = false;
593
+ sessionId = options.resumeSessionId;
594
+ // Modes are reported by session/new, not session/load. The permission
595
+ // handler is the guarantee regardless, so a resumed session simply runs
596
+ // without a reselected mode.
597
+ }
598
+ else {
599
+ // --- session/new ------------------------------------------------------
600
+ const sessionResult = await Promise.race([
601
+ request('session/new', {
602
+ cwd: options.cwd,
603
+ mcpServers: [],
604
+ ...(options.sessionMetaExtensions ? { _meta: options.sessionMetaExtensions } : {}),
605
+ }),
606
+ exitPromise,
607
+ ]);
608
+ if (!isRecord(sessionResult) || typeof sessionResult.sessionId !== 'string') {
609
+ throw failed('Agent returned a malformed session/new result', { sessionResult });
610
+ }
611
+ sessionId = sessionResult.sessionId;
612
+ // --- best-effort mode selection (an optimisation, never the guarantee) -
613
+ const modes = isRecord(sessionResult.modes) ? sessionResult.modes : undefined;
614
+ const available = modes && Array.isArray(modes.availableModes) ? modes.availableModes : [];
615
+ const preferred = options.preferredSessionModeIds ?? [];
616
+ const match = available.find((entry) => isRecord(entry) && typeof entry.id === 'string' && preferred.includes(entry.id));
617
+ if (isRecord(match) && typeof match.id === 'string') {
618
+ try {
619
+ // Raced against the death signal: before this, a `session/set_mode` sent
620
+ // to an agent that then died left a promise nobody would ever settle,
621
+ // with the turn timeout not yet armed — the run hung forever.
622
+ await Promise.race([request('session/set_mode', { sessionId, modeId: match.id }), exitPromise]);
623
+ sessionModeId = match.id;
624
+ }
625
+ catch {
626
+ // The ceiling is still enforced by the permission handler, so a mode we
627
+ // could not set costs round-trips, not safety.
628
+ sessionModeId = undefined;
629
+ }
630
+ }
631
+ else if (typeof modes?.currentModeId === 'string') {
632
+ sessionModeId = modes.currentModeId;
551
633
  }
552
634
  }
553
- else if (typeof modes?.currentModeId === 'string') {
554
- sessionModeId = modes.currentModeId;
635
+ // --- model delivery, when the agent takes it over ACP -------------------
636
+ //
637
+ // Unlike the mode selection above, this is NOT best-effort. A model that
638
+ // could not be set means the agent runs its own default while the run
639
+ // records the model that was requested — a false result rather than a
640
+ // degraded one, which is precisely the failure the provider-declared
641
+ // delivery channel exists to end. So a rejection fails the session before
642
+ // any prompt is sent, i.e. before the agent has touched the workspace.
643
+ if (options.modelSelection) {
644
+ const setModelResult = await Promise.race([
645
+ request('session/set_config_option', {
646
+ sessionId,
647
+ configId: options.modelSelection.configId,
648
+ value: options.modelSelection.model,
649
+ }),
650
+ exitPromise,
651
+ ]).catch((error) => {
652
+ throw failed(`Agent refused the model selection: ${error instanceof Error ? error.message : String(error)}`, { configId: options.modelSelection?.configId, model: options.modelSelection?.model });
653
+ });
654
+ void setModelResult;
555
655
  }
556
- // --- the turn -----------------------------------------------------------
557
- let timedOut = false;
558
- let timer;
559
- const cancelTurn = () => {
560
- write({ jsonrpc: '2.0', method: 'session/cancel', params: { sessionId } });
561
- setTimeout(() => {
562
- if (!state.settled)
563
- terminate();
564
- }, COOPERATIVE_CANCEL_GRACE_MS).unref?.();
656
+ const promptTurn = async (prompt, turnOptions) => {
657
+ if (session.childExited) {
658
+ throw failed('Agent process is no longer running; cannot start a turn', { sessionId });
659
+ }
660
+ // Per-turn slices are the cumulative arrays from this point on.
661
+ const eventStart = session.events.length;
662
+ const permissionStart = session.permissionDecisions.length;
663
+ const deniedStart = session.deniedPermissionCount;
664
+ const fileLocStart = session.reportedFileLocations.length;
665
+ session.turnFinalMessage = '';
666
+ session.turnLastUsageUpdate = undefined;
667
+ let settled = false;
668
+ let timedOut = false;
669
+ let timer;
670
+ const cancelTurn = () => {
671
+ write({ jsonrpc: '2.0', method: 'session/cancel', params: { sessionId } });
672
+ setTimeout(() => {
673
+ if (!settled)
674
+ terminate();
675
+ }, COOPERATIVE_CANCEL_GRACE_MS).unref?.();
676
+ };
677
+ const onAbort = () => cancelTurn();
678
+ const turnPromise = request('session/prompt', {
679
+ sessionId,
680
+ prompt: [{ type: 'text', text: prompt }],
681
+ });
682
+ if (turnOptions?.turnTimeoutMs !== undefined) {
683
+ timer = setTimeout(() => {
684
+ timedOut = true;
685
+ // Cooperative first: ACP requires the agent to answer a cancelled turn
686
+ // with stop reason `cancelled`, which lets the caller distinguish an
687
+ // interrupted run from a completed one. Kill only if it does not.
688
+ cancelTurn();
689
+ }, turnOptions.turnTimeoutMs);
690
+ timer.unref?.();
691
+ }
692
+ if (turnOptions?.abortSignal) {
693
+ if (turnOptions.abortSignal.aborted)
694
+ cancelTurn();
695
+ else
696
+ turnOptions.abortSignal.addEventListener('abort', onAbort, { once: true });
697
+ }
698
+ try {
699
+ const turnResult = await Promise.race([turnPromise, exitPromise]);
700
+ settled = true;
701
+ if (!isRecord(turnResult)) {
702
+ throw failed('Agent returned a malformed session/prompt result', { turnResult, timedOut });
703
+ }
704
+ const { stopReason, rawStopReason } = parseStopReason(turnResult.stopReason);
705
+ return {
706
+ finalMessage: session.turnFinalMessage,
707
+ stopReason,
708
+ ...(rawStopReason ? { rawStopReason } : {}),
709
+ usage: projectUsage(turnResult.usage, session.turnLastUsageUpdate),
710
+ reportedFileLocations: session.reportedFileLocations.slice(fileLocStart),
711
+ events: session.events.slice(eventStart),
712
+ eventsTruncated: session.eventsTruncated,
713
+ deniedPermissionCount: session.deniedPermissionCount - deniedStart,
714
+ permissionDecisions: session.permissionDecisions.slice(permissionStart),
715
+ };
716
+ }
717
+ finally {
718
+ settled = true;
719
+ if (timer)
720
+ clearTimeout(timer);
721
+ turnOptions?.abortSignal?.removeEventListener('abort', onAbort);
722
+ }
565
723
  };
566
- const turnPromise = request('session/prompt', {
567
- sessionId,
568
- prompt: [{ type: 'text', text: options.prompt }],
569
- });
570
- if (options.turnTimeoutMs !== undefined) {
571
- timer = setTimeout(() => {
572
- timedOut = true;
573
- // Cooperative first: ACP requires the agent to answer a cancelled turn
574
- // with stop reason `cancelled`, which lets the caller distinguish an
575
- // interrupted run from a completed one. Kill only if it does not.
576
- cancelTurn();
577
- }, options.turnTimeoutMs);
578
- timer.unref?.();
579
- }
580
- if (options.abortSignal) {
581
- if (options.abortSignal.aborted)
582
- cancelTurn();
583
- else
584
- options.abortSignal.addEventListener('abort', cancelTurn, { once: true });
585
- }
586
- const turnResult = await Promise.race([turnPromise, spawnFailure]);
587
- if (timer)
588
- clearTimeout(timer);
589
- state.settled = true;
590
- if (!isRecord(turnResult)) {
591
- throw failed('Agent returned a malformed session/prompt result', { turnResult, timedOut });
592
- }
593
- const { stopReason, rawStopReason } = parseStopReason(turnResult.stopReason);
594
724
  return {
595
- finalMessage: state.finalMessage,
596
- stopReason,
597
- ...(rawStopReason ? { rawStopReason } : {}),
598
- usage: projectUsage(turnResult.usage, state.lastUsageUpdate),
599
- reportedFileLocations: [...state.reportedFileLocations],
600
725
  sessionId,
601
726
  negotiatedProtocolVersion,
602
727
  ...(typeof agentInfo.name === 'string' ? { agentName: agentInfo.name } : {}),
603
728
  ...(typeof agentInfo.version === 'string' ? { agentVersion: agentInfo.version } : {}),
604
729
  ...(sessionModeId ? { sessionModeId } : {}),
605
- events: state.events,
606
- eventsTruncated: state.eventsTruncated,
607
- deniedPermissionCount: state.deniedPermissionCount,
608
- permissionDecisions: state.permissionDecisions,
730
+ capabilities: { loadSession: loadSessionSupported },
731
+ promptTurn,
732
+ close: terminate,
609
733
  };
610
734
  }
611
- finally {
612
- state.settled = true;
735
+ catch (error) {
736
+ // Setup failed: the child must not be left running.
613
737
  terminate();
738
+ throw error;
739
+ }
740
+ }
741
+ /**
742
+ * Drive exactly one coding turn end to end: open a session, send one prompt,
743
+ * settle, and close.
744
+ *
745
+ * The compatibility surface for every caller that does not need the turn
746
+ * cadence. It is a thin composition of {@link startACPAgentSession} +
747
+ * `promptTurn` + `close`, so its behaviour tracks the handle by construction.
748
+ */
749
+ export async function runACPCodingSession(options) {
750
+ const agentSession = await startACPAgentSession(options);
751
+ try {
752
+ const turn = await agentSession.promptTurn(options.prompt, {
753
+ ...(options.turnTimeoutMs !== undefined ? { turnTimeoutMs: options.turnTimeoutMs } : {}),
754
+ ...(options.abortSignal ? { abortSignal: options.abortSignal } : {}),
755
+ });
756
+ return {
757
+ finalMessage: turn.finalMessage,
758
+ stopReason: turn.stopReason,
759
+ ...(turn.rawStopReason ? { rawStopReason: turn.rawStopReason } : {}),
760
+ usage: turn.usage,
761
+ reportedFileLocations: turn.reportedFileLocations,
762
+ sessionId: agentSession.sessionId,
763
+ negotiatedProtocolVersion: agentSession.negotiatedProtocolVersion,
764
+ ...(agentSession.agentName ? { agentName: agentSession.agentName } : {}),
765
+ ...(agentSession.agentVersion ? { agentVersion: agentSession.agentVersion } : {}),
766
+ ...(agentSession.sessionModeId ? { sessionModeId: agentSession.sessionModeId } : {}),
767
+ events: turn.events,
768
+ eventsTruncated: turn.eventsTruncated,
769
+ deniedPermissionCount: turn.deniedPermissionCount,
770
+ permissionDecisions: turn.permissionDecisions,
771
+ };
772
+ }
773
+ finally {
774
+ agentSession.close();
614
775
  }
615
776
  }
616
777
  /** Re-exported so callers reason about ceilings through one ordering definition. */