aimeat 2.0.0 → 2.1.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 (412) hide show
  1. package/dist/locales/en.json +35 -1
  2. package/dist/locales/fi.json +35 -1
  3. package/dist/public/components/LinkPreview.js +101 -0
  4. package/dist/public/components/NotificationBell.js +18 -1
  5. package/dist/public/css/theme.css +57 -7
  6. package/dist/public/css/views/admin.css +8 -1
  7. package/dist/public/css/views/app-grant.css +18 -0
  8. package/dist/public/css/views/inbox.css +46 -0
  9. package/dist/public/css/views/portfolio.css +46 -0
  10. package/dist/public/css/views/profile.css +29 -4
  11. package/dist/public/js/services/apps.js +19 -3
  12. package/dist/public/js/services/messages-ai-prompts.js +38 -0
  13. package/dist/public/js/services/messages.js +26 -4
  14. package/dist/public/js/services/notebook.js +76 -0
  15. package/dist/public/js/services/unfurl.js +43 -0
  16. package/dist/public/lib/samples/LICENSE.md +11 -0
  17. package/dist/public/lib/samples/bass/A1.mp3 +0 -0
  18. package/dist/public/lib/samples/bass/B2.mp3 +0 -0
  19. package/dist/public/lib/samples/bass/D2.mp3 +0 -0
  20. package/dist/public/lib/samples/bass/E1.mp3 +0 -0
  21. package/dist/public/lib/samples/bass/E3.mp3 +0 -0
  22. package/dist/public/lib/samples/bass/G2.mp3 +0 -0
  23. package/dist/public/lib/samples/epiano/C2.mp3 +0 -0
  24. package/dist/public/lib/samples/epiano/C3.mp3 +0 -0
  25. package/dist/public/lib/samples/epiano/C4.mp3 +0 -0
  26. package/dist/public/lib/samples/epiano/C5.mp3 +0 -0
  27. package/dist/public/lib/samples/epiano/C6.mp3 +0 -0
  28. package/dist/public/lib/samples/epiano/G2.mp3 +0 -0
  29. package/dist/public/lib/samples/epiano/G3.mp3 +0 -0
  30. package/dist/public/lib/samples/epiano/G4.mp3 +0 -0
  31. package/dist/public/lib/samples/epiano/G5.mp3 +0 -0
  32. package/dist/public/lib/samples/guitar-steel/A2.mp3 +0 -0
  33. package/dist/public/lib/samples/guitar-steel/A4.mp3 +0 -0
  34. package/dist/public/lib/samples/guitar-steel/B3.mp3 +0 -0
  35. package/dist/public/lib/samples/guitar-steel/D3.mp3 +0 -0
  36. package/dist/public/lib/samples/guitar-steel/E2.mp3 +0 -0
  37. package/dist/public/lib/samples/guitar-steel/E4.mp3 +0 -0
  38. package/dist/public/lib/samples/guitar-steel/E5.mp3 +0 -0
  39. package/dist/public/lib/samples/guitar-steel/G3.mp3 +0 -0
  40. package/dist/public/lib/samples/organ/C2.mp3 +0 -0
  41. package/dist/public/lib/samples/organ/C3.mp3 +0 -0
  42. package/dist/public/lib/samples/organ/C4.mp3 +0 -0
  43. package/dist/public/lib/samples/organ/C5.mp3 +0 -0
  44. package/dist/public/lib/samples/organ/C6.mp3 +0 -0
  45. package/dist/public/lib/samples/organ/G2.mp3 +0 -0
  46. package/dist/public/lib/samples/organ/G3.mp3 +0 -0
  47. package/dist/public/lib/samples/organ/G4.mp3 +0 -0
  48. package/dist/public/lib/samples/organ/G5.mp3 +0 -0
  49. package/dist/public/lib/samples/strings/C2.mp3 +0 -0
  50. package/dist/public/lib/samples/strings/C3.mp3 +0 -0
  51. package/dist/public/lib/samples/strings/C4.mp3 +0 -0
  52. package/dist/public/lib/samples/strings/C5.mp3 +0 -0
  53. package/dist/public/lib/samples/strings/C6.mp3 +0 -0
  54. package/dist/public/lib/samples/strings/G2.mp3 +0 -0
  55. package/dist/public/lib/samples/strings/G3.mp3 +0 -0
  56. package/dist/public/lib/samples/strings/G4.mp3 +0 -0
  57. package/dist/public/lib/samples/strings/G5.mp3 +0 -0
  58. package/dist/public/lib/samples/trumpet/A3.mp3 +0 -0
  59. package/dist/public/lib/samples/trumpet/A4.mp3 +0 -0
  60. package/dist/public/lib/samples/trumpet/A5.mp3 +0 -0
  61. package/dist/public/lib/samples/trumpet/C4.mp3 +0 -0
  62. package/dist/public/lib/samples/trumpet/C5.mp3 +0 -0
  63. package/dist/public/lib/samples/trumpet/E3.mp3 +0 -0
  64. package/dist/public/lib/samples/trumpet/E4.mp3 +0 -0
  65. package/dist/public/lib/samples/trumpet/E5.mp3 +0 -0
  66. package/dist/public/spa.html +2 -0
  67. package/dist/public/views/app-grant.js +24 -4
  68. package/dist/public/views/portfolio.js +61 -6
  69. package/dist/public/views/profile/apps-tab.js +18 -1
  70. package/dist/public/views/profile/inbox-tab/ai-actions.js +86 -0
  71. package/dist/public/views/profile/inbox-tab/components.js +124 -9
  72. package/dist/public/views/profile/inbox-tab/helpers.js +26 -0
  73. package/dist/public/views/profile/inbox-tab/panels.js +18 -3
  74. package/dist/public/views/profile/inbox-tab/use-thread-ux.js +18 -1
  75. package/dist/public/views/profile/inbox-tab.js +46 -49
  76. package/dist/public/views/profile/landing-page.cards.js +7 -0
  77. package/dist/public/views/profile/landing-page.js +12 -1
  78. package/dist/public/views/profile/skills-tab.js +1 -1
  79. package/dist/public/views/public-workspace-viewer.js +1 -1
  80. package/dist/public/views/start.js +2 -1
  81. package/dist/scripts/build-sdk-libs.d.ts +16 -0
  82. package/dist/scripts/build-sdk-libs.d.ts.map +1 -0
  83. package/dist/scripts/build-sdk-libs.js +112 -0
  84. package/dist/scripts/build-sdk-libs.js.map +1 -0
  85. package/dist/src/cli/connect/auth.d.ts +15 -0
  86. package/dist/src/cli/connect/auth.d.ts.map +1 -1
  87. package/dist/src/cli/connect/auth.js +25 -6
  88. package/dist/src/cli/connect/auth.js.map +1 -1
  89. package/dist/src/cli/connect/keychain.d.ts +9 -0
  90. package/dist/src/cli/connect/keychain.d.ts.map +1 -1
  91. package/dist/src/cli/connect/keychain.js +21 -8
  92. package/dist/src/cli/connect/keychain.js.map +1 -1
  93. package/dist/src/cli/connect/mcp/tools/exchange.d.ts +18 -0
  94. package/dist/src/cli/connect/mcp/tools/exchange.d.ts.map +1 -0
  95. package/dist/src/cli/connect/mcp/tools/exchange.js +170 -0
  96. package/dist/src/cli/connect/mcp/tools/exchange.js.map +1 -0
  97. package/dist/src/cli/connect/mcp/tools/index.d.ts.map +1 -1
  98. package/dist/src/cli/connect/mcp/tools/index.js +2 -0
  99. package/dist/src/cli/connect/mcp/tools/index.js.map +1 -1
  100. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts +3 -0
  101. package/dist/src/cli/connect/tool-call-defs-exchange.d.ts.map +1 -0
  102. package/dist/src/cli/connect/tool-call-defs-exchange.js +146 -0
  103. package/dist/src/cli/connect/tool-call-defs-exchange.js.map +1 -0
  104. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  105. package/dist/src/cli/connect/tool-call.js +2 -0
  106. package/dist/src/cli/connect/tool-call.js.map +1 -1
  107. package/dist/src/commerce/session-service.d.ts +14 -0
  108. package/dist/src/commerce/session-service.d.ts.map +1 -1
  109. package/dist/src/commerce/session-service.js +1 -1
  110. package/dist/src/commerce/session-service.js.map +1 -1
  111. package/dist/src/data/app-templates/shells.d.ts +7 -3
  112. package/dist/src/data/app-templates/shells.d.ts.map +1 -1
  113. package/dist/src/data/app-templates/shells.js +10 -6
  114. package/dist/src/data/app-templates/shells.js.map +1 -1
  115. package/dist/src/data/appdev-pitfalls.d.ts +2 -0
  116. package/dist/src/data/appdev-pitfalls.d.ts.map +1 -1
  117. package/dist/src/data/appdev-pitfalls.js +24 -1
  118. package/dist/src/data/appdev-pitfalls.js.map +1 -1
  119. package/dist/src/generated/api-types.d.ts +1565 -9
  120. package/dist/src/generated/api-types.d.ts.map +1 -1
  121. package/dist/src/mcp/annotations.d.ts.map +1 -1
  122. package/dist/src/mcp/annotations.js +20 -0
  123. package/dist/src/mcp/annotations.js.map +1 -1
  124. package/dist/src/mcp/apps.d.ts.map +1 -1
  125. package/dist/src/mcp/apps.js +8 -4
  126. package/dist/src/mcp/apps.js.map +1 -1
  127. package/dist/src/mcp/catalog/definitions/exchange.d.ts +18 -0
  128. package/dist/src/mcp/catalog/definitions/exchange.d.ts.map +1 -0
  129. package/dist/src/mcp/catalog/definitions/exchange.js +182 -0
  130. package/dist/src/mcp/catalog/definitions/exchange.js.map +1 -0
  131. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  132. package/dist/src/mcp/catalog/definitions.js +2 -0
  133. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  134. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  135. package/dist/src/mcp/catalog/scopes.js +22 -0
  136. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  137. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  138. package/dist/src/mcp/catalog/surfaces.js +14 -0
  139. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  140. package/dist/src/mcp/exchange-run.d.ts +5 -0
  141. package/dist/src/mcp/exchange-run.d.ts.map +1 -0
  142. package/dist/src/mcp/exchange-run.js +226 -0
  143. package/dist/src/mcp/exchange-run.js.map +1 -0
  144. package/dist/src/mcp/exchange.d.ts +5 -0
  145. package/dist/src/mcp/exchange.d.ts.map +1 -0
  146. package/dist/src/mcp/exchange.js +351 -0
  147. package/dist/src/mcp/exchange.js.map +1 -0
  148. package/dist/src/mcp/extensions.d.ts.map +1 -1
  149. package/dist/src/mcp/extensions.js +11 -0
  150. package/dist/src/mcp/extensions.js.map +1 -1
  151. package/dist/src/mcp/index.d.ts.map +1 -1
  152. package/dist/src/mcp/index.js +6 -2
  153. package/dist/src/mcp/index.js.map +1 -1
  154. package/dist/src/models/app-tool-schemas.d.ts +55 -1
  155. package/dist/src/models/app-tool-schemas.d.ts.map +1 -1
  156. package/dist/src/models/app-tool-schemas.js +20 -1
  157. package/dist/src/models/app-tool-schemas.js.map +1 -1
  158. package/dist/src/models/offer-schemas.d.ts +2 -2
  159. package/dist/src/models/schemas.d.ts +1 -0
  160. package/dist/src/models/schemas.d.ts.map +1 -1
  161. package/dist/src/models/schemas.js +3 -0
  162. package/dist/src/models/schemas.js.map +1 -1
  163. package/dist/src/routes/agents/device-auth.d.ts +4 -0
  164. package/dist/src/routes/agents/device-auth.d.ts.map +1 -1
  165. package/dist/src/routes/agents/device-auth.js +19 -4
  166. package/dist/src/routes/agents/device-auth.js.map +1 -1
  167. package/dist/src/routes/app-grants.d.ts +6 -0
  168. package/dist/src/routes/app-grants.d.ts.map +1 -1
  169. package/dist/src/routes/app-grants.js +35 -2
  170. package/dist/src/routes/app-grants.js.map +1 -1
  171. package/dist/src/routes/apps/fork-manage.d.ts.map +1 -1
  172. package/dist/src/routes/apps/fork-manage.js +24 -1
  173. package/dist/src/routes/apps/fork-manage.js.map +1 -1
  174. package/dist/src/routes/apps/publish.d.ts +2 -0
  175. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  176. package/dist/src/routes/apps/publish.js +27 -1
  177. package/dist/src/routes/apps/publish.js.map +1 -1
  178. package/dist/src/routes/apps-cost.d.ts +25 -0
  179. package/dist/src/routes/apps-cost.d.ts.map +1 -0
  180. package/dist/src/routes/apps-cost.js +107 -0
  181. package/dist/src/routes/apps-cost.js.map +1 -0
  182. package/dist/src/routes/exchange-market.d.ts +28 -0
  183. package/dist/src/routes/exchange-market.d.ts.map +1 -0
  184. package/dist/src/routes/exchange-market.js +454 -0
  185. package/dist/src/routes/exchange-market.js.map +1 -0
  186. package/dist/src/routes/exchange.d.ts +33 -0
  187. package/dist/src/routes/exchange.d.ts.map +1 -0
  188. package/dist/src/routes/exchange.js +395 -0
  189. package/dist/src/routes/exchange.js.map +1 -0
  190. package/dist/src/routes/extensions/entitlement-gate.d.ts +33 -0
  191. package/dist/src/routes/extensions/entitlement-gate.d.ts.map +1 -0
  192. package/dist/src/routes/extensions/entitlement-gate.js +143 -0
  193. package/dist/src/routes/extensions/entitlement-gate.js.map +1 -0
  194. package/dist/src/routes/extensions/manifest.d.ts +9 -0
  195. package/dist/src/routes/extensions/manifest.d.ts.map +1 -1
  196. package/dist/src/routes/extensions/manifest.js +33 -1
  197. package/dist/src/routes/extensions/manifest.js.map +1 -1
  198. package/dist/src/routes/extensions/paywall.d.ts.map +1 -1
  199. package/dist/src/routes/extensions/paywall.js +9 -0
  200. package/dist/src/routes/extensions/paywall.js.map +1 -1
  201. package/dist/src/routes/federation-sync/messaging.d.ts.map +1 -1
  202. package/dist/src/routes/federation-sync/messaging.js +3 -1
  203. package/dist/src/routes/federation-sync/messaging.js.map +1 -1
  204. package/dist/src/routes/ghii/recovery.d.ts +2 -0
  205. package/dist/src/routes/ghii/recovery.d.ts.map +1 -1
  206. package/dist/src/routes/ghii/recovery.js +7 -0
  207. package/dist/src/routes/ghii/recovery.js.map +1 -1
  208. package/dist/src/routes/ghii/register-login.d.ts +4 -0
  209. package/dist/src/routes/ghii/register-login.d.ts.map +1 -1
  210. package/dist/src/routes/ghii/register-login.js +45 -22
  211. package/dist/src/routes/ghii/register-login.js.map +1 -1
  212. package/dist/src/routes/ghii/web-verify.d.ts +5 -0
  213. package/dist/src/routes/ghii/web-verify.d.ts.map +1 -1
  214. package/dist/src/routes/ghii/web-verify.js +24 -3
  215. package/dist/src/routes/ghii/web-verify.js.map +1 -1
  216. package/dist/src/routes/libs/sdk-serve.d.ts +11 -0
  217. package/dist/src/routes/libs/sdk-serve.d.ts.map +1 -0
  218. package/dist/src/routes/libs/sdk-serve.js +53 -0
  219. package/dist/src/routes/libs/sdk-serve.js.map +1 -0
  220. package/dist/src/routes/libs.d.ts +7 -1
  221. package/dist/src/routes/libs.d.ts.map +1 -1
  222. package/dist/src/routes/libs.js +65 -146
  223. package/dist/src/routes/libs.js.map +1 -1
  224. package/dist/src/routes/messages.d.ts +3 -0
  225. package/dist/src/routes/messages.d.ts.map +1 -1
  226. package/dist/src/routes/messages.js +9 -0
  227. package/dist/src/routes/messages.js.map +1 -1
  228. package/dist/src/routes/notifications.d.ts +6 -3
  229. package/dist/src/routes/notifications.d.ts.map +1 -1
  230. package/dist/src/routes/notifications.js +32 -3
  231. package/dist/src/routes/notifications.js.map +1 -1
  232. package/dist/src/routes/organisms/workspace-access.d.ts.map +1 -1
  233. package/dist/src/routes/organisms/workspace-access.js +38 -20
  234. package/dist/src/routes/organisms/workspace-access.js.map +1 -1
  235. package/dist/src/routes/unfurl.d.ts +27 -0
  236. package/dist/src/routes/unfurl.d.ts.map +1 -0
  237. package/dist/src/routes/unfurl.js +180 -0
  238. package/dist/src/routes/unfurl.js.map +1 -0
  239. package/dist/src/routes/upload.d.ts +2 -0
  240. package/dist/src/routes/upload.d.ts.map +1 -1
  241. package/dist/src/routes/upload.js +7 -0
  242. package/dist/src/routes/upload.js.map +1 -1
  243. package/dist/src/routes/webmcp.d.ts +3 -0
  244. package/dist/src/routes/webmcp.d.ts.map +1 -1
  245. package/dist/src/routes/webmcp.js +55 -0
  246. package/dist/src/routes/webmcp.js.map +1 -1
  247. package/dist/src/server-bootstrap/routes-loader.d.ts +1 -0
  248. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  249. package/dist/src/server-bootstrap/routes-loader.js +8 -0
  250. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  251. package/dist/src/services/agent-face.d.ts +10 -2
  252. package/dist/src/services/agent-face.d.ts.map +1 -1
  253. package/dist/src/services/agent-face.js +10 -4
  254. package/dist/src/services/agent-face.js.map +1 -1
  255. package/dist/src/services/app-tool-interfaces.d.ts +37 -0
  256. package/dist/src/services/app-tool-interfaces.d.ts.map +1 -0
  257. package/dist/src/services/app-tool-interfaces.js +101 -0
  258. package/dist/src/services/app-tool-interfaces.js.map +1 -0
  259. package/dist/src/services/build-app-prompt.d.ts +3 -0
  260. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  261. package/dist/src/services/build-app-prompt.js +12 -1
  262. package/dist/src/services/build-app-prompt.js.map +1 -1
  263. package/dist/src/services/contacts.d.ts +25 -1
  264. package/dist/src/services/contacts.d.ts.map +1 -1
  265. package/dist/src/services/contacts.js +30 -0
  266. package/dist/src/services/contacts.js.map +1 -1
  267. package/dist/src/services/entitlement-money.d.ts +55 -0
  268. package/dist/src/services/entitlement-money.d.ts.map +1 -0
  269. package/dist/src/services/entitlement-money.js +68 -0
  270. package/dist/src/services/entitlement-money.js.map +1 -0
  271. package/dist/src/services/exchange-market.d.ts +247 -0
  272. package/dist/src/services/exchange-market.d.ts.map +1 -0
  273. package/dist/src/services/exchange-market.js +254 -0
  274. package/dist/src/services/exchange-market.js.map +1 -0
  275. package/dist/src/services/exchange-proposals.d.ts +47 -0
  276. package/dist/src/services/exchange-proposals.d.ts.map +1 -0
  277. package/dist/src/services/exchange-proposals.js +71 -0
  278. package/dist/src/services/exchange-proposals.js.map +1 -0
  279. package/dist/src/services/exchange-work.d.ts +30 -0
  280. package/dist/src/services/exchange-work.d.ts.map +1 -0
  281. package/dist/src/services/exchange-work.js +43 -0
  282. package/dist/src/services/exchange-work.js.map +1 -0
  283. package/dist/src/services/message-send.d.ts.map +1 -1
  284. package/dist/src/services/message-send.js +4 -1
  285. package/dist/src/services/message-send.js.map +1 -1
  286. package/dist/src/services/metered-entitlements.d.ts +203 -0
  287. package/dist/src/services/metered-entitlements.d.ts.map +1 -0
  288. package/dist/src/services/metered-entitlements.js +264 -0
  289. package/dist/src/services/metered-entitlements.js.map +1 -0
  290. package/dist/src/services/notify.d.ts +7 -0
  291. package/dist/src/services/notify.d.ts.map +1 -1
  292. package/dist/src/services/notify.js +35 -0
  293. package/dist/src/services/notify.js.map +1 -1
  294. package/dist/src/services/owner-memory.d.ts +16 -0
  295. package/dist/src/services/owner-memory.d.ts.map +1 -1
  296. package/dist/src/services/owner-memory.js +23 -0
  297. package/dist/src/services/owner-memory.js.map +1 -1
  298. package/dist/src/services/owner-provisioning.d.ts +5 -0
  299. package/dist/src/services/owner-provisioning.d.ts.map +1 -1
  300. package/dist/src/services/owner-provisioning.js +20 -2
  301. package/dist/src/services/owner-provisioning.js.map +1 -1
  302. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts +1 -0
  303. package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts.map +1 -1
  304. package/dist/src/storage/providers/postgres-kysely/methods/apps.js +2 -0
  305. package/dist/src/storage/providers/postgres-kysely/methods/apps.js.map +1 -1
  306. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts +1 -0
  307. package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts.map +1 -1
  308. package/dist/src/storage/providers/postgres-kysely/methods/identity.js +4 -0
  309. package/dist/src/storage/providers/postgres-kysely/methods/identity.js.map +1 -1
  310. package/dist/src/storage/providers/postgres-kysely/migrations/0011_unique_verified_email.sql +25 -0
  311. package/dist/src/storage/providers/sqlite/methods/apps.d.ts +1 -0
  312. package/dist/src/storage/providers/sqlite/methods/apps.d.ts.map +1 -1
  313. package/dist/src/storage/providers/sqlite/methods/apps.js +2 -0
  314. package/dist/src/storage/providers/sqlite/methods/apps.js.map +1 -1
  315. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts +1 -0
  316. package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts.map +1 -1
  317. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js +4 -0
  318. package/dist/src/storage/providers/sqlite/methods/identity-nodes.js.map +1 -1
  319. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  320. package/dist/src/storage/providers/sqlite/schema.js +20 -0
  321. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  322. package/dist/src/storage/repositories/app.repository.d.ts +0 -0
  323. package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
  324. package/dist/src/storage/repositories/identity.repository.d.ts +6 -0
  325. package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -1
  326. package/dist/src/storage/types/apps.d.ts +1 -0
  327. package/dist/src/storage/types/apps.d.ts.map +1 -1
  328. package/dist/src/storage/types/organisms-federation.d.ts +21 -0
  329. package/dist/src/storage/types/organisms-federation.d.ts.map +1 -1
  330. package/dist/src/utils/app-mobile-lint.d.ts +17 -0
  331. package/dist/src/utils/app-mobile-lint.d.ts.map +1 -0
  332. package/dist/src/utils/app-mobile-lint.js +40 -0
  333. package/dist/src/utils/app-mobile-lint.js.map +1 -0
  334. package/dist/static/app-catalog/_template.html +12 -77
  335. package/dist/static/app-catalog/js/apps-io.js +51 -165
  336. package/dist/static/app-catalog/js/cost.js +100 -0
  337. package/dist/static/app-catalog/js/db.js +23 -93
  338. package/dist/static/app-catalog/js/detail.js +158 -24
  339. package/dist/static/app-catalog/js/favorites.js +71 -0
  340. package/dist/static/app-catalog/js/i18n-data.js +90 -16
  341. package/dist/static/app-catalog/js/main.js +23 -103
  342. package/dist/static/app-catalog/js/migrate.js +88 -0
  343. package/dist/static/app-catalog/js/monetize.js +1 -1
  344. package/dist/static/app-catalog/js/promote.js +70 -0
  345. package/dist/static/app-catalog/js/render.js +26 -139
  346. package/dist/static/app-catalog/js/server-io.js +126 -223
  347. package/dist/static/app-catalog/js/settings.js +11 -204
  348. package/dist/static/app-catalog/styles/app-catalog.css +40 -0
  349. package/dist/static/app-catalog.html +790 -912
  350. package/dist/static/sdk-libs/_core/config.js +52 -0
  351. package/dist/static/sdk-libs/_core/http.js +52 -0
  352. package/dist/static/sdk-libs/_core/namespace.js +33 -0
  353. package/dist/static/sdk-libs/_core/sdk-globals.d.ts +50 -0
  354. package/dist/static/sdk-libs/_core/session.js +66 -0
  355. package/dist/static/sdk-libs/agentface/index.js +102 -0
  356. package/dist/static/sdk-libs/agents/index.js +267 -0
  357. package/dist/static/sdk-libs/ai/index.js +153 -0
  358. package/dist/static/sdk-libs/audio/core.js +111 -0
  359. package/dist/static/sdk-libs/audio/index.js +380 -0
  360. package/dist/static/sdk-libs/audio/instruments.js +369 -0
  361. package/dist/static/sdk-libs/auth/config.js +46 -0
  362. package/dist/static/sdk-libs/auth/crypto.js +166 -0
  363. package/dist/static/sdk-libs/auth/events.js +27 -0
  364. package/dist/static/sdk-libs/auth/i18n.js +64 -0
  365. package/dist/static/sdk-libs/auth/index.js +37 -0
  366. package/dist/static/sdk-libs/auth/modal.js +545 -0
  367. package/dist/static/sdk-libs/auth/pill.js +167 -0
  368. package/dist/static/sdk-libs/auth/session.js +792 -0
  369. package/dist/static/sdk-libs/auth/signup.js +232 -0
  370. package/dist/static/sdk-libs/auth/theme.js +96 -0
  371. package/dist/static/sdk-libs/capabilities/index.js +179 -0
  372. package/dist/static/sdk-libs/commerce/index.js +243 -0
  373. package/dist/static/sdk-libs/data/index.js +188 -0
  374. package/dist/static/sdk-libs/dist/aimeat-agentface.js +91 -0
  375. package/dist/static/sdk-libs/dist/aimeat-agents.js +315 -0
  376. package/dist/static/sdk-libs/dist/aimeat-ai.js +168 -0
  377. package/dist/static/sdk-libs/dist/aimeat-audio.js +979 -0
  378. package/dist/static/sdk-libs/dist/aimeat-auth.js +1831 -0
  379. package/dist/static/sdk-libs/dist/aimeat-capabilities.js +177 -0
  380. package/dist/static/sdk-libs/dist/aimeat-commerce.js +265 -0
  381. package/dist/static/sdk-libs/dist/aimeat-data.js +205 -0
  382. package/dist/static/sdk-libs/dist/aimeat-editor.js +299 -0
  383. package/dist/static/sdk-libs/dist/aimeat-header.js +270 -0
  384. package/dist/static/sdk-libs/dist/aimeat-intake.js +94 -0
  385. package/dist/static/sdk-libs/dist/aimeat-live.js +265 -0
  386. package/dist/static/sdk-libs/dist/aimeat-markdown.js +602 -0
  387. package/dist/static/sdk-libs/dist/aimeat-organism.js +394 -0
  388. package/dist/static/sdk-libs/dist/aimeat-portfolio-standalone.js +90 -0
  389. package/dist/static/sdk-libs/dist/aimeat-social.js +157 -0
  390. package/dist/static/sdk-libs/dist/aimeat-speech.js +300 -0
  391. package/dist/static/sdk-libs/dist/aimeat-storage.js +210 -0
  392. package/dist/static/sdk-libs/dist/aimeat-tunnel.js +383 -0
  393. package/dist/static/sdk-libs/dist/aimeat-wallet.js +118 -0
  394. package/dist/static/sdk-libs/dist/aimeat-webmcp.js +187 -0
  395. package/dist/static/sdk-libs/dist/aimeat-work.js +213 -0
  396. package/dist/static/sdk-libs/dist/aimeat-workflows.js +147 -0
  397. package/dist/static/sdk-libs/editor/index.js +229 -0
  398. package/dist/static/sdk-libs/header/index.js +249 -0
  399. package/dist/static/sdk-libs/intake/index.js +75 -0
  400. package/dist/static/sdk-libs/live/index.js +156 -0
  401. package/dist/static/sdk-libs/markdown/index.js +522 -0
  402. package/dist/static/sdk-libs/organism/index.js +381 -0
  403. package/dist/static/sdk-libs/portfolio-standalone/index.js +78 -0
  404. package/dist/static/sdk-libs/social/index.js +140 -0
  405. package/dist/static/sdk-libs/speech/index.js +321 -0
  406. package/dist/static/sdk-libs/storage/index.js +189 -0
  407. package/dist/static/sdk-libs/tunnel/index.js +428 -0
  408. package/dist/static/sdk-libs/wallet/index.js +115 -0
  409. package/dist/static/sdk-libs/webmcp/index.js +185 -0
  410. package/dist/static/sdk-libs/work/index.js +191 -0
  411. package/dist/static/sdk-libs/workflows/index.js +113 -0
  412. package/package.json +5 -2
