@alneas/eaos-server 0.0.0-stage → 0.2.0

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 (360) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +49 -0
  4. package/README.md +46 -2
  5. package/dist/agentic/agent-jobs.d.ts +333 -0
  6. package/dist/agentic/agent-jobs.js +15 -0
  7. package/dist/agentic/agent-jobs.js.map +1 -0
  8. package/dist/agentic/agent-node.d.ts +40 -0
  9. package/dist/agentic/agent-node.js +7 -0
  10. package/dist/agentic/agent-node.js.map +1 -0
  11. package/dist/agentic/agent-runner.d.ts +33 -0
  12. package/dist/agentic/agent-runner.js +7 -0
  13. package/dist/agentic/agent-runner.js.map +1 -0
  14. package/dist/agentic/ai-broker.d.ts +169 -0
  15. package/dist/agentic/ai-broker.js +8 -0
  16. package/dist/agentic/ai-broker.js.map +1 -0
  17. package/dist/agentic/atomic-checkpointer.d.ts +137 -0
  18. package/dist/agentic/atomic-checkpointer.js +9 -0
  19. package/dist/agentic/atomic-checkpointer.js.map +1 -0
  20. package/dist/agentic/autonomous-worker.d.ts +122 -0
  21. package/dist/agentic/autonomous-worker.js +10 -0
  22. package/dist/agentic/autonomous-worker.js.map +1 -0
  23. package/dist/agentic/event-bridge.d.ts +350 -0
  24. package/dist/agentic/event-bridge.js +9 -0
  25. package/dist/agentic/event-bridge.js.map +1 -0
  26. package/dist/agentic/executor.d.ts +91 -0
  27. package/dist/agentic/executor.js +12 -0
  28. package/dist/agentic/executor.js.map +1 -0
  29. package/dist/agentic/graph-projection.d.ts +119 -0
  30. package/dist/agentic/graph-projection.js +7 -0
  31. package/dist/agentic/graph-projection.js.map +1 -0
  32. package/dist/agentic/graph.d.ts +524 -0
  33. package/dist/agentic/graph.js +7 -0
  34. package/dist/agentic/graph.js.map +1 -0
  35. package/dist/agentic/index.d.ts +28 -0
  36. package/dist/agentic/index.js +87 -0
  37. package/dist/agentic/index.js.map +1 -0
  38. package/dist/agentic/local-runner.d.ts +106 -0
  39. package/dist/agentic/local-runner.js +7 -0
  40. package/dist/agentic/local-runner.js.map +1 -0
  41. package/dist/agentic/remote-executor.d.ts +67 -0
  42. package/dist/agentic/remote-executor.js +8 -0
  43. package/dist/agentic/remote-executor.js.map +1 -0
  44. package/dist/agentic/types.d.ts +157 -0
  45. package/dist/agentic/types.js +7 -0
  46. package/dist/agentic/types.js.map +1 -0
  47. package/dist/agentic/workflow-catalog.d.ts +152 -0
  48. package/dist/agentic/workflow-catalog.js +7 -0
  49. package/dist/agentic/workflow-catalog.js.map +1 -0
  50. package/dist/agentic/workflow-compiler.d.ts +44 -0
  51. package/dist/agentic/workflow-compiler.js +8 -0
  52. package/dist/agentic/workflow-compiler.js.map +1 -0
  53. package/dist/agentic/workflow-coordinator.d.ts +170 -0
  54. package/dist/agentic/workflow-coordinator.js +8 -0
  55. package/dist/agentic/workflow-coordinator.js.map +1 -0
  56. package/dist/agentic/workflow-manager.d.ts +91 -0
  57. package/dist/agentic/workflow-manager.js +7 -0
  58. package/dist/agentic/workflow-manager.js.map +1 -0
  59. package/dist/agentic/workflow-registry.d.ts +334 -0
  60. package/dist/agentic/workflow-registry.js +7 -0
  61. package/dist/agentic/workflow-registry.js.map +1 -0
  62. package/dist/artifacts-CteHmCMI.d.ts +614 -0
  63. package/dist/auth-hooks/api-key.d.ts +75 -0
  64. package/dist/auth-hooks/api-key.js +7 -0
  65. package/dist/auth-hooks/api-key.js.map +1 -0
  66. package/dist/auth-hooks/index.d.ts +80 -0
  67. package/dist/auth-hooks/index.js +28 -0
  68. package/dist/auth-hooks/index.js.map +1 -0
  69. package/dist/browser-auth/account-memberships.d.ts +213 -0
  70. package/dist/browser-auth/account-memberships.js +13 -0
  71. package/dist/browser-auth/account-memberships.js.map +1 -0
  72. package/dist/browser-auth/index.d.ts +8 -0
  73. package/dist/browser-auth/index.js +59 -0
  74. package/dist/browser-auth/index.js.map +1 -0
  75. package/dist/browser-auth/kratos-session.d.ts +37 -0
  76. package/dist/browser-auth/kratos-session.js +7 -0
  77. package/dist/browser-auth/kratos-session.js.map +1 -0
  78. package/dist/browser-auth/platform-session.d.ts +120 -0
  79. package/dist/browser-auth/platform-session.js +7 -0
  80. package/dist/browser-auth/platform-session.js.map +1 -0
  81. package/dist/browser-auth/public-memberships.d.ts +22 -0
  82. package/dist/browser-auth/public-memberships.js +7 -0
  83. package/dist/browser-auth/public-memberships.js.map +1 -0
  84. package/dist/cache/index.d.ts +181 -0
  85. package/dist/cache/index.js +197 -0
  86. package/dist/cache/index.js.map +1 -0
  87. package/dist/chunk-32746UQZ.js +131 -0
  88. package/dist/chunk-32746UQZ.js.map +1 -0
  89. package/dist/chunk-3NLSWP2Y.js +223 -0
  90. package/dist/chunk-3NLSWP2Y.js.map +1 -0
  91. package/dist/chunk-3P4XTTQH.js +346 -0
  92. package/dist/chunk-3P4XTTQH.js.map +1 -0
  93. package/dist/chunk-3VITSHN3.js +15 -0
  94. package/dist/chunk-3VITSHN3.js.map +1 -0
  95. package/dist/chunk-46UWPEW2.js +226 -0
  96. package/dist/chunk-46UWPEW2.js.map +1 -0
  97. package/dist/chunk-4BARRLJR.js +180 -0
  98. package/dist/chunk-4BARRLJR.js.map +1 -0
  99. package/dist/chunk-4VORUFKR.js +45 -0
  100. package/dist/chunk-4VORUFKR.js.map +1 -0
  101. package/dist/chunk-55D4ERWO.js +1 -0
  102. package/dist/chunk-55D4ERWO.js.map +1 -0
  103. package/dist/chunk-5TBBZIND.js +18 -0
  104. package/dist/chunk-5TBBZIND.js.map +1 -0
  105. package/dist/chunk-5WOZWPZA.js +211 -0
  106. package/dist/chunk-5WOZWPZA.js.map +1 -0
  107. package/dist/chunk-6CBVZ6CT.js +168 -0
  108. package/dist/chunk-6CBVZ6CT.js.map +1 -0
  109. package/dist/chunk-6XZXYNJR.js +74 -0
  110. package/dist/chunk-6XZXYNJR.js.map +1 -0
  111. package/dist/chunk-753HWDSC.js +222 -0
  112. package/dist/chunk-753HWDSC.js.map +1 -0
  113. package/dist/chunk-7AHSS7SO.js +81 -0
  114. package/dist/chunk-7AHSS7SO.js.map +1 -0
  115. package/dist/chunk-7FTJN4SA.js +1 -0
  116. package/dist/chunk-7FTJN4SA.js.map +1 -0
  117. package/dist/chunk-AVDMLTPF.js +24 -0
  118. package/dist/chunk-AVDMLTPF.js.map +1 -0
  119. package/dist/chunk-BKAHUEIT.js +95 -0
  120. package/dist/chunk-BKAHUEIT.js.map +1 -0
  121. package/dist/chunk-CJ7OFEF7.js +134 -0
  122. package/dist/chunk-CJ7OFEF7.js.map +1 -0
  123. package/dist/chunk-EJKWDZIU.js +111 -0
  124. package/dist/chunk-EJKWDZIU.js.map +1 -0
  125. package/dist/chunk-F2J6IQ6I.js +247 -0
  126. package/dist/chunk-F2J6IQ6I.js.map +1 -0
  127. package/dist/chunk-F3O7CELI.js +23 -0
  128. package/dist/chunk-F3O7CELI.js.map +1 -0
  129. package/dist/chunk-F4IITPGX.js +221 -0
  130. package/dist/chunk-F4IITPGX.js.map +1 -0
  131. package/dist/chunk-FD6VC2NA.js +66 -0
  132. package/dist/chunk-FD6VC2NA.js.map +1 -0
  133. package/dist/chunk-FRRRWAHO.js +14 -0
  134. package/dist/chunk-FRRRWAHO.js.map +1 -0
  135. package/dist/chunk-HCKAGLLB.js +17 -0
  136. package/dist/chunk-HCKAGLLB.js.map +1 -0
  137. package/dist/chunk-HVC7FG6B.js +191 -0
  138. package/dist/chunk-HVC7FG6B.js.map +1 -0
  139. package/dist/chunk-HXFVOR7Z.js +496 -0
  140. package/dist/chunk-HXFVOR7Z.js.map +1 -0
  141. package/dist/chunk-IJWYS2PF.js +122 -0
  142. package/dist/chunk-IJWYS2PF.js.map +1 -0
  143. package/dist/chunk-INCHXAFK.js +1395 -0
  144. package/dist/chunk-INCHXAFK.js.map +1 -0
  145. package/dist/chunk-JT6BRGQM.js +1 -0
  146. package/dist/chunk-JT6BRGQM.js.map +1 -0
  147. package/dist/chunk-L6PMAEMB.js +115 -0
  148. package/dist/chunk-L6PMAEMB.js.map +1 -0
  149. package/dist/chunk-LOUGW6MU.js +126 -0
  150. package/dist/chunk-LOUGW6MU.js.map +1 -0
  151. package/dist/chunk-LYPZPE53.js +129 -0
  152. package/dist/chunk-LYPZPE53.js.map +1 -0
  153. package/dist/chunk-NNCCN7JP.js +186 -0
  154. package/dist/chunk-NNCCN7JP.js.map +1 -0
  155. package/dist/chunk-PBC3MZUL.js +212 -0
  156. package/dist/chunk-PBC3MZUL.js.map +1 -0
  157. package/dist/chunk-R4ADP2DC.js +20 -0
  158. package/dist/chunk-R4ADP2DC.js.map +1 -0
  159. package/dist/chunk-RHN4Y6VS.js +44 -0
  160. package/dist/chunk-RHN4Y6VS.js.map +1 -0
  161. package/dist/chunk-SDJNYPYK.js +770 -0
  162. package/dist/chunk-SDJNYPYK.js.map +1 -0
  163. package/dist/chunk-UGNTCOVR.js +28 -0
  164. package/dist/chunk-UGNTCOVR.js.map +1 -0
  165. package/dist/chunk-VC2PCK2S.js +31 -0
  166. package/dist/chunk-VC2PCK2S.js.map +1 -0
  167. package/dist/chunk-VF5YDZJC.js +305 -0
  168. package/dist/chunk-VF5YDZJC.js.map +1 -0
  169. package/dist/chunk-VISRDVTK.js +675 -0
  170. package/dist/chunk-VISRDVTK.js.map +1 -0
  171. package/dist/chunk-W6O3LVBY.js +102 -0
  172. package/dist/chunk-W6O3LVBY.js.map +1 -0
  173. package/dist/chunk-WFEAKJLR.js +47 -0
  174. package/dist/chunk-WFEAKJLR.js.map +1 -0
  175. package/dist/chunk-XIEY2OF4.js +67 -0
  176. package/dist/chunk-XIEY2OF4.js.map +1 -0
  177. package/dist/chunk-XITLHDG3.js +37 -0
  178. package/dist/chunk-XITLHDG3.js.map +1 -0
  179. package/dist/chunk-XMWPYZWZ.js +61 -0
  180. package/dist/chunk-XMWPYZWZ.js.map +1 -0
  181. package/dist/chunk-XUP6CNOM.js +34 -0
  182. package/dist/chunk-XUP6CNOM.js.map +1 -0
  183. package/dist/chunk-YABTQZDJ.js +25 -0
  184. package/dist/chunk-YABTQZDJ.js.map +1 -0
  185. package/dist/chunk-YMHVRBUU.js +199 -0
  186. package/dist/chunk-YMHVRBUU.js.map +1 -0
  187. package/dist/chunk-YMJ7BRKU.js +510 -0
  188. package/dist/chunk-YMJ7BRKU.js.map +1 -0
  189. package/dist/chunk-ZC3XWU7B.js +28 -0
  190. package/dist/chunk-ZC3XWU7B.js.map +1 -0
  191. package/dist/chunk-ZHMTD5KV.js +90 -0
  192. package/dist/chunk-ZHMTD5KV.js.map +1 -0
  193. package/dist/chunk-ZWZDLOE7.js +160 -0
  194. package/dist/chunk-ZWZDLOE7.js.map +1 -0
  195. package/dist/db-package/db/local-first-sqlite-adapter.d.ts +432 -0
  196. package/dist/db-package/db/local-first-sqlite-adapter.js +7 -0
  197. package/dist/db-package/db/local-first-sqlite-adapter.js.map +1 -0
  198. package/dist/db-package/index.d.ts +7 -0
  199. package/dist/db-package/index.js +16 -0
  200. package/dist/db-package/index.js.map +1 -0
  201. package/dist/db-package/migration/aggregator.d.ts +86 -0
  202. package/dist/db-package/migration/aggregator.js +7 -0
  203. package/dist/db-package/migration/aggregator.js.map +1 -0
  204. package/dist/db-package/migration/index.d.ts +3 -0
  205. package/dist/db-package/migration/index.js +8 -0
  206. package/dist/db-package/migration/index.js.map +1 -0
  207. package/dist/engine.d.ts +205 -0
  208. package/dist/engine.js +20 -0
  209. package/dist/engine.js.map +1 -0
  210. package/dist/entitlements/index.d.ts +313 -0
  211. package/dist/entitlements/index.js +23 -0
  212. package/dist/entitlements/index.js.map +1 -0
  213. package/dist/execution/chat.d.ts +7 -0
  214. package/dist/execution/chat.js +7 -0
  215. package/dist/execution/chat.js.map +1 -0
  216. package/dist/execution/index.d.ts +342 -0
  217. package/dist/execution/index.js +66 -0
  218. package/dist/execution/index.js.map +1 -0
  219. package/dist/execution/tool-agent.d.ts +7 -0
  220. package/dist/execution/tool-agent.js +8 -0
  221. package/dist/execution/tool-agent.js.map +1 -0
  222. package/dist/extensions/index.d.ts +172 -0
  223. package/dist/extensions/index.js +95 -0
  224. package/dist/extensions/index.js.map +1 -0
  225. package/dist/health/index.d.ts +35 -0
  226. package/dist/health/index.js +7 -0
  227. package/dist/health/index.js.map +1 -0
  228. package/dist/index.d.ts +43 -0
  229. package/dist/index.js +161 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/lifecycle/index.d.ts +133 -0
  232. package/dist/lifecycle/index.js +13 -0
  233. package/dist/lifecycle/index.js.map +1 -0
  234. package/dist/lifecycle-engine/backend-migration.d.ts +2 -0
  235. package/dist/lifecycle-engine/backend-migration.js +11 -0
  236. package/dist/lifecycle-engine/backend-migration.js.map +1 -0
  237. package/dist/lifecycle-engine/baseline.d.ts +2 -0
  238. package/dist/lifecycle-engine/baseline.js +9 -0
  239. package/dist/lifecycle-engine/baseline.js.map +1 -0
  240. package/dist/lifecycle-engine/index.d.ts +1497 -0
  241. package/dist/lifecycle-engine/index.js +41 -0
  242. package/dist/lifecycle-engine/index.js.map +1 -0
  243. package/dist/lifecycle-engine/platform/artifacts.d.ts +4 -0
  244. package/dist/lifecycle-engine/platform/artifacts.js +7 -0
  245. package/dist/lifecycle-engine/platform/artifacts.js.map +1 -0
  246. package/dist/lifecycle-engine/platform/control-plane.d.ts +12 -0
  247. package/dist/lifecycle-engine/platform/control-plane.js +2 -0
  248. package/dist/lifecycle-engine/platform/control-plane.js.map +1 -0
  249. package/dist/lifecycle-engine/platform/database-router.d.ts +118 -0
  250. package/dist/lifecycle-engine/platform/database-router.js +7 -0
  251. package/dist/lifecycle-engine/platform/database-router.js.map +1 -0
  252. package/dist/lifecycle-engine/platform/deployment-placements.d.ts +464 -0
  253. package/dist/lifecycle-engine/platform/deployment-placements.js +16 -0
  254. package/dist/lifecycle-engine/platform/deployment-placements.js.map +1 -0
  255. package/dist/lifecycle-engine/platform/deployment.d.ts +4 -0
  256. package/dist/lifecycle-engine/platform/deployment.js +17 -0
  257. package/dist/lifecycle-engine/platform/deployment.js.map +1 -0
  258. package/dist/lifecycle-engine/platform/index.d.ts +737 -0
  259. package/dist/lifecycle-engine/platform/index.js +60 -0
  260. package/dist/lifecycle-engine/platform/index.js.map +1 -0
  261. package/dist/lifecycle-engine/platform/runtime.d.ts +80 -0
  262. package/dist/lifecycle-engine/platform/runtime.js +11 -0
  263. package/dist/lifecycle-engine/platform/runtime.js.map +1 -0
  264. package/dist/lifecycle-engine/platform/site-publication.d.ts +102 -0
  265. package/dist/lifecycle-engine/platform/site-publication.js +7 -0
  266. package/dist/lifecycle-engine/platform/site-publication.js.map +1 -0
  267. package/dist/lifecycle-engine/platform/user-directory.d.ts +139 -0
  268. package/dist/lifecycle-engine/platform/user-directory.js +13 -0
  269. package/dist/lifecycle-engine/platform/user-directory.js.map +1 -0
  270. package/dist/mcp.d.ts +92 -0
  271. package/dist/mcp.js +10 -0
  272. package/dist/mcp.js.map +1 -0
  273. package/dist/middleware/auth.d.ts +118 -0
  274. package/dist/middleware/auth.js +7 -0
  275. package/dist/middleware/auth.js.map +1 -0
  276. package/dist/middleware/error-handler.d.ts +35 -0
  277. package/dist/middleware/error-handler.js +7 -0
  278. package/dist/middleware/error-handler.js.map +1 -0
  279. package/dist/middleware/module-guard.d.ts +33 -0
  280. package/dist/middleware/module-guard.js +7 -0
  281. package/dist/middleware/module-guard.js.map +1 -0
  282. package/dist/platform-admin/index.d.ts +37 -0
  283. package/dist/platform-admin/index.js +11 -0
  284. package/dist/platform-admin/index.js.map +1 -0
  285. package/dist/platform-admin/store.d.ts +346 -0
  286. package/dist/platform-admin/store.js +7 -0
  287. package/dist/platform-admin/store.js.map +1 -0
  288. package/dist/plugin-data/annotations.d.ts +6 -0
  289. package/dist/plugin-data/annotations.js +12 -0
  290. package/dist/plugin-data/annotations.js.map +1 -0
  291. package/dist/plugin-data/atomic-context.d.ts +41 -0
  292. package/dist/plugin-data/atomic-context.js +9 -0
  293. package/dist/plugin-data/atomic-context.js.map +1 -0
  294. package/dist/plugin-data/atomic.d.ts +6 -0
  295. package/dist/plugin-data/atomic.js +26 -0
  296. package/dist/plugin-data/atomic.js.map +1 -0
  297. package/dist/plugin-data/audit.d.ts +6 -0
  298. package/dist/plugin-data/audit.js +12 -0
  299. package/dist/plugin-data/audit.js.map +1 -0
  300. package/dist/plugin-data/commands.d.ts +6 -0
  301. package/dist/plugin-data/commands.js +8 -0
  302. package/dist/plugin-data/commands.js.map +1 -0
  303. package/dist/plugin-data/composite.d.ts +6 -0
  304. package/dist/plugin-data/composite.js +8 -0
  305. package/dist/plugin-data/composite.js.map +1 -0
  306. package/dist/plugin-data/delivery.d.ts +6 -0
  307. package/dist/plugin-data/delivery.js +16 -0
  308. package/dist/plugin-data/delivery.js.map +1 -0
  309. package/dist/plugin-data/index.d.ts +2798 -0
  310. package/dist/plugin-data/index.js +102 -0
  311. package/dist/plugin-data/index.js.map +1 -0
  312. package/dist/plugin-data/json-documents.d.ts +6 -0
  313. package/dist/plugin-data/json-documents.js +16 -0
  314. package/dist/plugin-data/json-documents.js.map +1 -0
  315. package/dist/plugin-data/outbox.d.ts +6 -0
  316. package/dist/plugin-data/outbox.js +16 -0
  317. package/dist/plugin-data/outbox.js.map +1 -0
  318. package/dist/plugin-data/scoped-records.d.ts +6 -0
  319. package/dist/plugin-data/scoped-records.js +10 -0
  320. package/dist/plugin-data/scoped-records.js.map +1 -0
  321. package/dist/plugin-sdk.d.ts +41 -0
  322. package/dist/plugin-sdk.js +10 -0
  323. package/dist/plugin-sdk.js.map +1 -0
  324. package/dist/sql-lifecycle/index.d.ts +138 -0
  325. package/dist/sql-lifecycle/index.js +167 -0
  326. package/dist/sql-lifecycle/index.js.map +1 -0
  327. package/dist/storage/index.d.ts +2 -0
  328. package/dist/storage/index.js +13 -0
  329. package/dist/storage/index.js.map +1 -0
  330. package/dist/storage/s3-compatible.d.ts +139 -0
  331. package/dist/storage/s3-compatible.js +11 -0
  332. package/dist/storage/s3-compatible.js.map +1 -0
  333. package/dist/tenant.d.ts +108 -0
  334. package/dist/tenant.js +9 -0
  335. package/dist/tenant.js.map +1 -0
  336. package/dist/workspace-context.d.ts +119 -0
  337. package/dist/workspace-context.js +9 -0
  338. package/dist/workspace-context.js.map +1 -0
  339. package/docs/api.md +30560 -0
  340. package/docs/db/README.md +49 -0
  341. package/docs/db/docs/api.md +1613 -0
  342. package/docs/db/docs/guide.md +47 -0
  343. package/docs/entitlements.md +60 -0
  344. package/docs/guide.md +92 -0
  345. package/docs/index.md +57 -0
  346. package/docs/ja/db/README.md +46 -0
  347. package/docs/ja/db/docs/guide.md +53 -0
  348. package/docs/ja/guide.md +46 -0
  349. package/docs/ja/lifecycle/README.md +46 -0
  350. package/docs/ja/lifecycle/docs/guide.md +45 -0
  351. package/docs/ja/storage/README.md +46 -0
  352. package/docs/ja/storage/docs/guide.md +43 -0
  353. package/docs/lifecycle/README.md +49 -0
  354. package/docs/lifecycle/docs/api.md +3770 -0
  355. package/docs/lifecycle/docs/baseline.md +50 -0
  356. package/docs/lifecycle/docs/guide.md +47 -0
  357. package/docs/storage/README.md +49 -0
  358. package/docs/storage/docs/api.md +470 -0
  359. package/docs/storage/docs/guide.md +47 -0
  360. package/package.json +354 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/execution/tool-agent.ts"],"sourcesContent":["import { createActionToolBridge, createExecutionSession, type ActionRegistry, type ActionToolDescriptor, type ActionToolBinding, type ActionToolCall } from '@alneas/appkit-core/ai/action'\nimport type { AIChatAdapter, AIChatMessage, AIChatPart } from '@alneas/appkit-core/ai/ai-chat'\nimport { createChatClient, type ChatClientOptions } from './chat'\nimport type { ExecutionPrincipal } from './index'\n\n/** Host-registered Action binding and explicit automatic-execution policy.\n * @see createToolAgent\n */\nexport interface AgentTool {\n /** Existing Appkit Action/command binding; registration and input/output schemas remain Appkit-owned. */\n binding: ActionToolBinding\n /** Only host-verified read-only actions may run automatically; handoffs remain unexecuted. */\n mode: 'read' | 'handoff'\n}\n/** Current host policies and limits for a single-flight Appkit execution session.\n * @see createToolAgent\n */\nexport interface ToolAgentOptions extends Omit<ChatClientOptions, 'tools'> {\n /**\n * Resolve the current host registry and explicit tool execution policy.\n * @param principal - Copied verified tenant/user identity.\n * @returns Existing Action registry and at most 100 read/handoff bindings.\n * @throws Rejects missing host session or registry resolution failures.\n * @example\n * ```typescript\n * import type { ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function agentSession(resolve: ToolAgentOptions['session']) { return resolve; }\n * ```\n */\n session(principal: ExecutionPrincipal): Promise<{\n /** Existing host-owned Appkit Action registry for this authorized session. */\n registry: ActionRegistry\n /** Explicit read/handoff policy for every disclosed binding. */\n tools: readonly AgentTool[]\n }>\n /**\n * Check current permission to disclose a tool descriptor or result to the model.\n * @param principal - Copied verified actor.\n * @param name - Host-registered tool name.\n * @returns Exactly true permits disclosure; other results deny it.\n * @throws Host policy errors propagate into the execution outcome.\n * @example\n * ```typescript\n * import type { ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function disclosurePolicy(policy: ToolAgentOptions['disclose']) { return policy; }\n * ```\n */\n disclose(principal: ExecutionPrincipal, name: string): Promise<boolean>\n /**\n * Check exact resource/input permission before execution and before result disclosure.\n * @param principal - Copied verified actor; callback mutation cannot change the trusted identity.\n * @param call - Untrusted model request with correlated ID, name and arguments.\n * @returns Exactly true admits the call; it does not approve a handoff for execution.\n * @throws Host policy errors propagate into the execution outcome.\n * @example\n * ```typescript\n * import type { ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function callPolicy(policy: ToolAgentOptions['authorizeCall']) { return policy; }\n * ```\n */\n authorizeCall(principal: ExecutionPrincipal, call: ActionToolCall): Promise<boolean>\n /** Maximum model rounds; default 6, allowed integers 1–20. */\n maxRounds?: number\n /** Maximum automatic Action calls per run; default 10, allowed integers 1–100. */\n maxCalls?: number\n}\n/** Final in-memory conversational outcome, separate from Appkit execution status.\n * @see createToolAgent\n */\nexport interface ToolAgentResult {\n /** Completed chat, unexecuted handoff, bounded stop, or an Action validation/execution failure. */\n status: 'completed' | 'handoff' | 'limited' | 'tool-error'\n /** Detached correlated chat history, including only authorized projected tool results. */\n messages: AIChatMessage[]\n /** Unexecuted requests; the host must validate them through its existing Action/Proposal review path. */\n pending: ActionToolCall[]\n /** Number of attempted automatic Action calls, including a returned Action failure. */\n callsExecuted: number\n}\n/**\n * Orchestrate bounded model rounds through existing Appkit Action/Execution and scoped EAOS chat.\n * @param options - Current session/disclosure/call policies, Appkit adapter and chat/round/call limits.\n * @returns Single-flight run, cancel, close and summary subscription methods backed by Appkit ExecutionSession.\n * @throws Invalid policies or round/call limits reject construction. Concurrent/closed runs reject through\n * Appkit; asynchronous authorization/provider failures become failed execution outcomes. Cancellation is\n * cooperative and does not roll back previously completed Action effects.\n * @remarks Only explicitly host-verified read tools execute automatically. A batch containing any handoff\n * returns all its calls without executing them. No durable command engine, approval grant or transaction\n * is created; retained tool-call/result history and descriptors are reauthorized at the exact adapter\n * boundary after chat governance, including caller-supplied history and guard substitutions. Approved writes belong to the host's existing proposal/approval and owning command service.\n * @example\n * ```typescript\n * import { createToolAgent, type ToolAgentOptions } from '@alneas/eaos-server/execution/tool-agent';\n * export function connectAgent(options: ToolAgentOptions) { return createToolAgent(options); }\n * ```\n */\nexport function createToolAgent(options: ToolAgentOptions) {\n const { session: makeSession, disclose, authorizeCall, authorize } = options\n const maxRounds = options.maxRounds ?? 6, maxCalls = options.maxCalls ?? 10, maxChars = options.maxInputChars ?? 200000\n if (typeof makeSession !== 'function' || typeof disclose !== 'function' || typeof authorizeCall !== 'function' || typeof authorize !== 'function' || !Number.isSafeInteger(maxRounds) || maxRounds < 1 || maxRounds > 20 || !Number.isSafeInteger(maxCalls) || maxCalls < 1 || maxCalls > 100) throw new Error('Agent policy and valid limits required')\n // Snapshot chat settings, while preserving the provider's existing transport implementation.\n const chatOptions = { ...options, parameters: structuredClone(options.parameters), modelAdapters: options.modelAdapters && Object.freeze({...options.modelAdapters}) }\n const execution = createExecutionSession()\n return {\n /**\n * Request cooperative cancellation of the current Appkit execution.\n * @returns No value; Appkit marks active work cancelling without rolling back completed effects.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function cancel(agent: ReturnType<typeof createToolAgent>) { return agent.cancel(); }\n * ```\n */\n cancel: () => execution.cancel(),\n /**\n * Read Appkit's summary-only in-memory execution history.\n * @returns Appkit execution summaries; raw model inputs/results are not stored in these summaries.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function snapshot(agent: ReturnType<typeof createToolAgent>) { return agent.getSnapshot(); }\n * ```\n */\n getSnapshot: () => execution.getSnapshot(),\n /**\n * Subscribe to Appkit execution summary changes.\n * @param listener - Callback notified when execution state changes; do not expose raw secrets in UI callbacks.\n * @returns Unsubscribe function owned by the subscribing host.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function observe(agent: ReturnType<typeof createToolAgent>, listener: () => void) { return agent.subscribe(listener); }\n * ```\n */\n subscribe: (listener: () => void) => execution.subscribe(listener),\n /**\n * Close the Appkit session and request cooperative cancellation.\n * @returns No value; the session no longer admits new runs.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function close(agent: ReturnType<typeof createToolAgent>) { agent.close(); }\n * ```\n */\n close: () => execution.close(),\n /**\n * Run a single authorized model/Action conversation.\n * @param principal - Verified current tenant/user identity, copied before host callbacks.\n * @param input - Detached initial messages and optional cooperative cancellation signal.\n * @returns Appkit execution outcome containing a ToolAgentResult on success; failed/cancelled outcomes omit it.\n * @throws Appkit rejects concurrent or closed session admission; run failures otherwise become outcomes.\n * @example\n * ```typescript\n * import { createToolAgent } from '@alneas/eaos-server/execution/tool-agent';\n * export function run(agent: ReturnType<typeof createToolAgent>, ...args: Parameters<typeof agent.run>) { return agent.run(...args); }\n * ```\n */\n async run(principal: ExecutionPrincipal, input: { messages: readonly AIChatMessage[]; signal?: AbortSignal }) {\n const p = structuredClone(principal), messages = structuredClone(input.messages) as AIChatMessage[]\n return execution.run('AI tool session', async context => {\n const externalAbort = () => execution.cancel()\n input.signal?.addEventListener('abort', externalAbort, { once: true })\n if (input.signal?.aborted) externalAbort()\n let bridge: ReturnType<typeof createActionToolBridge> | undefined\n let callsExecuted = 0\n const check = async () => {\n if (context.signal.aborted) throw new DOMException('Agent cancelled', 'AbortError')\n if (!p || [p.tenantId, p.userId].some(v => typeof v !== 'string' || !v.trim()) || await authorize(structuredClone(p), 'model:chat') !== true) throw new Error('Agent access denied')\n if (context.signal.aborted) throw new DOMException('Agent cancelled', 'AbortError')\n if (!Array.isArray(messages) || !messages.length || messages.length > 1000 || JSON.stringify(messages).length > maxChars) throw new Error('Agent history limit')\n }\n const allowed = async (call: ActionToolCall) => {\n await check()\n if (await disclose(structuredClone(p), call.name) !== true || await authorizeCall(structuredClone(p), structuredClone(call)) !== true) throw new Error('Agent tool access denied')\n await check()\n }\n const result = (status: ToolAgentResult['status'], pending: ActionToolCall[] = []): ToolAgentResult => ({ status, messages: structuredClone(messages), pending: structuredClone(pending), callsExecuted })\n try {\n await check()\n const session = await makeSession(structuredClone(p))\n await check()\n if (!Array.isArray(session.tools) || session.tools.length > 100 || session.tools.some(tool => !['read', 'handoff'].includes(tool.mode))) throw new Error('Invalid agent tool policy')\n const modes = new Map(session.tools.map(tool => [tool.binding.name, tool.mode]))\n const registrations = new Map(session.tools.filter(tool => tool.binding.kind === 'action').map(tool => {\n const binding = tool.binding as Extract<ActionToolBinding, { kind: 'action' }>\n return [binding.name, { id: binding.actionId, action: session.registry.getAction(binding.actionId) }]\n }))\n bridge = createActionToolBridge(session.registry, { tools: session.tools.map(tool => tool.binding), maxCalls })\n const activeBridge = bridge\n const authorizeHistory = async (history: readonly AIChatMessage[]) => {\n const prior = new Map<string, ActionToolCall>(), results = new Set<string>()\n for (const message of history) for (const part of message.parts) {\n if (part.type === 'tool-call') {\n if (prior.has(part.callId) || !modes.has(part.name)) throw new Error('Agent retained tool history is invalid')\n const call = {callId:part.callId,name:part.name,arguments:part.input}\n prior.set(call.callId,call)\n await allowed(call)\n } else if (part.type === 'tool-result') {\n const call = prior.get(part.callId)\n if (!call || call.name !== part.name || results.has(part.callId)) throw new Error('Agent retained tool result has no unique authorized call')\n results.add(part.callId)\n await allowed(call)\n }\n }\n }\n // A policy decorator checks the exact final request, including host-guard substitutions.\n // The existing Appkit adapter still owns transport, encoding and parsing.\n const authorizeAdapter = (transport: AIChatAdapter): AIChatAdapter => ({\n id:transport.id,capabilities:transport.capabilities,\n async *stream(request) {\n for (const descriptor of request.tools ?? []) {\n if (!modes.has(descriptor.name) || await disclose(structuredClone(p),descriptor.name) !== true) throw new Error('Agent tool descriptor disclosure denied')\n }\n await check()\n await authorizeHistory(request.messages)\n request.signal?.throwIfAborted()\n yield* transport.stream(request)\n },\n })\n const chat = createChatClient({ ...chatOptions,\n authorize:async (actor,operation) => {\n if (await authorize(actor,operation) !== true) return false\n await authorizeHistory(messages)\n return true\n },\n adapter:authorizeAdapter(chatOptions.adapter),\n ...(chatOptions.modelAdapters ? {modelAdapters:Object.fromEntries(Object.entries(chatOptions.modelAdapters).map(([model,adapter])=>[model,authorizeAdapter(adapter)]))} : {}),\n tools: async () => {\n const tools: ActionToolDescriptor[] = []\n for (const tool of activeBridge.listTools()) if (await disclose(structuredClone(p), tool.name) === true) tools.push(tool)\n return tools\n },\n })\n for (let round = 0; round < maxRounds; round++) {\n await check()\n const answer = await chat.complete(p, { messages, signal: context.signal, tools: 'catalog' })\n messages.push(answer.message)\n await check()\n if (answer.finishReason === 'stop') return result('completed')\n const calls = answer.message.parts.filter((part): part is Extract<AIChatPart, { type: 'tool-call' }> => part.type === 'tool-call').map(part => ({ callId: part.callId, name: part.name, arguments: part.input }))\n for (const call of calls) await allowed(call)\n if (calls.some(call => modes.get(call.name) === 'handoff')) return result('handoff', calls)\n if (callsExecuted + calls.length > maxCalls || round + 1 === maxRounds) return result('limited', calls)\n for (let index = 0; index < calls.length; index++) {\n const call = calls[index]\n await allowed(call)\n const registration = registrations.get(call.name)\n if (registration && session.registry.getAction(registration.id) !== registration.action) throw new Error('Agent action registration changed')\n const output = await activeBridge.execute(call, context)\n callsExecuted++\n await allowed(call)\n messages.push({ id: crypto.randomUUID(), role: 'tool', parts: [{ type: 'tool-result', callId: call.callId, name: call.name, output: output.ok ? output.data : { code: output.code, error: output.error }, ...(!output.ok ? { isError: true } : {}) }] })\n await check()\n context.reportProgress({ completed: callsExecuted, total: maxCalls })\n if (!output.ok) return result('tool-error', calls.slice(index + 1))\n }\n }\n return result('limited')\n } finally { bridge?.close(); input.signal?.removeEventListener('abort', externalAbort) }\n })\n },\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,45 @@
1
+ import {
2
+ createPluginEntitlementGuard
3
+ } from "./chunk-46UWPEW2.js";
4
+
5
+ // src/plugin-sdk.ts
6
+ import { Hono } from "hono";
7
+ import { bodyLimit } from "hono/body-limit";
8
+ import { assertPlatformPrincipal } from "@alneas/eaos-core";
9
+ function createSdkPluginRouter(plugin, host) {
10
+ const app = new Hono();
11
+ app.use("*", bodyLimit({ maxSize: 1024 * 1024 }));
12
+ app.use("*", async (c, next) => {
13
+ const p = await host.resolvePrincipal(c);
14
+ if (!p) return c.json({ error: "Unauthorized" }, 401);
15
+ assertPlatformPrincipal(p);
16
+ if (!await host.authorize(p, plugin.id, `${c.req.method} ${c.req.path}`)) return c.json({ error: "Plugin unavailable" }, 404);
17
+ await next();
18
+ });
19
+ if (plugin.entitlement) app.use("*", createPluginEntitlementGuard(plugin.id, plugin.entitlement, host.entitlements, host.resolvePrincipal));
20
+ for (const route of plugin.routeDefinitions) app.on(route.method, route.path, async (c) => {
21
+ const p = await host.resolvePrincipal(c);
22
+ if (!p) return c.json({ error: "Unauthorized" }, 401);
23
+ assertPlatformPrincipal(p);
24
+ const dependencies = await host.createContext(p, plugin.id);
25
+ if (!await host.authorize(p, plugin.id, `${c.req.method} ${c.req.path}`)) return c.json({ error: "Plugin unavailable" }, 404);
26
+ const entitlements = await host.entitlements?.snapshot(p) ?? null;
27
+ const ctx = Object.freeze({ ...dependencies, pluginId: plugin.id, principal: Object.freeze({ ...p, roles: Object.freeze([...p.roles]), entitlements }) });
28
+ let input = Object.fromEntries(new URL(c.req.url).searchParams);
29
+ if (route.method !== "GET" && route.method !== "DELETE") {
30
+ if (!/^application\/json(?:;|$)/i.test(c.req.header("Content-Type") ?? "")) return c.json({ error: "JSON body required" }, 415);
31
+ try {
32
+ input = await c.req.json();
33
+ } catch {
34
+ return c.json({ error: "Invalid JSON" }, 400);
35
+ }
36
+ }
37
+ return c.json(await route.handler(ctx, input));
38
+ });
39
+ return app;
40
+ }
41
+
42
+ export {
43
+ createSdkPluginRouter
44
+ };
45
+ //# sourceMappingURL=chunk-4VORUFKR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugin-sdk.ts"],"sourcesContent":["import { Hono } from 'hono'\nimport { bodyLimit } from 'hono/body-limit'\nimport type { DefinedPlugin, PluginContext, PlatformPrincipal } from '@alneas/eaos-core'\nimport { assertPlatformPrincipal } from '@alneas/eaos-core'\nimport { createPluginEntitlementGuard, type EntitlementPrincipalResolver, type PluginEntitlementRuntime } from './entitlements/index'\n\n/**\n * Host authentication, live admission, and scoped capabilities injected into {@link createSdkPluginRouter}.\n */\nexport interface PluginSdkHost {\n /** Resolves a verified current principal for each invocation, or null to deny; may be invoked multiple times in one request. */\n resolvePrincipal: EntitlementPrincipalResolver\n /** Mandatory live lifecycle/resource gate, independent of commercial licensing. */\n authorize: (principal: PlatformPrincipal, pluginId: string, operation: string) => Promise<boolean>\n /** Optional subscription/quota runtime; required when the plugin declares a rule needing external entitlement admission. */\n entitlements?: PluginEntitlementRuntime\n /** Must return tenant/plugin-scoped app-core/EAOS capabilities with per-operation authorization. */\n createContext: (principal: PlatformPrincipal, pluginId: string) => Promise<Omit<PluginContext<any>, 'principal' | 'pluginId'>>\n}\n/**\n * Mounts defined plugin routes behind host authentication, live authorization, and optional entitlement admission.\n * @param plugin - Trusted defined plugin containing route methods, paths, handlers, and optional entitlement policy.\n * @param host - Verified principal resolution, lifecycle/resource authorization, and tenant/plugin-scoped capability factory.\n * @returns A Hono router with a 1 MiB body limit; GET/DELETE inputs are query parameter objects, other methods require JSON input.\n * @throws Request handling propagates host, entitlement, context, and handler failures except malformed JSON/auth/admission responses explicitly returned by the router.\n * @remarks Authorization runs before route handling and again after asynchronous context creation. The verified principal/plugin scope overwrites factory dependencies, but the host must enforce scope inside supplied capabilities. Metered entitlement admission can count requests whose later body parsing or handler fails. No transactions, retries, rollback, or idempotency are supplied around handlers.\n * @example\n * ```typescript\n * import { createSdkPluginRouter, type PluginSdkHost } from \"@alneas/eaos-server/plugin-sdk\";\n * import type { DefinedPlugin } from \"@alneas/eaos-core\";\n * export function pluginRouter(plugin: DefinedPlugin, host: PluginSdkHost) {\n * return createSdkPluginRouter(plugin, host);\n * }\n * ```\n */\nexport function createSdkPluginRouter(plugin: DefinedPlugin, host: PluginSdkHost): Hono {\n const app = new Hono()\n app.use('*', bodyLimit({ maxSize: 1024 * 1024 }))\n app.use('*', async (c, next) => {\n const p = await host.resolvePrincipal(c)\n if (!p) return c.json({ error: 'Unauthorized' }, 401)\n assertPlatformPrincipal(p)\n if (!await host.authorize(p, plugin.id, `${c.req.method} ${c.req.path}`)) return c.json({ error: 'Plugin unavailable' }, 404)\n await next()\n })\n if (plugin.entitlement) app.use('*', createPluginEntitlementGuard(plugin.id, plugin.entitlement, host.entitlements, host.resolvePrincipal))\n for (const route of plugin.routeDefinitions) app.on(route.method, route.path, async c => {\n const p = await host.resolvePrincipal(c)\n if (!p) return c.json({ error: 'Unauthorized' }, 401)\n assertPlatformPrincipal(p)\n const dependencies = await host.createContext(p, plugin.id)\n if (!await host.authorize(p, plugin.id, `${c.req.method} ${c.req.path}`)) return c.json({ error: 'Plugin unavailable' }, 404)\n // Factories cannot overwrite the verified scope. They may not return request-selected tenants.\n const entitlements = await host.entitlements?.snapshot(p) ?? null\n const ctx: PluginContext = Object.freeze({ ...dependencies, pluginId: plugin.id, principal: Object.freeze({ ...p, roles: Object.freeze([...p.roles]), entitlements }) })\n let input: unknown = Object.fromEntries(new URL(c.req.url).searchParams)\n if (route.method !== 'GET' && route.method !== 'DELETE') {\n if (!/^application\\/json(?:;|$)/i.test(c.req.header('Content-Type') ?? '')) return c.json({ error: 'JSON body required' }, 415)\n try { input = await c.req.json() } catch { return c.json({ error: 'Invalid JSON' }, 400) }\n }\n return c.json(await route.handler(ctx, input))\n })\n return app\n}\n"],"mappings":";;;;;AAAA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAE1B,SAAS,+BAA+B;AAgCjC,SAAS,sBAAsB,QAAuB,MAA2B;AACtF,QAAM,MAAM,IAAI,KAAK;AACrB,MAAI,IAAI,KAAK,UAAU,EAAE,SAAS,OAAO,KAAK,CAAC,CAAC;AAChD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,UAAM,IAAI,MAAM,KAAK,iBAAiB,CAAC;AACvC,QAAI,CAAC,EAAG,QAAO,EAAE,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACpD,4BAAwB,CAAC;AACzB,QAAI,CAAC,MAAM,KAAK,UAAU,GAAG,OAAO,IAAI,GAAG,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,IAAI,EAAE,EAAG,QAAO,EAAE,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;AAC5H,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,OAAO,YAAa,KAAI,IAAI,KAAK,6BAA6B,OAAO,IAAI,OAAO,aAAa,KAAK,cAAc,KAAK,gBAAgB,CAAC;AAC1I,aAAW,SAAS,OAAO,iBAAkB,KAAI,GAAG,MAAM,QAAQ,MAAM,MAAM,OAAM,MAAK;AACvF,UAAM,IAAI,MAAM,KAAK,iBAAiB,CAAC;AACvC,QAAI,CAAC,EAAG,QAAO,EAAE,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AACpD,4BAAwB,CAAC;AACzB,UAAM,eAAe,MAAM,KAAK,cAAc,GAAG,OAAO,EAAE;AAC1D,QAAI,CAAC,MAAM,KAAK,UAAU,GAAG,OAAO,IAAI,GAAG,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,IAAI,EAAE,EAAG,QAAO,EAAE,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;AAE5H,UAAM,eAAe,MAAM,KAAK,cAAc,SAAS,CAAC,KAAK;AAC7D,UAAM,MAAqB,OAAO,OAAO,EAAE,GAAG,cAAc,UAAU,OAAO,IAAI,WAAW,OAAO,OAAO,EAAE,GAAG,GAAG,OAAO,OAAO,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC;AACvK,QAAI,QAAiB,OAAO,YAAY,IAAI,IAAI,EAAE,IAAI,GAAG,EAAE,YAAY;AACvE,QAAI,MAAM,WAAW,SAAS,MAAM,WAAW,UAAU;AACvD,UAAI,CAAC,6BAA6B,KAAK,EAAE,IAAI,OAAO,cAAc,KAAK,EAAE,EAAG,QAAO,EAAE,KAAK,EAAE,OAAO,qBAAqB,GAAG,GAAG;AAC9H,UAAI;AAAE,gBAAQ,MAAM,EAAE,IAAI,KAAK;AAAA,MAAE,QAAQ;AAAE,eAAO,EAAE,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG;AAAA,MAAE;AAAA,IAC3F;AACA,WAAO,EAAE,KAAK,MAAM,MAAM,QAAQ,KAAK,KAAK,CAAC;AAAA,EAC/C,CAAC;AACD,SAAO;AACT;","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-55D4ERWO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,18 @@
1
+ // src/lifecycle-engine/platform/site-publication.ts
2
+ function parseSitePublicationPolicy(value) {
3
+ const p = value;
4
+ const fields = { "pages-git": ["accountId", "project", "branch", "deployHookSecret"], "github-actions": ["repository", "workflow", "ref", "tokenSecret"], artifact: ["provider", "target"], manual: [] };
5
+ if (!p || typeof p !== "object" || Array.isArray(p) || ![Object.prototype, null].includes(Object.getPrototypeOf(p)) || !Object.hasOwn(fields, p.mode) || typeof p.requireApproval !== "boolean" || !["operator", "cms-published"].includes(p.trigger) || Object.keys(p).some((k) => !["mode", "requireApproval", "trigger", ...fields[p.mode]].includes(k))) throw Error("Invalid site publication policy");
6
+ const ref = (v) => typeof v === "string" && /^[A-Za-z0-9_][A-Za-z0-9_./-]{0,199}$/.test(v) && !v.includes("..") && !v.endsWith("/");
7
+ const secret = (v) => typeof v === "string" && /^[A-Z_][A-Z0-9_]{0,99}$/.test(v);
8
+ if (p.mode === "pages-git" && (typeof p.accountId !== "string" || typeof p.project !== "string" || !/^[a-f0-9]{32}$/.test(p.accountId) || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(p.project) || !ref(p.branch) || !secret(p.deployHookSecret))) throw Error("Invalid Pages publication registration");
9
+ if (p.mode === "github-actions" && (typeof p.repository !== "string" || typeof p.workflow !== "string" || !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(p.repository) || !/^[A-Za-z0-9_-]+\.ya?ml$/.test(p.workflow) || !ref(p.ref) || !secret(p.tokenSecret))) throw Error("Invalid Actions publication registration");
10
+ if (p.mode === "artifact" && ![p.provider, p.target].every((v) => typeof v === "string" && /^[A-Za-z0-9_-]{1,100}$/.test(v))) throw Error("Invalid artifact publication registration");
11
+ if (p.mode === "manual" && p.trigger !== "operator") throw Error("Manual publication requires operator initiation");
12
+ return structuredClone(p);
13
+ }
14
+
15
+ export {
16
+ parseSitePublicationPolicy
17
+ };
18
+ //# sourceMappingURL=chunk-5TBBZIND.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lifecycle-engine/platform/site-publication.ts"],"sourcesContent":["/**\n * Host-owned nonsecret publication mode and approval/trigger requirements; secret fields name bindings rather than contain secrets.\n * \n * \n * Host-owned policy; secrets and executable commands are never configuration values.\n * @see parseSitePublicationPolicy for canonical integration usage.\n */\nexport type SitePublicationPolicy = {\n /**\n * Whether host workflow must obtain approval before publication; parsing does not grant approval.\n */\n requireApproval:boolean;\n /**\n * Operator initiation or CMS-published event; manual mode permits only operator.\n */\n trigger:'operator'|'cms-published'} & (\n | {\n /**\n * Publication integration discriminator selecting its required nonsecret fields.\n */\n mode:'pages-git';\n /**\n * Cloudflare account identifier, exactly 32 lowercase hexadecimal characters; not an access token.\n */\n accountId:string;\n /**\n * Registered Pages project slug, at most 63 lowercase letters/digits/hyphens.\n */\n project:string;\n /**\n * Reviewed Git branch reference without traversal or trailing slash.\n */\n branch:string;\n /**\n * Uppercase host secret-binding name for the deploy hook; never the hook value.\n */\n deployHookSecret:string}\n | {\n /**\n * Publication integration discriminator selecting its required nonsecret fields.\n */\n mode:'github-actions';\n /**\n * Reviewed GitHub owner/repository reference.\n */\n repository:string;\n /**\n * Reviewed workflow basename ending .yml or .yaml.\n */\n workflow:string;\n /**\n * Reviewed Git ref without traversal or trailing slash.\n */\n ref:string;\n /**\n * Uppercase host secret-binding name for the provider token; never the token value.\n */\n tokenSecret:string}\n | {\n /**\n * Publication integration discriminator selecting its required nonsecret fields.\n */\n mode:'artifact';\n /**\n * Registered artifact publication adapter ID, up to 100 letters/digits/underscore/hyphen characters.\n */\n provider:string;\n /**\n * Registered nonsecret artifact publication target ID.\n */\n target:string}\n | {\n /**\n * Publication integration discriminator selecting its required nonsecret fields.\n */\n mode:'manual'}\n)\n/**\n * Supported publication integration: Pages Git, GitHub Actions, artifact adapter or manual operator flow.\n * \n * @see parseSitePublicationPolicy for canonical integration usage.\n */\nexport type SitePublicationMode = SitePublicationPolicy['mode']\n/**\n * Validates and clones a nonsecret host publication policy for one supported publication mode.\n * @param value - Untrusted plain policy declaration with explicit mode, approval flag and trigger plus mode-specific references.\n * @returns A structured clone narrowed to SitePublicationPolicy.\n * @throws Error for unknown/extra fields, malformed provider references, invalid secret-reference names or unsupported trigger/mode combinations.\n * \n * @remarks\n * Secret fields contain uppercase environment/binding names, never actual secret values. Manual publication requires operator trigger. Parsing does not execute publication, grant approval or contact a provider.\n * \n * @example\n * ```typescript\n * import { parseSitePublicationPolicy } from '@alneas/eaos-server/platform/site-publication';\n * const policy = parseSitePublicationPolicy({ mode: 'manual', requireApproval: true, trigger: 'operator' });\n * ```\n */\nexport function parseSitePublicationPolicy(value:unknown):SitePublicationPolicy {\n const p=value as SitePublicationPolicy\n const fields:Record<SitePublicationMode,string[]>={'pages-git':['accountId','project','branch','deployHookSecret'],'github-actions':['repository','workflow','ref','tokenSecret'],artifact:['provider','target'],manual:[]}\n if(!p||typeof p!=='object'||Array.isArray(p)||![Object.prototype,null].includes(Object.getPrototypeOf(p))||!Object.hasOwn(fields,p.mode)||typeof p.requireApproval!=='boolean'||!['operator','cms-published'].includes(p.trigger)||Object.keys(p).some(k=>!['mode','requireApproval','trigger',...fields[p.mode]].includes(k)))throw Error('Invalid site publication policy')\n const ref=(v:unknown)=>typeof v==='string'&&/^[A-Za-z0-9_][A-Za-z0-9_./-]{0,199}$/.test(v)&&!v.includes('..')&&!v.endsWith('/')\n const secret=(v:unknown)=>typeof v==='string'&&/^[A-Z_][A-Z0-9_]{0,99}$/.test(v)\n if(p.mode==='pages-git'&&(typeof p.accountId!=='string'||typeof p.project!=='string'||!/^[a-f0-9]{32}$/.test(p.accountId)||!/^[a-z0-9][a-z0-9-]{0,62}$/.test(p.project)||!ref(p.branch)||!secret(p.deployHookSecret)))throw Error('Invalid Pages publication registration')\n if(p.mode==='github-actions'&&(typeof p.repository!=='string'||typeof p.workflow!=='string'||!/^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/.test(p.repository)||!/^[A-Za-z0-9_-]+\\.ya?ml$/.test(p.workflow)||!ref(p.ref)||!secret(p.tokenSecret)))throw Error('Invalid Actions publication registration')\n if(p.mode==='artifact'&&![p.provider,p.target].every(v=>typeof v==='string'&&/^[A-Za-z0-9_-]{1,100}$/.test(v)))throw Error('Invalid artifact publication registration')\n if(p.mode==='manual'&&p.trigger!=='operator')throw Error('Manual publication requires operator initiation')\n return structuredClone(p)\n}\n"],"mappings":";AAkGO,SAAS,2BAA2B,OAAqC;AAC/E,QAAM,IAAE;AACR,QAAM,SAA4C,EAAC,aAAY,CAAC,aAAY,WAAU,UAAS,kBAAkB,GAAE,kBAAiB,CAAC,cAAa,YAAW,OAAM,aAAa,GAAE,UAAS,CAAC,YAAW,QAAQ,GAAE,QAAO,CAAC,EAAC;AAC1N,MAAG,CAAC,KAAG,OAAO,MAAI,YAAU,MAAM,QAAQ,CAAC,KAAG,CAAC,CAAC,OAAO,WAAU,IAAI,EAAE,SAAS,OAAO,eAAe,CAAC,CAAC,KAAG,CAAC,OAAO,OAAO,QAAO,EAAE,IAAI,KAAG,OAAO,EAAE,oBAAkB,aAAW,CAAC,CAAC,YAAW,eAAe,EAAE,SAAS,EAAE,OAAO,KAAG,OAAO,KAAK,CAAC,EAAE,KAAK,OAAG,CAAC,CAAC,QAAO,mBAAkB,WAAU,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,OAAM,MAAM,iCAAiC;AAC5W,QAAM,MAAI,CAAC,MAAY,OAAO,MAAI,YAAU,uCAAuC,KAAK,CAAC,KAAG,CAAC,EAAE,SAAS,IAAI,KAAG,CAAC,EAAE,SAAS,GAAG;AAC9H,QAAM,SAAO,CAAC,MAAY,OAAO,MAAI,YAAU,0BAA0B,KAAK,CAAC;AAC/E,MAAG,EAAE,SAAO,gBAAc,OAAO,EAAE,cAAY,YAAU,OAAO,EAAE,YAAU,YAAU,CAAC,iBAAiB,KAAK,EAAE,SAAS,KAAG,CAAC,4BAA4B,KAAK,EAAE,OAAO,KAAG,CAAC,IAAI,EAAE,MAAM,KAAG,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAM,MAAM,wCAAwC;AAC1Q,MAAG,EAAE,SAAO,qBAAmB,OAAO,EAAE,eAAa,YAAU,OAAO,EAAE,aAAW,YAAU,CAAC,qCAAqC,KAAK,EAAE,UAAU,KAAG,CAAC,0BAA0B,KAAK,EAAE,QAAQ,KAAG,CAAC,IAAI,EAAE,GAAG,KAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAM,MAAM,0CAA0C;AAC/R,MAAG,EAAE,SAAO,cAAY,CAAC,CAAC,EAAE,UAAS,EAAE,MAAM,EAAE,MAAM,OAAG,OAAO,MAAI,YAAU,yBAAyB,KAAK,CAAC,CAAC,EAAE,OAAM,MAAM,2CAA2C;AACtK,MAAG,EAAE,SAAO,YAAU,EAAE,YAAU,WAAW,OAAM,MAAM,iDAAiD;AAC1G,SAAO,gBAAgB,CAAC;AACzB;","names":[]}
@@ -0,0 +1,211 @@
1
+ // src/db-package/migration/aggregator.ts
2
+ import { resolveDataContracts } from "@alneas/eaos-core/contracts/data-contracts";
3
+ var MigrationAggregator = class {
4
+ /**
5
+ * Captures plugin manifests and available data contracts for later collection.
6
+ * @param plugins - Manifests consulted on every collection call; the array is retained rather than cloned.
7
+ * @param dataContracts - Available contracts used to resolve manifest requirements; defaults to none and is retained.
8
+ */
9
+ constructor(plugins, dataContracts = []) {
10
+ this.plugins = plugins;
11
+ this.dataContracts = dataContracts;
12
+ }
13
+ plugins;
14
+ dataContracts;
15
+ /**
16
+ * Collects resolved data contracts first, then plugin and extension schemas by migration order.
17
+ * @param resolveSchema - Called with plugin ID and optional extension ID; returns a legacy schema or null to skip it. Plugin schemas declaring data contracts skip the plugin-level callback, but extensions are still resolved.
18
+ * @returns Ordered schema sources; manifests with equal order retain their sort order and missing callback results are omitted.
19
+ * @throws Propagates contract resolution or callback errors.
20
+ * @example
21
+ * ```typescript
22
+ * import { MigrationAggregator } from "@alneas/eaos-server/db/migration/aggregator";
23
+ * const aggregator = new MigrationAggregator([]);
24
+ * console.log(aggregator.collectSchemas(() => null)); // []
25
+ * ```
26
+ */
27
+ collectSchemas(resolveSchema) {
28
+ const sources = [];
29
+ const requirements = {};
30
+ for (const plugin of this.plugins) {
31
+ resolveDataContracts(this.dataContracts, plugin.schema.dataContracts ?? {});
32
+ Object.assign(requirements, plugin.schema.dataContracts ?? {});
33
+ }
34
+ for (const contract of resolveDataContracts(this.dataContracts, requirements).contracts) sources.push({ pluginId: `data:${contract.id}`, pluginName: contract.description, schemaJson: contract.schema });
35
+ const sorted = [...this.plugins].sort(
36
+ (a, b) => (a.schema?.migrationOrder ?? 999) - (b.schema?.migrationOrder ?? 999)
37
+ );
38
+ for (const plugin of sorted) {
39
+ const schemaJson = Object.keys(plugin.schema.dataContracts ?? {}).length ? null : resolveSchema(plugin.id);
40
+ if (schemaJson) {
41
+ sources.push({
42
+ pluginId: plugin.id,
43
+ pluginName: plugin.name,
44
+ migrationOrder: plugin.schema?.migrationOrder ?? 999,
45
+ schemaJson
46
+ });
47
+ }
48
+ if (plugin.extensions) {
49
+ for (const ext of plugin.extensions) {
50
+ const extSchemaJson = resolveSchema(plugin.id, ext.id);
51
+ if (extSchemaJson) {
52
+ sources.push({
53
+ pluginId: plugin.id,
54
+ pluginName: plugin.name,
55
+ extensionId: ext.id,
56
+ migrationOrder: plugin.schema?.migrationOrder ?? 999,
57
+ schemaJson: extSchemaJson
58
+ });
59
+ }
60
+ }
61
+ }
62
+ }
63
+ return sources;
64
+ }
65
+ /**
66
+ * Renders PostgreSQL table DDL and tenant_id row-level-security policies as text.
67
+ * @param sources - Trusted legacy schemas rendered in supplied order. Every table must declare tenant_id not explicitly nullable.
68
+ * @param dbDriver - Label included in SQL comments only; defaults to postgres and does not change dialect.
69
+ * @returns SQL text with a generated timestamp, CREATE TABLE IF NOT EXISTS, and tenant policies using app.current_tenant as UUID.
70
+ * @throws For canonical x-db/$defs schemas or missing/nullable tenant_id columns.
71
+ * @remarks The host must set app.current_tenant appropriately and review/apply SQL separately.
72
+ * @example
73
+ * ```typescript
74
+ * import { MigrationAggregator } from "@alneas/eaos-server/db/migration/aggregator";
75
+ * const aggregator = new MigrationAggregator([]);
76
+ * console.log(aggregator.generatePostgres([]));
77
+ * ```
78
+ */
79
+ generatePostgres(sources, dbDriver = "postgres") {
80
+ let sqlOutput = `-- Auto-generated Supabase / PostgreSQL DDL & RLS Policies
81
+ `;
82
+ sqlOutput += `-- Driver: ${dbDriver}
83
+ -- Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}
84
+
85
+ `;
86
+ for (const source of sources) {
87
+ const identifier = source.extensionId ? `${source.pluginId}:${source.extensionId}` : source.pluginId;
88
+ sqlOutput += `-- ==========================================
89
+ `;
90
+ sqlOutput += `-- Plugin: ${source.pluginName || source.pluginId} (source: ${identifier})
91
+ `;
92
+ sqlOutput += `-- Migration Order: ${source.migrationOrder ?? 999}
93
+ `;
94
+ sqlOutput += `-- ==========================================
95
+
96
+ `;
97
+ sqlOutput += this.convertJsonSchemaToPostgresSql(identifier, source.schemaJson);
98
+ }
99
+ return sqlOutput;
100
+ }
101
+ /**
102
+ * Renders legacy Oracle table DDL as text.
103
+ * @param sources - Trusted legacy schemas rendered in supplied order; every table must declare tenant_id not explicitly nullable.
104
+ * @returns SQL text with a generated timestamp and CREATE TABLE statements; no VPD policies or default clauses are emitted by this converter.
105
+ * @throws For canonical x-db/$defs schemas or missing/nullable tenant_id columns.
106
+ * @remarks Applying SQL and enforcing Oracle tenant isolation remain host responsibilities.
107
+ * @example
108
+ * ```typescript
109
+ * import { MigrationAggregator } from "@alneas/eaos-server/db/migration/aggregator";
110
+ * const aggregator = new MigrationAggregator([]);
111
+ * console.log(aggregator.generateOracle([]));
112
+ * ```
113
+ */
114
+ generateOracle(sources) {
115
+ let sqlOutput = `-- Auto-generated Oracle ADB DDL & VPD Context Policies
116
+ `;
117
+ sqlOutput += `-- Driver: ORACLE
118
+ -- Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}
119
+
120
+ `;
121
+ for (const source of sources) {
122
+ const identifier = source.extensionId ? `${source.pluginId}:${source.extensionId}` : source.pluginId;
123
+ sqlOutput += `-- ==========================================
124
+ `;
125
+ sqlOutput += `-- Plugin: ${source.pluginName || source.pluginId} (source: ${identifier})
126
+ `;
127
+ sqlOutput += `-- Migration Order: ${source.migrationOrder ?? 999}
128
+ `;
129
+ sqlOutput += `-- ==========================================
130
+
131
+ `;
132
+ sqlOutput += this.convertJsonSchemaToOracleSql(identifier, source.schemaJson);
133
+ }
134
+ return sqlOutput;
135
+ }
136
+ convertJsonSchemaToPostgresSql(_identifier, schemaJson) {
137
+ let sql = "";
138
+ if (schemaJson["x-db"] || schemaJson.$defs) throw new Error("Use the data contract reviewed lifecycle migrations for canonical JSON Schema");
139
+ const tables = schemaJson.tables || {};
140
+ for (const [tableName, tableDef] of Object.entries(tables)) {
141
+ sql += `CREATE TABLE IF NOT EXISTS ${tableName} (
142
+ `;
143
+ const columnDefs = [];
144
+ const columns = tableDef.columns || {};
145
+ assertTenantColumn(tableName, columns);
146
+ for (const [colName, colDef] of Object.entries(columns)) {
147
+ let colType = "TEXT";
148
+ const rawType = (colDef.type || "").toUpperCase();
149
+ if (rawType === "UUID") colType = "UUID";
150
+ else if (rawType.includes("VARCHAR")) colType = "VARCHAR(255)";
151
+ else if (rawType.includes("NUMBER") || rawType.includes("DECIMAL")) colType = "NUMERIC(18,2)";
152
+ else if (rawType.includes("TIMESTAMP") || rawType.includes("DATE")) colType = "TIMESTAMPTZ";
153
+ else if (rawType.includes("INT")) colType = "BIGINT";
154
+ let line = ` ${colName} ${colType}`;
155
+ if (colDef.primaryKey) line += " PRIMARY KEY";
156
+ if (colDef.nullable === false) line += " NOT NULL";
157
+ if (colDef.default) line += ` DEFAULT ${colDef.default}`;
158
+ columnDefs.push(line);
159
+ }
160
+ sql += columnDefs.join(",\n") + "\n);\n\n";
161
+ if (columns["tenant_id"]) {
162
+ sql += `-- Supabase Row Level Security (RLS) for ${tableName}
163
+ `;
164
+ sql += `ALTER TABLE ${tableName} ENABLE ROW LEVEL SECURITY;
165
+ `;
166
+ sql += `DROP POLICY IF EXISTS ${tableName}_tenant_isolation ON ${tableName};
167
+ `;
168
+ sql += `CREATE POLICY ${tableName}_tenant_isolation ON ${tableName} FOR ALL USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
169
+
170
+ `;
171
+ }
172
+ }
173
+ return sql;
174
+ }
175
+ convertJsonSchemaToOracleSql(_identifier, schemaJson) {
176
+ let sql = "";
177
+ if (schemaJson["x-db"] || schemaJson.$defs) throw new Error("Use the data contract reviewed lifecycle migrations for canonical JSON Schema");
178
+ const tables = schemaJson.tables || {};
179
+ for (const [tableName, tableDef] of Object.entries(tables)) {
180
+ sql += `CREATE TABLE ${tableName} (
181
+ `;
182
+ const columnDefs = [];
183
+ const columns = tableDef.columns || {};
184
+ assertTenantColumn(tableName, columns);
185
+ for (const [colName, colDef] of Object.entries(columns)) {
186
+ let colType = "VARCHAR2(255)";
187
+ const rawType = (colDef.type || "").toUpperCase();
188
+ if (rawType === "UUID") colType = "VARCHAR2(36)";
189
+ else if (rawType.includes("VARCHAR")) colType = "VARCHAR2(255)";
190
+ else if (rawType.includes("NUMBER") || rawType.includes("DECIMAL")) colType = "NUMBER(18,2)";
191
+ else if (rawType.includes("TIMESTAMP") || rawType.includes("DATE")) colType = "TIMESTAMP WITH TIME ZONE";
192
+ else if (rawType.includes("INT")) colType = "NUMBER(19)";
193
+ let line = ` ${colName} ${colType}`;
194
+ if (colDef.primaryKey) line += " PRIMARY KEY";
195
+ if (colDef.nullable === false) line += " NOT NULL";
196
+ columnDefs.push(line);
197
+ }
198
+ sql += columnDefs.join(",\n") + "\n);\n\n";
199
+ }
200
+ return sql;
201
+ }
202
+ };
203
+ function assertTenantColumn(tableName, columns) {
204
+ const tenant = columns.tenant_id;
205
+ if (!tenant || tenant.nullable === true) throw new Error(`Schema table ${tableName} must declare a non-null tenant_id column`);
206
+ }
207
+
208
+ export {
209
+ MigrationAggregator
210
+ };
211
+ //# sourceMappingURL=chunk-5WOZWPZA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/db-package/migration/aggregator.ts"],"sourcesContent":["import { resolveDataContracts, type DataContract } from '@alneas/eaos-core/contracts/data-contracts'\nimport type { PluginManifest } from '@alneas/eaos-core/plugin-sdk/types'\n\n/**\n * Legacy table-schema input collected for migration text generation.\n * @see MigrationAggregator for a complete usage example.\n */\nexport interface SchemaSource {\n /** Plugin ID, or data:{contractId} for resolved data contracts. */\n pluginId: string\n /** Optional display label used in generated SQL comments. */\n pluginName?: string\n /** Optional extension ID appended to the source identifier. */\n extensionId?: string\n /** Sort order from the plugin manifest; defaults to 999 for plugin schemas. */\n migrationOrder?: number\n /** Legacy tables/columns schema; canonical x-db/$defs schemas require reviewed lifecycle migrations instead. */\n schemaJson: Record<string, any>\n}\n\n/**\n * Collects plugin schema sources and renders legacy PostgreSQL or Oracle DDL text.\n * @remarks Generation never executes SQL. Schema identifiers, defaults, and comments are interpolated from trusted schema inputs; review generated SQL before applying it. Canonical data-contract JSON Schema requires reviewed lifecycle migrations rather than these legacy converters.\n * @example\n * ```typescript\n * import { MigrationAggregator } from \"@alneas/eaos-server/db/migration/aggregator\";\n * const aggregator = new MigrationAggregator([]);\n * console.log(aggregator.generatePostgres([]));\n * ```\n */\nexport class MigrationAggregator {\n /**\n * Captures plugin manifests and available data contracts for later collection.\n * @param plugins - Manifests consulted on every collection call; the array is retained rather than cloned.\n * @param dataContracts - Available contracts used to resolve manifest requirements; defaults to none and is retained.\n */\n constructor(private plugins: PluginManifest[], private dataContracts: DataContract[] = []) {}\n\n /**\n * Collects resolved data contracts first, then plugin and extension schemas by migration order.\n * @param resolveSchema - Called with plugin ID and optional extension ID; returns a legacy schema or null to skip it. Plugin schemas declaring data contracts skip the plugin-level callback, but extensions are still resolved.\n * @returns Ordered schema sources; manifests with equal order retain their sort order and missing callback results are omitted.\n * @throws Propagates contract resolution or callback errors.\n * @example\n * ```typescript\n * import { MigrationAggregator } from \"@alneas/eaos-server/db/migration/aggregator\";\n * const aggregator = new MigrationAggregator([]);\n * console.log(aggregator.collectSchemas(() => null)); // []\n * ```\n */\n collectSchemas(\n resolveSchema: (pluginId: string, extensionId?: string) => Record<string, any> | null\n ): SchemaSource[] {\n const sources: SchemaSource[] = []\n const requirements: Record<string, string> = {}\n for (const plugin of this.plugins) {\n resolveDataContracts(this.dataContracts, plugin.schema.dataContracts ?? {})\n Object.assign(requirements, plugin.schema.dataContracts ?? {})\n }\n for (const contract of resolveDataContracts(this.dataContracts, requirements).contracts) sources.push({ pluginId: `data:${contract.id}`, pluginName: contract.description, schemaJson: contract.schema })\n const sorted = [...this.plugins].sort(\n (a, b) => (a.schema?.migrationOrder ?? 999) - (b.schema?.migrationOrder ?? 999)\n )\n\n for (const plugin of sorted) {\n const schemaJson = Object.keys(plugin.schema.dataContracts ?? {}).length ? null : resolveSchema(plugin.id)\n if (schemaJson) {\n sources.push({\n pluginId: plugin.id,\n pluginName: plugin.name,\n migrationOrder: plugin.schema?.migrationOrder ?? 999,\n schemaJson,\n })\n }\n\n if (plugin.extensions) {\n for (const ext of plugin.extensions) {\n const extSchemaJson = resolveSchema(plugin.id, ext.id)\n if (extSchemaJson) {\n sources.push({\n pluginId: plugin.id,\n pluginName: plugin.name,\n extensionId: ext.id,\n migrationOrder: plugin.schema?.migrationOrder ?? 999,\n schemaJson: extSchemaJson,\n })\n }\n }\n }\n }\n return sources\n }\n\n /**\n * Renders PostgreSQL table DDL and tenant_id row-level-security policies as text.\n * @param sources - Trusted legacy schemas rendered in supplied order. Every table must declare tenant_id not explicitly nullable.\n * @param dbDriver - Label included in SQL comments only; defaults to postgres and does not change dialect.\n * @returns SQL text with a generated timestamp, CREATE TABLE IF NOT EXISTS, and tenant policies using app.current_tenant as UUID.\n * @throws For canonical x-db/$defs schemas or missing/nullable tenant_id columns.\n * @remarks The host must set app.current_tenant appropriately and review/apply SQL separately.\n * @example\n * ```typescript\n * import { MigrationAggregator } from \"@alneas/eaos-server/db/migration/aggregator\";\n * const aggregator = new MigrationAggregator([]);\n * console.log(aggregator.generatePostgres([]));\n * ```\n */\n generatePostgres(sources: SchemaSource[], dbDriver: string = 'postgres'): string {\n let sqlOutput = `-- Auto-generated Supabase / PostgreSQL DDL & RLS Policies\\n`\n sqlOutput += `-- Driver: ${dbDriver}\\n-- Generated at: ${new Date().toISOString()}\\n\\n`\n\n for (const source of sources) {\n const identifier = source.extensionId ? `${source.pluginId}:${source.extensionId}` : source.pluginId\n sqlOutput += `-- ==========================================\\n`\n sqlOutput += `-- Plugin: ${source.pluginName || source.pluginId} (source: ${identifier})\\n`\n sqlOutput += `-- Migration Order: ${source.migrationOrder ?? 999}\\n`\n sqlOutput += `-- ==========================================\\n\\n`\n\n sqlOutput += this.convertJsonSchemaToPostgresSql(identifier, source.schemaJson)\n }\n\n return sqlOutput\n }\n\n /**\n * Renders legacy Oracle table DDL as text.\n * @param sources - Trusted legacy schemas rendered in supplied order; every table must declare tenant_id not explicitly nullable.\n * @returns SQL text with a generated timestamp and CREATE TABLE statements; no VPD policies or default clauses are emitted by this converter.\n * @throws For canonical x-db/$defs schemas or missing/nullable tenant_id columns.\n * @remarks Applying SQL and enforcing Oracle tenant isolation remain host responsibilities.\n * @example\n * ```typescript\n * import { MigrationAggregator } from \"@alneas/eaos-server/db/migration/aggregator\";\n * const aggregator = new MigrationAggregator([]);\n * console.log(aggregator.generateOracle([]));\n * ```\n */\n generateOracle(sources: SchemaSource[]): string {\n let sqlOutput = `-- Auto-generated Oracle ADB DDL & VPD Context Policies\\n`\n sqlOutput += `-- Driver: ORACLE\\n-- Generated at: ${new Date().toISOString()}\\n\\n`\n\n for (const source of sources) {\n const identifier = source.extensionId ? `${source.pluginId}:${source.extensionId}` : source.pluginId\n sqlOutput += `-- ==========================================\\n`\n sqlOutput += `-- Plugin: ${source.pluginName || source.pluginId} (source: ${identifier})\\n`\n sqlOutput += `-- Migration Order: ${source.migrationOrder ?? 999}\\n`\n sqlOutput += `-- ==========================================\\n\\n`\n\n sqlOutput += this.convertJsonSchemaToOracleSql(identifier, source.schemaJson)\n }\n\n return sqlOutput\n }\n\n private convertJsonSchemaToPostgresSql(_identifier: string, schemaJson: any): string {\n let sql = ''\n if (schemaJson['x-db'] || schemaJson.$defs) throw new Error('Use the data contract reviewed lifecycle migrations for canonical JSON Schema')\n const tables = schemaJson.tables || {}\n\n for (const [tableName, tableDef] of Object.entries<any>(tables)) {\n sql += `CREATE TABLE IF NOT EXISTS ${tableName} (\\n`\n const columnDefs: string[] = []\n const columns = tableDef.columns || {}\n assertTenantColumn(tableName, columns)\n\n for (const [colName, colDef] of Object.entries<any>(columns)) {\n let colType = 'TEXT'\n const rawType = (colDef.type || '').toUpperCase()\n\n if (rawType === 'UUID') colType = 'UUID'\n else if (rawType.includes('VARCHAR')) colType = 'VARCHAR(255)'\n else if (rawType.includes('NUMBER') || rawType.includes('DECIMAL')) colType = 'NUMERIC(18,2)'\n else if (rawType.includes('TIMESTAMP') || rawType.includes('DATE')) colType = 'TIMESTAMPTZ'\n else if (rawType.includes('INT')) colType = 'BIGINT'\n\n let line = ` ${colName} ${colType}`\n if (colDef.primaryKey) line += ' PRIMARY KEY'\n if (colDef.nullable === false) line += ' NOT NULL'\n if (colDef.default) line += ` DEFAULT ${colDef.default}`\n\n columnDefs.push(line)\n }\n\n sql += columnDefs.join(',\\n') + '\\n);\\n\\n'\n\n if (columns['tenant_id']) {\n sql += `-- Supabase Row Level Security (RLS) for ${tableName}\\n`\n sql += `ALTER TABLE ${tableName} ENABLE ROW LEVEL SECURITY;\\n`\n sql += `DROP POLICY IF EXISTS ${tableName}_tenant_isolation ON ${tableName};\\n`\n sql += `CREATE POLICY ${tableName}_tenant_isolation ON ${tableName} FOR ALL USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);\\n\\n`\n }\n }\n\n return sql\n }\n\n private convertJsonSchemaToOracleSql(_identifier: string, schemaJson: any): string {\n let sql = ''\n if (schemaJson['x-db'] || schemaJson.$defs) throw new Error('Use the data contract reviewed lifecycle migrations for canonical JSON Schema')\n const tables = schemaJson.tables || {}\n\n for (const [tableName, tableDef] of Object.entries<any>(tables)) {\n sql += `CREATE TABLE ${tableName} (\\n`\n const columnDefs: string[] = []\n const columns = tableDef.columns || {}\n assertTenantColumn(tableName, columns)\n\n for (const [colName, colDef] of Object.entries<any>(columns)) {\n let colType = 'VARCHAR2(255)'\n const rawType = (colDef.type || '').toUpperCase()\n\n if (rawType === 'UUID') colType = 'VARCHAR2(36)'\n else if (rawType.includes('VARCHAR')) colType = 'VARCHAR2(255)'\n else if (rawType.includes('NUMBER') || rawType.includes('DECIMAL')) colType = 'NUMBER(18,2)'\n else if (rawType.includes('TIMESTAMP') || rawType.includes('DATE')) colType = 'TIMESTAMP WITH TIME ZONE'\n else if (rawType.includes('INT')) colType = 'NUMBER(19)'\n\n let line = ` ${colName} ${colType}`\n if (colDef.primaryKey) line += ' PRIMARY KEY'\n if (colDef.nullable === false) line += ' NOT NULL'\n\n columnDefs.push(line)\n }\n\n sql += columnDefs.join(',\\n') + '\\n);\\n\\n'\n }\n\n return sql\n }\n}\n\nfunction assertTenantColumn(tableName: string, columns: Record<string, any>): void {\n const tenant = columns.tenant_id\n if (!tenant || tenant.nullable === true) throw new Error(`Schema table ${tableName} must declare a non-null tenant_id column`)\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,168 @@
1
+ // src/lifecycle-engine/platform/deployment.ts
2
+ var deploymentComponentKinds = ["frontend", "api", "mcp", "service", "function", "worker", "job", "webhook", "workflow", "database", "infrastructure", "storage", "cache", "queue", "search", "integration", "native", "model", "data-import"];
3
+ var deploymentActions = ["build", "test", "preview", "provision", "configure", "migrate", "deploy", "verify", "import", "enable"];
4
+ function object(value) {
5
+ return !!value && typeof value === "object" && !Array.isArray(value);
6
+ }
7
+ function nonempty(value) {
8
+ return typeof value === "string" && !!value.trim() && value === value.trim();
9
+ }
10
+ function id(value) {
11
+ return nonempty(value) && /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(value);
12
+ }
13
+ function strings(value, allowEmpty = true) {
14
+ return Array.isArray(value) && (allowEmpty || !!value.length) && value.every(nonempty) && new Set(value).size === value.length;
15
+ }
16
+ function fields(value, allowed) {
17
+ if (Object.keys(value).some((key) => !allowed.includes(key))) throw new Error("Unknown deployment declaration field");
18
+ }
19
+ function mapping(value) {
20
+ return object(value) && Object.entries(value).every(([key, v]) => nonempty(key) && nonempty(v));
21
+ }
22
+ function targetKey(target) {
23
+ return JSON.stringify([target?.environment ?? null, target?.backendId ?? null, target?.databaseId ?? null, target?.tenantId ?? null]);
24
+ }
25
+ function validateDeploymentPlugins(inventory) {
26
+ if (inventory.plugins === void 0) return void 0;
27
+ if (!Array.isArray(inventory.plugins) || !inventory.plugins.length || !strings(inventory.lifecycleBundle, false) || inventory.plugins.length !== inventory.lifecycleBundle.length) throw new Error("Deployment plugins must cover the lifecycle bundle");
28
+ const pluginIds = /* @__PURE__ */ new Set(), assets = new Set(inventory.assets.map((asset) => asset.path));
29
+ for (const plugin of inventory.plugins) {
30
+ if (!object(plugin) || !id(plugin.id) || pluginIds.has(plugin.id) || !inventory.lifecycleBundle.includes(plugin.id) || !Array.isArray(plugin.components) || !Array.isArray(plugin.tasks)) throw new Error("Invalid or duplicate deployment plugin");
31
+ fields(plugin, ["id", "components", "tasks"]);
32
+ pluginIds.add(plugin.id);
33
+ const components = /* @__PURE__ */ new Set(), tasks = /* @__PURE__ */ new Map();
34
+ for (const component of plugin.components) {
35
+ if (!object(component) || !id(component.id) || components.has(component.id) || !deploymentComponentKinds.includes(component.kind) || component.required !== void 0 && typeof component.required !== "boolean" || !["host", "container", "function", "database", "cloud", "native", "external"].includes(component.placement) || component.runtime !== void 0 && !nonempty(component.runtime) || component.assets !== void 0 && (!strings(component.assets) || component.assets.some((path) => !assets.has(path))) || component.assetPatterns !== void 0 && (!strings(component.assetPatterns, false) || component.assetPatterns.some((pattern) => pattern.startsWith("/") || pattern.includes("\\") || pattern.split("/").some((part) => !part || part === "." || part === ".."))) || component.entry !== void 0 && (!nonempty(component.entry) || !assets.has(component.entry)) || component.dataContracts !== void 0 && !mapping(component.dataContracts)) throw new Error("Invalid deployment component or unverified asset reference");
36
+ fields(component, ["id", "kind", "required", "placement", "runtime", "assets", "assetPatterns", "entry", "dataContracts", "requirements"]);
37
+ if (component.requirements !== void 0) {
38
+ const req = component.requirements;
39
+ if (!object(req) || req.tools !== void 0 && !mapping(req.tools) || req.bindings !== void 0 && (!strings(req.bindings) || req.bindings.some((key) => !/^[A-Z][A-Z0-9_]*$/.test(key))) || req.adapters !== void 0 && !strings(req.adapters)) throw new Error("Invalid deployment requirements; declare references, not secret values");
40
+ fields(req, ["tools", "bindings", "adapters"]);
41
+ }
42
+ components.add(component.id);
43
+ }
44
+ for (const task of plugin.tasks) {
45
+ if (!object(task) || !id(task.id) || tasks.has(task.id) || !strings(task.componentIds, false) || task.componentIds.some((ref) => !components.has(ref)) || !deploymentActions.includes(task.action) || !["artifact", "environment", "tenant"].includes(task.scope) || typeof task.required !== "boolean" || !strings(task.dependsOn) || !nonempty(task.executor) || task.argv !== void 0 && (!Array.isArray(task.argv) || !task.argv.length || task.argv.some((arg) => typeof arg !== "string")) || task.instructions !== void 0 && !nonempty(task.instructions)) throw new Error("Invalid deployment task or component reference");
46
+ fields(task, ["id", "componentIds", "action", "scope", "required", "dependsOn", "executor", "argv", "instructions"]);
47
+ if (task.scope === "artifact" && !["build", "test", "verify"].includes(task.action)) throw new Error("Environment-changing work cannot have artifact scope");
48
+ tasks.set(task.id, task);
49
+ }
50
+ const visiting = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set(), scopeRank = { artifact: 0, environment: 1, tenant: 2 };
51
+ const visit = (task) => {
52
+ if (visiting.has(task.id)) throw new Error("Cyclic deployment task dependency");
53
+ if (visited.has(task.id)) return;
54
+ visiting.add(task.id);
55
+ for (const ref of task.dependsOn) {
56
+ const dependency = tasks.get(ref);
57
+ if (!dependency) throw new Error("Unknown deployment task dependency");
58
+ if (scopeRank[dependency.scope] > scopeRank[task.scope]) throw new Error("Deployment dependency has a narrower target scope");
59
+ visit(dependency);
60
+ }
61
+ visiting.delete(task.id);
62
+ visited.add(task.id);
63
+ };
64
+ for (const task of tasks.values()) visit(task);
65
+ if (plugin.components.some((component) => !plugin.tasks.some((task) => (component.required === false || task.required) && task.componentIds.includes(component.id)))) throw new Error("Every required deployment component requires at least one required task; optional components still require declared work");
66
+ if (!components.size && tasks.size) throw new Error("Tasks require deployment components");
67
+ }
68
+ return inventory.plugins;
69
+ }
70
+ function validateDeploymentTarget(value) {
71
+ if (!object(value) || !nonempty(value.environment) || ["backendId", "databaseId", "tenantId"].some((key) => value[key] !== void 0 && !nonempty(value[key]))) throw new Error("Invalid deployment target");
72
+ fields(value, ["environment", "backendId", "databaseId", "tenantId"]);
73
+ }
74
+ function validateDeploymentReceipt(value) {
75
+ if (!object(value) || value.apiVersion !== 1 || !nonempty(value.owner) || typeof value.inventorySha256 !== "string" || !/^[a-f0-9]{64}$/.test(value.inventorySha256) || !Array.isArray(value.results)) throw new Error("Invalid deployment receipt");
76
+ fields(value, ["apiVersion", "owner", "inventorySha256", "results"]);
77
+ const times = /* @__PURE__ */ new Map();
78
+ for (const result of value.results) {
79
+ if (!object(result) || !id(result.pluginId) || !id(result.taskId) || !["running", "succeeded", "failed"].includes(result.status) || !nonempty(result.actor) || !strings(result.evidence, false) || !nonempty(result.recordedAt) || !/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(result.recordedAt) || !Number.isFinite(Date.parse(result.recordedAt)) || new Date(result.recordedAt).toISOString() !== result.recordedAt) throw new Error("Invalid deployment result; actor, timestamp and evidence are required");
80
+ fields(result, ["pluginId", "taskId", "target", "status", "recordedAt", "actor", "evidence", "destinationId", "placementSha256"]);
81
+ if (result.destinationId === void 0 !== (result.placementSha256 === void 0) || result.destinationId !== void 0 && (!id(result.destinationId) || !/^[a-f0-9]{64}$/.test(result.placementSha256))) throw Error("Placement evidence requires destinationId and placementSha256");
82
+ if (result.target !== void 0) validateDeploymentTarget(result.target);
83
+ const key = JSON.stringify([result.pluginId, result.taskId, targetKey(result.target), result.destinationId ?? null, result.placementSha256 ?? null]);
84
+ const time = Date.parse(result.recordedAt);
85
+ if (time <= (times.get(key) ?? -Infinity)) throw new Error("Deployment result timestamps must increase for each task/target");
86
+ times.set(key, time);
87
+ }
88
+ }
89
+ function taskTarget(task, target) {
90
+ if (task.scope === "artifact") return void 0;
91
+ if (!target || task.scope === "tenant" && !target.tenantId) return void 0;
92
+ const { tenantId: _tenantId, ...environment } = target;
93
+ return task.scope === "tenant" ? target : environment;
94
+ }
95
+ function summarizeDeployment(inventory, inventorySha256, receipts = [], target) {
96
+ if (!/^[a-f0-9]{64}$/.test(inventorySha256)) throw new Error("Invalid inventory SHA-256");
97
+ const plugins = validateDeploymentPlugins(inventory);
98
+ if (target !== void 0) validateDeploymentTarget(target);
99
+ const results = /* @__PURE__ */ new Map(), ignoredReceipts = [];
100
+ for (const receipt of receipts) {
101
+ validateDeploymentReceipt(receipt);
102
+ if (receipt.owner !== inventory.owner || receipt.inventorySha256 !== inventorySha256) {
103
+ ignoredReceipts.push({ owner: receipt.owner, reason: receipt.owner !== inventory.owner ? "different-owner" : "stale-inventory" });
104
+ continue;
105
+ }
106
+ for (const result of receipt.results) {
107
+ const task = plugins?.find((plugin2) => plugin2.id === result.pluginId)?.tasks.find((task2) => task2.id === result.taskId);
108
+ if (!task) throw new Error("Receipt references an undeclared deployment task");
109
+ if (result.destinationId !== void 0) {
110
+ if (task.scope === "artifact") throw Error("Artifact evidence must not be bound to a destination");
111
+ ignoredReceipts.push({ owner: receipt.owner, reason: "placement-context-required" });
112
+ continue;
113
+ }
114
+ if (task.scope === "artifact" && result.target !== void 0 || task.scope !== "artifact" && !result.target || task.scope === "environment" && result.target?.tenantId !== void 0 || task.scope === "tenant" && !result.target?.tenantId) throw new Error("Receipt target does not match task scope");
115
+ const plugin = plugins.find((plugin2) => plugin2.id === result.pluginId);
116
+ if (task.scope !== "artifact" && plugin.components.some((component) => component.kind === "database" && task.componentIds.includes(component.id)) && (!result.target?.backendId || !result.target.databaseId)) throw new Error("Database work requires explicit backendId and databaseId evidence");
117
+ const expected = taskTarget(task, target);
118
+ if (task.scope !== "artifact" && !expected || targetKey(result.target) !== targetKey(expected)) continue;
119
+ const key = JSON.stringify([result.pluginId, result.taskId]), old = results.get(key);
120
+ if (old && old.recordedAt === result.recordedAt && JSON.stringify(old) !== JSON.stringify(result)) throw new Error("Conflicting deployment results at the same timestamp");
121
+ if (!old || old.recordedAt < result.recordedAt) results.set(key, result);
122
+ }
123
+ }
124
+ const summaries = (plugins ?? []).map((plugin) => {
125
+ const artifactResolved = !plugin.components.some((component) => component.assetPatterns?.length);
126
+ const states = /* @__PURE__ */ new Map();
127
+ const status = (task) => {
128
+ const known = states.get(task.id);
129
+ if (known) return known;
130
+ const result = results.get(JSON.stringify([plugin.id, task.id]));
131
+ const dependencies = task.dependsOn.map((ref) => status(plugin.tasks.find((task2) => task2.id === ref)));
132
+ const blocked = dependencies.some((dependency) => dependency.status !== "succeeded");
133
+ const stale = result?.status === "succeeded" && dependencies.some((dependency) => dependency.result && dependency.result.recordedAt > result.recordedAt);
134
+ const state = { status: blocked ? "blocked" : stale ? "stale" : result?.status ?? "pending", result };
135
+ states.set(task.id, state);
136
+ return state;
137
+ };
138
+ const tasks = plugin.tasks.map((task) => ({ ...task, ...status(task) }));
139
+ return {
140
+ id: plugin.id,
141
+ artifactResolved,
142
+ complete: artifactResolved && tasks.filter((task) => task.required).every((task) => task.status === "succeeded"),
143
+ components: plugin.components.map((component) => ({ ...component, complete: artifactResolved && tasks.filter((task) => (component.required === false || task.required) && task.componentIds.includes(component.id)).every((task) => task.status === "succeeded") })),
144
+ tasks
145
+ };
146
+ });
147
+ return {
148
+ owner: inventory.owner,
149
+ inventorySha256,
150
+ target,
151
+ coverage: plugins ? "declared" : "legacy-unclassified",
152
+ artifactResolved: !!plugins && summaries.every((plugin) => plugin.artifactResolved),
153
+ complete: !!plugins && summaries.every((plugin) => plugin.complete),
154
+ plugins: summaries,
155
+ ignoredReceipts,
156
+ evidencePolicy: "Operator/host-reported evidence; not independent verification or runtime authorization"
157
+ };
158
+ }
159
+
160
+ export {
161
+ deploymentComponentKinds,
162
+ deploymentActions,
163
+ validateDeploymentPlugins,
164
+ validateDeploymentTarget,
165
+ validateDeploymentReceipt,
166
+ summarizeDeployment
167
+ };
168
+ //# sourceMappingURL=chunk-6CBVZ6CT.js.map