libre-webui 0.21.3 → 0.22.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 (945) hide show
  1. package/README.md +308 -328
  2. package/backend/dist/cli/migrateSqliteToPostgres.d.ts +2 -0
  3. package/backend/dist/cli/migrateSqliteToPostgres.d.ts.map +1 -0
  4. package/backend/dist/cli/migrateSqliteToPostgres.js +113 -0
  5. package/backend/dist/cli/migrateSqliteToPostgres.js.map +1 -0
  6. package/backend/dist/cli/recoveryBackup.d.ts +3 -0
  7. package/backend/dist/cli/recoveryBackup.d.ts.map +1 -0
  8. package/backend/dist/cli/recoveryBackup.js +251 -0
  9. package/backend/dist/cli/recoveryBackup.js.map +1 -0
  10. package/backend/dist/cli/recoveryInventory.d.ts +2 -0
  11. package/backend/dist/cli/recoveryInventory.d.ts.map +1 -0
  12. package/backend/dist/cli/recoveryInventory.js +109 -0
  13. package/backend/dist/cli/recoveryInventory.js.map +1 -0
  14. package/backend/dist/db.d.ts +27 -0
  15. package/backend/dist/db.d.ts.map +1 -1
  16. package/backend/dist/db.js +333 -16
  17. package/backend/dist/db.js.map +1 -1
  18. package/backend/dist/env.d.ts.map +1 -1
  19. package/backend/dist/env.js +12 -2
  20. package/backend/dist/env.js.map +1 -1
  21. package/backend/dist/index.d.ts.map +1 -1
  22. package/backend/dist/index.js +235 -47
  23. package/backend/dist/index.js.map +1 -1
  24. package/backend/dist/main.d.ts +2 -0
  25. package/backend/dist/main.d.ts.map +1 -0
  26. package/backend/dist/main.js +137 -0
  27. package/backend/dist/main.js.map +1 -0
  28. package/backend/dist/middleware/auth.d.ts.map +1 -1
  29. package/backend/dist/middleware/auth.js +7 -3
  30. package/backend/dist/middleware/auth.js.map +1 -1
  31. package/backend/dist/middleware/chatCancellationAdmission.d.ts +7 -0
  32. package/backend/dist/middleware/chatCancellationAdmission.d.ts.map +1 -0
  33. package/backend/dist/middleware/chatCancellationAdmission.js +17 -0
  34. package/backend/dist/middleware/chatCancellationAdmission.js.map +1 -0
  35. package/backend/dist/middleware/coordinatedRateLimit.d.ts +18 -0
  36. package/backend/dist/middleware/coordinatedRateLimit.d.ts.map +1 -0
  37. package/backend/dist/middleware/coordinatedRateLimit.js +52 -0
  38. package/backend/dist/middleware/coordinatedRateLimit.js.map +1 -0
  39. package/backend/dist/middleware/sharedRateLimit.d.ts +26 -0
  40. package/backend/dist/middleware/sharedRateLimit.d.ts.map +1 -0
  41. package/backend/dist/middleware/sharedRateLimit.js +99 -0
  42. package/backend/dist/middleware/sharedRateLimit.js.map +1 -0
  43. package/backend/dist/models/personaModel.d.ts +1 -26
  44. package/backend/dist/models/personaModel.d.ts.map +1 -1
  45. package/backend/dist/models/personaModel.js +54 -247
  46. package/backend/dist/models/personaModel.js.map +1 -1
  47. package/backend/dist/models/userModel.d.ts +23 -66
  48. package/backend/dist/models/userModel.d.ts.map +1 -1
  49. package/backend/dist/models/userModel.js +110 -187
  50. package/backend/dist/models/userModel.js.map +1 -1
  51. package/backend/dist/persistence/chatGenerationTypes.d.ts +24 -0
  52. package/backend/dist/persistence/chatGenerationTypes.d.ts.map +1 -0
  53. package/backend/dist/persistence/chatGenerationTypes.js +7 -0
  54. package/backend/dist/persistence/chatGenerationTypes.js.map +1 -0
  55. package/backend/dist/persistence/extensionTypes.d.ts +185 -0
  56. package/backend/dist/persistence/extensionTypes.d.ts.map +1 -0
  57. package/backend/dist/persistence/extensionTypes.js +13 -0
  58. package/backend/dist/persistence/extensionTypes.js.map +1 -0
  59. package/backend/dist/persistence/identityDeletionTypes.d.ts +16 -0
  60. package/backend/dist/persistence/identityDeletionTypes.d.ts.map +1 -0
  61. package/backend/dist/persistence/identityDeletionTypes.js +7 -0
  62. package/backend/dist/persistence/identityDeletionTypes.js.map +1 -0
  63. package/backend/dist/persistence/index.d.ts +48 -0
  64. package/backend/dist/persistence/index.d.ts.map +1 -0
  65. package/backend/dist/persistence/index.js +159 -0
  66. package/backend/dist/persistence/index.js.map +1 -0
  67. package/backend/dist/persistence/postgresConfig.d.ts +32 -0
  68. package/backend/dist/persistence/postgresConfig.d.ts.map +1 -0
  69. package/backend/dist/persistence/postgresConfig.js +91 -0
  70. package/backend/dist/persistence/postgresConfig.js.map +1 -0
  71. package/backend/dist/persistence/postgresCoreMigration.d.ts +8 -0
  72. package/backend/dist/persistence/postgresCoreMigration.d.ts.map +1 -0
  73. package/backend/dist/persistence/postgresCoreMigration.js +179 -0
  74. package/backend/dist/persistence/postgresCoreMigration.js.map +1 -0
  75. package/backend/dist/persistence/postgresDatabase.d.ts +40 -0
  76. package/backend/dist/persistence/postgresDatabase.d.ts.map +1 -0
  77. package/backend/dist/persistence/postgresDatabase.js +148 -0
  78. package/backend/dist/persistence/postgresDatabase.js.map +1 -0
  79. package/backend/dist/persistence/postgresExtensionMigration.d.ts +4 -0
  80. package/backend/dist/persistence/postgresExtensionMigration.d.ts.map +1 -0
  81. package/backend/dist/persistence/postgresExtensionMigration.js +143 -0
  82. package/backend/dist/persistence/postgresExtensionMigration.js.map +1 -0
  83. package/backend/dist/persistence/postgresExtensionRepositories.d.ts +6 -0
  84. package/backend/dist/persistence/postgresExtensionRepositories.d.ts.map +1 -0
  85. package/backend/dist/persistence/postgresExtensionRepositories.js +550 -0
  86. package/backend/dist/persistence/postgresExtensionRepositories.js.map +1 -0
  87. package/backend/dist/persistence/postgresImportState.d.ts +9 -0
  88. package/backend/dist/persistence/postgresImportState.d.ts.map +1 -0
  89. package/backend/dist/persistence/postgresImportState.js +64 -0
  90. package/backend/dist/persistence/postgresImportState.js.map +1 -0
  91. package/backend/dist/persistence/postgresMigrationRegistry.d.ts +4 -0
  92. package/backend/dist/persistence/postgresMigrationRegistry.d.ts.map +1 -0
  93. package/backend/dist/persistence/postgresMigrationRegistry.js +33 -0
  94. package/backend/dist/persistence/postgresMigrationRegistry.js.map +1 -0
  95. package/backend/dist/persistence/postgresMigrationTypes.d.ts +24 -0
  96. package/backend/dist/persistence/postgresMigrationTypes.d.ts.map +1 -0
  97. package/backend/dist/persistence/postgresMigrationTypes.js +7 -0
  98. package/backend/dist/persistence/postgresMigrationTypes.js.map +1 -0
  99. package/backend/dist/persistence/postgresMigrations.d.ts +15 -0
  100. package/backend/dist/persistence/postgresMigrations.d.ts.map +1 -0
  101. package/backend/dist/persistence/postgresMigrations.js +333 -0
  102. package/backend/dist/persistence/postgresMigrations.js.map +1 -0
  103. package/backend/dist/persistence/postgresPersistence.d.ts +17 -0
  104. package/backend/dist/persistence/postgresPersistence.d.ts.map +1 -0
  105. package/backend/dist/persistence/postgresPersistence.js +332 -0
  106. package/backend/dist/persistence/postgresPersistence.js.map +1 -0
  107. package/backend/dist/persistence/postgresPluginDefinitionMigration.d.ts +4 -0
  108. package/backend/dist/persistence/postgresPluginDefinitionMigration.d.ts.map +1 -0
  109. package/backend/dist/persistence/postgresPluginDefinitionMigration.js +40 -0
  110. package/backend/dist/persistence/postgresPluginDefinitionMigration.js.map +1 -0
  111. package/backend/dist/persistence/postgresResourceRepositories.d.ts +7 -0
  112. package/backend/dist/persistence/postgresResourceRepositories.d.ts.map +1 -0
  113. package/backend/dist/persistence/postgresResourceRepositories.js +776 -0
  114. package/backend/dist/persistence/postgresResourceRepositories.js.map +1 -0
  115. package/backend/dist/persistence/postgresSchemaInspector.d.ts +14 -0
  116. package/backend/dist/persistence/postgresSchemaInspector.d.ts.map +1 -0
  117. package/backend/dist/persistence/postgresSchemaInspector.js +817 -0
  118. package/backend/dist/persistence/postgresSchemaInspector.js.map +1 -0
  119. package/backend/dist/persistence/resourceTypes.d.ts +207 -0
  120. package/backend/dist/persistence/resourceTypes.d.ts.map +1 -0
  121. package/backend/dist/persistence/resourceTypes.js +38 -0
  122. package/backend/dist/persistence/resourceTypes.js.map +1 -0
  123. package/backend/dist/persistence/sqliteExtensionRepositories.d.ts +4 -0
  124. package/backend/dist/persistence/sqliteExtensionRepositories.d.ts.map +1 -0
  125. package/backend/dist/persistence/sqliteExtensionRepositories.js +494 -0
  126. package/backend/dist/persistence/sqliteExtensionRepositories.js.map +1 -0
  127. package/backend/dist/persistence/sqliteMigrations.d.ts +93 -0
  128. package/backend/dist/persistence/sqliteMigrations.d.ts.map +1 -0
  129. package/backend/dist/persistence/sqliteMigrations.js +2232 -0
  130. package/backend/dist/persistence/sqliteMigrations.js.map +1 -0
  131. package/backend/dist/persistence/sqlitePersistence.d.ts +23 -0
  132. package/backend/dist/persistence/sqlitePersistence.d.ts.map +1 -0
  133. package/backend/dist/persistence/sqlitePersistence.js +596 -0
  134. package/backend/dist/persistence/sqlitePersistence.js.map +1 -0
  135. package/backend/dist/persistence/sqliteResourceRepositories.d.ts +4 -0
  136. package/backend/dist/persistence/sqliteResourceRepositories.d.ts.map +1 -0
  137. package/backend/dist/persistence/sqliteResourceRepositories.js +663 -0
  138. package/backend/dist/persistence/sqliteResourceRepositories.js.map +1 -0
  139. package/backend/dist/persistence/sqliteSyncExecutor.d.ts +5 -0
  140. package/backend/dist/persistence/sqliteSyncExecutor.d.ts.map +1 -0
  141. package/backend/dist/persistence/sqliteSyncExecutor.js +19 -0
  142. package/backend/dist/persistence/sqliteSyncExecutor.js.map +1 -0
  143. package/backend/dist/persistence/sqliteToPostgresMigration.d.ts +80 -0
  144. package/backend/dist/persistence/sqliteToPostgresMigration.d.ts.map +1 -0
  145. package/backend/dist/persistence/sqliteToPostgresMigration.js +1543 -0
  146. package/backend/dist/persistence/sqliteToPostgresMigration.js.map +1 -0
  147. package/backend/dist/persistence/types.d.ts +131 -0
  148. package/backend/dist/persistence/types.d.ts.map +1 -0
  149. package/backend/dist/persistence/types.js +18 -0
  150. package/backend/dist/persistence/types.js.map +1 -0
  151. package/backend/dist/persistence/voiceProfileNameLookup.d.ts +9 -0
  152. package/backend/dist/persistence/voiceProfileNameLookup.d.ts.map +1 -0
  153. package/backend/dist/persistence/voiceProfileNameLookup.js +15 -0
  154. package/backend/dist/persistence/voiceProfileNameLookup.js.map +1 -0
  155. package/backend/dist/platform/coordination/index.d.ts +7 -0
  156. package/backend/dist/platform/coordination/index.d.ts.map +1 -0
  157. package/backend/dist/platform/coordination/index.js +24 -0
  158. package/backend/dist/platform/coordination/index.js.map +1 -0
  159. package/backend/dist/platform/coordination/localCoordinator.d.ts +49 -0
  160. package/backend/dist/platform/coordination/localCoordinator.d.ts.map +1 -0
  161. package/backend/dist/platform/coordination/localCoordinator.js +380 -0
  162. package/backend/dist/platform/coordination/localCoordinator.js.map +1 -0
  163. package/backend/dist/platform/coordination/redisCoordinator.d.ts +83 -0
  164. package/backend/dist/platform/coordination/redisCoordinator.d.ts.map +1 -0
  165. package/backend/dist/platform/coordination/redisCoordinator.js +726 -0
  166. package/backend/dist/platform/coordination/redisCoordinator.js.map +1 -0
  167. package/backend/dist/platform/coordination/service.d.ts +11 -0
  168. package/backend/dist/platform/coordination/service.d.ts.map +1 -0
  169. package/backend/dist/platform/coordination/service.js +55 -0
  170. package/backend/dist/platform/coordination/service.js.map +1 -0
  171. package/backend/dist/platform/coordination/sharedAdmission.d.ts +53 -0
  172. package/backend/dist/platform/coordination/sharedAdmission.d.ts.map +1 -0
  173. package/backend/dist/platform/coordination/sharedAdmission.js +194 -0
  174. package/backend/dist/platform/coordination/sharedAdmission.js.map +1 -0
  175. package/backend/dist/platform/coordination/types.d.ts +76 -0
  176. package/backend/dist/platform/coordination/types.d.ts.map +1 -0
  177. package/backend/dist/platform/coordination/types.js +32 -0
  178. package/backend/dist/platform/coordination/types.js.map +1 -0
  179. package/backend/dist/platform/events/durableEventGateway.d.ts +54 -0
  180. package/backend/dist/platform/events/durableEventGateway.d.ts.map +1 -0
  181. package/backend/dist/platform/events/durableEventGateway.js +262 -0
  182. package/backend/dist/platform/events/durableEventGateway.js.map +1 -0
  183. package/backend/dist/platform/events/index.d.ts +3 -0
  184. package/backend/dist/platform/events/index.d.ts.map +1 -0
  185. package/backend/dist/platform/events/index.js +8 -0
  186. package/backend/dist/platform/events/index.js.map +1 -0
  187. package/backend/dist/platform/events/service.d.ts +8 -0
  188. package/backend/dist/platform/events/service.d.ts.map +1 -0
  189. package/backend/dist/platform/events/service.js +25 -0
  190. package/backend/dist/platform/events/service.js.map +1 -0
  191. package/backend/dist/platform/jobs/chatGenerationEnqueuer.d.ts +3 -0
  192. package/backend/dist/platform/jobs/chatGenerationEnqueuer.d.ts.map +1 -0
  193. package/backend/dist/platform/jobs/chatGenerationEnqueuer.js +55 -0
  194. package/backend/dist/platform/jobs/chatGenerationEnqueuer.js.map +1 -0
  195. package/backend/dist/platform/jobs/documentIngestionEnqueuer.d.ts +3 -0
  196. package/backend/dist/platform/jobs/documentIngestionEnqueuer.d.ts.map +1 -0
  197. package/backend/dist/platform/jobs/documentIngestionEnqueuer.js +38 -0
  198. package/backend/dist/platform/jobs/documentIngestionEnqueuer.js.map +1 -0
  199. package/backend/dist/platform/jobs/domainJobContracts.d.ts +30 -0
  200. package/backend/dist/platform/jobs/domainJobContracts.d.ts.map +1 -0
  201. package/backend/dist/platform/jobs/domainJobContracts.js +53 -0
  202. package/backend/dist/platform/jobs/domainJobContracts.js.map +1 -0
  203. package/backend/dist/platform/jobs/domainJobHandlers.d.ts +11 -0
  204. package/backend/dist/platform/jobs/domainJobHandlers.d.ts.map +1 -0
  205. package/backend/dist/platform/jobs/domainJobHandlers.js +612 -0
  206. package/backend/dist/platform/jobs/domainJobHandlers.js.map +1 -0
  207. package/backend/dist/platform/jobs/durableEventIdentity.d.ts +8 -0
  208. package/backend/dist/platform/jobs/durableEventIdentity.d.ts.map +1 -0
  209. package/backend/dist/platform/jobs/durableEventIdentity.js +33 -0
  210. package/backend/dist/platform/jobs/durableEventIdentity.js.map +1 -0
  211. package/backend/dist/platform/jobs/durableJobRuntime.d.ts +57 -0
  212. package/backend/dist/platform/jobs/durableJobRuntime.d.ts.map +1 -0
  213. package/backend/dist/platform/jobs/durableJobRuntime.js +131 -0
  214. package/backend/dist/platform/jobs/durableJobRuntime.js.map +1 -0
  215. package/backend/dist/platform/jobs/durableJobRuntimeBackend.d.ts +28 -0
  216. package/backend/dist/platform/jobs/durableJobRuntimeBackend.d.ts.map +1 -0
  217. package/backend/dist/platform/jobs/durableJobRuntimeBackend.js +62 -0
  218. package/backend/dist/platform/jobs/durableJobRuntimeBackend.js.map +1 -0
  219. package/backend/dist/platform/jobs/durableJobService.d.ts +85 -0
  220. package/backend/dist/platform/jobs/durableJobService.d.ts.map +1 -0
  221. package/backend/dist/platform/jobs/durableJobService.js +726 -0
  222. package/backend/dist/platform/jobs/durableJobService.js.map +1 -0
  223. package/backend/dist/platform/jobs/durableJobTypes.d.ts +195 -0
  224. package/backend/dist/platform/jobs/durableJobTypes.d.ts.map +1 -0
  225. package/backend/dist/platform/jobs/durableJobTypes.js +72 -0
  226. package/backend/dist/platform/jobs/durableJobTypes.js.map +1 -0
  227. package/backend/dist/platform/jobs/embeddedDurableJobWorker.d.ts +87 -0
  228. package/backend/dist/platform/jobs/embeddedDurableJobWorker.d.ts.map +1 -0
  229. package/backend/dist/platform/jobs/embeddedDurableJobWorker.js +429 -0
  230. package/backend/dist/platform/jobs/embeddedDurableJobWorker.js.map +1 -0
  231. package/backend/dist/platform/jobs/identityDeletionEnqueuer.d.ts +3 -0
  232. package/backend/dist/platform/jobs/identityDeletionEnqueuer.d.ts.map +1 -0
  233. package/backend/dist/platform/jobs/identityDeletionEnqueuer.js +36 -0
  234. package/backend/dist/platform/jobs/identityDeletionEnqueuer.js.map +1 -0
  235. package/backend/dist/platform/jobs/index.d.ts +18 -0
  236. package/backend/dist/platform/jobs/index.d.ts.map +1 -0
  237. package/backend/dist/platform/jobs/index.js +34 -0
  238. package/backend/dist/platform/jobs/index.js.map +1 -0
  239. package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.d.ts +4 -0
  240. package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.d.ts.map +1 -0
  241. package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.js +25 -0
  242. package/backend/dist/platform/jobs/postgresDurableEventIdempotencyMigration.js.map +1 -0
  243. package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.d.ts +4 -0
  244. package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.d.ts.map +1 -0
  245. package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.js +23 -0
  246. package/backend/dist/platform/jobs/postgresDurableEventReplayIndexMigration.js.map +1 -0
  247. package/backend/dist/platform/jobs/postgresDurableJobMigration.d.ts +11 -0
  248. package/backend/dist/platform/jobs/postgresDurableJobMigration.d.ts.map +1 -0
  249. package/backend/dist/platform/jobs/postgresDurableJobMigration.js +106 -0
  250. package/backend/dist/platform/jobs/postgresDurableJobMigration.js.map +1 -0
  251. package/backend/dist/platform/jobs/postgresDurableJobRepository.d.ts +88 -0
  252. package/backend/dist/platform/jobs/postgresDurableJobRepository.d.ts.map +1 -0
  253. package/backend/dist/platform/jobs/postgresDurableJobRepository.js +1185 -0
  254. package/backend/dist/platform/jobs/postgresDurableJobRepository.js.map +1 -0
  255. package/backend/dist/platform/jobs/postgresDurableJobService.d.ts +86 -0
  256. package/backend/dist/platform/jobs/postgresDurableJobService.d.ts.map +1 -0
  257. package/backend/dist/platform/jobs/postgresDurableJobService.js +696 -0
  258. package/backend/dist/platform/jobs/postgresDurableJobService.js.map +1 -0
  259. package/backend/dist/platform/jobs/postgresDurableJobWorker.d.ts +53 -0
  260. package/backend/dist/platform/jobs/postgresDurableJobWorker.d.ts.map +1 -0
  261. package/backend/dist/platform/jobs/postgresDurableJobWorker.js +393 -0
  262. package/backend/dist/platform/jobs/postgresDurableJobWorker.js.map +1 -0
  263. package/backend/dist/platform/jobs/resourceDeletionEnqueuer.d.ts +3 -0
  264. package/backend/dist/platform/jobs/resourceDeletionEnqueuer.d.ts.map +1 -0
  265. package/backend/dist/platform/jobs/resourceDeletionEnqueuer.js +43 -0
  266. package/backend/dist/platform/jobs/resourceDeletionEnqueuer.js.map +1 -0
  267. package/backend/dist/platform/jobs/sqliteDurableJobRepository.d.ts +166 -0
  268. package/backend/dist/platform/jobs/sqliteDurableJobRepository.d.ts.map +1 -0
  269. package/backend/dist/platform/jobs/sqliteDurableJobRepository.js +1008 -0
  270. package/backend/dist/platform/jobs/sqliteDurableJobRepository.js.map +1 -0
  271. package/backend/dist/platform/jobs/videoGenerationEnqueuer.d.ts +4 -0
  272. package/backend/dist/platform/jobs/videoGenerationEnqueuer.d.ts.map +1 -0
  273. package/backend/dist/platform/jobs/videoGenerationEnqueuer.js +46 -0
  274. package/backend/dist/platform/jobs/videoGenerationEnqueuer.js.map +1 -0
  275. package/backend/dist/platform/jobs/workExecutionEnqueuer.d.ts +3 -0
  276. package/backend/dist/platform/jobs/workExecutionEnqueuer.d.ts.map +1 -0
  277. package/backend/dist/platform/jobs/workExecutionEnqueuer.js +38 -0
  278. package/backend/dist/platform/jobs/workExecutionEnqueuer.js.map +1 -0
  279. package/backend/dist/platform/ollamaRuntimeConfig.d.ts +40 -0
  280. package/backend/dist/platform/ollamaRuntimeConfig.d.ts.map +1 -0
  281. package/backend/dist/platform/ollamaRuntimeConfig.js +72 -0
  282. package/backend/dist/platform/ollamaRuntimeConfig.js.map +1 -0
  283. package/backend/dist/platform/recovery/backupArchive.d.ts +120 -0
  284. package/backend/dist/platform/recovery/backupArchive.d.ts.map +1 -0
  285. package/backend/dist/platform/recovery/backupArchive.js +842 -0
  286. package/backend/dist/platform/recovery/backupArchive.js.map +1 -0
  287. package/backend/dist/platform/recovery/index.d.ts +3 -0
  288. package/backend/dist/platform/recovery/index.d.ts.map +1 -0
  289. package/backend/dist/platform/recovery/index.js +8 -0
  290. package/backend/dist/platform/recovery/index.js.map +1 -0
  291. package/backend/dist/platform/recovery/teamBackupArchive.d.ts +98 -0
  292. package/backend/dist/platform/recovery/teamBackupArchive.d.ts.map +1 -0
  293. package/backend/dist/platform/recovery/teamBackupArchive.js +1203 -0
  294. package/backend/dist/platform/recovery/teamBackupArchive.js.map +1 -0
  295. package/backend/dist/platform/runtimeConfig.d.ts +70 -0
  296. package/backend/dist/platform/runtimeConfig.d.ts.map +1 -0
  297. package/backend/dist/platform/runtimeConfig.js +205 -0
  298. package/backend/dist/platform/runtimeConfig.js.map +1 -0
  299. package/backend/dist/platform/storage/aesGcmKeyring.d.ts +26 -0
  300. package/backend/dist/platform/storage/aesGcmKeyring.d.ts.map +1 -0
  301. package/backend/dist/platform/storage/aesGcmKeyring.js +135 -0
  302. package/backend/dist/platform/storage/aesGcmKeyring.js.map +1 -0
  303. package/backend/dist/platform/storage/blobReferenceRepository.d.ts +36 -0
  304. package/backend/dist/platform/storage/blobReferenceRepository.d.ts.map +1 -0
  305. package/backend/dist/platform/storage/blobReferenceRepository.js +117 -0
  306. package/backend/dist/platform/storage/blobReferenceRepository.js.map +1 -0
  307. package/backend/dist/platform/storage/blobStore.d.ts +111 -0
  308. package/backend/dist/platform/storage/blobStore.d.ts.map +1 -0
  309. package/backend/dist/platform/storage/blobStore.js +46 -0
  310. package/backend/dist/platform/storage/blobStore.js.map +1 -0
  311. package/backend/dist/platform/storage/documentVectorIndex.d.ts +44 -0
  312. package/backend/dist/platform/storage/documentVectorIndex.d.ts.map +1 -0
  313. package/backend/dist/platform/storage/documentVectorIndex.js +110 -0
  314. package/backend/dist/platform/storage/documentVectorIndex.js.map +1 -0
  315. package/backend/dist/platform/storage/durableBlobQuotaPolicy.d.ts +82 -0
  316. package/backend/dist/platform/storage/durableBlobQuotaPolicy.d.ts.map +1 -0
  317. package/backend/dist/platform/storage/durableBlobQuotaPolicy.js +583 -0
  318. package/backend/dist/platform/storage/durableBlobQuotaPolicy.js.map +1 -0
  319. package/backend/dist/platform/storage/index.d.ts +19 -0
  320. package/backend/dist/platform/storage/index.d.ts.map +1 -0
  321. package/backend/dist/platform/storage/index.js +35 -0
  322. package/backend/dist/platform/storage/index.js.map +1 -0
  323. package/backend/dist/platform/storage/localEncryptedBlobStore.d.ts +120 -0
  324. package/backend/dist/platform/storage/localEncryptedBlobStore.d.ts.map +1 -0
  325. package/backend/dist/platform/storage/localEncryptedBlobStore.js +1205 -0
  326. package/backend/dist/platform/storage/localEncryptedBlobStore.js.map +1 -0
  327. package/backend/dist/platform/storage/personaMemoryIndexing.d.ts +12 -0
  328. package/backend/dist/platform/storage/personaMemoryIndexing.d.ts.map +1 -0
  329. package/backend/dist/platform/storage/personaMemoryIndexing.js +25 -0
  330. package/backend/dist/platform/storage/personaMemoryIndexing.js.map +1 -0
  331. package/backend/dist/platform/storage/pgVectorStore.d.ts +37 -0
  332. package/backend/dist/platform/storage/pgVectorStore.d.ts.map +1 -0
  333. package/backend/dist/platform/storage/pgVectorStore.js +493 -0
  334. package/backend/dist/platform/storage/pgVectorStore.js.map +1 -0
  335. package/backend/dist/platform/storage/platformDomainRepositories.d.ts +244 -0
  336. package/backend/dist/platform/storage/platformDomainRepositories.d.ts.map +1 -0
  337. package/backend/dist/platform/storage/platformDomainRepositories.js +7 -0
  338. package/backend/dist/platform/storage/platformDomainRepositories.js.map +1 -0
  339. package/backend/dist/platform/storage/platformStorageRuntime.d.ts +35 -0
  340. package/backend/dist/platform/storage/platformStorageRuntime.d.ts.map +1 -0
  341. package/backend/dist/platform/storage/platformStorageRuntime.js +299 -0
  342. package/backend/dist/platform/storage/platformStorageRuntime.js.map +1 -0
  343. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.d.ts +4 -0
  344. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.d.ts.map +1 -0
  345. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.js +1017 -0
  346. package/backend/dist/platform/storage/postgresPlatformDomainRepositories.js.map +1 -0
  347. package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.d.ts +4 -0
  348. package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.d.ts.map +1 -0
  349. package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.js +40 -0
  350. package/backend/dist/platform/storage/postgresResourceDeletionLifecycleMigration.js.map +1 -0
  351. package/backend/dist/platform/storage/resourceContentCleanup.d.ts +29 -0
  352. package/backend/dist/platform/storage/resourceContentCleanup.d.ts.map +1 -0
  353. package/backend/dist/platform/storage/resourceContentCleanup.js +100 -0
  354. package/backend/dist/platform/storage/resourceContentCleanup.js.map +1 -0
  355. package/backend/dist/platform/storage/resourceDeletionLifecycle.d.ts +14 -0
  356. package/backend/dist/platform/storage/resourceDeletionLifecycle.d.ts.map +1 -0
  357. package/backend/dist/platform/storage/resourceDeletionLifecycle.js +31 -0
  358. package/backend/dist/platform/storage/resourceDeletionLifecycle.js.map +1 -0
  359. package/backend/dist/platform/storage/s3EncryptedBlobStore.d.ts +140 -0
  360. package/backend/dist/platform/storage/s3EncryptedBlobStore.d.ts.map +1 -0
  361. package/backend/dist/platform/storage/s3EncryptedBlobStore.js +1309 -0
  362. package/backend/dist/platform/storage/s3EncryptedBlobStore.js.map +1 -0
  363. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.d.ts +71 -0
  364. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.d.ts.map +1 -0
  365. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.js +766 -0
  366. package/backend/dist/platform/storage/sqliteEncryptedVectorStore.js.map +1 -0
  367. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.d.ts +4 -0
  368. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.d.ts.map +1 -0
  369. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.js +1037 -0
  370. package/backend/dist/platform/storage/sqlitePlatformDomainRepositories.js.map +1 -0
  371. package/backend/dist/platform/storage/sqliteToTeamStorageMigration.d.ts +25 -0
  372. package/backend/dist/platform/storage/sqliteToTeamStorageMigration.d.ts.map +1 -0
  373. package/backend/dist/platform/storage/sqliteToTeamStorageMigration.js +1292 -0
  374. package/backend/dist/platform/storage/sqliteToTeamStorageMigration.js.map +1 -0
  375. package/backend/dist/platform/storage/storageFactory.d.ts +81 -0
  376. package/backend/dist/platform/storage/storageFactory.d.ts.map +1 -0
  377. package/backend/dist/platform/storage/storageFactory.js +518 -0
  378. package/backend/dist/platform/storage/storageFactory.js.map +1 -0
  379. package/backend/dist/platform/storage/storageSchemaContracts.d.ts +22 -0
  380. package/backend/dist/platform/storage/storageSchemaContracts.d.ts.map +1 -0
  381. package/backend/dist/platform/storage/storageSchemaContracts.js +299 -0
  382. package/backend/dist/platform/storage/storageSchemaContracts.js.map +1 -0
  383. package/backend/dist/platform/storage/vectorStore.d.ts +117 -0
  384. package/backend/dist/platform/storage/vectorStore.d.ts.map +1 -0
  385. package/backend/dist/platform/storage/vectorStore.js +40 -0
  386. package/backend/dist/platform/storage/vectorStore.js.map +1 -0
  387. package/backend/dist/platform/workPersistence/index.d.ts +9 -0
  388. package/backend/dist/platform/workPersistence/index.d.ts.map +1 -0
  389. package/backend/dist/platform/workPersistence/index.js +14 -0
  390. package/backend/dist/platform/workPersistence/index.js.map +1 -0
  391. package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.d.ts +9 -0
  392. package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.d.ts.map +1 -0
  393. package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.js +47 -0
  394. package/backend/dist/platform/workPersistence/postgresWorkLifecycleMigration.js.map +1 -0
  395. package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.d.ts +3 -0
  396. package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.d.ts.map +1 -0
  397. package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.js +28 -0
  398. package/backend/dist/platform/workPersistence/postgresWorkMessageContentMigration.js.map +1 -0
  399. package/backend/dist/platform/workPersistence/postgresWorkMigration.d.ts +3 -0
  400. package/backend/dist/platform/workPersistence/postgresWorkMigration.d.ts.map +1 -0
  401. package/backend/dist/platform/workPersistence/postgresWorkMigration.js +101 -0
  402. package/backend/dist/platform/workPersistence/postgresWorkMigration.js.map +1 -0
  403. package/backend/dist/platform/workPersistence/postgresWorkPersistence.d.ts +79 -0
  404. package/backend/dist/platform/workPersistence/postgresWorkPersistence.d.ts.map +1 -0
  405. package/backend/dist/platform/workPersistence/postgresWorkPersistence.js +521 -0
  406. package/backend/dist/platform/workPersistence/postgresWorkPersistence.js.map +1 -0
  407. package/backend/dist/platform/workPersistence/service.d.ts +6 -0
  408. package/backend/dist/platform/workPersistence/service.d.ts.map +1 -0
  409. package/backend/dist/platform/workPersistence/service.js +27 -0
  410. package/backend/dist/platform/workPersistence/service.js.map +1 -0
  411. package/backend/dist/platform/workPersistence/sqliteWorkPersistence.d.ts +77 -0
  412. package/backend/dist/platform/workPersistence/sqliteWorkPersistence.d.ts.map +1 -0
  413. package/backend/dist/platform/workPersistence/sqliteWorkPersistence.js +463 -0
  414. package/backend/dist/platform/workPersistence/sqliteWorkPersistence.js.map +1 -0
  415. package/backend/dist/platform/workPersistence/types.d.ts +159 -0
  416. package/backend/dist/platform/workPersistence/types.d.ts.map +1 -0
  417. package/backend/dist/platform/workPersistence/types.js +13 -0
  418. package/backend/dist/platform/workPersistence/types.js.map +1 -0
  419. package/backend/dist/platform/workPersistence/workExecutionTypes.d.ts +13 -0
  420. package/backend/dist/platform/workPersistence/workExecutionTypes.d.ts.map +1 -0
  421. package/backend/dist/platform/workPersistence/workExecutionTypes.js +7 -0
  422. package/backend/dist/platform/workPersistence/workExecutionTypes.js.map +1 -0
  423. package/backend/dist/platform/workPersistence/workMessageContentCodec.d.ts +8 -0
  424. package/backend/dist/platform/workPersistence/workMessageContentCodec.d.ts.map +1 -0
  425. package/backend/dist/platform/workPersistence/workMessageContentCodec.js +25 -0
  426. package/backend/dist/platform/workPersistence/workMessageContentCodec.js.map +1 -0
  427. package/backend/dist/platform/workPersistence/workTextSafety.d.ts +3 -0
  428. package/backend/dist/platform/workPersistence/workTextSafety.d.ts.map +1 -0
  429. package/backend/dist/platform/workPersistence/workTextSafety.js +8 -0
  430. package/backend/dist/platform/workPersistence/workTextSafety.js.map +1 -0
  431. package/backend/dist/routes/agentCli.js +1 -1
  432. package/backend/dist/routes/agentCli.js.map +1 -1
  433. package/backend/dist/routes/artifacts.d.ts.map +1 -1
  434. package/backend/dist/routes/artifacts.js +2 -1
  435. package/backend/dist/routes/artifacts.js.map +1 -1
  436. package/backend/dist/routes/auth.d.ts.map +1 -1
  437. package/backend/dist/routes/auth.js +64 -18
  438. package/backend/dist/routes/auth.js.map +1 -1
  439. package/backend/dist/routes/chat.d.ts.map +1 -1
  440. package/backend/dist/routes/chat.js +519 -85
  441. package/backend/dist/routes/chat.js.map +1 -1
  442. package/backend/dist/routes/documents.d.ts.map +1 -1
  443. package/backend/dist/routes/documents.js +134 -28
  444. package/backend/dist/routes/documents.js.map +1 -1
  445. package/backend/dist/routes/embeddings.d.ts.map +1 -1
  446. package/backend/dist/routes/embeddings.js +2 -1
  447. package/backend/dist/routes/embeddings.js.map +1 -1
  448. package/backend/dist/routes/health.d.ts +3 -0
  449. package/backend/dist/routes/health.d.ts.map +1 -0
  450. package/backend/dist/routes/health.js +52 -0
  451. package/backend/dist/routes/health.js.map +1 -0
  452. package/backend/dist/routes/huggingfaceHub.d.ts.map +1 -1
  453. package/backend/dist/routes/huggingfaceHub.js +2 -1
  454. package/backend/dist/routes/huggingfaceHub.js.map +1 -1
  455. package/backend/dist/routes/imageGen.d.ts.map +1 -1
  456. package/backend/dist/routes/imageGen.js +42 -10
  457. package/backend/dist/routes/imageGen.js.map +1 -1
  458. package/backend/dist/routes/jobs.d.ts +3 -0
  459. package/backend/dist/routes/jobs.d.ts.map +1 -0
  460. package/backend/dist/routes/jobs.js +117 -0
  461. package/backend/dist/routes/jobs.js.map +1 -0
  462. package/backend/dist/routes/libreClaw.d.ts.map +1 -1
  463. package/backend/dist/routes/libreClaw.js +10 -7
  464. package/backend/dist/routes/libreClaw.js.map +1 -1
  465. package/backend/dist/routes/media.d.ts.map +1 -1
  466. package/backend/dist/routes/media.js +523 -77
  467. package/backend/dist/routes/media.js.map +1 -1
  468. package/backend/dist/routes/notes.d.ts.map +1 -1
  469. package/backend/dist/routes/notes.js +21 -21
  470. package/backend/dist/routes/notes.js.map +1 -1
  471. package/backend/dist/routes/ollama.d.ts.map +1 -1
  472. package/backend/dist/routes/ollama.js +40 -12
  473. package/backend/dist/routes/ollama.js.map +1 -1
  474. package/backend/dist/routes/personas.d.ts.map +1 -1
  475. package/backend/dist/routes/personas.js +4 -2
  476. package/backend/dist/routes/personas.js.map +1 -1
  477. package/backend/dist/routes/plugins.d.ts.map +1 -1
  478. package/backend/dist/routes/plugins.js +79 -51
  479. package/backend/dist/routes/plugins.js.map +1 -1
  480. package/backend/dist/routes/preferences.d.ts.map +1 -1
  481. package/backend/dist/routes/preferences.js +290 -25
  482. package/backend/dist/routes/preferences.js.map +1 -1
  483. package/backend/dist/routes/search.d.ts.map +1 -1
  484. package/backend/dist/routes/search.js +23 -14
  485. package/backend/dist/routes/search.js.map +1 -1
  486. package/backend/dist/routes/stt.d.ts +9 -0
  487. package/backend/dist/routes/stt.d.ts.map +1 -0
  488. package/backend/dist/routes/stt.js +217 -0
  489. package/backend/dist/routes/stt.js.map +1 -0
  490. package/backend/dist/routes/systemDiagnostics.d.ts.map +1 -1
  491. package/backend/dist/routes/systemDiagnostics.js +2 -1
  492. package/backend/dist/routes/systemDiagnostics.js.map +1 -1
  493. package/backend/dist/routes/tts.d.ts.map +1 -1
  494. package/backend/dist/routes/tts.js +577 -28
  495. package/backend/dist/routes/tts.js.map +1 -1
  496. package/backend/dist/routes/users.d.ts.map +1 -1
  497. package/backend/dist/routes/users.js +16 -25
  498. package/backend/dist/routes/users.js.map +1 -1
  499. package/backend/dist/routes/work.d.ts.map +1 -1
  500. package/backend/dist/routes/work.js +167 -113
  501. package/backend/dist/routes/work.js.map +1 -1
  502. package/backend/dist/services/agentAccessService.d.ts +2 -2
  503. package/backend/dist/services/agentAccessService.d.ts.map +1 -1
  504. package/backend/dist/services/agentAccessService.js +5 -14
  505. package/backend/dist/services/agentAccessService.js.map +1 -1
  506. package/backend/dist/services/agentCliService.d.ts +3 -2
  507. package/backend/dist/services/agentCliService.d.ts.map +1 -1
  508. package/backend/dist/services/agentCliService.js +44 -16
  509. package/backend/dist/services/agentCliService.js.map +1 -1
  510. package/backend/dist/services/assistantCompletionService.d.ts +2 -1
  511. package/backend/dist/services/assistantCompletionService.d.ts.map +1 -1
  512. package/backend/dist/services/assistantCompletionService.js +7 -3
  513. package/backend/dist/services/assistantCompletionService.js.map +1 -1
  514. package/backend/dist/services/authService.d.ts +7 -2
  515. package/backend/dist/services/authService.d.ts.map +1 -1
  516. package/backend/dist/services/authService.js +23 -10
  517. package/backend/dist/services/authService.js.map +1 -1
  518. package/backend/dist/services/chatGenerationService.d.ts +5 -4
  519. package/backend/dist/services/chatGenerationService.d.ts.map +1 -1
  520. package/backend/dist/services/chatGenerationService.js +23 -17
  521. package/backend/dist/services/chatGenerationService.js.map +1 -1
  522. package/backend/dist/services/chatRequestService.d.ts +4 -3
  523. package/backend/dist/services/chatRequestService.d.ts.map +1 -1
  524. package/backend/dist/services/chatRequestService.js +3 -3
  525. package/backend/dist/services/chatRequestService.js.map +1 -1
  526. package/backend/dist/services/chatService.d.ts +66 -16
  527. package/backend/dist/services/chatService.d.ts.map +1 -1
  528. package/backend/dist/services/chatService.js +402 -111
  529. package/backend/dist/services/chatService.js.map +1 -1
  530. package/backend/dist/services/codexOAuthService.d.ts +2 -2
  531. package/backend/dist/services/codexOAuthService.d.ts.map +1 -1
  532. package/backend/dist/services/codexOAuthService.js +63 -7
  533. package/backend/dist/services/codexOAuthService.js.map +1 -1
  534. package/backend/dist/services/dataArchiveService.d.ts +88 -0
  535. package/backend/dist/services/dataArchiveService.d.ts.map +1 -0
  536. package/backend/dist/services/dataArchiveService.js +1027 -0
  537. package/backend/dist/services/dataArchiveService.js.map +1 -0
  538. package/backend/dist/services/documentService.d.ts +67 -14
  539. package/backend/dist/services/documentService.d.ts.map +1 -1
  540. package/backend/dist/services/documentService.js +938 -193
  541. package/backend/dist/services/documentService.js.map +1 -1
  542. package/backend/dist/services/durableChatCompletion.d.ts +16 -0
  543. package/backend/dist/services/durableChatCompletion.d.ts.map +1 -0
  544. package/backend/dist/services/durableChatCompletion.js +34 -0
  545. package/backend/dist/services/durableChatCompletion.js.map +1 -0
  546. package/backend/dist/services/durableChatGenerationService.d.ts +19 -0
  547. package/backend/dist/services/durableChatGenerationService.d.ts.map +1 -0
  548. package/backend/dist/services/durableChatGenerationService.js +341 -0
  549. package/backend/dist/services/durableChatGenerationService.js.map +1 -0
  550. package/backend/dist/services/embeddingService.d.ts +1 -1
  551. package/backend/dist/services/embeddingService.d.ts.map +1 -1
  552. package/backend/dist/services/embeddingService.js +16 -13
  553. package/backend/dist/services/embeddingService.js.map +1 -1
  554. package/backend/dist/services/encryptionService.d.ts +28 -1
  555. package/backend/dist/services/encryptionService.d.ts.map +1 -1
  556. package/backend/dist/services/encryptionService.js +131 -51
  557. package/backend/dist/services/encryptionService.js.map +1 -1
  558. package/backend/dist/services/followUpService.d.ts +1 -1
  559. package/backend/dist/services/followUpService.d.ts.map +1 -1
  560. package/backend/dist/services/followUpService.js +1 -1
  561. package/backend/dist/services/followUpService.js.map +1 -1
  562. package/backend/dist/services/galleryService.d.ts +38 -37
  563. package/backend/dist/services/galleryService.d.ts.map +1 -1
  564. package/backend/dist/services/galleryService.js +356 -251
  565. package/backend/dist/services/galleryService.js.map +1 -1
  566. package/backend/dist/services/healthService.d.ts +65 -0
  567. package/backend/dist/services/healthService.d.ts.map +1 -0
  568. package/backend/dist/services/healthService.js +379 -0
  569. package/backend/dist/services/healthService.js.map +1 -0
  570. package/backend/dist/services/legacyCiphertextIntegrity.d.ts +40 -0
  571. package/backend/dist/services/legacyCiphertextIntegrity.d.ts.map +1 -0
  572. package/backend/dist/services/legacyCiphertextIntegrity.js +406 -0
  573. package/backend/dist/services/legacyCiphertextIntegrity.js.map +1 -0
  574. package/backend/dist/services/mediaGenerationJobService.d.ts +27 -5
  575. package/backend/dist/services/mediaGenerationJobService.d.ts.map +1 -1
  576. package/backend/dist/services/mediaGenerationJobService.js +185 -55
  577. package/backend/dist/services/mediaGenerationJobService.js.map +1 -1
  578. package/backend/dist/services/memoryService.d.ts +7 -83
  579. package/backend/dist/services/memoryService.d.ts.map +1 -1
  580. package/backend/dist/services/memoryService.js +428 -573
  581. package/backend/dist/services/memoryService.js.map +1 -1
  582. package/backend/dist/services/memoryUtils.d.ts.map +1 -1
  583. package/backend/dist/services/memoryUtils.js +8 -1
  584. package/backend/dist/services/memoryUtils.js.map +1 -1
  585. package/backend/dist/services/modelAccessService.d.ts +3 -3
  586. package/backend/dist/services/modelAccessService.d.ts.map +1 -1
  587. package/backend/dist/services/modelAccessService.js +8 -16
  588. package/backend/dist/services/modelAccessService.js.map +1 -1
  589. package/backend/dist/services/mutationEngineService.d.ts +0 -7
  590. package/backend/dist/services/mutationEngineService.d.ts.map +1 -1
  591. package/backend/dist/services/mutationEngineService.js +7 -78
  592. package/backend/dist/services/mutationEngineService.js.map +1 -1
  593. package/backend/dist/services/ollamaService.d.ts +4 -4
  594. package/backend/dist/services/ollamaService.d.ts.map +1 -1
  595. package/backend/dist/services/ollamaService.js +62 -31
  596. package/backend/dist/services/ollamaService.js.map +1 -1
  597. package/backend/dist/services/personaService.d.ts.map +1 -1
  598. package/backend/dist/services/personaService.js +19 -54
  599. package/backend/dist/services/personaService.js.map +1 -1
  600. package/backend/dist/services/pluginActivationService.d.ts +6 -5
  601. package/backend/dist/services/pluginActivationService.d.ts.map +1 -1
  602. package/backend/dist/services/pluginActivationService.js +36 -76
  603. package/backend/dist/services/pluginActivationService.js.map +1 -1
  604. package/backend/dist/services/pluginAudioGenerationService.d.ts +11 -6
  605. package/backend/dist/services/pluginAudioGenerationService.d.ts.map +1 -1
  606. package/backend/dist/services/pluginAudioGenerationService.js +74 -16
  607. package/backend/dist/services/pluginAudioGenerationService.js.map +1 -1
  608. package/backend/dist/services/pluginCacheInvalidation.d.ts +38 -0
  609. package/backend/dist/services/pluginCacheInvalidation.d.ts.map +1 -0
  610. package/backend/dist/services/pluginCacheInvalidation.js +198 -0
  611. package/backend/dist/services/pluginCacheInvalidation.js.map +1 -0
  612. package/backend/dist/services/pluginCapabilityRegistryService.d.ts +3 -3
  613. package/backend/dist/services/pluginCapabilityRegistryService.d.ts.map +1 -1
  614. package/backend/dist/services/pluginCapabilityRegistryService.js +11 -7
  615. package/backend/dist/services/pluginCapabilityRegistryService.js.map +1 -1
  616. package/backend/dist/services/pluginCredentialsService.d.ts +9 -8
  617. package/backend/dist/services/pluginCredentialsService.d.ts.map +1 -1
  618. package/backend/dist/services/pluginCredentialsService.js +48 -89
  619. package/backend/dist/services/pluginCredentialsService.js.map +1 -1
  620. package/backend/dist/services/pluginEmbeddingService.d.ts +8 -7
  621. package/backend/dist/services/pluginEmbeddingService.d.ts.map +1 -1
  622. package/backend/dist/services/pluginEmbeddingService.js +13 -11
  623. package/backend/dist/services/pluginEmbeddingService.js.map +1 -1
  624. package/backend/dist/services/pluginImageGenerationService.d.ts +10 -8
  625. package/backend/dist/services/pluginImageGenerationService.d.ts.map +1 -1
  626. package/backend/dist/services/pluginImageGenerationService.js +119 -14
  627. package/backend/dist/services/pluginImageGenerationService.js.map +1 -1
  628. package/backend/dist/services/pluginSTTService.d.ts +47 -0
  629. package/backend/dist/services/pluginSTTService.d.ts.map +1 -0
  630. package/backend/dist/services/pluginSTTService.js +199 -0
  631. package/backend/dist/services/pluginSTTService.js.map +1 -0
  632. package/backend/dist/services/pluginService.d.ts +94 -40
  633. package/backend/dist/services/pluginService.d.ts.map +1 -1
  634. package/backend/dist/services/pluginService.js +799 -274
  635. package/backend/dist/services/pluginService.js.map +1 -1
  636. package/backend/dist/services/pluginTTSService.d.ts +26 -8
  637. package/backend/dist/services/pluginTTSService.d.ts.map +1 -1
  638. package/backend/dist/services/pluginTTSService.js +277 -25
  639. package/backend/dist/services/pluginTTSService.js.map +1 -1
  640. package/backend/dist/services/pluginUsageService.d.ts +4 -4
  641. package/backend/dist/services/pluginUsageService.d.ts.map +1 -1
  642. package/backend/dist/services/pluginUsageService.js +44 -93
  643. package/backend/dist/services/pluginUsageService.js.map +1 -1
  644. package/backend/dist/services/pluginVariablesService.d.ts +14 -7
  645. package/backend/dist/services/pluginVariablesService.d.ts.map +1 -1
  646. package/backend/dist/services/pluginVariablesService.js +116 -81
  647. package/backend/dist/services/pluginVariablesService.js.map +1 -1
  648. package/backend/dist/services/pluginVideoGenerationService.d.ts +19 -8
  649. package/backend/dist/services/pluginVideoGenerationService.d.ts.map +1 -1
  650. package/backend/dist/services/pluginVideoGenerationService.js +116 -20
  651. package/backend/dist/services/pluginVideoGenerationService.js.map +1 -1
  652. package/backend/dist/services/preferencesService.d.ts +31 -21
  653. package/backend/dist/services/preferencesService.d.ts.map +1 -1
  654. package/backend/dist/services/preferencesService.js +104 -102
  655. package/backend/dist/services/preferencesService.js.map +1 -1
  656. package/backend/dist/services/recoveryInventoryService.d.ts +244 -0
  657. package/backend/dist/services/recoveryInventoryService.d.ts.map +1 -0
  658. package/backend/dist/services/recoveryInventoryService.js +1436 -0
  659. package/backend/dist/services/recoveryInventoryService.js.map +1 -0
  660. package/backend/dist/services/simpleGitHubOAuth.js +3 -3
  661. package/backend/dist/services/simpleGitHubOAuth.js.map +1 -1
  662. package/backend/dist/services/simpleHuggingFaceOAuth.d.ts.map +1 -1
  663. package/backend/dist/services/simpleHuggingFaceOAuth.js +3 -3
  664. package/backend/dist/services/simpleHuggingFaceOAuth.js.map +1 -1
  665. package/backend/dist/services/systemDiagnosticsService.d.ts.map +1 -1
  666. package/backend/dist/services/systemDiagnosticsService.js +2 -2
  667. package/backend/dist/services/systemDiagnosticsService.js.map +1 -1
  668. package/backend/dist/services/systemSettingsService.d.ts +5 -0
  669. package/backend/dist/services/systemSettingsService.d.ts.map +1 -0
  670. package/backend/dist/services/systemSettingsService.js +24 -0
  671. package/backend/dist/services/systemSettingsService.js.map +1 -0
  672. package/backend/dist/services/titleGenerationService.d.ts +1 -1
  673. package/backend/dist/services/titleGenerationService.d.ts.map +1 -1
  674. package/backend/dist/services/titleGenerationService.js +1 -1
  675. package/backend/dist/services/titleGenerationService.js.map +1 -1
  676. package/backend/dist/services/voiceProfileService.d.ts +44 -0
  677. package/backend/dist/services/voiceProfileService.d.ts.map +1 -0
  678. package/backend/dist/services/voiceProfileService.js +195 -0
  679. package/backend/dist/services/voiceProfileService.js.map +1 -0
  680. package/backend/dist/services/webSearchService.d.ts +7 -7
  681. package/backend/dist/services/webSearchService.d.ts.map +1 -1
  682. package/backend/dist/services/webSearchService.js +40 -35
  683. package/backend/dist/services/webSearchService.js.map +1 -1
  684. package/backend/dist/services/websocketTicketService.d.ts +39 -0
  685. package/backend/dist/services/websocketTicketService.d.ts.map +1 -0
  686. package/backend/dist/services/websocketTicketService.js +183 -0
  687. package/backend/dist/services/websocketTicketService.js.map +1 -0
  688. package/backend/dist/services/workAccessService.d.ts +3 -3
  689. package/backend/dist/services/workAccessService.d.ts.map +1 -1
  690. package/backend/dist/services/workAccessService.js +8 -16
  691. package/backend/dist/services/workAccessService.js.map +1 -1
  692. package/backend/dist/services/workAdminService.d.ts +3 -3
  693. package/backend/dist/services/workAdminService.d.ts.map +1 -1
  694. package/backend/dist/services/workAdminService.js +4 -4
  695. package/backend/dist/services/workAdminService.js.map +1 -1
  696. package/backend/dist/services/workAgentService.d.ts +25 -1
  697. package/backend/dist/services/workAgentService.d.ts.map +1 -1
  698. package/backend/dist/services/workAgentService.js +294 -126
  699. package/backend/dist/services/workAgentService.js.map +1 -1
  700. package/backend/dist/services/workEventService.d.ts +15 -2
  701. package/backend/dist/services/workEventService.d.ts.map +1 -1
  702. package/backend/dist/services/workEventService.js +201 -3
  703. package/backend/dist/services/workEventService.js.map +1 -1
  704. package/backend/dist/services/workKubernetesDriver.d.ts +8 -7
  705. package/backend/dist/services/workKubernetesDriver.d.ts.map +1 -1
  706. package/backend/dist/services/workKubernetesDriver.js +65 -21
  707. package/backend/dist/services/workKubernetesDriver.js.map +1 -1
  708. package/backend/dist/services/workModelProviderService.d.ts +2 -2
  709. package/backend/dist/services/workModelProviderService.d.ts.map +1 -1
  710. package/backend/dist/services/workModelProviderService.js +38 -34
  711. package/backend/dist/services/workModelProviderService.js.map +1 -1
  712. package/backend/dist/services/workPolicyService.d.ts +7 -7
  713. package/backend/dist/services/workPolicyService.d.ts.map +1 -1
  714. package/backend/dist/services/workPolicyService.js +50 -51
  715. package/backend/dist/services/workPolicyService.js.map +1 -1
  716. package/backend/dist/services/workPreviewProxyService.d.ts +8 -8
  717. package/backend/dist/services/workPreviewProxyService.d.ts.map +1 -1
  718. package/backend/dist/services/workPreviewProxyService.js +47 -44
  719. package/backend/dist/services/workPreviewProxyService.js.map +1 -1
  720. package/backend/dist/services/workRuntimeDriver.d.ts +21 -18
  721. package/backend/dist/services/workRuntimeDriver.d.ts.map +1 -1
  722. package/backend/dist/services/workRuntimeDriver.js +69 -20
  723. package/backend/dist/services/workRuntimeDriver.js.map +1 -1
  724. package/backend/dist/services/workRuntimeService.d.ts +18 -13
  725. package/backend/dist/services/workRuntimeService.d.ts.map +1 -1
  726. package/backend/dist/services/workRuntimeService.js +438 -194
  727. package/backend/dist/services/workRuntimeService.js.map +1 -1
  728. package/backend/dist/services/workRuntimeShared.d.ts +2 -0
  729. package/backend/dist/services/workRuntimeShared.d.ts.map +1 -1
  730. package/backend/dist/services/workRuntimeShared.js.map +1 -1
  731. package/backend/dist/services/workTaskService.d.ts +42 -36
  732. package/backend/dist/services/workTaskService.d.ts.map +1 -1
  733. package/backend/dist/services/workTaskService.js +445 -350
  734. package/backend/dist/services/workTaskService.js.map +1 -1
  735. package/backend/dist/services/workTerminalService.d.ts +1 -1
  736. package/backend/dist/services/workTerminalService.d.ts.map +1 -1
  737. package/backend/dist/services/workTerminalService.js +33 -6
  738. package/backend/dist/services/workTerminalService.js.map +1 -1
  739. package/backend/dist/storage.d.ts +72 -40
  740. package/backend/dist/storage.d.ts.map +1 -1
  741. package/backend/dist/storage.js +312 -660
  742. package/backend/dist/storage.js.map +1 -1
  743. package/backend/dist/types/index.d.ts +28 -0
  744. package/backend/dist/types/index.d.ts.map +1 -1
  745. package/backend/dist/types/index.js.map +1 -1
  746. package/backend/dist/types/work.d.ts +7 -2
  747. package/backend/dist/types/work.d.ts.map +1 -1
  748. package/backend/dist/utils/chatCancellation.d.ts +48 -0
  749. package/backend/dist/utils/chatCancellation.d.ts.map +1 -0
  750. package/backend/dist/utils/chatCancellation.js +152 -0
  751. package/backend/dist/utils/chatCancellation.js.map +1 -0
  752. package/backend/dist/utils/chatDocumentContext.d.ts +1 -1
  753. package/backend/dist/utils/chatDocumentContext.d.ts.map +1 -1
  754. package/backend/dist/utils/chatDocumentContext.js +11 -5
  755. package/backend/dist/utils/chatDocumentContext.js.map +1 -1
  756. package/backend/dist/utils/chatStreamCoalescer.d.ts +15 -0
  757. package/backend/dist/utils/chatStreamCoalescer.d.ts.map +1 -0
  758. package/backend/dist/utils/chatStreamCoalescer.js +59 -0
  759. package/backend/dist/utils/chatStreamCoalescer.js.map +1 -0
  760. package/backend/dist/utils/dataDirectory.d.ts +49 -0
  761. package/backend/dist/utils/dataDirectory.d.ts.map +1 -0
  762. package/backend/dist/utils/dataDirectory.js +291 -0
  763. package/backend/dist/utils/dataDirectory.js.map +1 -0
  764. package/backend/dist/utils/generationUtils.d.ts.map +1 -1
  765. package/backend/dist/utils/generationUtils.js +18 -6
  766. package/backend/dist/utils/generationUtils.js.map +1 -1
  767. package/backend/dist/utils/jwt.d.ts.map +1 -1
  768. package/backend/dist/utils/jwt.js +2 -3
  769. package/backend/dist/utils/jwt.js.map +1 -1
  770. package/backend/dist/utils/ollamaModelDefaults.d.ts.map +1 -1
  771. package/backend/dist/utils/ollamaModelDefaults.js +2 -7
  772. package/backend/dist/utils/ollamaModelDefaults.js.map +1 -1
  773. package/backend/dist/utils/ollamaStreaming.d.ts +2 -1
  774. package/backend/dist/utils/ollamaStreaming.d.ts.map +1 -1
  775. package/backend/dist/utils/ollamaStreaming.js +49 -11
  776. package/backend/dist/utils/ollamaStreaming.js.map +1 -1
  777. package/backend/dist/utils/pluginConnectionVariables.d.ts.map +1 -1
  778. package/backend/dist/utils/pluginConnectionVariables.js +11 -3
  779. package/backend/dist/utils/pluginConnectionVariables.js.map +1 -1
  780. package/backend/dist/utils/pluginDefinitionTrust.d.ts.map +1 -1
  781. package/backend/dist/utils/pluginDefinitionTrust.js +4 -3
  782. package/backend/dist/utils/pluginDefinitionTrust.js.map +1 -1
  783. package/backend/dist/utils/pluginStreaming.d.ts +2 -1
  784. package/backend/dist/utils/pluginStreaming.d.ts.map +1 -1
  785. package/backend/dist/utils/pluginStreaming.js +5 -1
  786. package/backend/dist/utils/pluginStreaming.js.map +1 -1
  787. package/backend/dist/utils/pluginUpload.d.ts +1 -0
  788. package/backend/dist/utils/pluginUpload.d.ts.map +1 -1
  789. package/backend/dist/utils/pluginUpload.js +9 -2
  790. package/backend/dist/utils/pluginUpload.js.map +1 -1
  791. package/backend/dist/utils/pluginValidation.d.ts.map +1 -1
  792. package/backend/dist/utils/pluginValidation.js +29 -1
  793. package/backend/dist/utils/pluginValidation.js.map +1 -1
  794. package/backend/dist/utils/sttAudioUpload.d.ts +24 -0
  795. package/backend/dist/utils/sttAudioUpload.d.ts.map +1 -0
  796. package/backend/dist/utils/sttAudioUpload.js +500 -0
  797. package/backend/dist/utils/sttAudioUpload.js.map +1 -0
  798. package/backend/dist/utils/ttsVoiceCloneUpload.d.ts +34 -0
  799. package/backend/dist/utils/ttsVoiceCloneUpload.d.ts.map +1 -0
  800. package/backend/dist/utils/ttsVoiceCloneUpload.js +224 -0
  801. package/backend/dist/utils/ttsVoiceCloneUpload.js.map +1 -0
  802. package/backend/dist/utils/websocketMessages.d.ts +2 -1
  803. package/backend/dist/utils/websocketMessages.d.ts.map +1 -1
  804. package/backend/dist/utils/websocketMessages.js +16 -2
  805. package/backend/dist/utils/websocketMessages.js.map +1 -1
  806. package/backend/dist/websocketServer.d.ts +4 -1
  807. package/backend/dist/websocketServer.d.ts.map +1 -1
  808. package/backend/dist/websocketServer.js +290 -44
  809. package/backend/dist/websocketServer.js.map +1 -1
  810. package/backend/dist/workTerminalServer.d.ts +9 -0
  811. package/backend/dist/workTerminalServer.d.ts.map +1 -1
  812. package/backend/dist/workTerminalServer.js +221 -52
  813. package/backend/dist/workTerminalServer.js.map +1 -1
  814. package/backend/dist/worker.d.ts +2 -0
  815. package/backend/dist/worker.d.ts.map +1 -0
  816. package/backend/dist/worker.js +250 -0
  817. package/backend/dist/worker.js.map +1 -0
  818. package/backend/package.json +19 -9
  819. package/bin/cli.js +126 -99
  820. package/bin/runtime-paths.js +108 -0
  821. package/frontend/dist/artifact-runtime/.build-fingerprint +1 -1
  822. package/frontend/dist/artifact-runtime/framer-motion.js +5 -5
  823. package/frontend/dist/artifact-runtime/lucide-react.js +1 -1
  824. package/frontend/dist/assets/index-CUhEG7E2.js +33 -0
  825. package/frontend/dist/assets/index-kxtZQLV6.css +1 -0
  826. package/frontend/dist/assets/{markdown-math-ClQbWekD.css → markdown-math-ClTedVi7.css} +1 -1
  827. package/frontend/dist/index.html +18 -18
  828. package/frontend/dist/js/{ArtifactContainer-Dy2Q0iIL.js → ArtifactContainer-BTEDhBnv.js} +1 -1
  829. package/frontend/dist/js/{ArtifactDemoPage-K79dWshB.js → ArtifactDemoPage-B0gN3YTl.js} +1 -1
  830. package/frontend/dist/js/{ArtifactSandboxFrame-DhqLNUtY.js → ArtifactSandboxFrame-CLBXQkZs.js} +3 -3
  831. package/frontend/dist/js/{ArtifactSlideOutPanel-Cl8JG7bz.js → ArtifactSlideOutPanel-CfqHPFdE.js} +1 -1
  832. package/frontend/dist/js/{Button-CTXHujOd.js → Button-BV44cTnj.js} +1 -1
  833. package/frontend/dist/js/ChatPage-DIkAXZWA.js +23 -0
  834. package/frontend/dist/js/{FirstTimeSetup-kHhRzGJ8.js → FirstTimeSetup-B8phXGNA.js} +1 -1
  835. package/frontend/dist/js/GalleryPage-W4uI043I.js +1 -0
  836. package/frontend/dist/js/{HomePage-C1L8WAXL.js → HomePage-DlxehbyO.js} +1 -1
  837. package/frontend/dist/js/{LibreClawPage-Dyua8IUu.js → LibreClawPage-CgD0_G_F.js} +1 -1
  838. package/frontend/dist/js/{ModelManagerModals-CuMRGUd-.js → ModelManagerModals-D7jIT3v1.js} +1 -1
  839. package/frontend/dist/js/{ModelSelector-CqHc-Ln4.js → ModelSelector-BYxJU1UV.js} +1 -1
  840. package/frontend/dist/js/ModelsPage-C4XdCKP5.js +2 -0
  841. package/frontend/dist/js/NotesPage-CDECOl4V.js +1 -0
  842. package/frontend/dist/js/{OptimizedSyntaxHighlighter-CWYUn9Oe.js → OptimizedSyntaxHighlighter-XwqZEoTf.js} +1 -1
  843. package/frontend/dist/js/{PersonasPage-D_6WBCH5.js → PersonasPage-CjSLPrgS.js} +2 -2
  844. package/frontend/dist/js/PluginUsagePage-DJOXJuH4.js +1 -0
  845. package/frontend/dist/js/RichMessageContent-Debeh6bi.js +3 -0
  846. package/frontend/dist/js/SettingsModal-cUqAeYUP.js +1 -0
  847. package/frontend/dist/js/{SettingsToggle-DLHlCDBl.js → SettingsToggle-WTa0rgvY.js} +1 -1
  848. package/frontend/dist/js/{SystemPage-BMWEet9e.js → SystemPage-DxPw0GS7.js} +1 -1
  849. package/frontend/dist/js/UserManagementPage-CEdYFe_Z.js +1 -0
  850. package/frontend/dist/js/WorkPage-DDVeuG_9.js +6 -0
  851. package/frontend/dist/js/api-IzobHGND.js +14 -0
  852. package/frontend/dist/js/appStore-DKwC2vgn.js +2 -0
  853. package/frontend/dist/js/ar-xTSvTq05.js +2 -0
  854. package/frontend/dist/js/authStore-OaTuapL7.js +4 -0
  855. package/frontend/dist/js/{babel-CmENXdZw.js → babel-D24oDI9y.js} +1 -1
  856. package/frontend/dist/js/bn-iYAsohEA.js +2 -0
  857. package/frontend/dist/js/chatStore-DXGUVLXD.js +3 -0
  858. package/frontend/dist/js/{config-DkV1ka7I.js → config-DPEEuTAe.js} +1 -1
  859. package/frontend/dist/js/cs-YBHN88Hb.js +2 -0
  860. package/frontend/dist/js/da-D7qlLy_k.js +2 -0
  861. package/frontend/dist/js/de-DV671k2c.js +2 -0
  862. package/frontend/dist/js/es-kyBgzNq-.js +2 -0
  863. package/frontend/dist/js/{estree-D5KP-qbw.js → estree-ChwJsD2w.js} +1 -1
  864. package/frontend/dist/js/fr-Cw1vut7I.js +2 -0
  865. package/frontend/dist/js/hi-DWEFC024.js +2 -0
  866. package/frontend/dist/js/{html-Cm9c2akd.js → html-DFrVjciF.js} +1 -1
  867. package/frontend/dist/js/id-DlMHjjy0.js +2 -0
  868. package/frontend/dist/js/is-B9E_a7dG.js +2 -0
  869. package/frontend/dist/js/it-DawmVbLC.js +2 -0
  870. package/frontend/dist/js/ja-DmVvwY3W.js +2 -0
  871. package/frontend/dist/js/ko-DzOPpkVs.js +2 -0
  872. package/frontend/dist/js/{markdown-B2u7CnKN.js → markdown-FLLx7b67.js} +1 -1
  873. package/frontend/dist/js/markdown-core-BmPPZiuD.js +31 -0
  874. package/frontend/dist/js/{markdown-math-B7FlYsmr.js → markdown-math-mH7AZ_mb.js} +6 -6
  875. package/frontend/dist/js/{messageCodeStyles-DalG2j6U.js → messageCodeStyles-CBkkZY4n.js} +1 -1
  876. package/frontend/dist/js/ms-DpsaOPht.js +2 -0
  877. package/frontend/dist/js/nl-B1d8W22n.js +2 -0
  878. package/frontend/dist/js/pl-nCncRVgt.js +2 -0
  879. package/frontend/dist/js/{postcss-B5WIGhAY.js → postcss-Bx9CTcIc.js} +1 -1
  880. package/frontend/dist/js/pt-DHw8fGuu.js +2 -0
  881. package/frontend/dist/js/{react-vendor-DPNXrO-8.js → react-vendor-C5yShNlM.js} +1 -1
  882. package/frontend/dist/js/{router-vendor-Ca9zqOqT.js → router-vendor-CbPDks39.js} +1 -1
  883. package/frontend/dist/js/ru-Derl_YP_.js +2 -0
  884. package/frontend/dist/js/{standalone-Dwm1daef.js → standalone-i8-5bg5p.js} +1 -1
  885. package/frontend/dist/js/sv-pJAfBVo0.js +2 -0
  886. package/frontend/dist/js/{syntax-highlight-Ca9bHsaz.js → syntax-highlight-3EEX6CGL.js} +3 -3
  887. package/frontend/dist/js/th-C_7fIGnk.js +2 -0
  888. package/frontend/dist/js/tr-CPqsJvaP.js +2 -0
  889. package/frontend/dist/js/{typescript-CwieSptM.js → typescript-CQ3x-Uni.js} +1 -1
  890. package/frontend/dist/js/{ui-BnDZpjfc.js → ui-BHhR3Vok.js} +2 -2
  891. package/frontend/dist/js/ui-vendor-D3Ahl1x5.js +177 -0
  892. package/frontend/dist/js/uk-3o8P_kFi.js +2 -0
  893. package/frontend/dist/js/{useTranslation-CXY69qNk.js → useTranslation-C3ei3mJq.js} +1 -1
  894. package/frontend/dist/js/{utils-BM0_0iFj.js → utils-CuC1beTY.js} +1 -1
  895. package/frontend/dist/js/{utils-vendor-1zob7nK9.js → utils-vendor-BBa8OxtB.js} +1 -1
  896. package/frontend/dist/js/vi-Dv6N7OVD.js +2 -0
  897. package/frontend/dist/js/{workApi-BOS7crs9.js → workApi-Czu69yWS.js} +2 -2
  898. package/frontend/dist/js/{yaml-QD4znPfZ.js → yaml-DioTxVLA.js} +1 -1
  899. package/frontend/dist/js/zh-qg5iqtPi.js +2 -0
  900. package/package.json +16 -5
  901. package/plugins/huggingface.json +12 -3
  902. package/plugins/llama-cpp.json +18 -6
  903. package/plugins/longcat-audiodit.json +114 -0
  904. package/plugins/openai.json +18 -0
  905. package/frontend/dist/assets/index-BBpNbfKW.js +0 -16
  906. package/frontend/dist/assets/index-BLATyFmD.css +0 -1
  907. package/frontend/dist/js/ChatPage-BBayfMLS.js +0 -16
  908. package/frontend/dist/js/GalleryPage-By8VI39Q.js +0 -1
  909. package/frontend/dist/js/ModelsPage-ODeXhDDk.js +0 -2
  910. package/frontend/dist/js/NotesPage-CApzDjOq.js +0 -1
  911. package/frontend/dist/js/PluginUsagePage-kutS6SOd.js +0 -1
  912. package/frontend/dist/js/RichMessageContent-g6WT75Te.js +0 -3
  913. package/frontend/dist/js/SettingsModal-B7z51BCx.js +0 -1
  914. package/frontend/dist/js/UserManagementPage-D08lM51c.js +0 -1
  915. package/frontend/dist/js/WorkPage-DdVLefsK.js +0 -6
  916. package/frontend/dist/js/api-CLEmGcEh.js +0 -14
  917. package/frontend/dist/js/appStore-CGdhvp9P.js +0 -2
  918. package/frontend/dist/js/ar-BTmB2WVm.js +0 -2
  919. package/frontend/dist/js/authStore-Dh3beEOq.js +0 -4
  920. package/frontend/dist/js/bn-CQnH7YVT.js +0 -2
  921. package/frontend/dist/js/chatStore-CDeYWL_q.js +0 -3
  922. package/frontend/dist/js/cs-oTTZkQXr.js +0 -2
  923. package/frontend/dist/js/da-Br0gB6J6.js +0 -2
  924. package/frontend/dist/js/de-DE2iztTF.js +0 -2
  925. package/frontend/dist/js/es-DgthfVtl.js +0 -2
  926. package/frontend/dist/js/fr-BjxjFwPh.js +0 -2
  927. package/frontend/dist/js/hi-D1q7E-9N.js +0 -2
  928. package/frontend/dist/js/id-CDJZqLTF.js +0 -2
  929. package/frontend/dist/js/is-BU7Um_Tq.js +0 -2
  930. package/frontend/dist/js/it-CdAxr8P_.js +0 -2
  931. package/frontend/dist/js/ja-BLbQwz9u.js +0 -2
  932. package/frontend/dist/js/ko-CY5lpkAe.js +0 -2
  933. package/frontend/dist/js/markdown-core-DHnR5Hw8.js +0 -16
  934. package/frontend/dist/js/ms-tQ8AYXEQ.js +0 -2
  935. package/frontend/dist/js/nl-CRNi2oWT.js +0 -2
  936. package/frontend/dist/js/pl-CWtFRS_W.js +0 -2
  937. package/frontend/dist/js/pt-C7SPoLF8.js +0 -2
  938. package/frontend/dist/js/ru-Dz4AX8xc.js +0 -2
  939. package/frontend/dist/js/sv-ETy5-boa.js +0 -2
  940. package/frontend/dist/js/th-DpuMqvxU.js +0 -2
  941. package/frontend/dist/js/tr-C-1AYAqg.js +0 -2
  942. package/frontend/dist/js/ui-vendor-xUzKqAXI.js +0 -177
  943. package/frontend/dist/js/uk-CyS680gr.js +0 -2
  944. package/frontend/dist/js/vi-BG8HuiTz.js +0 -2
  945. package/frontend/dist/js/zh-NCs2mkHj.js +0 -2