@@ -0,0 +1,395 @@
1
+ /**
2
+ * @file src/routes/exchange.ts
3
+ * @description EXCHANGE contract-acceptance surface (TARGET-045) — the WRITE side of the G1 metered
4
+ * entitlement. When a negotiation concludes (a human in an MCP chat, or a closed negotiation agent),
5
+ * the CONSUMER's owner accepts the contract here, which mints the durable entitlement the G2 gateway
6
+ * then honours on every call. Safety by construction: the consumer chooses only the BUDGET (their own
7
+ * spend cap) and the contract ref — the per-call PRICE is read authoritatively from the provider's
8
+ * extension action (`commercial.payMorsels`), so a consumer can neither undercut the provider nor be
9
+ * charged a price they did not accept. The entitlement's consumer is always the caller's own owner
10
+ * (strictly cross-owner via resolveIdentity), so accepting a contract authorises only one's own spend.
11
+ *
12
+ * Slice-1 covers the `morsels` unit (fully in-repo); the money unit rides the same acceptance flow once
13
+ * the Stripe/EE drawdown is wired. Dynamic agent-negotiated pricing (a signed price quote that differs
14
+ * from the list price) is a later addition — slice-1 accepts the provider's listed price + a budget.
15
+ * @structure exchangeRouter — POST /v1/exchange/entitlements · GET /v1/exchange/entitlements ·
16
+ * POST /v1/exchange/entitlements/off
17
+ * @usage
18
+ * import { exchangeRouter } from './routes/exchange.js';
19
+ * app.use(exchangeRouter(config, storage));
20
+ * @version-history
21
+ * v1.3.0 — 2026-07-21 — Agent work (Gap 2): POST /work (start) + /work/:id/deliver (settle on delivery) +
22
+ * GET /work — the async third sellable surface, metered per delivered task via the shared settlement.
23
+ * v1.2.0 — 2026-07-21 — Renegotiation + history: POST/GET /proposals (+ accept/decline/withdraw) with a
24
+ * Profile>Messages notification; GET /entitlements/history + /provider/history (superseded contracts).
25
+ * v1.1.0 — 2026-07-21 — Accept by `offering_id` (works for ext-action AND app-tool kinds; app-tool contract
26
+ * pins the offering's interface version) via the shared resolveOfferingPricing; legacy ext+action retained.
27
+ * v1.0.0 — 2026-07-20 — Initial acceptance surface: mint (authoritative price) / list mine / pause+revoke.
28
+ */
29
+ import { Router } from 'express';
30
+ import { requireAuth } from '../auth/middleware.js';
31
+ import { success, error } from '../middleware/envelope.js';
32
+ import { resolveIdentity } from '../utils/gaii.js';
33
+ import { commerceFeePercent } from '../services/marketplace-fee.js';
34
+ import { percentFee } from '../commerce/money.js';
35
+ import { createEntitlement, readEntitlementForCall, listEntitlementsByConsumer, pauseEntitlement, revokeEntitlement, listEntitlementHistoryByConsumer, listEntitlementHistoryByProvider, } from '../services/metered-entitlements.js';
36
+ import { resolveActionPricing, resolveOfferingPricing, getOffering } from '../services/exchange-market.js';
37
+ import { newProposalId, putProposal, getProposal, listProposalsForOwner, supersedeWithProposal, ownerOfGaii, } from '../services/exchange-proposals.js';
38
+ import { sendDirectMessage } from '../services/message-send.js';
39
+ import { settleMeteredCoordinate } from './extensions/entitlement-gate.js';
40
+ import { newWorkId, putWork, getWork, listWorkByConsumer, listWorkByProvider, } from '../services/exchange-work.js';
41
+ function ownerOf(gaii) {
42
+ return gaii.split('@')[0].split('#').pop() ?? gaii;
43
+ }
44
+ function view(config, e) {
45
+ const rakePct = e.rakePercent ?? commerceFeePercent(config);
46
+ return {
47
+ entitlement_id: e.entitlementId,
48
+ consumer_gaii: e.consumerGaii,
49
+ app_id: e.appId,
50
+ provider: e.providerGhii,
51
+ ext: e.ext,
52
+ action: e.action,
53
+ surface: e.surface ?? null,
54
+ capability: e.capabilityLabel,
55
+ unit: e.unit,
56
+ currency: e.currency,
57
+ price_per_call: e.pricePerCall,
58
+ pricing: e.pricing ?? { model: 'per_call' },
59
+ rake_percent: rakePct,
60
+ rake_per_call: percentFee(e.pricePerCall, rakePct),
61
+ contract_ref: e.contractRef,
62
+ escrow_party: e.escrowParty,
63
+ state: e.state,
64
+ budget: {
65
+ cap_units: e.budget.capUnits,
66
+ spent_units: e.budget.spentUnits,
67
+ remaining_units: e.budget.capUnits === null ? null : Math.max(0, e.budget.capUnits - e.budget.spentUnits),
68
+ calls: e.budget.calls,
69
+ },
70
+ };
71
+ }
72
+ export function exchangeRouter(config, storage) {
73
+ const router = Router();
74
+ /**
75
+ * POST /v1/exchange/entitlements — accept a contract → mint a durable entitlement for the caller's
76
+ * owner. Body: { ext, action, contract_ref, cap_units?, app_id?, escrow_party? }. The per-call price
77
+ * is taken from the provider's ext action (authoritative), never the request.
78
+ */
79
+ router.post('/v1/exchange/entitlements', requireAuth(), async (req, res) => {
80
+ const consumerGaii = resolveIdentity(req.auth, config.nodeId);
81
+ const owner = req.auth.owner;
82
+ const b = (req.body ?? {});
83
+ const capUnits = typeof b.cap_units === 'number' && Number.isFinite(b.cap_units) && b.cap_units >= 0
84
+ ? Math.floor(b.cap_units) : null;
85
+ const appId = typeof b.app_id === 'string' && b.app_id ? b.app_id : null;
86
+ const escrowParty = b.escrow_party === 'consumer' || b.escrow_party === 'provider' ? b.escrow_party : null;
87
+ const planId = typeof b.plan_id === 'string' && b.plan_id ? b.plan_id : null;
88
+ // ── Preferred path: accept an OFFERING by id (works for BOTH ext-action and app-tool kinds). The
89
+ // offering pins the metered coordinate (+ the app-tool interface version); pricing is authoritative. ──
90
+ if (typeof b.offering_id === 'string' && b.offering_id) {
91
+ const contractRef = typeof b.contract_ref === 'string' && b.contract_ref ? b.contract_ref : `offering:${b.offering_id}`;
92
+ const o = await getOffering(storage, b.offering_id);
93
+ if (!o || o.state !== 'listed')
94
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such listed offering'));
95
+ const priced = await resolveOfferingPricing(storage, o, planId);
96
+ if (!priced.ok)
97
+ return res.status(priced.status).json(error(config.nodeId, priced.code, priced.message));
98
+ const minCharge = priced.pricing?.model === 'bundle' ? priced.pricing.blockPrice : priced.pricing?.model === 'subscription' ? priced.pricing.periodPrice : priced.pricePerCall;
99
+ if (capUnits !== null && capUnits < minCharge) {
100
+ return res.status(400).json(error(config.nodeId, 'BUDGET_TOO_LOW', `Budget cap (${capUnits}) is below the ${minCharge}-${priced.unit === 'money' ? priced.currency : 'morsel'} minimum charge`));
101
+ }
102
+ const existing = await readEntitlementForCall(storage, consumerGaii, priced.ext, priced.action);
103
+ const ent = await createEntitlement(storage, {
104
+ consumerGaii, appId, providerGhii: priced.providerGhii, ext: priced.ext, action: priced.action,
105
+ capabilityLabel: priced.capabilityLabel, unit: priced.unit, pricePerCall: priced.pricePerCall,
106
+ currency: priced.currency, pricing: priced.pricing, capUnits, contractRef, surface: priced.surface,
107
+ escrowParty, createdBy: owner, carrySpend: existing,
108
+ });
109
+ return res.status(201).json(success(config.nodeId, { entitlement: view(config, ent) }, [
110
+ { description: 'This app’s cost & contracts', method: 'GET', url: appId ? `/v1/apps/cost?app_id=${encodeURIComponent(appId)}` : '/v1/exchange/entitlements' },
111
+ ]));
112
+ }
113
+ // ── Legacy path: accept a raw ext-action directly by (ext, action). ──
114
+ const ext = typeof b.ext === 'string' ? b.ext : '';
115
+ const action = typeof b.action === 'string' ? b.action : '';
116
+ const contractRef = typeof b.contract_ref === 'string' ? b.contract_ref : '';
117
+ if (!ext || !action || !contractRef) {
118
+ return res.status(400).json(error(config.nodeId, 'BAD_REQUEST', 'ext, action and contract_ref are required (or pass offering_id)'));
119
+ }
120
+ // Resolve the provider + AUTHORITATIVE price from the extension action.
121
+ const extRec = await storage.getExtension(ext);
122
+ if (!extRec)
123
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', `Extension "${ext}" not found`));
124
+ const act = extRec.actions.find(a => a.id === action);
125
+ if (!act)
126
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', `Action "${action}" not found on "${ext}"`));
127
+ // AUTHORITATIVE price + unit + (optional plan) pricing — shared resolver, so a consumer can never
128
+ // undercut the provider. `plan_id` picks a provider-declared bundle/subscription plan; none → per_call.
129
+ const priced = resolveActionPricing(act.commercial, planId);
130
+ if (!priced.ok)
131
+ return res.status(priced.code === 'NOT_PRICED' ? 400 : 404).json(error(config.nodeId, priced.code, `Action "${ext}/${action}": ${priced.message}`));
132
+ const { unit, pricePerCall, currency, pricing } = priced;
133
+ // Budget floor: the cap must cover a single charge (per-call price, or a bundle block / subscription period).
134
+ const minCharge = pricing?.model === 'bundle' ? pricing.blockPrice : pricing?.model === 'subscription' ? pricing.periodPrice : pricePerCall;
135
+ if (capUnits !== null && capUnits < minCharge) {
136
+ return res.status(400).json(error(config.nodeId, 'BUDGET_TOO_LOW', `Budget cap (${capUnits}) is below the ${minCharge}-${unit === 'money' ? currency : 'morsel'} minimum charge`));
137
+ }
138
+ const providerGhii = `${extRec.installedBy}@${config.nodeId}`;
139
+ // Carry spend forward on re-acceptance (renegotiation) so a new contract does not reset the meter.
140
+ const existing = await readEntitlementForCall(storage, consumerGaii, ext, action);
141
+ const ent = await createEntitlement(storage, {
142
+ consumerGaii, appId, providerGhii, ext, action, capabilityLabel: `${ext}/${action}`,
143
+ unit, pricePerCall, currency, pricing, capUnits, contractRef, escrowParty, createdBy: owner,
144
+ carrySpend: existing,
145
+ });
146
+ return res.status(201).json(success(config.nodeId, { entitlement: view(config, ent) }, [
147
+ { description: 'This app’s cost & contracts', method: 'GET', url: appId ? `/v1/apps/cost?app_id=${encodeURIComponent(appId)}` : '/v1/exchange/entitlements' },
148
+ ]));
149
+ });
150
+ /** GET /v1/exchange/entitlements — every entitlement the caller's owner holds (as consumer). */
151
+ router.get('/v1/exchange/entitlements', requireAuth(), async (req, res) => {
152
+ const consumerGaii = resolveIdentity(req.auth, config.nodeId);
153
+ const mine = await listEntitlementsByConsumer(storage, consumerGaii);
154
+ return res.json(success(config.nodeId, { entitlements: mine.map(e => view(config, e)) }));
155
+ });
156
+ /**
157
+ * POST /v1/exchange/entitlements/off — the consumer's off-switch. Body: { ext, action, mode }
158
+ * with mode `pause` (reversible) or `revoke` (terminal). Only the entitlement's own consumer may.
159
+ */
160
+ router.post('/v1/exchange/entitlements/off', requireAuth(), async (req, res) => {
161
+ const consumerGaii = resolveIdentity(req.auth, config.nodeId);
162
+ const owner = req.auth.owner;
163
+ const b = (req.body ?? {});
164
+ const ext = typeof b.ext === 'string' ? b.ext : '';
165
+ const action = typeof b.action === 'string' ? b.action : '';
166
+ const mode = b.mode === 'revoke' ? 'revoke' : 'pause';
167
+ if (!ext || !action)
168
+ return res.status(400).json(error(config.nodeId, 'BAD_REQUEST', 'ext and action are required'));
169
+ const ent = await readEntitlementForCall(storage, consumerGaii, ext, action);
170
+ if (!ent || ownerOf(ent.consumerGaii) !== owner) {
171
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No entitlement of yours for that capability'));
172
+ }
173
+ const ok = mode === 'revoke'
174
+ ? await revokeEntitlement(storage, consumerGaii, ext, action)
175
+ : await pauseEntitlement(storage, consumerGaii, ext, action);
176
+ return res.json(success(config.nodeId, { ext, action, mode, applied: ok }));
177
+ });
178
+ // ── RENEGOTIATION (proposals) + HISTORY ─────────────────────────────────────
179
+ const gh = (owner) => `${owner}@${config.nodeId}`;
180
+ /** Deliver a same-node inbox message (Profile > Messages) to notify a party of a proposal event. */
181
+ async function notify(senderOwner, recipientOwner, subject, body) {
182
+ try {
183
+ await sendDirectMessage({ config, storage, peers: new Map() }, {
184
+ senderGhii: gh(senderOwner), recipientGhii: gh(recipientOwner), body, subject, respondable: false, skipContactGate: true,
185
+ });
186
+ }
187
+ catch { /* a notification failure must not fail the proposal itself */ }
188
+ }
189
+ function proposalView(p) {
190
+ return {
191
+ proposal_id: p.proposalId, consumer_gaii: p.consumerGaii, provider: p.providerGhii,
192
+ ext: p.ext, action: p.action, capability: p.capabilityLabel,
193
+ proposed_by: p.proposedByRole, proposer_owner: p.proposerOwner, counterparty_owner: p.counterpartyOwner,
194
+ new_price_per_call: p.newPricePerCall, new_cap_units: p.newCapUnits, note: p.note,
195
+ current_terms: p.currentTerms, status: p.status, created_at: p.createdAt, resolved_at: p.resolvedAt,
196
+ };
197
+ }
198
+ function historyView(config2, e) {
199
+ return { ...view(config2, e), archived_at: e.archivedAt, archive_reason: e.archiveReason, superseded_by_proposal: e.supersededByProposal };
200
+ }
201
+ /**
202
+ * POST /v1/exchange/proposals — propose new terms for a live contract (renegotiation). Either party may:
203
+ * a consumer renegotiates their own contract; a provider renegotiates a specific consumer's contract
204
+ * (pass `consumer_gaii`). Body: `{ ext, action, consumer_gaii?, new_price_per_call?, new_cap_units?, note? }`.
205
+ * A message is delivered to the counterparty; they accept/decline. Nothing changes until accepted.
206
+ */
207
+ router.post('/v1/exchange/proposals', requireAuth(), async (req, res) => {
208
+ const owner = req.auth.owner;
209
+ const b = (req.body ?? {});
210
+ const ext = typeof b.ext === 'string' ? b.ext : '';
211
+ const action = typeof b.action === 'string' ? b.action : '';
212
+ if (!ext || !action)
213
+ return res.status(400).json(error(config.nodeId, 'BAD_REQUEST', 'ext and action are required'));
214
+ const targetConsumer = typeof b.consumer_gaii === 'string' && b.consumer_gaii ? b.consumer_gaii : resolveIdentity(req.auth, config.nodeId);
215
+ const ent = await readEntitlementForCall(storage, targetConsumer, ext, action);
216
+ if (!ent)
217
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such contract'));
218
+ const isConsumer = ownerOfGaii(ent.consumerGaii) === owner;
219
+ const isProvider = ownerOfGaii(ent.providerGhii) === owner;
220
+ if (!isConsumer && !isProvider)
221
+ return res.status(403).json(error(config.nodeId, 'FORBIDDEN', 'You are not a party to this contract'));
222
+ const proposedByRole = isConsumer ? 'consumer' : 'provider';
223
+ const proposerGhii = proposedByRole === 'consumer' ? ent.consumerGaii : ent.providerGhii;
224
+ const counterpartyGhii = proposedByRole === 'consumer' ? ent.providerGhii : ent.consumerGaii;
225
+ const newPrice = typeof b.new_price_per_call === 'number' && Number.isFinite(b.new_price_per_call) && b.new_price_per_call >= 0 ? Math.floor(b.new_price_per_call) : null;
226
+ const newCap = typeof b.new_cap_units === 'number' && Number.isFinite(b.new_cap_units) && b.new_cap_units >= 0 ? Math.floor(b.new_cap_units) : null;
227
+ if (newPrice === null && newCap === null)
228
+ return res.status(400).json(error(config.nodeId, 'BAD_REQUEST', 'Propose at least a new_price_per_call or new_cap_units'));
229
+ const now = new Date().toISOString();
230
+ const proposal = {
231
+ proposalId: newProposalId(), consumerGaii: ent.consumerGaii, providerGhii: ent.providerGhii,
232
+ ext, action, capabilityLabel: ent.capabilityLabel, proposedByRole,
233
+ proposerGhii, proposerOwner: owner, counterpartyGhii, counterpartyOwner: ownerOfGaii(counterpartyGhii),
234
+ newPricePerCall: newPrice, newCapUnits: newCap, note: typeof b.note === 'string' ? b.note.slice(0, 2000) : '',
235
+ currentTerms: { unit: ent.unit, pricePerCall: ent.pricePerCall, pricingModel: (ent.pricing?.model ?? 'per_call'), capUnits: ent.budget.capUnits },
236
+ status: 'pending', createdAt: now, resolvedAt: null,
237
+ };
238
+ await putProposal(storage, proposal);
239
+ const priceLine = newPrice !== null ? `price → ${newPrice} ${ent.unit === 'money' ? (ent.currency ?? '') : 'morsels'}/call` : '';
240
+ const capLine = newCap !== null ? `budget cap → ${newCap}` : '';
241
+ await notify(owner, proposal.counterpartyOwner, 'EXCHANGE — contract change proposed', `${owner} proposed a change to your contract for ${ent.capabilityLabel}: ${[priceLine, capLine].filter(Boolean).join(', ')}. ${proposal.note ? `Note: ${proposal.note}. ` : ''}Review it in the EXCHANGE app (Proposals) to accept or decline.`);
242
+ return res.status(201).json(success(config.nodeId, { proposal: proposalView(proposal) }));
243
+ });
244
+ /** GET /v1/exchange/proposals — every proposal the caller is party to (incoming + outgoing). */
245
+ router.get('/v1/exchange/proposals', requireAuth(), async (req, res) => {
246
+ const list = await listProposalsForOwner(storage, req.auth.owner);
247
+ return res.json(success(config.nodeId, { proposals: list.map(proposalView), count: list.length }));
248
+ });
249
+ /** POST /v1/exchange/proposals/:id/accept — the COUNTERPARTY accepts → supersede (archive old + mint new). */
250
+ router.post('/v1/exchange/proposals/:id/accept', requireAuth(), async (req, res) => {
251
+ const owner = req.auth.owner;
252
+ const p = await getProposal(storage, typeof req.params.id === 'string' ? req.params.id : '');
253
+ if (!p || p.status !== 'pending')
254
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such pending proposal'));
255
+ if (p.counterpartyOwner !== owner)
256
+ return res.status(403).json(error(config.nodeId, 'FORBIDDEN', 'Only the counterparty may accept this proposal'));
257
+ const ent = await supersedeWithProposal(storage, p);
258
+ if (!ent)
259
+ return res.status(409).json(error(config.nodeId, 'CONTRACT_GONE', 'The contract no longer exists'));
260
+ p.status = 'accepted';
261
+ p.resolvedAt = new Date().toISOString();
262
+ await putProposal(storage, p);
263
+ await notify(owner, p.proposerOwner, 'EXCHANGE — contract change accepted', `${owner} accepted your proposed change to ${p.capabilityLabel}. The new contract is in effect; the previous one is in your contract history.`);
264
+ return res.status(200).json(success(config.nodeId, { proposal: proposalView(p), entitlement: view(config, ent) }));
265
+ });
266
+ /** POST /v1/exchange/proposals/:id/decline — the counterparty declines (no change). */
267
+ router.post('/v1/exchange/proposals/:id/decline', requireAuth(), async (req, res) => {
268
+ const owner = req.auth.owner;
269
+ const p = await getProposal(storage, typeof req.params.id === 'string' ? req.params.id : '');
270
+ if (!p || p.status !== 'pending')
271
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such pending proposal'));
272
+ if (p.counterpartyOwner !== owner)
273
+ return res.status(403).json(error(config.nodeId, 'FORBIDDEN', 'Only the counterparty may decline this proposal'));
274
+ p.status = 'declined';
275
+ p.resolvedAt = new Date().toISOString();
276
+ await putProposal(storage, p);
277
+ await notify(owner, p.proposerOwner, 'EXCHANGE — contract change declined', `${owner} declined your proposed change to ${p.capabilityLabel}. The contract is unchanged.`);
278
+ return res.json(success(config.nodeId, { proposal: proposalView(p) }));
279
+ });
280
+ /** POST /v1/exchange/proposals/:id/withdraw — the PROPOSER withdraws their own pending proposal. */
281
+ router.post('/v1/exchange/proposals/:id/withdraw', requireAuth(), async (req, res) => {
282
+ const owner = req.auth.owner;
283
+ const p = await getProposal(storage, typeof req.params.id === 'string' ? req.params.id : '');
284
+ if (!p || p.status !== 'pending')
285
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such pending proposal'));
286
+ if (p.proposerOwner !== owner)
287
+ return res.status(403).json(error(config.nodeId, 'FORBIDDEN', 'Only the proposer may withdraw'));
288
+ p.status = 'withdrawn';
289
+ p.resolvedAt = new Date().toISOString();
290
+ await putProposal(storage, p);
291
+ return res.json(success(config.nodeId, { proposal: proposalView(p) }));
292
+ });
293
+ /** GET /v1/exchange/entitlements/history — the caller-owner's PAST (archived/superseded) contracts as consumer. */
294
+ router.get('/v1/exchange/entitlements/history', requireAuth(), async (req, res) => {
295
+ const consumerGaii = resolveIdentity(req.auth, config.nodeId);
296
+ const past = await listEntitlementHistoryByConsumer(storage, consumerGaii);
297
+ return res.json(success(config.nodeId, { history: past.map(e => historyView(config, e)), count: past.length }));
298
+ });
299
+ /** GET /v1/exchange/provider/history — the caller-owner's PAST (archived/superseded) contracts as provider. */
300
+ router.get('/v1/exchange/provider/history', requireAuth(), async (req, res) => {
301
+ const providerGhii = resolveIdentity(req.auth, config.nodeId);
302
+ const past = await listEntitlementHistoryByProvider(storage, providerGhii);
303
+ return res.json(success(config.nodeId, { history: past.map(e => historyView(config, e)), count: past.length }));
304
+ });
305
+ // ── AGENT WORK (async surface — settled per delivered task, Gap 2) ───────────
306
+ function workView(w) {
307
+ return {
308
+ work_id: w.workId, offering_id: w.offeringId, consumer: w.consumerGaii, provider: w.providerGhii,
309
+ agent: w.agentGaii, task_type: w.taskType, ext: w.ext, action: w.action, input: w.input, output: w.output,
310
+ note: w.note, state: w.state, unit: w.unit, currency: w.currency, charged_units: w.chargedUnits,
311
+ created_at: w.createdAt, delivered_at: w.deliveredAt,
312
+ };
313
+ }
314
+ /**
315
+ * POST /v1/exchange/work — the CONSUMER starts a task under an agent-work contract. Body:
316
+ * `{ offering_id, input, note? }`. Requires an active metered entitlement for the offering's coordinate
317
+ * (contract first). Nothing is charged yet — the per-task price is metered when the provider DELIVERS.
318
+ */
319
+ router.post('/v1/exchange/work', requireAuth(), async (req, res) => {
320
+ const consumerGaii = resolveIdentity(req.auth, config.nodeId);
321
+ const owner = req.auth.owner;
322
+ const b = (req.body ?? {});
323
+ const offeringId = typeof b.offering_id === 'string' ? b.offering_id : '';
324
+ if (!offeringId)
325
+ return res.status(400).json(error(config.nodeId, 'BAD_REQUEST', 'offering_id is required'));
326
+ const o = await getOffering(storage, offeringId);
327
+ if (!o || o.state !== 'listed' || o.kind !== 'agent-work' || !o.surface || o.surface.kind !== 'agent-work') {
328
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such listed agent-work offering'));
329
+ }
330
+ const ent = await readEntitlementForCall(storage, consumerGaii, o.ext, o.action);
331
+ if (!ent || ent.state !== 'active') {
332
+ return res.status(402).json(error(config.nodeId, 'NO_CONTRACT', 'Accept a contract for this agent-work offering before starting a task'));
333
+ }
334
+ const s = o.surface;
335
+ const now = new Date().toISOString();
336
+ const work = {
337
+ workId: newWorkId(), offeringId, consumerGaii, consumerOwner: owner,
338
+ providerGhii: o.providerGhii, providerOwner: o.providerOwner,
339
+ agentGaii: `${s.agentName}#${o.providerOwner}@${config.nodeId}`, taskType: s.taskType,
340
+ ext: o.ext, action: o.action, input: b.input ?? {}, output: null,
341
+ note: typeof b.note === 'string' ? b.note.slice(0, 2000) : '',
342
+ state: 'open', unit: ent.unit, currency: ent.currency, chargedUnits: 0, createdAt: now, deliveredAt: null,
343
+ };
344
+ await putWork(storage, work);
345
+ await notify(owner, o.providerOwner, 'EXCHANGE — new agent work started', `${owner} started a "${s.taskType}" task for your agent ${s.agentName} (work ${work.workId}). Deliver it in the EXCHANGE app to get paid.`);
346
+ return res.status(201).json(success(config.nodeId, { work: workView(work) }));
347
+ });
348
+ /**
349
+ * POST /v1/exchange/work/:id/deliver — the PROVIDER delivers a task → settle ON DELIVERY (charge the
350
+ * consumer the per-task price, credit the provider, route the rake, decrement the budget). Body:
351
+ * `{ output, note? }`. A 402/429 (budget/rate) leaves the work open and unpaid.
352
+ */
353
+ router.post('/v1/exchange/work/:id/deliver', requireAuth(), async (req, res) => {
354
+ const owner = req.auth.owner;
355
+ const w = await getWork(storage, typeof req.params.id === 'string' ? req.params.id : '');
356
+ if (!w || w.providerOwner !== owner)
357
+ return res.status(404).json(error(config.nodeId, 'NOT_FOUND', 'No such work of yours to deliver'));
358
+ if (w.state !== 'open')
359
+ return res.status(409).json(error(config.nodeId, 'WORK_NOT_OPEN', `Work is ${w.state}`));
360
+ const b = (req.body ?? {});
361
+ // Settle the per-task price against the CONSUMER's contract (the consumer pays; the provider is credited).
362
+ const before = await readEntitlementForCall(storage, w.consumerGaii, w.ext, w.action);
363
+ if (!before || before.state !== 'active') {
364
+ return res.status(402).json(error(config.nodeId, 'CONTRACT_INACTIVE', 'The consumer contract is no longer active — cannot settle this delivery'));
365
+ }
366
+ const outcome = await settleMeteredCoordinate({
367
+ config, storage, coordExt: w.ext, coordAction: w.action, label: `${w.agentGaii}:${w.taskType}`,
368
+ callerGaii: w.consumerGaii, res,
369
+ });
370
+ if (!outcome)
371
+ return res.status(402).json(error(config.nodeId, 'NO_CONTRACT', 'No active contract to settle against'));
372
+ if (!outcome.ok)
373
+ return; // 402/429 already sent (budget/rate) — work stays open
374
+ const after = await readEntitlementForCall(storage, w.consumerGaii, w.ext, w.action);
375
+ const charged = after && before ? Math.max(0, (after.budget.spentUnits) - (before.budget.spentUnits)) : 0;
376
+ w.state = 'delivered';
377
+ w.output = b.output ?? null;
378
+ w.chargedUnits = charged;
379
+ w.deliveredAt = new Date().toISOString();
380
+ if (typeof b.note === 'string' && b.note)
381
+ w.note = b.note.slice(0, 2000);
382
+ await putWork(storage, w);
383
+ await notify(owner, w.consumerOwner, 'EXCHANGE — your agent work was delivered', `Your "${w.taskType}" task (work ${w.workId}) was delivered by ${owner} and charged to your contract. See it in the EXCHANGE app.`);
384
+ return res.json(success(config.nodeId, { work: workView(w) }));
385
+ });
386
+ /** GET /v1/exchange/work?role=consumer|provider — the caller-owner's agent-work items (default: consumer). */
387
+ router.get('/v1/exchange/work', requireAuth(), async (req, res) => {
388
+ const owner = req.auth.owner;
389
+ const role = req.query.role === 'provider' ? 'provider' : 'consumer';
390
+ const items = role === 'provider' ? await listWorkByProvider(storage, owner) : await listWorkByConsumer(storage, owner);
391
+ return res.json(success(config.nodeId, { work: items.map(workView), count: items.length, role }));
392
+ });
393
+ return router;
394
+ }
395
+ //# sourceMappingURL=exchange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../../src/routes/exchange.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAIjC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,iBAAiB,EAAE,sBAAsB,EAAE,0BAA0B,EACrE,gBAAgB,EAAE,iBAAiB,EACnC,gCAAgC,EAAE,gCAAgC,GAEnE,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,WAAW,EAAyB,MAAM,gCAAgC,CAAC;AAClI,OAAO,EACkB,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,qBAAqB,EACrF,qBAAqB,EAAE,WAAW,GACnC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EACW,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,GACpF,MAAM,8BAA8B,CAAC;AAEtC,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,IAAI,CAAC,MAAoB,EAAE,CAAqB;IACvD,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC5D,OAAO;QACL,cAAc,EAAE,CAAC,CAAC,aAAa;QAC/B,aAAa,EAAE,CAAC,CAAC,YAAY;QAC7B,MAAM,EAAE,CAAC,CAAC,KAAK;QACf,QAAQ,EAAE,CAAC,CAAC,YAAY;QACxB,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI;QAC1B,UAAU,EAAE,CAAC,CAAC,eAAe;QAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,cAAc,EAAE,CAAC,CAAC,YAAY;QAC9B,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE;QAC3C,YAAY,EAAE,OAAO;QACrB,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC;QAClD,YAAY,EAAE,CAAC,CAAC,WAAW;QAC3B,YAAY,EAAE,CAAC,CAAC,WAAW;QAC3B,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,MAAM,EAAE;YACN,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ;YAC5B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU;YAChC,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;YACzG,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK;SACtB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAoB,EAAE,OAAgB;IACnE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC5F,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC;YAClG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,MAAM,WAAW,GAAG,CAAC,CAAC,YAAY,KAAK,UAAU,IAAI,CAAC,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3G,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QAE7E,kGAAkG;QAClG,wGAAwG;QACxG,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACvD,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YACxH,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YACpD,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,yBAAyB,CAAC,CAAC,CAAC;YAC1H,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAChE,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YACzG,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;YAC/K,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,GAAG,SAAS,EAAE,CAAC;gBAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAC/D,eAAe,QAAQ,kBAAkB,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;YAClI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAChG,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE;gBAC3C,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM;gBAC9F,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY;gBAC7F,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO;gBAClG,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ;aACpD,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE;gBACrF,EAAE,WAAW,EAAE,6BAA6B,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,wBAAwB,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,2BAA2B,EAAE;aAC9J,CAAC,CAAC,CAAC;QACN,CAAC;QAED,wEAAwE;QACxE,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACpC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,iEAAiE,CAAC,CAAC,CAAC;QACtI,CAAC;QAED,wEAAwE;QACxE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC;QAC5G,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,MAAM,mBAAmB,GAAG,GAAG,CAAC,CAAC,CAAC;QAErH,kGAAkG;QAClG,wGAAwG;QACxG,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,UAA0C,EAAE,MAAM,CAAC,CAAC;QAC5F,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,MAAM,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpK,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACzD,8GAA8G;QAC9G,MAAM,SAAS,GAAG,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;QAC5I,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,GAAG,SAAS,EAAE,CAAC;YAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAC/D,eAAe,QAAQ,kBAAkB,SAAS,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;QACpH,CAAC;QACD,MAAM,YAAY,GAAG,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAE9D,mGAAmG;QACnG,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE;YAC3C,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,IAAI,MAAM,EAAE;YACnF,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK;YAC3F,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE;YACrF,EAAE,WAAW,EAAE,6BAA6B,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,wBAAwB,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,2BAA2B,EAAE;SAC9J,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,gGAAgG;IAChG,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC3F,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,MAAM,0BAA0B,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACrE,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAChG,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACtD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;QACtD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,6BAA6B,CAAC,CAAC,CAAC;QAErH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7E,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,KAAK,EAAE,CAAC;YAChD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,6CAA6C,CAAC,CAAC,CAAC;QAChH,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,KAAK,QAAQ;YAC1B,CAAC,CAAC,MAAM,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC;YAC7D,CAAC,CAAC,MAAM,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC/D,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,MAAM,EAAE,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;IAC1D,oGAAoG;IACpG,KAAK,UAAU,MAAM,CAAC,WAAmB,EAAE,cAAsB,EAAE,OAAe,EAAE,IAAY;QAC9F,IAAI,CAAC;YACH,MAAM,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,EAAoB,EAAE,EAAE;gBAC/E,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,aAAa,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI;aACzH,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAC,8DAA8D,CAAC,CAAC;IAC5E,CAAC;IACD,SAAS,YAAY,CAAC,CAAmB;QACvC,OAAO;YACL,WAAW,EAAE,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,YAAY;YAClF,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,eAAe;YAC3D,WAAW,EAAE,CAAC,CAAC,cAAc,EAAE,cAAc,EAAE,CAAC,CAAC,aAAa,EAAE,kBAAkB,EAAE,CAAC,CAAC,iBAAiB;YACvG,kBAAkB,EAAE,CAAC,CAAC,eAAe,EAAE,aAAa,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;YACjF,aAAa,EAAE,CAAC,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC,UAAU;SACpG,CAAC;IACJ,CAAC;IACD,SAAS,WAAW,CAAC,OAAqB,EAAE,CAA0B;QACpE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,aAAa,EAAE,sBAAsB,EAAE,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC7I,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACzF,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACtD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,6BAA6B,CAAC,CAAC,CAAC;QACrH,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5I,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC/E,IAAI,CAAC,GAAG;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC7F,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,KAAK,CAAC;QAC3D,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,KAAK,CAAC;QAC3D,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,sCAAsC,CAAC,CAAC,CAAC;QACvI,MAAM,cAAc,GAA4B,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QACrF,MAAM,YAAY,GAAG,cAAc,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;QACzF,MAAM,gBAAgB,GAAG,cAAc,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;QAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,kBAAkB,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,kBAAkB,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1K,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpJ,IAAI,QAAQ,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,wDAAwD,CAAC,CAAC,CAAC;QACrK,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAqB;YACjC,UAAU,EAAE,aAAa,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY;YAC3F,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,cAAc;YACjE,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,CAAC,gBAAgB,CAAC;YACtG,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7G,YAAY,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE;YACjJ,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI;SACpD,CAAC;QACF,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACjI,MAAM,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,MAAM,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,iBAAiB,EAAE,qCAAqC,EACnF,GAAG,KAAK,2CAA2C,GAAG,CAAC,eAAe,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,iEAAiE,CAAC,CAAC;QACnP,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,gGAAgG;IAChG,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACxF,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC;QACnE,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC;IAEH,8GAA8G;IAC9G,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACpG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,0BAA0B,CAAC,CAAC,CAAC;QAC7H,IAAI,CAAC,CAAC,iBAAiB,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,gDAAgD,CAAC,CAAC,CAAC;QACpJ,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,+BAA+B,CAAC,CAAC,CAAC;QAC9G,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QAAC,CAAC,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAAC,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9F,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,qCAAqC,EACxE,GAAG,KAAK,qCAAqC,CAAC,CAAC,eAAe,gFAAgF,CAAC,CAAC;QAClJ,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACrH,CAAC,CAAC,CAAC;IAEH,uFAAuF;IACvF,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACrG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,0BAA0B,CAAC,CAAC,CAAC;QAC7H,IAAI,CAAC,CAAC,iBAAiB,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,iDAAiD,CAAC,CAAC,CAAC;QACrJ,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QAAC,CAAC,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAAC,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9F,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,qCAAqC,EAAE,GAAG,KAAK,qCAAqC,CAAC,CAAC,eAAe,8BAA8B,CAAC,CAAC;QAC1K,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,oGAAoG;IACpG,MAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACtG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,0BAA0B,CAAC,CAAC,CAAC;QAC7H,IAAI,CAAC,CAAC,aAAa,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,gCAAgC,CAAC,CAAC,CAAC;QAChI,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;QAAC,CAAC,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAAC,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC/F,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,mHAAmH;IACnH,MAAM,CAAC,GAAG,CAAC,mCAAmC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACnG,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,MAAM,gCAAgC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC3E,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClH,CAAC,CAAC,CAAC;IAEH,+GAA+G;IAC/G,MAAM,CAAC,GAAG,CAAC,+BAA+B,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC/F,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,MAAM,gCAAgC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC3E,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClH,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,SAAS,QAAQ,CAAC,CAAY;QAC5B,OAAO;YACL,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,YAAY;YAChG,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM;YACzG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,YAAY;YAC/F,UAAU,EAAE,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,WAAW;SACrD,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACpF,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,IAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACtD,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,IAAI,CAAC,UAAU;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,yBAAyB,CAAC,CAAC,CAAC;QAC7G,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC3G,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,oCAAoC,CAAC,CAAC,CAAC;QACvG,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACjF,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,uEAAuE,CAAC,CAAC,CAAC;QAC5I,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;QACpB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,IAAI,GAAc;YACtB,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK;YACnE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,aAAa;YAC5D,SAAS,EAAE,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACrF,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI;YAChE,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7D,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI;SAC1G,CAAC;QACF,MAAM,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,mCAAmC,EACtE,GAAG,KAAK,eAAe,CAAC,CAAC,QAAQ,yBAAyB,CAAC,CAAC,SAAS,UAAU,IAAI,CAAC,MAAM,gDAAgD,CAAC,CAAC;QAC9I,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAChG,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,kCAAkC,CAAC,CAAC,CAAC;QACxI,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACjH,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACtD,2GAA2G;QAC3G,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACtF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACzC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,EAAE,yEAAyE,CAAC,CAAC,CAAC;QACpJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC;YAC5C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,QAAQ,EAAE;YAC9F,UAAU,EAAE,CAAC,CAAC,YAAY,EAAE,GAAG;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,sCAAsC,CAAC,CAAC,CAAC;QACvH,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,CAAC,uDAAuD;QAChF,MAAM,KAAK,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACrF,MAAM,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1G,CAAC,CAAC,KAAK,GAAG,WAAW,CAAC;QAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC;QAAC,CAAC,CAAC,YAAY,GAAG,OAAO,CAAC;QAAC,CAAC,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvH,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI;YAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACzE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,0CAA0C,EAC7E,SAAS,CAAC,CAAC,QAAQ,gBAAgB,CAAC,CAAC,MAAM,sBAAsB,KAAK,4DAA4D,CAAC,CAAC;QACtI,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,8GAA8G;IAC9G,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACnF,MAAM,KAAK,GAAG,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC;QAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QACrE,MAAM,KAAK,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACxH,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { Response } from 'express';
2
+ import type { AimeatConfig } from '../../config.js';
3
+ import type { Storage, ExtensionRecord } from '../../storage/interface.js';
4
+ import type { PaywallOutcome } from './paywall.js';
5
+ type ExtAction = ExtensionRecord['actions'][number];
6
+ /**
7
+ * Settle a metered call at a COORDINATE (ext/action strings) through a durable entitlement, or return `null`
8
+ * to fall through to the standard paywall. Shared by the ext raw-invoke path and the app-tool WebMCP invoke
9
+ * path (EXCHANGE cross-app selling). On an `ok:false` outcome a 402/429/500 has already been sent.
10
+ */
11
+ export declare function settleMeteredCoordinate(args: {
12
+ config: AimeatConfig;
13
+ storage: Storage;
14
+ coordExt: string;
15
+ coordAction: string;
16
+ label: string;
17
+ callerGaii: string;
18
+ res: Response;
19
+ }): Promise<PaywallOutcome | null>;
20
+ /**
21
+ * Settle a raw extension invoke through a durable entitlement (the ext-action path wrapper), or return
22
+ * `null` to fall through to the standard paywall.
23
+ */
24
+ export declare function settleViaEntitlement(args: {
25
+ config: AimeatConfig;
26
+ storage: Storage;
27
+ ext: ExtensionRecord;
28
+ action: ExtAction;
29
+ callerGaii: string;
30
+ res: Response;
31
+ }): Promise<PaywallOutcome | null>;
32
+ export {};
33
+ //# sourceMappingURL=entitlement-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entitlement-gate.d.ts","sourceRoot":"","sources":["../../../../src/routes/extensions/entitlement-gate.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAU3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,KAAK,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAepD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,MAAM,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC;CACjI,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA8BjC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,MAAM,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC;CACpH,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAMjC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @file src/routes/extensions/entitlement-gate.ts
3
+ * @description G2 — the metered-call GATEWAY for EXCHANGE (TARGET-045). When a cross-owner caller holds a
4
+ * durable {@link MeteredEntitlement} for the exact (ext, action) it is invoking, this takes over the
5
+ * commercial settlement instead of the per-call one-time token: it authorises against the entitlement's
6
+ * budget cap, moves the value, and applies the platform RAKE — all at the node (the trust boundary a
7
+ * client-side app could never enforce). It is purely ADDITIVE: with no entitlement it returns `null` and
8
+ * the existing paywall channels (one-time money token / plain morsel charge) run unchanged.
9
+ *
10
+ * The PRICING MODEL ({@link computeCharge}) decides what THIS call costs (per_call → base price; bundle →
11
+ * 0 within quota, block price on refill; subscription → 0 within a paid period + rate-limited, period fee
12
+ * on renewal). The SETTLEMENT RAIL (the entitlement `unit`) decides how that amount moves:
13
+ * - `morsels` — atomic in-repo debit/credit + rake via {@link settleMarketplaceFee}.
14
+ * - `money` — real EUR/USD accrual via {@link settleEntitlementMoney} (off the morsel ledger).
15
+ * @structure settleMeteredCoordinate · settleViaEntitlement (ext wrapper) · settleMorsels · settleMoney
16
+ * @version-history
17
+ * v1.3.0 — 2026-07-21 — Generalised to a metered COORDINATE (ext, action strings) so it settles app-tool
18
+ * calls too (EXCHANGE cross-app selling, Gap 1); settleViaEntitlement is now the ext wrapper.
19
+ * v1.2.0 — 2026-07-20 — Pricing models (Phase B): computeCharge drives per-call amount (bundle/subscription + rate limit).
20
+ * v1.1.0 — 2026-07-20 — Wire the money unit to the accrual rail (real EUR/USD); split morsel/money settlement.
21
+ * v1.0.0 — 2026-07-20 — Initial G2 gateway: entitlement authorise + morsel settlement + platform rake.
22
+ */
23
+ import { randomUUID } from 'node:crypto';
24
+ import { error } from '../../middleware/envelope.js';
25
+ import { paymentChallenge } from '../../commerce/x402.js';
26
+ import { percentFee, formatMoneyMajor } from '../../commerce/money.js';
27
+ import { commerceFeePercent, settleMarketplaceFee } from '../../services/marketplace-fee.js';
28
+ import { readEntitlementForCall, budgetAllows, commitSpend, refundSpend, computeCharge, } from '../../services/metered-entitlements.js';
29
+ import { settleEntitlementMoney, refundEntitlementMoney } from '../../services/entitlement-money.js';
30
+ import { logger } from '../../utils/logger.js';
31
+ /**
32
+ * Settle a metered call at a COORDINATE (ext/action strings) through a durable entitlement, or return `null`
33
+ * to fall through to the standard paywall. Shared by the ext raw-invoke path and the app-tool WebMCP invoke
34
+ * path (EXCHANGE cross-app selling). On an `ok:false` outcome a 402/429/500 has already been sent.
35
+ */
36
+ export async function settleMeteredCoordinate(args) {
37
+ const { config, storage, coordExt, coordAction, label, callerGaii, res } = args;
38
+ const ent = await readEntitlementForCall(storage, callerGaii, coordExt, coordAction);
39
+ if (!ent)
40
+ return null; // no contract for this call → standard paywall applies
41
+ if (ent.state !== 'active') {
42
+ res.status(402).json({ ...error(config.nodeId, 'ENTITLEMENT_INACTIVE', `Your EXCHANGE entitlement for ${label} is ${ent.state} (contract ${ent.contractRef}).`),
43
+ ...paymentChallenge(config) });
44
+ return { ok: false };
45
+ }
46
+ // Pricing model decides the per-call charge (bundle quota / subscription period + rate limit).
47
+ const decision = computeCharge(ent, Date.now());
48
+ if (!decision.allowed) {
49
+ res.status(429).json(error(config.nodeId, 'RATE_LIMITED', `Your EXCHANGE subscription for ${label} is over its rate limit — retry shortly (contract ${ent.contractRef}).`));
50
+ return { ok: false };
51
+ }
52
+ // Budget cap is checked against THIS call's charge (a refill/renewal may cost a block/period fee).
53
+ if (!budgetAllows(ent, decision.chargeUnits)) {
54
+ const cap = ent.unit === 'money' ? `${formatMoneyMajor(ent.budget.capUnits ?? 0)} ${ent.currency ?? ''}`.trim() : `${ent.budget.capUnits} morsel`;
55
+ res.status(402).json({ ...error(config.nodeId, 'BUDGET_EXHAUSTED', `Your EXCHANGE entitlement for ${label} has spent its ${cap} budget (contract ${ent.contractRef}).`),
56
+ ...paymentChallenge(config) });
57
+ return { ok: false };
58
+ }
59
+ const settleArgs = { config, storage, coordExt, coordAction, label, callerGaii, res, ent, charge: decision.chargeUnits, newPricing: decision.pricing };
60
+ return ent.unit === 'money' ? settleMoney(settleArgs) : settleMorsels(settleArgs);
61
+ }
62
+ /**
63
+ * Settle a raw extension invoke through a durable entitlement (the ext-action path wrapper), or return
64
+ * `null` to fall through to the standard paywall.
65
+ */
66
+ export async function settleViaEntitlement(args) {
67
+ return settleMeteredCoordinate({
68
+ config: args.config, storage: args.storage,
69
+ coordExt: args.ext.name, coordAction: args.action.id, label: `${args.ext.name}/${args.action.id}`,
70
+ callerGaii: args.callerGaii, res: args.res,
71
+ });
72
+ }
73
+ /** Morsel rail: atomic debit caller / credit provider cut / route rake for THIS call's charge, then commit. */
74
+ async function settleMorsels({ config, storage, coordExt, coordAction, label, callerGaii, res, ent, charge, newPricing }) {
75
+ const price = Math.max(0, charge);
76
+ const rakePct = ent.rakePercent ?? commerceFeePercent(config);
77
+ const fee = percentFee(price, rakePct); // ceils — a positive charge always carries its rake
78
+ const providerCut = price - fee;
79
+ const track = `exchange:${coordExt}:${coordAction}:${ent.contractRef}`;
80
+ const ts = new Date().toISOString();
81
+ if (price > 0) {
82
+ const debited = await storage.debitBalance(callerGaii, price);
83
+ if (!debited) {
84
+ res.status(402).json({ ...error(config.nodeId, 'INSUFFICIENT_MORSELS', `This EXCHANGE call costs ${price} morsels and your balance does not cover it`), ...paymentChallenge(config) });
85
+ return { ok: false };
86
+ }
87
+ if (providerCut > 0) {
88
+ const credited = await storage.creditBalance(ent.providerGhii, providerCut);
89
+ if (!credited) {
90
+ await storage.creditBalance(callerGaii, price);
91
+ logger.error('[entitlement-gate] provider credit failed; refunded caller', { label, provider: ent.providerGhii });
92
+ res.status(500).json(error(config.nodeId, 'SETTLEMENT_FAILED', 'Payment could not be settled to the provider; you were not charged'));
93
+ return { ok: false };
94
+ }
95
+ await storage.addTransaction({ id: `xchg-earn-${randomUUID()}`, gaii: ent.providerGhii, type: 'extension_earn', amount: providerCut, counterpartyGaii: callerGaii, trackingCode: track, timestamp: ts });
96
+ }
97
+ await storage.addTransaction({ id: `xchg-pay-${randomUUID()}`, gaii: callerGaii, type: 'extension_pay', amount: -price, counterpartyGaii: ent.providerGhii, trackingCode: track, timestamp: ts });
98
+ await settleMarketplaceFee(storage, config, { fee, payerGhii: callerGaii, trackingCode: track, source: 'exchange' });
99
+ }
100
+ await commitSpend(storage, ent, price, newPricing);
101
+ return {
102
+ ok: true,
103
+ refund: async () => {
104
+ if (price > 0) {
105
+ if (providerCut > 0)
106
+ await storage.debitBalance(ent.providerGhii, providerCut);
107
+ await storage.creditBalance(callerGaii, price);
108
+ }
109
+ await refundSpend(storage, callerGaii, coordExt, coordAction, price);
110
+ logger.warn(`[entitlement-gate] refunded ${price} morsels (script threw after payment)`, { label });
111
+ },
112
+ };
113
+ }
114
+ /** Money rail: accrue a REAL currency obligation for THIS call's charge (buyer → provider, minus rake), then commit. */
115
+ async function settleMoney({ config, storage, coordExt, coordAction, label, callerGaii, res, ent, charge, newPricing }) {
116
+ const price = Math.max(0, charge); // micro-units
117
+ const currency = ent.currency ?? 'EUR';
118
+ const rakePct = ent.rakePercent ?? commerceFeePercent(config);
119
+ const reference = `exchange:${coordExt}:${coordAction}:${ent.contractRef}`;
120
+ let trackingCode = '';
121
+ if (price > 0) {
122
+ const settled = await settleEntitlementMoney(storage, config, {
123
+ consumerGhii: callerGaii, providerGhii: ent.providerGhii, priceMicros: price, currency, feePct: rakePct, reference,
124
+ });
125
+ if (!settled.ok) {
126
+ res.status(402).json({ ...error(config.nodeId, 'MONEY_SETTLEMENT_UNAVAILABLE', `This EXCHANGE call is priced ${formatMoneyMajor(price)} ${currency} but the money rail could not settle (${settled.reason}).`),
127
+ ...paymentChallenge(config) });
128
+ return { ok: false };
129
+ }
130
+ trackingCode = settled.trackingCode;
131
+ }
132
+ await commitSpend(storage, ent, price, newPricing);
133
+ return {
134
+ ok: true,
135
+ refund: async () => {
136
+ if (price > 0)
137
+ await refundEntitlementMoney(storage, config, { consumerGhii: callerGaii, providerGhii: ent.providerGhii, priceMicros: price, currency, trackingCode });
138
+ await refundSpend(storage, callerGaii, coordExt, coordAction, price);
139
+ logger.warn(`[entitlement-gate] refunded ${formatMoneyMajor(price)} ${currency} (script threw after payment)`, { label });
140
+ },
141
+ };
142
+ }
143
+ //# sourceMappingURL=entitlement-gate.js.map