@nxuss/lemma 1.43.0 → 1.44.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 (322) hide show
  1. package/README.md +1 -1
  2. package/bin/brain-ingest.js +18 -0
  3. package/bin/cloud.js +228 -0
  4. package/dist/cjs/cli/hostHooks.d.ts +6 -0
  5. package/dist/cjs/cli/hostHooks.d.ts.map +1 -1
  6. package/dist/cjs/cli/hostHooks.js +13 -3
  7. package/dist/cjs/cli/hostHooks.js.map +1 -1
  8. package/dist/cjs/cloud/CloudBrainClient.d.ts +52 -0
  9. package/dist/cjs/cloud/CloudBrainClient.d.ts.map +1 -0
  10. package/dist/cjs/cloud/CloudBrainClient.js +161 -0
  11. package/dist/cjs/cloud/CloudBrainClient.js.map +1 -0
  12. package/dist/cjs/cloud/CloudConfig.d.ts +41 -0
  13. package/dist/cjs/cloud/CloudConfig.d.ts.map +1 -0
  14. package/dist/cjs/cloud/CloudConfig.js +133 -0
  15. package/dist/cjs/cloud/CloudConfig.js.map +1 -0
  16. package/dist/cjs/cloud/CloudEntitlement.d.ts +55 -0
  17. package/dist/cjs/cloud/CloudEntitlement.d.ts.map +1 -0
  18. package/dist/cjs/cloud/CloudEntitlement.js +174 -0
  19. package/dist/cjs/cloud/CloudEntitlement.js.map +1 -0
  20. package/dist/cjs/cloud/billing/stripeApi.d.ts +43 -0
  21. package/dist/cjs/cloud/billing/stripeApi.d.ts.map +1 -0
  22. package/dist/cjs/cloud/billing/stripeApi.js +111 -0
  23. package/dist/cjs/cloud/billing/stripeApi.js.map +1 -0
  24. package/dist/cjs/cloud/billing/stripeWebhook.d.ts +35 -0
  25. package/dist/cjs/cloud/billing/stripeWebhook.d.ts.map +1 -0
  26. package/dist/cjs/cloud/billing/stripeWebhook.js +185 -0
  27. package/dist/cjs/cloud/billing/stripeWebhook.js.map +1 -0
  28. package/dist/cjs/cloud/console/ConsoleStore.d.ts +111 -0
  29. package/dist/cjs/cloud/console/ConsoleStore.d.ts.map +1 -0
  30. package/dist/cjs/cloud/console/ConsoleStore.js +172 -0
  31. package/dist/cjs/cloud/console/ConsoleStore.js.map +1 -0
  32. package/dist/cjs/cloud/console/consoleRouter.d.ts +68 -0
  33. package/dist/cjs/cloud/console/consoleRouter.d.ts.map +1 -0
  34. package/dist/cjs/cloud/console/consoleRouter.js +263 -0
  35. package/dist/cjs/cloud/console/consoleRouter.js.map +1 -0
  36. package/dist/cjs/cloud/console/mailer.d.ts +22 -0
  37. package/dist/cjs/cloud/console/mailer.d.ts.map +1 -0
  38. package/dist/cjs/cloud/console/mailer.js +35 -0
  39. package/dist/cjs/cloud/console/mailer.js.map +1 -0
  40. package/dist/cjs/cloud/identity/PlanPolicy.d.ts +16 -1
  41. package/dist/cjs/cloud/identity/PlanPolicy.d.ts.map +1 -1
  42. package/dist/cjs/cloud/identity/PlanPolicy.js +47 -7
  43. package/dist/cjs/cloud/identity/PlanPolicy.js.map +1 -1
  44. package/dist/cjs/cloud/identity/RateLimiter.d.ts +21 -1
  45. package/dist/cjs/cloud/identity/RateLimiter.d.ts.map +1 -1
  46. package/dist/cjs/cloud/identity/RateLimiter.js +59 -2
  47. package/dist/cjs/cloud/identity/RateLimiter.js.map +1 -1
  48. package/dist/cjs/cloud/identity/TenantResolver.d.ts +4 -1
  49. package/dist/cjs/cloud/identity/TenantResolver.d.ts.map +1 -1
  50. package/dist/cjs/cloud/identity/TenantResolver.js +1 -1
  51. package/dist/cjs/cloud/identity/TenantResolver.js.map +1 -1
  52. package/dist/cjs/cloud/identity/authenticateV2.d.ts.map +1 -1
  53. package/dist/cjs/cloud/identity/authenticateV2.js +7 -4
  54. package/dist/cjs/cloud/identity/authenticateV2.js.map +1 -1
  55. package/dist/cjs/cloud/identity/identityStore.d.ts +85 -10
  56. package/dist/cjs/cloud/identity/identityStore.d.ts.map +1 -1
  57. package/dist/cjs/cloud/identity/identityStore.js +184 -2
  58. package/dist/cjs/cloud/identity/identityStore.js.map +1 -1
  59. package/dist/cjs/cloud/metering/PostgresLedgerStore.d.ts +16 -0
  60. package/dist/cjs/cloud/metering/PostgresLedgerStore.d.ts.map +1 -0
  61. package/dist/cjs/cloud/metering/PostgresLedgerStore.js +44 -0
  62. package/dist/cjs/cloud/metering/PostgresLedgerStore.js.map +1 -0
  63. package/dist/cjs/cloud/metering/UsageLedger.d.ts +37 -0
  64. package/dist/cjs/cloud/metering/UsageLedger.d.ts.map +1 -1
  65. package/dist/cjs/cloud/metering/UsageLedger.js +80 -17
  66. package/dist/cjs/cloud/metering/UsageLedger.js.map +1 -1
  67. package/dist/cjs/cloud/metering/index.d.ts +1 -0
  68. package/dist/cjs/cloud/metering/index.d.ts.map +1 -1
  69. package/dist/cjs/cloud/metering/index.js +1 -0
  70. package/dist/cjs/cloud/metering/index.js.map +1 -1
  71. package/dist/cjs/cloud/store/FileBrainStore.d.ts +1 -0
  72. package/dist/cjs/cloud/store/FileBrainStore.d.ts.map +1 -1
  73. package/dist/cjs/cloud/store/FileBrainStore.js +3 -0
  74. package/dist/cjs/cloud/store/FileBrainStore.js.map +1 -1
  75. package/dist/cjs/cloud/store/PostgresBrainStore.d.ts +1 -0
  76. package/dist/cjs/cloud/store/PostgresBrainStore.d.ts.map +1 -1
  77. package/dist/cjs/cloud/store/PostgresBrainStore.js +4 -0
  78. package/dist/cjs/cloud/store/PostgresBrainStore.js.map +1 -1
  79. package/dist/cjs/cloud/v2/app.d.ts.map +1 -1
  80. package/dist/cjs/cloud/v2/app.js +6 -0
  81. package/dist/cjs/cloud/v2/app.js.map +1 -1
  82. package/dist/cjs/cloud/v2/inputGuard.d.ts +23 -0
  83. package/dist/cjs/cloud/v2/inputGuard.d.ts.map +1 -0
  84. package/dist/cjs/cloud/v2/inputGuard.js +71 -0
  85. package/dist/cjs/cloud/v2/inputGuard.js.map +1 -0
  86. package/dist/cjs/cloud/v2/routes/admin.d.ts +24 -0
  87. package/dist/cjs/cloud/v2/routes/admin.d.ts.map +1 -0
  88. package/dist/cjs/cloud/v2/routes/admin.js +329 -0
  89. package/dist/cjs/cloud/v2/routes/admin.js.map +1 -0
  90. package/dist/cjs/cloud/v2/routes/entitlement.d.ts +13 -0
  91. package/dist/cjs/cloud/v2/routes/entitlement.d.ts.map +1 -0
  92. package/dist/cjs/cloud/v2/routes/entitlement.js +24 -0
  93. package/dist/cjs/cloud/v2/routes/entitlement.js.map +1 -0
  94. package/dist/cjs/cloud/v2/routes/index.d.ts +14 -1
  95. package/dist/cjs/cloud/v2/routes/index.d.ts.map +1 -1
  96. package/dist/cjs/cloud/v2/routes/index.js +36 -0
  97. package/dist/cjs/cloud/v2/routes/index.js.map +1 -1
  98. package/dist/cjs/cloud/v2/routes/memories.d.ts +21 -2
  99. package/dist/cjs/cloud/v2/routes/memories.d.ts.map +1 -1
  100. package/dist/cjs/cloud/v2/routes/memories.js +77 -0
  101. package/dist/cjs/cloud/v2/routes/memories.js.map +1 -1
  102. package/dist/cjs/cloud/v2/routes/recall.d.ts +1 -0
  103. package/dist/cjs/cloud/v2/routes/recall.d.ts.map +1 -1
  104. package/dist/cjs/cloud/v2/routes/recall.js +4 -0
  105. package/dist/cjs/cloud/v2/routes/recall.js.map +1 -1
  106. package/dist/cjs/cloud/v2/routes/tenant.d.ts +35 -0
  107. package/dist/cjs/cloud/v2/routes/tenant.d.ts.map +1 -0
  108. package/dist/cjs/cloud/v2/routes/tenant.js +62 -0
  109. package/dist/cjs/cloud/v2/routes/tenant.js.map +1 -0
  110. package/dist/cjs/cloud/v2/routes/usage.d.ts +1 -1
  111. package/dist/cjs/cloud/v2/routes/usage.d.ts.map +1 -1
  112. package/dist/cjs/cloud/v2/routes/verify.d.ts +1 -0
  113. package/dist/cjs/cloud/v2/routes/verify.d.ts.map +1 -1
  114. package/dist/cjs/cloud/v2/routes/verify.js +4 -0
  115. package/dist/cjs/cloud/v2/routes/verify.js.map +1 -1
  116. package/dist/cjs/cloud/v2/server.d.ts +9 -3
  117. package/dist/cjs/cloud/v2/server.d.ts.map +1 -1
  118. package/dist/cjs/cloud/v2/server.js +36 -2
  119. package/dist/cjs/cloud/v2/server.js.map +1 -1
  120. package/dist/cjs/cloud/v2/usageRecorder.d.ts +19 -0
  121. package/dist/cjs/cloud/v2/usageRecorder.d.ts.map +1 -0
  122. package/dist/cjs/cloud/v2/usageRecorder.js +42 -0
  123. package/dist/cjs/cloud/v2/usageRecorder.js.map +1 -0
  124. package/dist/cjs/contracts/api-v2.types.d.ts +90 -2
  125. package/dist/cjs/contracts/api-v2.types.d.ts.map +1 -1
  126. package/dist/cjs/contracts/store.d.ts +2 -0
  127. package/dist/cjs/contracts/store.d.ts.map +1 -1
  128. package/dist/cjs/mcp/index.js +3 -0
  129. package/dist/cjs/mcp/index.js.map +1 -1
  130. package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
  131. package/dist/cjs/mcp/tools/memory.js +74 -4
  132. package/dist/cjs/mcp/tools/memory.js.map +1 -1
  133. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  134. package/dist/cjs/mcp/tools.js.map +1 -1
  135. package/dist/cjs/proxy/KeyManager.d.ts.map +1 -1
  136. package/dist/cjs/proxy/KeyManager.js +5 -0
  137. package/dist/cjs/proxy/KeyManager.js.map +1 -1
  138. package/dist/cjs/subconscious/CloudBrain.d.ts +77 -0
  139. package/dist/cjs/subconscious/CloudBrain.d.ts.map +1 -0
  140. package/dist/cjs/subconscious/CloudBrain.js +347 -0
  141. package/dist/cjs/subconscious/CloudBrain.js.map +1 -0
  142. package/dist/cjs/subconscious/ProjectIdentity.d.ts +9 -0
  143. package/dist/cjs/subconscious/ProjectIdentity.d.ts.map +1 -0
  144. package/dist/cjs/subconscious/ProjectIdentity.js +63 -0
  145. package/dist/cjs/subconscious/ProjectIdentity.js.map +1 -0
  146. package/dist/cjs/subconscious/TeamBrain.d.ts +9 -3
  147. package/dist/cjs/subconscious/TeamBrain.d.ts.map +1 -1
  148. package/dist/cjs/subconscious/TeamBrain.js +39 -5
  149. package/dist/cjs/subconscious/TeamBrain.js.map +1 -1
  150. package/dist/cjs/utils/ProLicense.d.ts.map +1 -1
  151. package/dist/cjs/utils/ProLicense.js +11 -3
  152. package/dist/cjs/utils/ProLicense.js.map +1 -1
  153. package/dist/cjs/utils/SessionCapture.d.ts +2 -0
  154. package/dist/cjs/utils/SessionCapture.d.ts.map +1 -1
  155. package/dist/cjs/utils/SessionCapture.js +5 -0
  156. package/dist/cjs/utils/SessionCapture.js.map +1 -1
  157. package/dist/cjs/utils/StopNudge.d.ts +8 -0
  158. package/dist/cjs/utils/StopNudge.d.ts.map +1 -0
  159. package/dist/cjs/utils/StopNudge.js +93 -0
  160. package/dist/cjs/utils/StopNudge.js.map +1 -0
  161. package/dist/esm/cli/hostHooks.d.ts +6 -0
  162. package/dist/esm/cli/hostHooks.d.ts.map +1 -1
  163. package/dist/esm/cli/hostHooks.js +12 -2
  164. package/dist/esm/cli/hostHooks.js.map +1 -1
  165. package/dist/esm/cloud/CloudBrainClient.d.ts +52 -0
  166. package/dist/esm/cloud/CloudBrainClient.d.ts.map +1 -0
  167. package/dist/esm/cloud/CloudBrainClient.js +153 -0
  168. package/dist/esm/cloud/CloudBrainClient.js.map +1 -0
  169. package/dist/esm/cloud/CloudConfig.d.ts +41 -0
  170. package/dist/esm/cloud/CloudConfig.d.ts.map +1 -0
  171. package/dist/esm/cloud/CloudConfig.js +118 -0
  172. package/dist/esm/cloud/CloudConfig.js.map +1 -0
  173. package/dist/esm/cloud/CloudEntitlement.d.ts +55 -0
  174. package/dist/esm/cloud/CloudEntitlement.d.ts.map +1 -0
  175. package/dist/esm/cloud/CloudEntitlement.js +159 -0
  176. package/dist/esm/cloud/CloudEntitlement.js.map +1 -0
  177. package/dist/esm/cloud/billing/stripeApi.d.ts +43 -0
  178. package/dist/esm/cloud/billing/stripeApi.d.ts.map +1 -0
  179. package/dist/esm/cloud/billing/stripeApi.js +103 -0
  180. package/dist/esm/cloud/billing/stripeApi.js.map +1 -0
  181. package/dist/esm/cloud/billing/stripeWebhook.d.ts +35 -0
  182. package/dist/esm/cloud/billing/stripeWebhook.d.ts.map +1 -0
  183. package/dist/esm/cloud/billing/stripeWebhook.js +176 -0
  184. package/dist/esm/cloud/billing/stripeWebhook.js.map +1 -0
  185. package/dist/esm/cloud/console/ConsoleStore.d.ts +111 -0
  186. package/dist/esm/cloud/console/ConsoleStore.d.ts.map +1 -0
  187. package/dist/esm/cloud/console/ConsoleStore.js +161 -0
  188. package/dist/esm/cloud/console/ConsoleStore.js.map +1 -0
  189. package/dist/esm/cloud/console/consoleRouter.d.ts +68 -0
  190. package/dist/esm/cloud/console/consoleRouter.d.ts.map +1 -0
  191. package/dist/esm/cloud/console/consoleRouter.js +252 -0
  192. package/dist/esm/cloud/console/consoleRouter.js.map +1 -0
  193. package/dist/esm/cloud/console/mailer.d.ts +22 -0
  194. package/dist/esm/cloud/console/mailer.d.ts.map +1 -0
  195. package/dist/esm/cloud/console/mailer.js +30 -0
  196. package/dist/esm/cloud/console/mailer.js.map +1 -0
  197. package/dist/esm/cloud/identity/PlanPolicy.d.ts +16 -1
  198. package/dist/esm/cloud/identity/PlanPolicy.d.ts.map +1 -1
  199. package/dist/esm/cloud/identity/PlanPolicy.js +46 -6
  200. package/dist/esm/cloud/identity/PlanPolicy.js.map +1 -1
  201. package/dist/esm/cloud/identity/RateLimiter.d.ts +21 -1
  202. package/dist/esm/cloud/identity/RateLimiter.d.ts.map +1 -1
  203. package/dist/esm/cloud/identity/RateLimiter.js +57 -2
  204. package/dist/esm/cloud/identity/RateLimiter.js.map +1 -1
  205. package/dist/esm/cloud/identity/TenantResolver.d.ts +4 -1
  206. package/dist/esm/cloud/identity/TenantResolver.d.ts.map +1 -1
  207. package/dist/esm/cloud/identity/TenantResolver.js +1 -1
  208. package/dist/esm/cloud/identity/TenantResolver.js.map +1 -1
  209. package/dist/esm/cloud/identity/authenticateV2.d.ts.map +1 -1
  210. package/dist/esm/cloud/identity/authenticateV2.js +7 -4
  211. package/dist/esm/cloud/identity/authenticateV2.js.map +1 -1
  212. package/dist/esm/cloud/identity/identityStore.d.ts +85 -10
  213. package/dist/esm/cloud/identity/identityStore.d.ts.map +1 -1
  214. package/dist/esm/cloud/identity/identityStore.js +180 -1
  215. package/dist/esm/cloud/identity/identityStore.js.map +1 -1
  216. package/dist/esm/cloud/metering/PostgresLedgerStore.d.ts +16 -0
  217. package/dist/esm/cloud/metering/PostgresLedgerStore.d.ts.map +1 -0
  218. package/dist/esm/cloud/metering/PostgresLedgerStore.js +40 -0
  219. package/dist/esm/cloud/metering/PostgresLedgerStore.js.map +1 -0
  220. package/dist/esm/cloud/metering/UsageLedger.d.ts +37 -0
  221. package/dist/esm/cloud/metering/UsageLedger.d.ts.map +1 -1
  222. package/dist/esm/cloud/metering/UsageLedger.js +78 -16
  223. package/dist/esm/cloud/metering/UsageLedger.js.map +1 -1
  224. package/dist/esm/cloud/metering/index.d.ts +1 -0
  225. package/dist/esm/cloud/metering/index.d.ts.map +1 -1
  226. package/dist/esm/cloud/metering/index.js +1 -0
  227. package/dist/esm/cloud/metering/index.js.map +1 -1
  228. package/dist/esm/cloud/store/FileBrainStore.d.ts +1 -0
  229. package/dist/esm/cloud/store/FileBrainStore.d.ts.map +1 -1
  230. package/dist/esm/cloud/store/FileBrainStore.js +3 -0
  231. package/dist/esm/cloud/store/FileBrainStore.js.map +1 -1
  232. package/dist/esm/cloud/store/PostgresBrainStore.d.ts +1 -0
  233. package/dist/esm/cloud/store/PostgresBrainStore.d.ts.map +1 -1
  234. package/dist/esm/cloud/store/PostgresBrainStore.js +4 -0
  235. package/dist/esm/cloud/store/PostgresBrainStore.js.map +1 -1
  236. package/dist/esm/cloud/v2/app.d.ts.map +1 -1
  237. package/dist/esm/cloud/v2/app.js +6 -0
  238. package/dist/esm/cloud/v2/app.js.map +1 -1
  239. package/dist/esm/cloud/v2/inputGuard.d.ts +23 -0
  240. package/dist/esm/cloud/v2/inputGuard.d.ts.map +1 -0
  241. package/dist/esm/cloud/v2/inputGuard.js +63 -0
  242. package/dist/esm/cloud/v2/inputGuard.js.map +1 -0
  243. package/dist/esm/cloud/v2/routes/admin.d.ts +24 -0
  244. package/dist/esm/cloud/v2/routes/admin.d.ts.map +1 -0
  245. package/dist/esm/cloud/v2/routes/admin.js +322 -0
  246. package/dist/esm/cloud/v2/routes/admin.js.map +1 -0
  247. package/dist/esm/cloud/v2/routes/entitlement.d.ts +13 -0
  248. package/dist/esm/cloud/v2/routes/entitlement.d.ts.map +1 -0
  249. package/dist/esm/cloud/v2/routes/entitlement.js +21 -0
  250. package/dist/esm/cloud/v2/routes/entitlement.js.map +1 -0
  251. package/dist/esm/cloud/v2/routes/index.d.ts +14 -1
  252. package/dist/esm/cloud/v2/routes/index.d.ts.map +1 -1
  253. package/dist/esm/cloud/v2/routes/index.js +37 -1
  254. package/dist/esm/cloud/v2/routes/index.js.map +1 -1
  255. package/dist/esm/cloud/v2/routes/memories.d.ts +21 -2
  256. package/dist/esm/cloud/v2/routes/memories.d.ts.map +1 -1
  257. package/dist/esm/cloud/v2/routes/memories.js +75 -0
  258. package/dist/esm/cloud/v2/routes/memories.js.map +1 -1
  259. package/dist/esm/cloud/v2/routes/recall.d.ts +1 -0
  260. package/dist/esm/cloud/v2/routes/recall.d.ts.map +1 -1
  261. package/dist/esm/cloud/v2/routes/recall.js +5 -1
  262. package/dist/esm/cloud/v2/routes/recall.js.map +1 -1
  263. package/dist/esm/cloud/v2/routes/tenant.d.ts +35 -0
  264. package/dist/esm/cloud/v2/routes/tenant.d.ts.map +1 -0
  265. package/dist/esm/cloud/v2/routes/tenant.js +58 -0
  266. package/dist/esm/cloud/v2/routes/tenant.js.map +1 -0
  267. package/dist/esm/cloud/v2/routes/usage.d.ts +1 -1
  268. package/dist/esm/cloud/v2/routes/usage.d.ts.map +1 -1
  269. package/dist/esm/cloud/v2/routes/verify.d.ts +1 -0
  270. package/dist/esm/cloud/v2/routes/verify.d.ts.map +1 -1
  271. package/dist/esm/cloud/v2/routes/verify.js +5 -1
  272. package/dist/esm/cloud/v2/routes/verify.js.map +1 -1
  273. package/dist/esm/cloud/v2/server.d.ts +9 -3
  274. package/dist/esm/cloud/v2/server.d.ts.map +1 -1
  275. package/dist/esm/cloud/v2/server.js +36 -3
  276. package/dist/esm/cloud/v2/server.js.map +1 -1
  277. package/dist/esm/cloud/v2/usageRecorder.d.ts +19 -0
  278. package/dist/esm/cloud/v2/usageRecorder.d.ts.map +1 -0
  279. package/dist/esm/cloud/v2/usageRecorder.js +37 -0
  280. package/dist/esm/cloud/v2/usageRecorder.js.map +1 -0
  281. package/dist/esm/contracts/api-v2.types.d.ts +90 -2
  282. package/dist/esm/contracts/api-v2.types.d.ts.map +1 -1
  283. package/dist/esm/contracts/store.d.ts +2 -0
  284. package/dist/esm/contracts/store.d.ts.map +1 -1
  285. package/dist/esm/mcp/index.js +3 -0
  286. package/dist/esm/mcp/index.js.map +1 -1
  287. package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
  288. package/dist/esm/mcp/tools/memory.js +74 -4
  289. package/dist/esm/mcp/tools/memory.js.map +1 -1
  290. package/dist/esm/mcp/tools.d.ts.map +1 -1
  291. package/dist/esm/mcp/tools.js.map +1 -1
  292. package/dist/esm/proxy/KeyManager.d.ts.map +1 -1
  293. package/dist/esm/proxy/KeyManager.js +5 -0
  294. package/dist/esm/proxy/KeyManager.js.map +1 -1
  295. package/dist/esm/subconscious/CloudBrain.d.ts +77 -0
  296. package/dist/esm/subconscious/CloudBrain.d.ts.map +1 -0
  297. package/dist/esm/subconscious/CloudBrain.js +330 -0
  298. package/dist/esm/subconscious/CloudBrain.js.map +1 -0
  299. package/dist/esm/subconscious/ProjectIdentity.d.ts +9 -0
  300. package/dist/esm/subconscious/ProjectIdentity.d.ts.map +1 -0
  301. package/dist/esm/subconscious/ProjectIdentity.js +56 -0
  302. package/dist/esm/subconscious/ProjectIdentity.js.map +1 -0
  303. package/dist/esm/subconscious/TeamBrain.d.ts +9 -3
  304. package/dist/esm/subconscious/TeamBrain.d.ts.map +1 -1
  305. package/dist/esm/subconscious/TeamBrain.js +39 -7
  306. package/dist/esm/subconscious/TeamBrain.js.map +1 -1
  307. package/dist/esm/utils/ProLicense.d.ts.map +1 -1
  308. package/dist/esm/utils/ProLicense.js +11 -3
  309. package/dist/esm/utils/ProLicense.js.map +1 -1
  310. package/dist/esm/utils/SessionCapture.d.ts +2 -0
  311. package/dist/esm/utils/SessionCapture.d.ts.map +1 -1
  312. package/dist/esm/utils/SessionCapture.js +5 -0
  313. package/dist/esm/utils/SessionCapture.js.map +1 -1
  314. package/dist/esm/utils/StopNudge.d.ts +8 -0
  315. package/dist/esm/utils/StopNudge.d.ts.map +1 -0
  316. package/dist/esm/utils/StopNudge.js +86 -0
  317. package/dist/esm/utils/StopNudge.js.map +1 -0
  318. package/lemma-proxy.cjs +5 -0
  319. package/package.json +2 -1
  320. package/sdks/crewai/dist/ts/src/client.d.ts +5 -1
  321. package/sdks/crewai/dist/ts/src/client.js +8 -0
  322. package/sdks/crewai/dist/ts/src/types.d.ts +32 -1