@@ -0,0 +1,1203 @@
1
+ /*
2
+ * Libre WebUI
3
+ * Copyright (C) 2025 Kroonen AI, Inc.
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ */
6
+ import crypto from 'node:crypto';
7
+ import { spawn } from 'node:child_process';
8
+ import fs from 'node:fs';
9
+ import os from 'node:os';
10
+ import path from 'node:path';
11
+ import { DeleteObjectCommand, GetBucketVersioningCommand, GetObjectCommand, HeadObjectCommand, ListObjectVersionsCommand, PutObjectCommand, S3Client, } from '@aws-sdk/client-s3';
12
+ import { resolvePostgresRuntimeConfig, } from '../../persistence/postgresConfig.js';
13
+ import { createPostgresDatabase, } from '../../persistence/postgresDatabase.js';
14
+ import { POSTGRES_MIGRATIONS } from '../../persistence/postgresMigrationRegistry.js';
15
+ import { inspectPostgresSchema } from '../../persistence/postgresSchemaInspector.js';
16
+ import { loadAppPackage } from '../../utils/packagePaths.js';
17
+ import { parseAesGcmEnvelope, } from '../storage/aesGcmKeyring.js';
18
+ import { createS3EncryptedBlobStore, resolveS3BlobConfiguration, } from '../storage/s3EncryptedBlobStore.js';
19
+ import { createStorageKeyringFromEnvironment, inspectStorageKeyConfiguration, } from '../storage/storageFactory.js';
20
+ import { PgVectorStore } from '../storage/pgVectorStore.js';
21
+ import { extractBackupPayload, sealBackupPayload, stageProtectedRuntimeConfiguration, } from './backupArchive.js';
22
+ const TEAM_INVENTORY_FORMAT = 'libre-webui-team-backup-inventory';
23
+ const TEAM_INVENTORY_VERSION = 2;
24
+ const COPY_BUFFER_BYTES = 1024 * 1024;
25
+ const DEFAULT_MAX_BLOB_OBJECTS = 250000;
26
+ const DEFAULT_MAX_BLOB_BYTES = 64 * 1024 * 1024 * 1024;
27
+ const MAX_DURABLE_IDENTIFIER_BYTES = 256;
28
+ const MAX_DURABLE_REFERENCE_BYTES = 2048;
29
+ const MAX_DURABLE_PLAINTEXT_BYTES = 64 * 1024;
30
+ const MAX_DURABLE_ENVELOPE_BYTES = 128 * 1024;
31
+ const MAX_DURABLE_JSON_DEPTH = 32;
32
+ const MAX_DURABLE_JSON_NODES = 10000;
33
+ const MAX_DURABLE_PAYLOAD_RECORDS = 250000;
34
+ const MAX_DURABLE_STREAM_HEADS = 250000;
35
+ const MAX_DURABLE_CIPHERTEXT_BYTES = 4 * 1024 * 1024 * 1024;
36
+ const MAX_DURABLE_PLAINTEXT_AGGREGATE_BYTES = 16 * 1024 * 1024 * 1024;
37
+ const DURABLE_PAGE_SIZE = 128;
38
+ const DEFAULT_TOOL_TIMEOUT_MS = 60 * 60 * 1000;
39
+ const MAX_ROLLBACK_FAILURE_DETAILS = 32;
40
+ const TOOL_PATTERN = /^(?:[A-Za-z0-9_.-]+|\/[A-Za-z0-9_./-]+)$/;
41
+ const POSTGRES_BOOTSTRAP_SCHEMAS = new Set([
42
+ 'information_schema',
43
+ 'pg_catalog',
44
+ 'pg_toast',
45
+ 'public',
46
+ ]);
47
+ const POSTGRES_BOOTSTRAP_EXTENSIONS = new Map([['plpgsql', 'pg_catalog']]);
48
+ const POSTGRES_TEMPORARY_SCHEMA_PATTERN = /^pg_(?:temp|toast_temp)_[0-9]+$/;
49
+ /**
50
+ * A restore apply failed and one or more compensating cleanup operations also
51
+ * failed. Callers must treat the target as dirty until both PostgreSQL and the
52
+ * exact versioned S3 prefix have been inspected and cleaned.
53
+ */
54
+ export class TeamRestoreRollbackError extends Error {
55
+ constructor(originalFailure, rollbackFailures, rollbackFailureCount) {
56
+ super(`Team restore failed and rollback was incomplete (${rollbackFailureCount} cleanup failure${rollbackFailureCount === 1 ? '' : 's'}). ` +
57
+ 'The target may contain restored PostgreSQL data and/or immutable S3 versions. ' +
58
+ 'Do not retry until both targets have been inspected and cleaned; clean-target preflight will reject residual state.');
59
+ this.name = 'TeamRestoreRollbackError';
60
+ this.errors = [originalFailure, ...rollbackFailures];
61
+ this.rollbackFailureCount = rollbackFailureCount;
62
+ Object.defineProperty(this, 'cause', {
63
+ value: originalFailure,
64
+ enumerable: false,
65
+ });
66
+ }
67
+ }
68
+ const normalizeError = (error) => error instanceof Error ? error : new Error(String(error));
69
+ const contextualRollbackError = (context, error) => {
70
+ const cause = normalizeError(error);
71
+ const failure = new Error(`${context}: ${cause.message}`);
72
+ Object.defineProperty(failure, 'cause', {
73
+ value: cause,
74
+ enumerable: false,
75
+ });
76
+ return failure;
77
+ };
78
+ const canonicalJson = (value) => {
79
+ const visit = (candidate) => {
80
+ if (candidate === null || typeof candidate !== 'object') {
81
+ return JSON.stringify(candidate);
82
+ }
83
+ if (Array.isArray(candidate))
84
+ return `[${candidate.map(visit).join(',')}]`;
85
+ const object = candidate;
86
+ return `{${Object.keys(object)
87
+ .sort()
88
+ .map(key => `${JSON.stringify(key)}:${visit(object[key])}`)
89
+ .join(',')}}`;
90
+ };
91
+ return visit(value);
92
+ };
93
+ const sha256 = (value) => crypto.createHash('sha256').update(value).digest('hex');
94
+ const safeInteger = (value, field) => {
95
+ const result = typeof value === 'number' ? value : Number(value);
96
+ if (!Number.isSafeInteger(result) || result < 0) {
97
+ throw new Error(`Invalid team backup ${field}.`);
98
+ }
99
+ return result;
100
+ };
101
+ const validateDurableText = (value, maximum = MAX_DURABLE_IDENTIFIER_BYTES) => {
102
+ if (typeof value !== 'string' ||
103
+ value.length === 0 ||
104
+ Buffer.byteLength(value, 'utf8') > maximum) {
105
+ return false;
106
+ }
107
+ return ![...value].some(character => {
108
+ const point = character.codePointAt(0) ?? 0;
109
+ return point <= 31 || point === 127;
110
+ });
111
+ };
112
+ /** Mirrors the immutable durable-payload JSON wire contract. */
113
+ const canonicalDurableJson = (value) => {
114
+ let nodes = 0;
115
+ const ancestors = new Set();
116
+ const visit = (candidate, depth) => {
117
+ nodes += 1;
118
+ if (nodes > MAX_DURABLE_JSON_NODES || depth > MAX_DURABLE_JSON_DEPTH) {
119
+ throw new Error('Durable payload is too complex for backup verification.');
120
+ }
121
+ if (candidate === null)
122
+ return 'null';
123
+ if (typeof candidate === 'string' || typeof candidate === 'boolean') {
124
+ return JSON.stringify(candidate);
125
+ }
126
+ if (typeof candidate === 'number') {
127
+ if (!Number.isFinite(candidate)) {
128
+ throw new Error('Durable payload contains a non-finite number.');
129
+ }
130
+ return JSON.stringify(candidate);
131
+ }
132
+ if (typeof candidate !== 'object' || ancestors.has(candidate)) {
133
+ throw new Error('Durable payload is not acyclic JSON.');
134
+ }
135
+ ancestors.add(candidate);
136
+ try {
137
+ if (Array.isArray(candidate)) {
138
+ return `[${candidate.map(item => visit(item, depth + 1)).join(',')}]`;
139
+ }
140
+ const prototype = Object.getPrototypeOf(candidate);
141
+ if (prototype !== Object.prototype && prototype !== null) {
142
+ throw new Error('Durable payload is not plain JSON.');
143
+ }
144
+ const object = candidate;
145
+ return `{${Object.keys(object)
146
+ .sort()
147
+ .map(key => `${JSON.stringify(key)}:${visit(object[key], depth + 1)}`)
148
+ .join(',')}}`;
149
+ }
150
+ finally {
151
+ ancestors.delete(candidate);
152
+ }
153
+ };
154
+ const serialized = visit(value, 0);
155
+ if (Buffer.byteLength(serialized, 'utf8') > MAX_DURABLE_PLAINTEXT_BYTES) {
156
+ throw new Error('Durable payload exceeds the backup verification limit.');
157
+ }
158
+ return serialized;
159
+ };
160
+ const jobAad = (id, type, actor) => Buffer.from(`durable-job:v1\0${id}\0${type}\0${actor}`);
161
+ const eventAad = (id, stream, type, subject, actor) => Buffer.from(`durable-event:v1\0${id}\0${stream}\0${type}\0${subject}\0${actor ?? ''}`);
162
+ const sameDurableIntegrity = (actual, expected) => canonicalJson(actual) === canonicalJson(expected);
163
+ const positiveLimit = (value, fallback, field) => {
164
+ const selected = value ?? fallback;
165
+ if (!Number.isSafeInteger(selected) || selected <= 0) {
166
+ throw new Error(`Invalid team backup ${field}.`);
167
+ }
168
+ return selected;
169
+ };
170
+ const hashFile = (target) => {
171
+ const before = fs.lstatSync(target);
172
+ if (!before.isFile() || before.isSymbolicLink() || before.nlink !== 1) {
173
+ throw new Error('Team backup payload must be a physical single-link file.');
174
+ }
175
+ const descriptor = fs.openSync(target, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0));
176
+ const hash = crypto.createHash('sha256');
177
+ const buffer = Buffer.allocUnsafe(COPY_BUFFER_BYTES);
178
+ let bytes = 0;
179
+ try {
180
+ const opened = fs.fstatSync(descriptor);
181
+ if (opened.dev !== before.dev || opened.ino !== before.ino) {
182
+ throw new Error('Team backup payload changed while opening.');
183
+ }
184
+ let read;
185
+ while ((read = fs.readSync(descriptor, buffer, 0, buffer.length, null)) > 0) {
186
+ hash.update(buffer.subarray(0, read));
187
+ bytes += read;
188
+ }
189
+ const after = fs.fstatSync(descriptor);
190
+ if (bytes !== before.size ||
191
+ after.size !== before.size ||
192
+ after.mtimeMs !== before.mtimeMs) {
193
+ throw new Error('Team backup payload changed during hashing.');
194
+ }
195
+ return { bytes, sha256: hash.digest('hex') };
196
+ }
197
+ finally {
198
+ buffer.fill(0);
199
+ fs.closeSync(descriptor);
200
+ }
201
+ };
202
+ const parseJsonObject = (target) => {
203
+ const bytes = fs.readFileSync(target);
204
+ try {
205
+ const value = JSON.parse(bytes.toString('utf8'));
206
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
207
+ throw new Error('Protected backup configuration is invalid.');
208
+ }
209
+ const output = {};
210
+ for (const [key, item] of Object.entries(value)) {
211
+ if (typeof item !== 'string') {
212
+ throw new Error('Protected backup configuration is invalid.');
213
+ }
214
+ output[key] = item;
215
+ }
216
+ return output;
217
+ }
218
+ finally {
219
+ bytes.fill(0);
220
+ }
221
+ };
222
+ const postgresToolEnvironment = (config, base) => {
223
+ const url = new URL(config.connectionString);
224
+ const database = decodeURIComponent(url.pathname.replace(/^\//, ''));
225
+ if (!database)
226
+ throw new Error('PostgreSQL URL must name a database.');
227
+ return {
228
+ ...base,
229
+ PGHOST: url.hostname,
230
+ PGPORT: url.port || '5432',
231
+ PGDATABASE: database,
232
+ PGUSER: decodeURIComponent(url.username),
233
+ PGPASSWORD: decodeURIComponent(url.password),
234
+ PGSSLMODE: config.sslMode,
235
+ PGAPPNAME: `${config.applicationName}-recovery`,
236
+ PGCONNECT_TIMEOUT: String(Math.max(1, Math.ceil(config.connectionTimeoutMs / 1000))),
237
+ };
238
+ };
239
+ const postgresDatabaseName = (config) => {
240
+ const database = decodeURIComponent(new URL(config.connectionString).pathname.replace(/^\//, ''));
241
+ if (!database)
242
+ throw new Error('PostgreSQL URL must name a database.');
243
+ return database;
244
+ };
245
+ const runPostgresTool = async (command, args, config, baseEnv, timeoutMs) => {
246
+ if (!TOOL_PATTERN.test(command) || command.includes('..')) {
247
+ throw new Error('PostgreSQL recovery tool path is invalid.');
248
+ }
249
+ await new Promise((resolve, reject) => {
250
+ const child = spawn(command, [...args], {
251
+ env: postgresToolEnvironment(config, baseEnv),
252
+ stdio: ['ignore', 'ignore', 'pipe'],
253
+ });
254
+ let stderrBytes = 0;
255
+ child.stderr.on('data', (chunk) => {
256
+ stderrBytes += chunk.byteLength;
257
+ if (stderrBytes > 1024 * 1024)
258
+ child.kill('SIGKILL');
259
+ });
260
+ const timer = setTimeout(() => child.kill('SIGKILL'), timeoutMs);
261
+ timer.unref?.();
262
+ child.once('error', error => {
263
+ clearTimeout(timer);
264
+ const failure = new Error('Unable to start the PostgreSQL recovery tool.');
265
+ Object.defineProperty(failure, 'cause', {
266
+ value: error,
267
+ enumerable: false,
268
+ });
269
+ reject(failure);
270
+ });
271
+ child.once('exit', (code, signal) => {
272
+ clearTimeout(timer);
273
+ if (code === 0)
274
+ resolve();
275
+ else
276
+ reject(new Error(`PostgreSQL recovery tool failed (${signal ? 'terminated' : `exit ${code ?? 'unknown'}`}).`));
277
+ });
278
+ });
279
+ };
280
+ const validateToolTimeout = (value) => {
281
+ const selected = value ?? DEFAULT_TOOL_TIMEOUT_MS;
282
+ if (!Number.isSafeInteger(selected) ||
283
+ selected < 1000 ||
284
+ selected > 24 * 60 * 60 * 1000) {
285
+ throw new Error('PostgreSQL recovery tool timeout is invalid.');
286
+ }
287
+ return selected;
288
+ };
289
+ const validateTeamSelection = (env) => {
290
+ if (env.LIBRE_PLATFORM_MODE?.trim().toLowerCase() !== 'team' ||
291
+ env.DATABASE_BACKEND?.trim().toLowerCase() !== 'postgres' ||
292
+ env.BLOB_STORE_BACKEND?.trim().toLowerCase() !== 's3' ||
293
+ env.VECTOR_STORE_BACKEND?.trim().toLowerCase() !== 'pgvector') {
294
+ throw new Error('Team backup requires team mode with PostgreSQL, S3, and PGVector selected.');
295
+ }
296
+ };
297
+ const keyFingerprint = (env) => {
298
+ const inspection = inspectStorageKeyConfiguration(env);
299
+ if (inspection.status !== 'configured' ||
300
+ inspection.keyFingerprints.length === 0) {
301
+ throw new Error('Team backup requires the complete storage encryption key set.');
302
+ }
303
+ return sha256(canonicalJson({
304
+ activeKeyId: inspection.activeKeyId,
305
+ keys: inspection.keyFingerprints,
306
+ }));
307
+ };
308
+ const verifyDurablePayload = (keyring, row, aad, totals) => {
309
+ const bytes = Buffer.byteLength(row.payload, 'utf8');
310
+ if (!Number.isSafeInteger(bytes) || bytes < 0) {
311
+ throw new Error('Durable payload byte accounting is invalid.');
312
+ }
313
+ if (row.payload_format === 'reference') {
314
+ if (!validateDurableText(row.payload, MAX_DURABLE_REFERENCE_BYTES)) {
315
+ throw new Error('Durable payload reference is invalid.');
316
+ }
317
+ totals.referenceRecords += 1;
318
+ totals.referenceBytes += bytes;
319
+ return;
320
+ }
321
+ if (row.payload_format !== 'encrypted' ||
322
+ bytes > MAX_DURABLE_ENVELOPE_BYTES) {
323
+ throw new Error('Durable encrypted payload envelope is invalid.');
324
+ }
325
+ totals.encryptedRecords += 1;
326
+ totals.ciphertextBytes += bytes;
327
+ let plaintext;
328
+ try {
329
+ plaintext = keyring.decrypt(parseAesGcmEnvelope(JSON.parse(row.payload)), aad);
330
+ if (plaintext.byteLength > MAX_DURABLE_PLAINTEXT_BYTES) {
331
+ throw new Error('Durable payload exceeds the backup verification limit.');
332
+ }
333
+ totals.plaintextBytes += plaintext.byteLength;
334
+ const decoded = new TextDecoder('utf-8', { fatal: true }).decode(plaintext);
335
+ if (canonicalDurableJson(JSON.parse(decoded)) !== decoded) {
336
+ throw new Error('Durable payload is not canonical JSON.');
337
+ }
338
+ }
339
+ catch (error) {
340
+ if (error instanceof Error && error.message.startsWith('Durable payload')) {
341
+ throw error;
342
+ }
343
+ const failure = new Error('Durable payload authentication failed.');
344
+ Object.defineProperty(failure, 'cause', {
345
+ value: error,
346
+ enumerable: false,
347
+ });
348
+ throw failure;
349
+ }
350
+ finally {
351
+ plaintext?.fill(0);
352
+ }
353
+ };
354
+ /**
355
+ * Stream-head invariants: every event's stream must have a head, and a head
356
+ * may never sit behind its newest retained event. A head may legitimately
357
+ * exceed the retained events: chat cancellation commits a zero-event head as
358
+ * its lock anchor when Stop wins before any durable event exists, and the
359
+ * retention sweep removes aged events without rewriting heads.
360
+ */
361
+ const verifyDurableDatabaseIntegrity = async (executor, keyring) => {
362
+ const aggregate = await executor.query(`WITH payloads AS (
363
+ SELECT payload_format, octet_length(payload) AS bytes FROM platform_jobs
364
+ UNION ALL
365
+ SELECT payload_format, octet_length(payload) AS bytes FROM platform_events
366
+ ), event_groups AS (
367
+ SELECT stream_id, MIN(stream_sequence) AS first_sequence,
368
+ MAX(stream_sequence) AS last_sequence, COUNT(*) AS event_count
369
+ FROM platform_events GROUP BY stream_id
370
+ )
371
+ SELECT
372
+ (SELECT COUNT(*) FROM platform_jobs) AS jobs,
373
+ (SELECT COUNT(*) FROM platform_events) AS events,
374
+ (SELECT COUNT(*) FROM platform_event_stream_heads) AS streams,
375
+ (SELECT COALESCE(MAX(global_cursor), 0) FROM platform_events) AS last_global_cursor,
376
+ COALESCE(SUM((payload_format = 'encrypted')::integer), 0) AS encrypted_records,
377
+ COALESCE(SUM((payload_format = 'reference')::integer), 0) AS reference_records,
378
+ COALESCE(SUM(CASE WHEN payload_format = 'encrypted' THEN bytes ELSE 0 END), 0) AS ciphertext_bytes,
379
+ COALESCE(SUM(CASE WHEN payload_format = 'reference' THEN bytes ELSE 0 END), 0) AS reference_bytes,
380
+ COALESCE(MAX(CASE WHEN payload_format = 'encrypted' THEN bytes ELSE 0 END), 0) AS largest_envelope,
381
+ (SELECT COUNT(*)
382
+ FROM platform_event_stream_heads heads
383
+ FULL OUTER JOIN event_groups events ON events.stream_id = heads.stream_id
384
+ WHERE heads.stream_id IS NULL
385
+ OR events.last_sequence > heads.last_sequence) AS inconsistent_heads
386
+ FROM payloads`);
387
+ const row = aggregate.rows[0];
388
+ if (!row)
389
+ throw new Error('Durable backup inventory query returned no row.');
390
+ const jobs = safeInteger(row.jobs, 'durable job count');
391
+ const events = safeInteger(row.events, 'durable event count');
392
+ const streams = safeInteger(row.streams, 'durable stream count');
393
+ const lastGlobalCursor = safeInteger(row.last_global_cursor, 'durable event cursor');
394
+ const encryptedRecords = safeInteger(row.encrypted_records, 'durable encrypted payload count');
395
+ const referenceRecords = safeInteger(row.reference_records, 'durable reference payload count');
396
+ const ciphertextBytes = safeInteger(row.ciphertext_bytes, 'durable ciphertext bytes');
397
+ const referenceBytes = safeInteger(row.reference_bytes, 'durable reference bytes');
398
+ const largestEnvelope = safeInteger(row.largest_envelope, 'largest durable envelope');
399
+ const inconsistentHeads = safeInteger(row.inconsistent_heads, 'inconsistent durable stream heads');
400
+ const records = jobs + events;
401
+ if (!Number.isSafeInteger(records) ||
402
+ records !== encryptedRecords + referenceRecords ||
403
+ records > MAX_DURABLE_PAYLOAD_RECORDS ||
404
+ streams > MAX_DURABLE_STREAM_HEADS ||
405
+ ciphertextBytes > MAX_DURABLE_CIPHERTEXT_BYTES ||
406
+ largestEnvelope > MAX_DURABLE_ENVELOPE_BYTES ||
407
+ encryptedRecords >
408
+ Math.floor(MAX_DURABLE_PLAINTEXT_AGGREGATE_BYTES / MAX_DURABLE_PLAINTEXT_BYTES)) {
409
+ throw new Error('Durable state exceeds bounded backup verification limits.');
410
+ }
411
+ if (inconsistentHeads !== 0) {
412
+ throw new Error('Durable event stream heads are not contiguous.');
413
+ }
414
+ const sequence = await executor.query(`SELECT last_value, is_called
415
+ FROM platform_events_global_cursor_seq`);
416
+ const globalSequenceValue = safeInteger(sequence.rows[0]?.last_value ?? 0, 'durable global cursor sequence');
417
+ const globalSequenceCalled = sequence.rows[0]?.is_called === true;
418
+ if (sequence.rowCount !== 1 ||
419
+ (events > 0 &&
420
+ (!globalSequenceCalled || globalSequenceValue < lastGlobalCursor))) {
421
+ throw new Error('Durable global event cursor sequence is inconsistent.');
422
+ }
423
+ const totals = {
424
+ encryptedRecords: 0,
425
+ referenceRecords: 0,
426
+ ciphertextBytes: 0,
427
+ referenceBytes: 0,
428
+ plaintextBytes: 0,
429
+ };
430
+ let afterJobId = '';
431
+ for (;;) {
432
+ const page = await executor.query(`SELECT id::text, job_type, actor_user_id, payload_format, payload
433
+ FROM platform_jobs WHERE id::text > $1
434
+ ORDER BY id::text LIMIT $2`, [afterJobId, DURABLE_PAGE_SIZE]);
435
+ for (const job of page.rows) {
436
+ if (!validateDurableText(job.id) ||
437
+ !validateDurableText(job.job_type) ||
438
+ !validateDurableText(job.actor_user_id)) {
439
+ throw new Error('Durable job identity is invalid.');
440
+ }
441
+ verifyDurablePayload(keyring, job, jobAad(job.id, job.job_type, job.actor_user_id), totals);
442
+ afterJobId = job.id;
443
+ }
444
+ if (page.rows.length < DURABLE_PAGE_SIZE)
445
+ break;
446
+ }
447
+ let afterCursor = 0;
448
+ for (;;) {
449
+ const page = await executor.query(`SELECT global_cursor, event_id::text, stream_id, stream_sequence,
450
+ event_type, subject_id, actor_user_id, payload_format, payload
451
+ FROM platform_events WHERE global_cursor > $1
452
+ ORDER BY global_cursor LIMIT $2`, [afterCursor, DURABLE_PAGE_SIZE]);
453
+ for (const event of page.rows) {
454
+ const cursor = safeInteger(event.global_cursor, 'durable event cursor');
455
+ if (cursor <= afterCursor ||
456
+ safeInteger(event.stream_sequence, 'durable stream sequence') < 1 ||
457
+ !validateDurableText(event.event_id) ||
458
+ !validateDurableText(event.stream_id) ||
459
+ !validateDurableText(event.event_type) ||
460
+ !validateDurableText(event.subject_id) ||
461
+ (event.actor_user_id !== null &&
462
+ !validateDurableText(event.actor_user_id))) {
463
+ throw new Error('Durable event identity is invalid.');
464
+ }
465
+ verifyDurablePayload(keyring, event, eventAad(event.event_id, event.stream_id, event.event_type, event.subject_id, event.actor_user_id), totals);
466
+ afterCursor = cursor;
467
+ }
468
+ if (page.rows.length < DURABLE_PAGE_SIZE)
469
+ break;
470
+ }
471
+ if (totals.encryptedRecords !== encryptedRecords ||
472
+ totals.referenceRecords !== referenceRecords ||
473
+ totals.ciphertextBytes !== ciphertextBytes ||
474
+ totals.referenceBytes !== referenceBytes ||
475
+ afterCursor !== lastGlobalCursor ||
476
+ totals.plaintextBytes > MAX_DURABLE_PLAINTEXT_AGGREGATE_BYTES) {
477
+ throw new Error('Durable backup verification totals are inconsistent.');
478
+ }
479
+ return {
480
+ verified: true,
481
+ encryptedAuthenticated: true,
482
+ streamHeadsVerified: true,
483
+ referenceTargetsVerified: false,
484
+ jobs,
485
+ events,
486
+ streams,
487
+ lastGlobalCursor,
488
+ globalSequenceValue,
489
+ globalSequenceCalled,
490
+ records,
491
+ ...totals,
492
+ };
493
+ };
494
+ const validateDatabaseSnapshot = async (executor, keyring) => {
495
+ const ledger = await executor.query(`SELECT version, name, checksum, minimum_compatible_version
496
+ FROM libre_schema_migrations ORDER BY version`);
497
+ if (ledger.rows.length !== POSTGRES_MIGRATIONS.length ||
498
+ !POSTGRES_MIGRATIONS.every((migration, index) => Number(ledger.rows[index]?.version) === migration.version &&
499
+ ledger.rows[index]?.name === migration.name &&
500
+ ledger.rows[index]?.checksum === migration.checksum &&
501
+ Number(ledger.rows[index]?.minimum_compatible_version) ===
502
+ migration.minimumCompatibleVersion)) {
503
+ throw new Error('PostgreSQL migration ledger is not backup-compatible.');
504
+ }
505
+ const state = await executor.query(`SELECT status, current_version, target_version, schema_fingerprint
506
+ FROM libre_schema_compatibility WHERE singleton = 1`);
507
+ const target = POSTGRES_MIGRATIONS.length;
508
+ if (state.rowCount !== 1 ||
509
+ state.rows[0]?.status !== 'compatible' ||
510
+ Number(state.rows[0]?.current_version) !== target ||
511
+ Number(state.rows[0]?.target_version) !== target ||
512
+ !state.rows[0]?.schema_fingerprint) {
513
+ throw new Error('PostgreSQL schema is not quiesced at the backup target.');
514
+ }
515
+ const structure = await inspectPostgresSchema(executor, POSTGRES_MIGRATIONS);
516
+ if (!structure.compatible ||
517
+ structure.fingerprint !== state.rows[0].schema_fingerprint) {
518
+ throw new Error('PostgreSQL schema structure is not backup-compatible.');
519
+ }
520
+ const activity = await executor.query(`SELECT
521
+ (SELECT COUNT(*) FROM platform_jobs WHERE state = 'running') AS running_jobs,
522
+ (SELECT COUNT(*) FROM platform_job_attempts WHERE outcome = 'running') AS running_attempts,
523
+ (SELECT COUNT(*) FROM work_runs WHERE status IN ('queued', 'preparing', 'running')) AS active_work_runs,
524
+ (SELECT COUNT(*) FROM work_tasks WHERE preview_status IN ('starting', 'running')) AS active_previews,
525
+ (SELECT COUNT(*) FROM platform_blob_objects WHERE state = 'deleting') AS deleting_blobs`);
526
+ const active = activity.rows[0];
527
+ if (!active ||
528
+ safeInteger(active.running_jobs, 'running job count') > 0 ||
529
+ safeInteger(active.running_attempts, 'running attempt count') > 0 ||
530
+ safeInteger(active.active_work_runs, 'active Work run count') > 0 ||
531
+ safeInteger(active.active_previews, 'active Work preview count') > 0 ||
532
+ safeInteger(active.deleting_blobs, 'deleting blob count') > 0) {
533
+ throw new Error('Team backup requires no running work or incomplete blob deletion.');
534
+ }
535
+ const blobs = await executor.query(`SELECT id, owner_user_id, object_key, encrypted_bytes, ciphertext_sha256
536
+ FROM platform_blob_objects WHERE state = 'ready' ORDER BY id`);
537
+ const durable = await verifyDurableDatabaseIntegrity(executor, keyring);
538
+ return {
539
+ schemaVersion: target,
540
+ schemaFingerprint: structure.fingerprint,
541
+ blobs: blobs.rows,
542
+ durable,
543
+ };
544
+ };
545
+ const assertBucketVersioning = async (client, bucket) => {
546
+ const versioning = await client.send(new GetBucketVersioningCommand({ Bucket: bucket }));
547
+ if (versioning.Status !== 'Enabled') {
548
+ throw new Error('Team backup requires S3 bucket versioning to be enabled.');
549
+ }
550
+ };
551
+ const bodyIterable = (body) => {
552
+ if (!body ||
553
+ typeof body !== 'object' ||
554
+ !(Symbol.asyncIterator in body) ||
555
+ typeof body[Symbol.asyncIterator] !==
556
+ 'function') {
557
+ throw new Error('S3 returned a non-streaming backup object.');
558
+ }
559
+ return body;
560
+ };
561
+ const copyVersionedS3Objects = async (client, bucket, keyPrefix, rows, payloadDirectory, maxObjects, maxBytes) => {
562
+ if (rows.length > maxObjects) {
563
+ throw new Error('Team backup exceeds the configured S3 object limit.');
564
+ }
565
+ const objectDirectory = path.join(payloadDirectory, 'team', 's3');
566
+ fs.mkdirSync(objectDirectory, { recursive: true, mode: 0o700 });
567
+ const objects = [];
568
+ let totalEncryptedBytes = 0;
569
+ for (const [index, row] of rows.entries()) {
570
+ const encryptedBytes = safeInteger(row.encrypted_bytes, 'blob byte count');
571
+ totalEncryptedBytes += encryptedBytes;
572
+ if (!Number.isSafeInteger(totalEncryptedBytes) ||
573
+ totalEncryptedBytes > maxBytes) {
574
+ throw new Error('Team backup exceeds the configured S3 byte limit.');
575
+ }
576
+ if (!row.object_key.startsWith(`${keyPrefix}/v1/`) ||
577
+ !/^[a-f0-9]{64}$/.test(row.ciphertext_sha256)) {
578
+ throw new Error('PostgreSQL contains an invalid S3 blob descriptor.');
579
+ }
580
+ const head = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: row.object_key }));
581
+ if (!head.VersionId) {
582
+ throw new Error('An S3 blob has no immutable version identifier.');
583
+ }
584
+ if (head.ContentLength !== encryptedBytes ||
585
+ head.ContentType !== 'application/octet-stream' ||
586
+ head.Metadata?.['libre-format'] !== '1') {
587
+ throw new Error('An S3 blob does not match its PostgreSQL descriptor.');
588
+ }
589
+ const response = await client.send(new GetObjectCommand({
590
+ Bucket: bucket,
591
+ Key: row.object_key,
592
+ VersionId: head.VersionId,
593
+ }));
594
+ if (response.VersionId !== head.VersionId) {
595
+ throw new Error('S3 returned a different object version during backup.');
596
+ }
597
+ const relative = `team/s3/${String(index).padStart(8, '0')}.blob`;
598
+ const target = path.join(payloadDirectory, ...relative.split('/'));
599
+ const descriptor = fs.openSync(target, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL, 0o600);
600
+ const hash = crypto.createHash('sha256');
601
+ let written = 0;
602
+ try {
603
+ for await (const value of bodyIterable(response.Body)) {
604
+ const bytes = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
605
+ let offset = 0;
606
+ while (offset < bytes.byteLength) {
607
+ offset += fs.writeSync(descriptor, bytes, offset, bytes.byteLength - offset);
608
+ }
609
+ hash.update(bytes);
610
+ written += bytes.byteLength;
611
+ }
612
+ fs.fsyncSync(descriptor);
613
+ }
614
+ finally {
615
+ fs.closeSync(descriptor);
616
+ response.Body?.destroy?.();
617
+ }
618
+ if (written !== encryptedBytes ||
619
+ hash.digest('hex') !== row.ciphertext_sha256) {
620
+ throw new Error('Versioned S3 ciphertext failed backup verification.');
621
+ }
622
+ objects.push({
623
+ id: row.id,
624
+ ownerUserId: row.owner_user_id,
625
+ objectKey: row.object_key,
626
+ sourceVersionId: head.VersionId,
627
+ encryptedBytes,
628
+ ciphertextSha256: row.ciphertext_sha256,
629
+ payloadPath: relative,
630
+ contentType: 'application/octet-stream',
631
+ metadata: Object.freeze({ 'libre-format': '1' }),
632
+ });
633
+ }
634
+ return { objects, totalEncryptedBytes };
635
+ };
636
+ const writeTeamInventory = (payloadDirectory, inventory) => {
637
+ fs.writeFileSync(path.join(payloadDirectory, 'team', 'inventory.json'), canonicalJson(inventory), { mode: 0o600, flag: 'wx' });
638
+ };
639
+ const parseTeamInventory = (payloadDirectory, header) => {
640
+ const bytes = fs.readFileSync(path.join(payloadDirectory, 'team', 'inventory.json'));
641
+ try {
642
+ const parsed = JSON.parse(bytes.toString('utf8'));
643
+ if (parsed?.format !== TEAM_INVENTORY_FORMAT ||
644
+ parsed.version !== TEAM_INVENTORY_VERSION ||
645
+ !Number.isSafeInteger(parsed.schemaVersion) ||
646
+ parsed.schemaVersion <= 0 ||
647
+ !/^[a-f0-9]{64}$/.test(parsed.schemaFingerprint) ||
648
+ !/^[a-f0-9]{64}$/.test(parsed.databaseDumpSha256) ||
649
+ !/^[a-f0-9]{64}$/.test(parsed.storageKeyFingerprint) ||
650
+ parsed.s3?.versioning !== 'Enabled' ||
651
+ !Array.isArray(parsed.s3.objects) ||
652
+ !Number.isSafeInteger(parsed.s3.totalEncryptedBytes) ||
653
+ parsed.s3.totalEncryptedBytes < 0 ||
654
+ !Number.isSafeInteger(parsed.s3.totalPlaintextBytes) ||
655
+ parsed.s3.totalPlaintextBytes < 0 ||
656
+ !Number.isSafeInteger(parsed.vectors?.records) ||
657
+ !Number.isSafeInteger(parsed.vectors?.components) ||
658
+ parsed.vectors.records < 0 ||
659
+ parsed.vectors.components < 0 ||
660
+ parsed.durable?.verified !== true ||
661
+ parsed.durable.encryptedAuthenticated !== true ||
662
+ parsed.durable.streamHeadsVerified !== true ||
663
+ parsed.durable.referenceTargetsVerified !== false ||
664
+ ![
665
+ parsed.durable.jobs,
666
+ parsed.durable.events,
667
+ parsed.durable.streams,
668
+ parsed.durable.lastGlobalCursor,
669
+ parsed.durable.globalSequenceValue,
670
+ parsed.durable.records,
671
+ parsed.durable.encryptedRecords,
672
+ parsed.durable.referenceRecords,
673
+ parsed.durable.ciphertextBytes,
674
+ parsed.durable.referenceBytes,
675
+ parsed.durable.plaintextBytes,
676
+ ].every(value => Number.isSafeInteger(value) && value >= 0) ||
677
+ typeof parsed.durable.globalSequenceCalled !== 'boolean' ||
678
+ parsed.durable.records !==
679
+ parsed.durable.encryptedRecords + parsed.durable.referenceRecords ||
680
+ parsed.durable.records !== parsed.durable.jobs + parsed.durable.events ||
681
+ parsed.durable.jobs + parsed.durable.events >
682
+ MAX_DURABLE_PAYLOAD_RECORDS ||
683
+ parsed.durable.streams > MAX_DURABLE_STREAM_HEADS ||
684
+ parsed.durable.ciphertextBytes > MAX_DURABLE_CIPHERTEXT_BYTES ||
685
+ parsed.durable.plaintextBytes > MAX_DURABLE_PLAINTEXT_AGGREGATE_BYTES ||
686
+ (parsed.durable.events > 0 &&
687
+ (!parsed.durable.globalSequenceCalled ||
688
+ parsed.durable.lastGlobalCursor < 1 ||
689
+ parsed.durable.globalSequenceValue < parsed.durable.lastGlobalCursor))) {
690
+ throw new Error('Team backup inventory is invalid.');
691
+ }
692
+ const seenIds = new Set();
693
+ const seenKeys = new Set();
694
+ let total = 0;
695
+ for (const entry of parsed.s3.objects) {
696
+ if (typeof entry.id !== 'string' ||
697
+ typeof entry.ownerUserId !== 'string' ||
698
+ typeof entry.objectKey !== 'string' ||
699
+ !entry.objectKey.startsWith(`${parsed.s3.keyPrefix}/v1/`) ||
700
+ typeof entry.sourceVersionId !== 'string' ||
701
+ !entry.sourceVersionId ||
702
+ !Number.isSafeInteger(entry.encryptedBytes) ||
703
+ entry.encryptedBytes < 0 ||
704
+ !/^[a-f0-9]{64}$/.test(entry.ciphertextSha256) ||
705
+ !/^team\/s3\/[0-9]{8}\.blob$/.test(entry.payloadPath) ||
706
+ entry.contentType !== 'application/octet-stream' ||
707
+ entry.metadata?.['libre-format'] !== '1' ||
708
+ seenIds.has(entry.id) ||
709
+ seenKeys.has(entry.objectKey)) {
710
+ throw new Error('Team backup S3 inventory is invalid.');
711
+ }
712
+ seenIds.add(entry.id);
713
+ seenKeys.add(entry.objectKey);
714
+ total += entry.encryptedBytes;
715
+ const file = hashFile(path.join(payloadDirectory, ...entry.payloadPath.split('/')));
716
+ if (file.bytes !== entry.encryptedBytes ||
717
+ file.sha256 !== entry.ciphertextSha256) {
718
+ throw new Error('Team backup S3 payload does not match its inventory.');
719
+ }
720
+ }
721
+ if (total !== parsed.s3.totalEncryptedBytes) {
722
+ throw new Error('Team backup S3 inventory byte total is invalid.');
723
+ }
724
+ const dump = hashFile(path.join(payloadDirectory, 'team', 'postgres.dump'));
725
+ if (dump.sha256 !== parsed.databaseDumpSha256) {
726
+ throw new Error('Team PostgreSQL dump does not match its inventory.');
727
+ }
728
+ if (header.manifest.source.platformMode !== 'team' ||
729
+ header.manifest.source.databaseBackend !== 'postgres' ||
730
+ header.manifest.source.blobBackend !== 's3' ||
731
+ header.manifest.source.vectorBackend !== 'pgvector' ||
732
+ header.manifest.inventory.schemaVersion !== parsed.schemaVersion ||
733
+ header.manifest.inventory.schemaFingerprint !==
734
+ parsed.schemaFingerprint ||
735
+ header.manifest.inventory.databaseDumpSha256 !==
736
+ parsed.databaseDumpSha256 ||
737
+ header.manifest.inventory.blobObjects !== parsed.s3.objects.length ||
738
+ header.manifest.inventory.vectorRecords !== parsed.vectors.records) {
739
+ throw new Error('Team archive header and protected inventory disagree.');
740
+ }
741
+ return parsed;
742
+ }
743
+ finally {
744
+ bytes.fill(0);
745
+ }
746
+ };
747
+ export const createTeamBackupArchive = async (options) => {
748
+ if (!options.offline) {
749
+ throw new Error('Team backup requires --offline after every application and worker replica is stopped.');
750
+ }
751
+ const env = options.env ?? process.env;
752
+ validateTeamSelection(env);
753
+ const keySetFingerprint = keyFingerprint(env);
754
+ const postgresConfig = resolvePostgresRuntimeConfig(env);
755
+ const s3Config = resolveS3BlobConfiguration(env);
756
+ const timeoutMs = validateToolTimeout(options.toolTimeoutMs);
757
+ const maxObjects = positiveLimit(options.maxBlobObjects, DEFAULT_MAX_BLOB_OBJECTS, 'object limit');
758
+ const maxBytes = positiveLimit(options.maxBlobBytes, DEFAULT_MAX_BLOB_BYTES, 'byte limit');
759
+ const output = path.resolve(options.outputPath);
760
+ if (fs.existsSync(output))
761
+ throw new Error('Backup output already exists.');
762
+ const parent = path.dirname(output);
763
+ fs.mkdirSync(parent, { recursive: true, mode: 0o700 });
764
+ const scratch = fs.mkdtempSync(path.join(parent, '.libre-team-backup-'));
765
+ const payload = path.join(scratch, 'payload');
766
+ fs.mkdirSync(path.join(payload, 'team'), { recursive: true, mode: 0o700 });
767
+ const dumpPath = path.join(payload, 'team', 'postgres.dump');
768
+ // A pg_dump wrapper may execute in a rootful container with this scratch
769
+ // directory bind-mounted from the host. Create the output inode as the
770
+ // Libre process first so pg_dump only truncates it and cannot leave behind
771
+ // a root-owned file that the host process is unable to secure or remove.
772
+ fs.writeFileSync(dumpPath, '', { flag: 'wx', mode: 0o600 });
773
+ const database = createPostgresDatabase(postgresConfig);
774
+ const s3Client = new S3Client(s3Config.clientConfig);
775
+ const keyring = createStorageKeyringFromEnvironment(env);
776
+ try {
777
+ await assertBucketVersioning(s3Client, s3Config.bucket);
778
+ let databaseInventory;
779
+ await database.withClient(async (client) => {
780
+ await client.query('BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY');
781
+ try {
782
+ databaseInventory = await validateDatabaseSnapshot(client, keyring);
783
+ const snapshot = await client.query('SELECT pg_export_snapshot() AS snapshot');
784
+ const snapshotId = snapshot.rows[0]?.snapshot;
785
+ if (!snapshotId || !/^[A-Za-z0-9:-]+$/.test(snapshotId)) {
786
+ throw new Error('PostgreSQL did not export a safe backup snapshot.');
787
+ }
788
+ await runPostgresTool(options.pgDumpCommand ?? env.POSTGRES_DUMP_COMMAND ?? 'pg_dump', [
789
+ '--format=custom',
790
+ '--no-owner',
791
+ '--no-privileges',
792
+ `--snapshot=${snapshotId}`,
793
+ `--file=${dumpPath}`,
794
+ ], postgresConfig, env, timeoutMs);
795
+ await client.query('COMMIT');
796
+ }
797
+ catch (error) {
798
+ await client.query('ROLLBACK').catch(() => undefined);
799
+ throw error;
800
+ }
801
+ });
802
+ if (!databaseInventory) {
803
+ throw new Error('PostgreSQL backup snapshot produced no inventory.');
804
+ }
805
+ fs.chmodSync(dumpPath, 0o600);
806
+ // Authenticate every source object and every PGVector record before
807
+ // sealing the exported snapshot. These checks are intentionally bounded.
808
+ const blobStore = createS3EncryptedBlobStore({
809
+ database,
810
+ keyring,
811
+ env: env,
812
+ });
813
+ const blobIntegrity = await blobStore.verifyIntegrity({
814
+ maxObjects,
815
+ maxEncryptedBytes: maxBytes,
816
+ maxPlaintextBytes: maxBytes,
817
+ });
818
+ if (blobIntegrity.objects !== databaseInventory.blobs.length) {
819
+ throw new Error('S3 integrity count changed outside the database snapshot.');
820
+ }
821
+ const vectors = await new PgVectorStore({ database }).verifyIntegrity();
822
+ const copied = await copyVersionedS3Objects(s3Client, s3Config.bucket, s3Config.keyPrefix, databaseInventory.blobs, payload, maxObjects, maxBytes);
823
+ const dump = hashFile(dumpPath);
824
+ const inventory = {
825
+ format: TEAM_INVENTORY_FORMAT,
826
+ version: TEAM_INVENTORY_VERSION,
827
+ schemaVersion: databaseInventory.schemaVersion,
828
+ schemaFingerprint: databaseInventory.schemaFingerprint,
829
+ databaseDumpSha256: dump.sha256,
830
+ storageKeyFingerprint: keySetFingerprint,
831
+ s3: {
832
+ bucket: s3Config.bucket,
833
+ keyPrefix: s3Config.keyPrefix,
834
+ versioning: 'Enabled',
835
+ objects: copied.objects,
836
+ totalEncryptedBytes: copied.totalEncryptedBytes,
837
+ totalPlaintextBytes: blobIntegrity.plaintextBytes,
838
+ },
839
+ vectors,
840
+ durable: databaseInventory.durable,
841
+ };
842
+ writeTeamInventory(payload, inventory);
843
+ stageProtectedRuntimeConfiguration(payload, env);
844
+ const pkg = loadAppPackage(import.meta.url);
845
+ const manifest = {
846
+ format: 'libre-webui-integrated-backup',
847
+ version: 1,
848
+ backupId: crypto.randomUUID(),
849
+ createdAt: (options.now ?? new Date()).toISOString(),
850
+ application: {
851
+ name: 'libre-webui',
852
+ version: pkg.version || 'unknown',
853
+ nodeVersion: process.version,
854
+ },
855
+ source: {
856
+ platformMode: 'team',
857
+ databaseBackend: 'postgres',
858
+ blobBackend: 's3',
859
+ vectorBackend: 'pgvector',
860
+ coordinationBackend: env.COORDINATION_BACKEND || 'redis',
861
+ jobWorkerMode: env.JOB_WORKER_MODE || 'external',
862
+ },
863
+ inventory: {
864
+ format: 'libre-webui-recovery-inventory',
865
+ version: 1,
866
+ schemaFingerprint: inventory.schemaFingerprint,
867
+ encryptionKeyFingerprint: inventory.storageKeyFingerprint,
868
+ schemaVersion: inventory.schemaVersion,
869
+ databaseDumpSha256: inventory.databaseDumpSha256,
870
+ s3InventorySha256: sha256(canonicalJson(inventory.s3)),
871
+ blobObjects: inventory.s3.objects.length,
872
+ vectorRecords: inventory.vectors.records,
873
+ },
874
+ exclusions: [
875
+ 'Redis cache, presence, leases, and wake-up notifications are reconstructed from canonical SQL state.',
876
+ 'External Work workspace volumes require their own coordinated storage snapshot.',
877
+ ],
878
+ };
879
+ const verification = sealBackupPayload({
880
+ payloadDirectory: payload,
881
+ outputPath: output,
882
+ encryptionKeyPath: options.encryptionKeyPath,
883
+ signingPrivateKeyPath: options.signingPrivateKeyPath,
884
+ manifest,
885
+ });
886
+ return { verification, inventory };
887
+ }
888
+ finally {
889
+ s3Client.destroy();
890
+ await database.close().catch(() => undefined);
891
+ fs.rmSync(scratch, { recursive: true, force: true });
892
+ }
893
+ };
894
+ const assertCleanTargetDatabase = async (database) => {
895
+ const schemas = await database.query(`SELECT nspname AS schema_name FROM pg_namespace ORDER BY nspname`);
896
+ if (schemas.rows.some(row => !POSTGRES_BOOTSTRAP_SCHEMAS.has(row.schema_name) &&
897
+ !POSTGRES_TEMPORARY_SCHEMA_PATTERN.test(row.schema_name))) {
898
+ throw new Error('Team restore requires a clean PostgreSQL database with only bootstrap schemas.');
899
+ }
900
+ const extensions = await database.query(`SELECT extension.extname AS extension_name,
901
+ namespace.nspname AS schema_name
902
+ FROM pg_extension extension
903
+ JOIN pg_namespace namespace ON namespace.oid = extension.extnamespace
904
+ ORDER BY extension.extname`);
905
+ if (extensions.rows.some(row => POSTGRES_BOOTSTRAP_EXTENSIONS.get(row.extension_name) !==
906
+ row.schema_name)) {
907
+ throw new Error('Team restore requires a clean PostgreSQL database with only bootstrap extensions.');
908
+ }
909
+ const relations = await database.query(`SELECT relation.oid::text AS relation_oid,
910
+ namespace.nspname AS schema_name,
911
+ extension.extname AS extension_name
912
+ FROM pg_class relation
913
+ JOIN pg_namespace namespace ON namespace.oid = relation.relnamespace
914
+ LEFT JOIN pg_depend extension_dependency
915
+ ON extension_dependency.classid = 'pg_class'::regclass
916
+ AND extension_dependency.objid = relation.oid
917
+ AND extension_dependency.deptype = 'e'
918
+ LEFT JOIN pg_extension extension
919
+ ON extension.oid = extension_dependency.refobjid`);
920
+ if (relations.rows.some(row => {
921
+ if (POSTGRES_TEMPORARY_SCHEMA_PATTERN.test(row.schema_name))
922
+ return false;
923
+ const extensionSchema = row.extension_name
924
+ ? POSTGRES_BOOTSTRAP_EXTENSIONS.get(row.extension_name)
925
+ : undefined;
926
+ if (extensionSchema === row.schema_name)
927
+ return false;
928
+ return (!POSTGRES_BOOTSTRAP_SCHEMAS.has(row.schema_name) ||
929
+ Number(row.relation_oid) >= 16384);
930
+ })) {
931
+ throw new Error('Team restore requires a clean PostgreSQL database.');
932
+ }
933
+ };
934
+ const assertCleanTargetPrefix = async (client, bucket, prefix) => {
935
+ await assertBucketVersioning(client, bucket);
936
+ const page = await client.send(new ListObjectVersionsCommand({
937
+ Bucket: bucket,
938
+ Prefix: `${prefix}/`,
939
+ MaxKeys: 1,
940
+ }));
941
+ if ((page.Versions?.length ?? 0) > 0 ||
942
+ (page.DeleteMarkers?.length ?? 0) > 0) {
943
+ throw new Error('Team restore requires an empty versioned S3 prefix.');
944
+ }
945
+ };
946
+ const rollbackTargetDatabase = async (database) => {
947
+ await database.transaction(async (client) => {
948
+ await client.query('DROP SCHEMA IF EXISTS public CASCADE');
949
+ await client.query('CREATE SCHEMA public AUTHORIZATION CURRENT_USER');
950
+ });
951
+ };
952
+ const restoreS3Objects = async (client, bucket, payload, inventory, uploaded) => {
953
+ for (const entry of inventory.s3.objects) {
954
+ const target = path.join(payload, ...entry.payloadPath.split('/'));
955
+ const result = await client.send(new PutObjectCommand({
956
+ Bucket: bucket,
957
+ Key: entry.objectKey,
958
+ Body: fs.createReadStream(target),
959
+ ContentLength: entry.encryptedBytes,
960
+ ContentType: entry.contentType,
961
+ Metadata: { ...entry.metadata },
962
+ ChecksumSHA256: Buffer.from(entry.ciphertextSha256, 'hex').toString('base64'),
963
+ }));
964
+ if (!result.VersionId) {
965
+ throw new Error('Restored S3 object has no immutable version identifier.');
966
+ }
967
+ // Record the exact immutable version before any later verification can
968
+ // fail. The caller owns this journal, so a rejection in the middle of the
969
+ // loop still leaves every completed PUT available for rollback.
970
+ uploaded.push({ key: entry.objectKey, versionId: result.VersionId });
971
+ const head = await client.send(new HeadObjectCommand({
972
+ Bucket: bucket,
973
+ Key: entry.objectKey,
974
+ VersionId: result.VersionId,
975
+ }));
976
+ if (head.ContentLength !== entry.encryptedBytes ||
977
+ head.Metadata?.['libre-format'] !== '1') {
978
+ throw new Error('Restored S3 object failed metadata verification.');
979
+ }
980
+ }
981
+ };
982
+ const removeUploadedVersions = async (client, bucket, uploaded) => {
983
+ const failures = [];
984
+ let failureCount = 0;
985
+ for (let offset = 1; offset <= uploaded.length; offset += 1) {
986
+ const item = uploaded[uploaded.length - offset];
987
+ if (!item)
988
+ continue;
989
+ try {
990
+ await client.send(new DeleteObjectCommand({
991
+ Bucket: bucket,
992
+ Key: item.key,
993
+ VersionId: item.versionId,
994
+ }));
995
+ }
996
+ catch (error) {
997
+ failureCount += 1;
998
+ if (failures.length < MAX_ROLLBACK_FAILURE_DETAILS) {
999
+ failures.push(contextualRollbackError(`S3 rollback failed for key ${JSON.stringify(item.key)} version ${JSON.stringify(item.versionId)}`, error));
1000
+ }
1001
+ }
1002
+ }
1003
+ if (failureCount > failures.length) {
1004
+ failures.push(new Error(`S3 rollback had ${failureCount - failures.length} additional cleanup failure${failureCount - failures.length === 1 ? '' : 's'}.`));
1005
+ }
1006
+ return { failures, failureCount };
1007
+ };
1008
+ const restoredEnvironment = (payload, target) => {
1009
+ const runtime = parseJsonObject(path.join(payload, 'configuration', 'runtime.json'));
1010
+ const secrets = parseJsonObject(path.join(payload, 'configuration', 'secrets.json'));
1011
+ return {
1012
+ ...runtime,
1013
+ ...secrets,
1014
+ ...target,
1015
+ LIBRE_PLATFORM_MODE: 'team',
1016
+ DATABASE_BACKEND: 'postgres',
1017
+ BLOB_STORE_BACKEND: 's3',
1018
+ VECTOR_STORE_BACKEND: 'pgvector',
1019
+ };
1020
+ };
1021
+ const syncPhysicalFile = (target) => {
1022
+ const descriptor = fs.openSync(target, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0));
1023
+ try {
1024
+ fs.fsyncSync(descriptor);
1025
+ }
1026
+ finally {
1027
+ fs.closeSync(descriptor);
1028
+ }
1029
+ };
1030
+ const syncPhysicalDirectory = (target) => {
1031
+ const descriptor = fs.openSync(target, fs.constants.O_RDONLY |
1032
+ (fs.constants.O_DIRECTORY || 0) |
1033
+ (fs.constants.O_NOFOLLOW || 0));
1034
+ try {
1035
+ fs.fsyncSync(descriptor);
1036
+ }
1037
+ finally {
1038
+ fs.closeSync(descriptor);
1039
+ }
1040
+ };
1041
+ const publishRestoredConfiguration = (targetDirectory, env) => {
1042
+ const requested = path.resolve(targetDirectory);
1043
+ const requestedParent = path.dirname(requested);
1044
+ if (!fs.existsSync(requestedParent)) {
1045
+ throw new Error('Restored configuration parent must already exist as a physical directory.');
1046
+ }
1047
+ const parent = fs.realpathSync(requestedParent);
1048
+ const target = path.join(parent, path.basename(requested));
1049
+ if (fs.existsSync(target)) {
1050
+ throw new Error('Restored configuration target must not already exist.');
1051
+ }
1052
+ const parentStat = fs.lstatSync(parent);
1053
+ if (!parentStat.isDirectory() || parentStat.isSymbolicLink()) {
1054
+ throw new Error('Restored configuration parent must be a physical directory.');
1055
+ }
1056
+ const staging = fs.mkdtempSync(path.join(parent, '.libre-team-config-'));
1057
+ try {
1058
+ stageProtectedRuntimeConfiguration(staging, env);
1059
+ const configuration = path.join(staging, 'configuration');
1060
+ for (const name of ['runtime.json', 'secrets.json']) {
1061
+ syncPhysicalFile(path.join(configuration, name));
1062
+ }
1063
+ syncPhysicalDirectory(configuration);
1064
+ fs.renameSync(configuration, target);
1065
+ syncPhysicalDirectory(staging);
1066
+ syncPhysicalDirectory(parent);
1067
+ return target;
1068
+ }
1069
+ catch (error) {
1070
+ if (fs.existsSync(target)) {
1071
+ fs.rmSync(target, { recursive: true, force: true });
1072
+ try {
1073
+ syncPhysicalDirectory(parent);
1074
+ }
1075
+ catch {
1076
+ // Preserve the original publication error; the caller still rolls
1077
+ // back PostgreSQL and exact S3 versions.
1078
+ }
1079
+ }
1080
+ throw error;
1081
+ }
1082
+ finally {
1083
+ fs.rmSync(staging, { recursive: true, force: true });
1084
+ }
1085
+ };
1086
+ export const restoreTeamBackupArchive = async (options) => {
1087
+ validateTeamSelection(options.targetEnv);
1088
+ const scratch = fs.mkdtempSync(path.join(os.tmpdir(), 'libre-team-restore-'));
1089
+ const payload = path.join(scratch, 'payload');
1090
+ const extracted = extractBackupPayload({
1091
+ archivePath: options.archivePath,
1092
+ signingPublicKeyPath: options.signingPublicKeyPath,
1093
+ encryptionKeyPath: options.encryptionKeyPath,
1094
+ destinationDirectory: payload,
1095
+ });
1096
+ const inventory = parseTeamInventory(payload, extracted.header);
1097
+ const env = restoredEnvironment(payload, options.targetEnv);
1098
+ if (keyFingerprint(env) !== inventory.storageKeyFingerprint) {
1099
+ fs.rmSync(scratch, { recursive: true, force: true });
1100
+ throw new Error('Restored storage key set does not match the signed inventory.');
1101
+ }
1102
+ if (options.apply && !options.configurationOutputDirectory?.trim()) {
1103
+ fs.rmSync(scratch, { recursive: true, force: true });
1104
+ throw new Error('Team restore apply requires a new protected configuration output directory.');
1105
+ }
1106
+ const postgresConfig = resolvePostgresRuntimeConfig(options.targetEnv);
1107
+ const s3Config = resolveS3BlobConfiguration(options.targetEnv);
1108
+ if (s3Config.keyPrefix !== inventory.s3.keyPrefix) {
1109
+ fs.rmSync(scratch, { recursive: true, force: true });
1110
+ throw new Error('Target S3 prefix must match the protected backup inventory.');
1111
+ }
1112
+ const database = createPostgresDatabase(postgresConfig);
1113
+ const client = new S3Client(s3Config.clientConfig);
1114
+ const uploaded = [];
1115
+ let databaseRollbackArmed = false;
1116
+ try {
1117
+ await assertCleanTargetDatabase(database);
1118
+ await assertCleanTargetPrefix(client, s3Config.bucket, s3Config.keyPrefix);
1119
+ if (!options.apply) {
1120
+ return {
1121
+ applied: false,
1122
+ verification: extracted.verification,
1123
+ inventory,
1124
+ };
1125
+ }
1126
+ // A recovery tool can commit its single transaction and then terminate or
1127
+ // report a non-zero status before this process observes success. From this
1128
+ // point onward the PostgreSQL outcome is therefore unknown on every
1129
+ // failure, even when runPostgresTool rejects. Resetting an already-clean
1130
+ // public schema is safe; skipping cleanup after an unobserved commit is not.
1131
+ databaseRollbackArmed = true;
1132
+ await restoreS3Objects(client, s3Config.bucket, payload, inventory, uploaded);
1133
+ await runPostgresTool(options.pgRestoreCommand ??
1134
+ options.targetEnv.POSTGRES_RESTORE_COMMAND ??
1135
+ 'pg_restore', [
1136
+ '--exit-on-error',
1137
+ '--single-transaction',
1138
+ '--no-owner',
1139
+ '--no-privileges',
1140
+ `--dbname=${postgresDatabaseName(postgresConfig)}`,
1141
+ path.join(payload, 'team', 'postgres.dump'),
1142
+ ], postgresConfig, options.targetEnv, validateToolTimeout(options.toolTimeoutMs));
1143
+ const keyring = createStorageKeyringFromEnvironment(env);
1144
+ const restored = await validateDatabaseSnapshot(database, keyring);
1145
+ if (restored.schemaVersion !== inventory.schemaVersion ||
1146
+ restored.schemaFingerprint !== inventory.schemaFingerprint ||
1147
+ restored.blobs.length !== inventory.s3.objects.length ||
1148
+ !sameDurableIntegrity(restored.durable, inventory.durable)) {
1149
+ throw new Error('Restored PostgreSQL state does not match the signed inventory.');
1150
+ }
1151
+ const store = createS3EncryptedBlobStore({
1152
+ database,
1153
+ keyring,
1154
+ env: options.targetEnv,
1155
+ });
1156
+ const blobResult = await store.verifyIntegrity({
1157
+ maxObjects: Math.max(1, inventory.s3.objects.length),
1158
+ maxEncryptedBytes: Math.max(1, inventory.s3.totalEncryptedBytes),
1159
+ maxPlaintextBytes: Math.max(1, inventory.s3.totalPlaintextBytes),
1160
+ });
1161
+ const vectorResult = await new PgVectorStore({ database }).verifyIntegrity({
1162
+ maxRecords: Math.max(1, inventory.vectors.records),
1163
+ maxComponents: Math.max(1, inventory.vectors.components),
1164
+ });
1165
+ if (blobResult.objects !== inventory.s3.objects.length ||
1166
+ blobResult.encryptedBytes !== inventory.s3.totalEncryptedBytes ||
1167
+ blobResult.plaintextBytes !== inventory.s3.totalPlaintextBytes ||
1168
+ vectorResult.records !== inventory.vectors.records ||
1169
+ vectorResult.components !== inventory.vectors.components) {
1170
+ throw new Error('Restored storage integrity totals do not match the backup.');
1171
+ }
1172
+ const configurationOutputDirectory = publishRestoredConfiguration(options.configurationOutputDirectory, env);
1173
+ return {
1174
+ applied: true,
1175
+ verification: extracted.verification,
1176
+ inventory,
1177
+ configurationOutputDirectory,
1178
+ };
1179
+ }
1180
+ catch (error) {
1181
+ const originalFailure = normalizeError(error);
1182
+ const rollback = await removeUploadedVersions(client, s3Config.bucket, uploaded);
1183
+ if (databaseRollbackArmed) {
1184
+ try {
1185
+ await rollbackTargetDatabase(database);
1186
+ }
1187
+ catch (rollbackError) {
1188
+ rollback.failureCount += 1;
1189
+ rollback.failures.push(contextualRollbackError('PostgreSQL restore rollback failed', rollbackError));
1190
+ }
1191
+ }
1192
+ if (rollback.failureCount > 0) {
1193
+ throw new TeamRestoreRollbackError(originalFailure, rollback.failures, rollback.failureCount);
1194
+ }
1195
+ throw error;
1196
+ }
1197
+ finally {
1198
+ client.destroy();
1199
+ await database.close().catch(() => undefined);
1200
+ fs.rmSync(scratch, { recursive: true, force: true });
1201
+ }
1202
+ };
1203
+ //# sourceMappingURL=teamBackupArchive.js.map