@@ -2,13 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PostgresRateLimiter = exports.InMemoryRateLimiter = void 0;
4
4
  exports.rateLimitErrorBody = rateLimitErrorBody;
5
- function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl) {
5
+ exports.monthBucket = monthBucket;
6
+ exports.nextMonthStart = nextMonthStart;
7
+ function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl, window = 'day') {
8
+ const scope = window === 'month' ? 'requests this month' : 'requests in the current window';
6
9
  return {
7
10
  error: {
8
11
  code: 'rate_limited',
9
12
  status: 429,
10
- message: `rate limit exceeded: ${decision.used}/${decision.limit} requests in the current window. ` +
13
+ message: `rate limit exceeded: ${decision.used}/${decision.limit} ${scope}. ` +
11
14
  `Back off and retry after ${retryAfterSeconds}s, or upgrade at ${upgradeUrl}.`,
15
+ window,
12
16
  limit: decision.limit,
13
17
  used: decision.used,
14
18
  remaining: decision.remaining,
@@ -18,10 +22,21 @@ function rateLimitErrorBody(decision, retryAfterSeconds, upgradeUrl) {
18
22
  },
19
23
  };
20
24
  }
25
+ /** Bucket id of the calendar month (UTC) that contains `now`, e.g. `m:2026-10`. Text, so it shares the daily buckets' table without clashing. */
26
+ function monthBucket(now) {
27
+ const d = new Date(now);
28
+ return `m:${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
29
+ }
30
+ /** First instant (epoch ms) of the UTC month after the one containing `now`. */
31
+ function nextMonthStart(now) {
32
+ const d = new Date(now);
33
+ return Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
34
+ }
21
35
  /** In-process fixed-window limiter. Suitable for single-instance dev and tests. */
22
36
  class InMemoryRateLimiter {
23
37
  constructor() {
24
38
  this.buckets = new Map();
39
+ this.months = new Map();
25
40
  }
26
41
  async consume(tenantId, limit, windowMs, now = Date.now()) {
27
42
  const bucket = Math.floor(now / windowMs);
@@ -46,6 +61,24 @@ class InMemoryRateLimiter {
46
61
  resetAt,
47
62
  };
48
63
  }
64
+ async peek(tenantId, windowMs, now = Date.now()) {
65
+ return this.buckets.get(`${tenantId}:${Math.floor(now / windowMs)}`)?.count ?? 0;
66
+ }
67
+ async consumeMonthly(tenantId, limit, now = Date.now()) {
68
+ const bucket = monthBucket(now);
69
+ // Keep only the current month, as the daily map does: no background timers.
70
+ for (const k of this.months.keys()) {
71
+ if (!k.endsWith(`:${bucket}`))
72
+ this.months.delete(k);
73
+ }
74
+ const key = `${tenantId}:${bucket}`;
75
+ const used = (this.months.get(key) ?? 0) + 1;
76
+ this.months.set(key, used);
77
+ return { allowed: used <= limit, used, limit, remaining: Math.max(0, limit - used), resetAt: nextMonthStart(now) };
78
+ }
79
+ async peekMonthly(tenantId, now = Date.now()) {
80
+ return this.months.get(`${tenantId}:${monthBucket(now)}`) ?? 0;
81
+ }
49
82
  }
50
83
  exports.InMemoryRateLimiter = InMemoryRateLimiter;
51
84
  /** Postgres-backed fixed-window limiter, atomic via a single upsert. */
@@ -70,6 +103,30 @@ class PostgresRateLimiter {
70
103
  resetAt: (bucket + 1) * windowMs,
71
104
  };
72
105
  }
106
+ async peek(tenantId, windowMs, now = Date.now()) {
107
+ const { rows } = await this.pool.query('SELECT request_count FROM tenant_rate_limits WHERE tenant_id = $1 AND bucket = $2', [
108
+ tenantId,
109
+ String(Math.floor(now / windowMs)),
110
+ ]);
111
+ return Number(rows[0]?.request_count ?? 0);
112
+ }
113
+ async consumeMonthly(tenantId, limit, now = Date.now()) {
114
+ const { rows } = await this.pool.query(`INSERT INTO tenant_rate_limits (tenant_id, bucket, request_count)
115
+ VALUES ($1, $2, 1)
116
+ ON CONFLICT (tenant_id, bucket) DO UPDATE
117
+ SET request_count = tenant_rate_limits.request_count + 1,
118
+ updated_at = CURRENT_TIMESTAMP
119
+ RETURNING request_count`, [tenantId, monthBucket(now)]);
120
+ const used = Number(rows[0]?.request_count ?? 1);
121
+ return { allowed: used <= limit, used, limit, remaining: Math.max(0, limit - used), resetAt: nextMonthStart(now) };
122
+ }
123
+ async peekMonthly(tenantId, now = Date.now()) {
124
+ const { rows } = await this.pool.query('SELECT request_count FROM tenant_rate_limits WHERE tenant_id = $1 AND bucket = $2', [
125
+ tenantId,
126
+ monthBucket(now),
127
+ ]);
128
+ return Number(rows[0]?.request_count ?? 0);
129
+ }
73
130
  }
74
131
  exports.PostgresRateLimiter = PostgresRateLimiter;
75
132
  //# sourceMappingURL=RateLimiter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../../../src/cloud/identity/RateLimiter.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  import type { IdentityStore } from './identityStore';
2
+ import type { PlanId } from './PlanPolicy';
2
3
  export interface Tenant {
3
4
  id: string;
4
- plan: 'free' | 'pro' | 'scale';
5
+ plan: PlanId;
5
6
  keyId: string;
7
+ /** Human label of the presented key (e.g. "dev-a"); recorded as the memory's author. */
8
+ keyName?: string;
6
9
  }
7
10
  export declare class TenantResolver {
8
11
  private readonly store;
@@ -1 +1 @@
1
- {"version":3,"file":"TenantResolver.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,QAAQ,CAAC,IAAI,OAAO;gBAES,KAAK,EAAE,aAAa;IAEjD;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAY3D;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"TenantResolver.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,QAAQ,CAAC,IAAI,OAAO;gBAES,KAAK,EAAE,aAAa;IAEjD;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAY3D;AAED,eAAe,cAAc,CAAC"}
@@ -32,7 +32,7 @@ class TenantResolver {
32
32
  return null;
33
33
  if (record.expiresAt !== null && Date.now() > record.expiresAt)
34
34
  return null;
35
- return { id: record.tenantId, plan: record.plan, keyId: record.id };
35
+ return { id: record.tenantId, plan: record.plan, keyId: record.id, keyName: record.name };
36
36
  }
37
37
  }
38
38
  exports.TenantResolver = TenantResolver;
@@ -1 +1 @@
1
- {"version":3,"file":"TenantResolver.js","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACH,qCAAuD;AASvD,MAAa,cAAc;IAGzB,YAA6B,KAAoB;QAApB,UAAK,GAAL,KAAK,CAAe;QAFxC,SAAI,GAAG,GAAG,CAAC;IAEgC,CAAC;IAErD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,IAAI,CAAC,IAAA,wBAAe,EAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/C,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,WAAW,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5E,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;IACtE,CAAC;CACF;AAtBD,wCAsBC;AAED,kBAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"TenantResolver.js","sourceRoot":"","sources":["../../../../src/cloud/identity/TenantResolver.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACH,qCAAuD;AAYvD,MAAa,cAAc;IAGzB,YAA6B,KAAoB;QAApB,UAAK,GAAL,KAAK,CAAe;QAFxC,SAAI,GAAG,GAAG,CAAC;IAEgC,CAAC;IAErD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,IAAI,CAAC,IAAA,wBAAe,EAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/C,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,WAAW,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5E,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5F,CAAC;CACF;AAtBD,wCAsBC;AAED,kBAAe,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticateV2.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gEAAgE;YAChE,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CA0CvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"authenticateV2.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gEAAgE;YAChE,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBhE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CA6CvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,eAAe,cAAc,CAAC"}
@@ -41,16 +41,19 @@ function authenticateV2(deps) {
41
41
  return;
42
42
  }
43
43
  if (deps.rateLimiter) {
44
- const limit = policy.limitsFor(tenant.plan).dailyRequests;
45
- const decision = await deps.rateLimiter.consume(tenant.id, limit, windowMs, now());
44
+ const limits = policy.limitsFor(tenant.plan);
45
+ const daily = await deps.rateLimiter.consume(tenant.id, limits.dailyRequests, windowMs, now());
46
+ // A request the day already refused does not eat the month's allowance.
47
+ const decision = !daily.allowed || !deps.rateLimiter.consumeMonthly
48
+ ? daily
49
+ : await deps.rateLimiter.consumeMonthly(tenant.id, limits.monthlyRequests, now());
46
50
  if (!decision.allowed) {
47
51
  const retryAfter = Math.max(1, Math.ceil((decision.resetAt - now()) / 1000));
48
- const upgradeUrl = policy.limitsFor(tenant.plan).upgradeUrl;
49
52
  res
50
53
  .status(429)
51
54
  .set('Retry-After', String(retryAfter))
52
55
  .set('WWW-Authenticate', 'Bearer')
53
- .json((0, RateLimiter_1.rateLimitErrorBody)(decision, retryAfter, upgradeUrl));
56
+ .json((0, RateLimiter_1.rateLimitErrorBody)(decision, retryAfter, limits.upgradeUrl, decision === daily ? 'day' : 'month'));
54
57
  return;
55
58
  }
56
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"authenticateV2.js","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authenticateV2.js","sourceRoot":"","sources":["../../../../src/cloud/identity/authenticateV2.ts"],"names":[],"mappings":";;;AA+DA,wCA6CC;AA7FD,mDAAuD;AACvD,6CAAgE;AA8FvD,qGA9FY,iCAAoB,OA8FZ;AA5F7B,+CAAmD;AA0BnD,SAAS,WAAW,CAAC,MAA0B;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,IAAI,sBAAa,CAAC;QACvB,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,4BAA4B;KACtC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,IAAwB;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,uBAAU,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,IAAI,iCAAoB,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAEjC,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC9B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAErD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxF,OAAO;YACT,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC/F,wEAAwE;gBACxE,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc;oBACjE,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;gBAEpF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;oBACtB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;oBAC7E,GAAG;yBACA,MAAM,CAAC,GAAG,CAAC;yBACX,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;yBACtC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,CAAC;yBACjC,IAAI,CAAC,IAAA,gCAAkB,EAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC3G,OAAO;gBACT,CAAC;YACH,CAAC;YAEA,GAA4B,CAAC,MAAM,GAAG,MAAM,CAAC;YAC9C,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAGD,kBAAe,cAAc,CAAC"}
@@ -1,13 +1,3 @@
1
- /**
2
- * Lemma API v2 — identity store (Lane D)
3
- *
4
- * Persistence behind TenantResolver. Keys are stored as SHA-256 hashes only:
5
- * `key_hash` is the sole column that ever touches key material, and every write
6
- * is a parameterized insert that receives the hash, never the plaintext value.
7
- *
8
- * `InMemoryIdentityStore` powers unit tests and local/dev defaults.
9
- * `PostgresIdentityStore` is the production implementation over `pg`.
10
- */
11
1
  import type { Pool } from 'pg';
12
2
  import type { KeyPrefix } from './ApiKey';
13
3
  import type { PlanId } from './PlanPolicy';
@@ -30,6 +20,45 @@ export interface KeyRecord {
30
20
  expiresAt: number | null;
31
21
  revokedAt: number | null;
32
22
  }
23
+ /** What Stripe last told us about the tenant's subscription. Display and webhook bookkeeping only: quota code reads `plan`. */
24
+ export interface TenantBilling {
25
+ customerId: string | null;
26
+ subscriptionId: string | null;
27
+ /** Stripe's subscription status verbatim (active, past_due, canceled, ...). */
28
+ status: string | null;
29
+ /** Epoch ms of the end of the paid period: the next charge, or the last day of service when cancelling. */
30
+ currentPeriodEnd: number | null;
31
+ /** Epoch ms of the first failed payment of the current late streak; null while paid up. */
32
+ pastDueSince: number | null;
33
+ /** Epoch ms `created` of the last Stripe event applied; older events are dropped (delivery is unordered). */
34
+ eventAt: number | null;
35
+ }
36
+ export declare const NO_BILLING: Readonly<TenantBilling>;
37
+ export interface TenantRecord {
38
+ id: string;
39
+ name: string;
40
+ plan: PlanId;
41
+ createdAt: number;
42
+ billing: TenantBilling;
43
+ }
44
+ /** Outcome of applying a Stripe event to a tenant. */
45
+ export type BillingApplyResult = {
46
+ ok: true;
47
+ tenant: TenantRecord;
48
+ } | {
49
+ ok: false;
50
+ reason: 'no_tenant' | 'stale';
51
+ };
52
+ /** Outcome of an atomic "issue a key if the tenant still has a free seat". */
53
+ export type SeatedKeyResult = {
54
+ ok: true;
55
+ key: KeyRecord;
56
+ } | {
57
+ ok: false;
58
+ reason: 'no_tenant' | 'seats_full' | 'duplicate_name';
59
+ seats: number;
60
+ used: number;
61
+ };
33
62
  export interface IdentityStore {
34
63
  /** Look up a key by its hash. The ONLY read path — plaintext never enters a query. */
35
64
  findKeyByHash(hash: string): Promise<KeyRecord | null>;
@@ -37,12 +66,47 @@ export interface IdentityStore {
37
66
  createKey(input: NewKeyInput): Promise<KeyRecord>;
38
67
  /** Soft-revoke: the key dies on the NEXT lookup. No 24h cache can survive this. */
39
68
  revokeKey(keyId: string): Promise<boolean>;
69
+ /** Create a tenant; resolves null when the id is already taken. */
70
+ createTenant(input: {
71
+ id: string;
72
+ name: string;
73
+ plan: PlanId;
74
+ }): Promise<TenantRecord | null>;
75
+ getTenant(id: string): Promise<TenantRecord | null>;
76
+ setTenantPlan(id: string, plan: PlanId): Promise<TenantRecord | null>;
77
+ findTenantByStripeCustomer(customerId: string): Promise<TenantRecord | null>;
78
+ /**
79
+ * Write the plan and the full billing state in one statement, unless a NEWER Stripe event was
80
+ * already applied (`billing.eventAt` older than the stored one): then nothing changes and the
81
+ * result says `stale`. The caller passes the complete state, so a field is cleared by sending null.
82
+ */
83
+ applyBilling(id: string, plan: PlanId, billing: TenantBilling): Promise<BillingApplyResult>;
84
+ /** Every key the tenant ever had, newest first (hashes are never returned). */
85
+ listKeys(tenantId: string): Promise<KeyRecord[]>;
86
+ /**
87
+ * Issue a key only if the tenant has a free seat (active, unexpired keys < `seats`) and
88
+ * no active key already carries `input.name`. The check and the insert are atomic: two
89
+ * concurrent calls can never take the last seat twice.
90
+ */
91
+ createKeyWithinSeats(input: NewKeyInput, seats: number): Promise<SeatedKeyResult>;
40
92
  }
41
93
  /** In-memory store. Records carry the hash only — same invariant as Postgres. */
42
94
  export declare class InMemoryIdentityStore implements IdentityStore {
43
95
  readonly records: Map<string, KeyRecord>;
44
96
  findKeyByHash(hash: string): Promise<KeyRecord | null>;
45
97
  createKey(input: NewKeyInput): Promise<KeyRecord>;
98
+ readonly tenants: Map<string, TenantRecord>;
99
+ createTenant(input: {
100
+ id: string;
101
+ name: string;
102
+ plan: PlanId;
103
+ }): Promise<TenantRecord | null>;
104
+ getTenant(id: string): Promise<TenantRecord | null>;
105
+ setTenantPlan(id: string, plan: PlanId): Promise<TenantRecord | null>;
106
+ findTenantByStripeCustomer(customerId: string): Promise<TenantRecord | null>;
107
+ applyBilling(id: string, plan: PlanId, billing: TenantBilling): Promise<BillingApplyResult>;
108
+ listKeys(tenantId: string): Promise<KeyRecord[]>;
109
+ createKeyWithinSeats(input: NewKeyInput, seats: number): Promise<SeatedKeyResult>;
46
110
  revokeKey(keyId: string): Promise<boolean>;
47
111
  }
48
112
  /** Production store. All queries parameterized; key material appears only as hashed params. */
@@ -51,6 +115,17 @@ export declare class PostgresIdentityStore implements IdentityStore {
51
115
  constructor(pool: Pool);
52
116
  findKeyByHash(hash: string): Promise<KeyRecord | null>;
53
117
  createKey(input: NewKeyInput): Promise<KeyRecord>;
118
+ createTenant(input: {
119
+ id: string;
120
+ name: string;
121
+ plan: PlanId;
122
+ }): Promise<TenantRecord | null>;
123
+ getTenant(id: string): Promise<TenantRecord | null>;
124
+ setTenantPlan(id: string, plan: PlanId): Promise<TenantRecord | null>;
125
+ findTenantByStripeCustomer(customerId: string): Promise<TenantRecord | null>;
126
+ applyBilling(id: string, plan: PlanId, b: TenantBilling): Promise<BillingApplyResult>;
127
+ listKeys(tenantId: string): Promise<KeyRecord[]>;
128
+ createKeyWithinSeats(input: NewKeyInput, seats: number): Promise<SeatedKeyResult>;
54
129
  revokeKey(keyId: string): Promise<boolean>;
55
130
  }
56
131
  //# sourceMappingURL=identityStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityStore.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACvD,sFAAsF;IACtF,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,mFAAmF;IACnF,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5C;AAED,iFAAiF;AACjF,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,OAAO,yBAAgC;IAE1C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAItD,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IAgBjD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAWjD;AAED,+FAA+F;AAC/F,qBAAa,qBAAsB,YAAW,aAAa;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAwBtD,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IA6BjD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CASjD"}
1
+ {"version":3,"file":"identityStore.d.ts","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,43 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PostgresIdentityStore = exports.InMemoryIdentityStore = void 0;
6
+ exports.PostgresIdentityStore = exports.InMemoryIdentityStore = exports.NO_BILLING = void 0;
7
+ /**
8
+ * Lemma API v2 — identity store (Lane D)
9
+ *
10
+ * Persistence behind TenantResolver. Keys are stored as SHA-256 hashes only:
11
+ * `key_hash` is the sole column that ever touches key material, and every write
12
+ * is a parameterized insert that receives the hash, never the plaintext value.
13
+ *
14
+ * `InMemoryIdentityStore` powers unit tests and local/dev defaults.
15
+ * `PostgresIdentityStore` is the production implementation over `pg`.
16
+ */
17
+ const crypto_1 = __importDefault(require("crypto"));
18
+ exports.NO_BILLING = Object.freeze({
19
+ customerId: null,
20
+ subscriptionId: null,
21
+ status: null,
22
+ currentPeriodEnd: null,
23
+ pastDueSince: null,
24
+ eventAt: null,
25
+ });
26
+ const isLive = (r, now) => r.active && (r.expiresAt === null || r.expiresAt > now);
4
27
  /** In-memory store. Records carry the hash only — same invariant as Postgres. */
5
28
  class InMemoryIdentityStore {
6
29
  constructor() {
7
30
  this.records = new Map();
31
+ this.tenants = new Map();
8
32
  }
9
33
  async findKeyByHash(hash) {
10
34
  return this.records.get(hash) ?? null;
11
35
  }
12
36
  async createKey(input) {
13
37
  const record = {
14
- id: 'key_' + Math.random().toString(16).slice(2, 14),
38
+ // Always 12 hex chars, like the Postgres ids. Math.random().toString(16) drops trailing zeros,
39
+ // so slicing it yielded an 11-char id now and then: a key that /v2/admin could not address.
40
+ id: 'key_' + crypto_1.default.randomBytes(6).toString('hex'),
15
41
  tenantId: input.tenantId,
16
42
  name: input.name,
17
43
  plan: input.plan,
@@ -24,6 +50,56 @@ class InMemoryIdentityStore {
24
50
  this.records.set(input.hash, record);
25
51
  return record;
26
52
  }
53
+ async createTenant(input) {
54
+ if (this.tenants.has(input.id))
55
+ return null;
56
+ const t = { id: input.id, name: input.name, plan: input.plan, createdAt: Date.now(), billing: { ...exports.NO_BILLING } };
57
+ this.tenants.set(input.id, t);
58
+ return { ...t };
59
+ }
60
+ async getTenant(id) {
61
+ const t = this.tenants.get(id);
62
+ return t ? { ...t } : null;
63
+ }
64
+ async setTenantPlan(id, plan) {
65
+ const t = this.tenants.get(id);
66
+ if (!t)
67
+ return null;
68
+ t.plan = plan;
69
+ return { ...t };
70
+ }
71
+ async findTenantByStripeCustomer(customerId) {
72
+ for (const t of this.tenants.values())
73
+ if (t.billing.customerId === customerId)
74
+ return { ...t, billing: { ...t.billing } };
75
+ return null;
76
+ }
77
+ async applyBilling(id, plan, billing) {
78
+ const t = this.tenants.get(id);
79
+ if (!t)
80
+ return { ok: false, reason: 'no_tenant' };
81
+ if (t.billing.eventAt !== null && billing.eventAt !== null && billing.eventAt < t.billing.eventAt)
82
+ return { ok: false, reason: 'stale' };
83
+ t.plan = plan;
84
+ t.billing = { ...billing };
85
+ return { ok: true, tenant: { ...t, billing: { ...t.billing } } };
86
+ }
87
+ async listKeys(tenantId) {
88
+ return [...this.records.values()].filter((r) => r.tenantId === tenantId).sort((a, b) => b.createdAt - a.createdAt).map((r) => ({ ...r }));
89
+ }
90
+ async createKeyWithinSeats(input, seats) {
91
+ // Synchronous between the check and the insert, so it is atomic on a single event loop.
92
+ const tenant = this.tenants.get(input.tenantId);
93
+ if (!tenant)
94
+ return { ok: false, reason: 'no_tenant', seats, used: 0 };
95
+ const now = Date.now();
96
+ const live = [...this.records.values()].filter((r) => r.tenantId === input.tenantId && isLive(r, now));
97
+ if (live.some((r) => r.name === input.name))
98
+ return { ok: false, reason: 'duplicate_name', seats, used: live.length };
99
+ if (live.length >= seats)
100
+ return { ok: false, reason: 'seats_full', seats, used: live.length };
101
+ return { ok: true, key: await this.createKey({ ...input, plan: tenant.plan }) };
102
+ }
27
103
  async revokeKey(keyId) {
28
104
  let found = false;
29
105
  for (const record of this.records.values()) {
@@ -88,6 +164,82 @@ class PostgresIdentityStore {
88
164
  revokedAt: null,
89
165
  };
90
166
  }
167
+ async createTenant(input) {
168
+ const { rows } = await this.pool.query(`INSERT INTO tenants (id, name, plan) VALUES ($1, $2, $3)
169
+ ON CONFLICT (id) DO NOTHING
170
+ RETURNING id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end, past_due_since, billing_event_at`, [input.id, input.name, input.plan]);
171
+ return rows.length ? toTenant(rows[0]) : null;
172
+ }
173
+ async getTenant(id) {
174
+ const { rows } = await this.pool.query(`SELECT id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status,
175
+ current_period_end, past_due_since, billing_event_at
176
+ FROM tenants WHERE id = $1`, [id]);
177
+ return rows.length ? toTenant(rows[0]) : null;
178
+ }
179
+ async setTenantPlan(id, plan) {
180
+ const { rows } = await this.pool.query(`UPDATE tenants SET plan = $2, updated_at = now() WHERE id = $1 RETURNING id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end, past_due_since, billing_event_at`, [id, plan]);
181
+ return rows.length ? toTenant(rows[0]) : null;
182
+ }
183
+ async findTenantByStripeCustomer(customerId) {
184
+ const { rows } = await this.pool.query(`SELECT id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status,
185
+ current_period_end, past_due_since, billing_event_at
186
+ FROM tenants WHERE stripe_customer_id = $1`, [customerId]);
187
+ return rows.length ? toTenant(rows[0]) : null;
188
+ }
189
+ async applyBilling(id, plan, b) {
190
+ const at = (ms) => (ms === null ? null : new Date(ms));
191
+ const { rows } = await this.pool.query(`UPDATE tenants
192
+ SET plan = $2, stripe_customer_id = $3, stripe_subscription_id = $4, subscription_status = $5,
193
+ current_period_end = $6, past_due_since = $7, billing_event_at = $8, updated_at = now()
194
+ WHERE id = $1 AND (billing_event_at IS NULL OR $8::timestamptz IS NULL OR billing_event_at <= $8::timestamptz)
195
+ RETURNING id, name, plan, created_at, stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end, past_due_since, billing_event_at`, [id, plan, b.customerId, b.subscriptionId, b.status, at(b.currentPeriodEnd), at(b.pastDueSince), at(b.eventAt)]);
196
+ if (rows.length)
197
+ return { ok: true, tenant: toTenant(rows[0]) };
198
+ // No row updated: either the tenant does not exist or a newer event already won.
199
+ return { ok: false, reason: (await this.getTenant(id)) ? 'stale' : 'no_tenant' };
200
+ }
201
+ async listKeys(tenantId) {
202
+ const { rows } = await this.pool.query(`SELECT k.id, k.tenant_id, t.plan, k.name, k.prefix, k.active, k.created_at, k.expires_at, k.revoked_at
203
+ FROM api_keys k JOIN tenants t ON t.id = k.tenant_id
204
+ WHERE k.tenant_id = $1 ORDER BY k.created_at DESC, k.id`, [tenantId]);
205
+ return rows.map(toKey);
206
+ }
207
+ async createKeyWithinSeats(input, seats) {
208
+ const client = await this.pool.connect();
209
+ try {
210
+ await client.query('BEGIN');
211
+ // The tenant row is the lock: concurrent issuers for one tenant queue here, so the
212
+ // count below cannot go stale before the insert.
213
+ const t = await client.query('SELECT plan FROM tenants WHERE id = $1 FOR UPDATE', [input.tenantId]);
214
+ if (!t.rows.length) {
215
+ await client.query('ROLLBACK');
216
+ return { ok: false, reason: 'no_tenant', seats, used: 0 };
217
+ }
218
+ const live = await client.query(`SELECT name FROM api_keys
219
+ WHERE tenant_id = $1 AND active = TRUE AND (expires_at IS NULL OR expires_at > now())`, [input.tenantId]);
220
+ if (live.rows.some((r) => r.name === input.name)) {
221
+ await client.query('ROLLBACK');
222
+ return { ok: false, reason: 'duplicate_name', seats, used: live.rows.length };
223
+ }
224
+ if (live.rows.length >= seats) {
225
+ await client.query('ROLLBACK');
226
+ return { ok: false, reason: 'seats_full', seats, used: live.rows.length };
227
+ }
228
+ const plan = t.rows[0].plan;
229
+ const ins = await client.query(`INSERT INTO api_keys (id, tenant_id, name, key_hash, prefix, plan, active)
230
+ VALUES ($1, $2, $3, $4, $5, $6, TRUE)
231
+ RETURNING id, tenant_id, name, prefix, active, created_at, expires_at, revoked_at`, ['key_' + input.hash.slice(0, 12), input.tenantId, input.name, input.hash, input.prefix, plan]);
232
+ await client.query('COMMIT');
233
+ return { ok: true, key: toKey({ ...ins.rows[0], plan }) };
234
+ }
235
+ catch (err) {
236
+ await client.query('ROLLBACK').catch(() => undefined);
237
+ throw err;
238
+ }
239
+ finally {
240
+ client.release();
241
+ }
242
+ }
91
243
  async revokeKey(keyId) {
92
244
  const { rowCount } = await this.pool.query(`UPDATE api_keys
93
245
  SET active = FALSE, revoked_at = CURRENT_TIMESTAMP
@@ -96,4 +248,34 @@ class PostgresIdentityStore {
96
248
  }
97
249
  }
98
250
  exports.PostgresIdentityStore = PostgresIdentityStore;
251
+ function toTenant(r) {
252
+ const ms = (v) => (v ? new Date(v).getTime() : null);
253
+ return {
254
+ id: r.id,
255
+ name: r.name ?? '',
256
+ plan: r.plan,
257
+ createdAt: new Date(r.created_at).getTime(),
258
+ billing: {
259
+ customerId: r.stripe_customer_id ?? null,
260
+ subscriptionId: r.stripe_subscription_id ?? null,
261
+ status: r.subscription_status ?? null,
262
+ currentPeriodEnd: ms(r.current_period_end),
263
+ pastDueSince: ms(r.past_due_since),
264
+ eventAt: ms(r.billing_event_at),
265
+ },
266
+ };
267
+ }
268
+ function toKey(r) {
269
+ return {
270
+ id: r.id,
271
+ tenantId: r.tenant_id,
272
+ plan: r.plan,
273
+ name: r.name ?? '',
274
+ prefix: r.prefix,
275
+ active: r.active,
276
+ createdAt: new Date(r.created_at).getTime(),
277
+ expiresAt: r.expires_at ? new Date(r.expires_at).getTime() : null,
278
+ revokedAt: r.revoked_at ? new Date(r.revoked_at).getTime() : null,
279
+ };
280
+ }
99
281
  //# sourceMappingURL=identityStore.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityStore.js","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"identityStore.js","sourceRoot":"","sources":["../../../../src/cloud/identity/identityStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Lemma API v2 — durable usage ledger on Postgres (migration 003_usage.sql).
3
+ *
4
+ * Append-only by construction: the only write is INSERT. Reads are aggregated in SQL so
5
+ * /v2/usage costs one grouped query however many events a tenant has accumulated.
6
+ */
7
+ import type { Pool } from 'pg';
8
+ import type { AggregateRow, AppendOnlyStore, LedgerEvent, UsageQuery } from './UsageLedger';
9
+ export declare class PostgresLedgerStore implements AppendOnlyStore {
10
+ private readonly pool;
11
+ constructor(pool: Pool);
12
+ append(row: LedgerEvent): Promise<void>;
13
+ rows(): Promise<LedgerEvent[]>;
14
+ aggregate(query: UsageQuery): Promise<AggregateRow[]>;
15
+ }
16
+ //# sourceMappingURL=PostgresLedgerStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostgresLedgerStore.d.ts","sourceRoot":"","sources":["../../../../src/cloud/metering/PostgresLedgerStore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE5F,qBAAa,mBAAoB,YAAW,eAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAK9B,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAoB5D"}