@cosmicdrift/kumiko-samples 0.366.0 → 0.368.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 (411) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +16 -2
  3. package/packages/bundled-features/src/audit/handlers/details.query.ts +1 -1
  4. package/packages/bundled-features/src/audit/handlers/list.query.ts +1 -1
  5. package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +5 -5
  6. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +1 -1
  7. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -3
  8. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +10 -3
  9. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  10. package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +6 -2
  11. package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +1 -1
  12. package/packages/bundled-features/src/auth-email-password/seeding.ts +2 -2
  13. package/packages/bundled-features/src/auth-foundation/feature.ts +43 -34
  14. package/packages/bundled-features/src/auth-foundation/index.ts +1 -0
  15. package/packages/bundled-features/src/auth-mfa/db/queries.ts +5 -2
  16. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
  17. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  18. package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +2 -2
  19. package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
  20. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  21. package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +1 -1
  22. package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +1 -1
  23. package/packages/bundled-features/src/auth-mfa-user-data/index.ts +19 -10
  24. package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +1 -1
  25. package/packages/bundled-features/src/billing-foundation/feature.ts +138 -135
  26. package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +1 -1
  27. package/packages/bundled-features/src/billing-foundation/projection.ts +3 -2
  28. package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +52 -1
  29. package/packages/bundled-features/src/cap-counter/cap-reservation.ts +203 -15
  30. package/packages/bundled-features/src/cap-counter/changes.json +13 -0
  31. package/packages/bundled-features/src/cap-counter/feature.ts +84 -73
  32. package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +3 -4
  33. package/packages/bundled-features/src/cap-counter/index.ts +9 -1
  34. package/packages/bundled-features/src/cap-counter/tables.ts +10 -3
  35. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -2
  36. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +6 -2
  37. package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
  38. package/packages/bundled-features/src/channel-email/changes.json +6 -0
  39. package/packages/bundled-features/src/channel-email/email-channel.ts +12 -2
  40. package/packages/bundled-features/src/channel-email/feature.ts +1 -1
  41. package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
  42. package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
  43. package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
  44. package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
  45. package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
  46. package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
  47. package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
  48. package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
  49. package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
  50. package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
  51. package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
  52. package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
  53. package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
  54. package/packages/bundled-features/src/config/resolver.ts +1 -1
  55. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  56. package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
  57. package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
  58. package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
  59. package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
  60. package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
  61. package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
  62. package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
  63. package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
  64. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
  65. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
  66. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
  67. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
  68. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
  69. package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
  70. package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
  71. package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
  72. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
  73. package/packages/bundled-features/src/delivery/changes.json +12 -0
  74. package/packages/bundled-features/src/delivery/channel-context.ts +2 -1
  75. package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
  76. package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
  77. package/packages/bundled-features/src/delivery/delivery-service.ts +70 -8
  78. package/packages/bundled-features/src/delivery/feature.ts +2 -2
  79. package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
  80. package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
  81. package/packages/bundled-features/src/delivery/handlers/unsubscribe-address.write.ts +10 -5
  82. package/packages/bundled-features/src/delivery/index.ts +6 -0
  83. package/packages/bundled-features/src/delivery/testing.ts +2 -0
  84. package/packages/bundled-features/src/delivery/types.ts +4 -0
  85. package/packages/bundled-features/src/delivery/unsubscribe-link.ts +73 -0
  86. package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +17 -0
  87. package/packages/bundled-features/src/delivery/unsubscribe.ts +94 -31
  88. package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
  89. package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
  90. package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
  91. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
  92. package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
  93. package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
  94. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
  95. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
  96. package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
  97. package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
  98. package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
  99. package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
  100. package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
  101. package/packages/bundled-features/src/file-foundation/index.ts +1 -0
  102. package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
  103. package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
  104. package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
  105. package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
  106. package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
  107. package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
  108. package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
  109. package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
  110. package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
  111. package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
  112. package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
  113. package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
  114. package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
  115. package/packages/bundled-features/src/folders/feature.ts +8 -3
  116. package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
  117. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
  118. package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
  119. package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
  120. package/packages/bundled-features/src/form-draft/feature.ts +6 -1
  121. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
  122. package/packages/bundled-features/src/form-draft/index.ts +1 -1
  123. package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
  124. package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
  125. package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
  126. package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
  127. package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
  128. package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
  129. package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
  130. package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
  131. package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
  132. package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
  133. package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
  134. package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
  135. package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
  136. package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
  137. package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
  138. package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
  139. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  140. package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
  141. package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
  142. package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
  143. package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
  144. package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
  145. package/packages/bundled-features/src/ledger/feature.ts +6 -3
  146. package/packages/bundled-features/src/mail-foundation/feature.ts +107 -55
  147. package/packages/bundled-features/src/mail-foundation/index.ts +4 -0
  148. package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +25 -17
  149. package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
  150. package/packages/bundled-features/src/mail-transport-smtp/feature.ts +91 -79
  151. package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
  152. package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
  153. package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
  154. package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
  155. package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
  156. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  157. package/packages/bundled-features/src/metrics/filters.ts +1 -1
  158. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  159. package/packages/bundled-features/src/notes-history/feature.ts +6 -3
  160. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  161. package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
  162. package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
  163. package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
  164. package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
  165. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  166. package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
  167. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  168. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  169. package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
  170. package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
  171. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
  172. package/packages/bundled-features/src/readiness/feature.ts +25 -16
  173. package/packages/bundled-features/src/readiness/index.ts +1 -1
  174. package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
  175. package/packages/bundled-features/src/secrets/feature.ts +8 -3
  176. package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
  177. package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
  178. package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
  179. package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
  180. package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
  181. package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
  182. package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
  183. package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
  184. package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
  185. package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
  186. package/packages/bundled-features/src/sessions/testing.ts +1 -1
  187. package/packages/bundled-features/src/tags/feature.ts +6 -3
  188. package/packages/bundled-features/src/template-resolver/api.ts +1 -1
  189. package/packages/bundled-features/src/template-resolver/changes.json +25 -0
  190. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +61 -9
  191. package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +19 -0
  192. package/packages/bundled-features/src/template-resolver/document-schema.ts +33 -0
  193. package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +10 -2
  194. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
  195. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
  196. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  197. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
  198. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
  199. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +9 -3
  200. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
  201. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
  202. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +9 -2
  203. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
  204. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +7 -2
  205. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +8 -3
  206. package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
  207. package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
  208. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
  209. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +22 -2
  210. package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
  211. package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
  212. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
  213. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
  214. package/packages/bundled-features/src/template-resolver/index.ts +4 -0
  215. package/packages/bundled-features/src/template-resolver/qualified-names.ts +1 -0
  216. package/packages/bundled-features/src/template-resolver/seeding.ts +57 -10
  217. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
  218. package/packages/bundled-features/src/template-resolver/template-preview.ts +3 -1
  219. package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
  220. package/packages/bundled-features/src/template-resolver/template-system-only.ts +21 -0
  221. package/packages/bundled-features/src/template-resolver/template-validation.ts +48 -24
  222. package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
  223. package/packages/bundled-features/src/template-resolver/web/i18n.ts +2 -0
  224. package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
  225. package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
  226. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
  227. package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
  228. package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
  229. package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
  230. package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
  231. package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
  232. package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
  233. package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -1
  234. package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
  235. package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
  236. package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
  237. package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -2
  238. package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
  239. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
  240. package/packages/bundled-features/src/tenant/seeding.ts +12 -12
  241. package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
  242. package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
  243. package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
  244. package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
  245. package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
  246. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
  247. package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
  248. package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
  249. package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
  250. package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
  251. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
  252. package/packages/bundled-features/src/user/changes.json +6 -0
  253. package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
  254. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
  255. package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
  256. package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
  257. package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
  258. package/packages/bundled-features/src/user/index.ts +5 -1
  259. package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
  260. package/packages/bundled-features/src/user/principal-status.ts +13 -3
  261. package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
  262. package/packages/bundled-features/src/user/seeding.ts +5 -5
  263. package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
  264. package/packages/bundled-features/src/user-data-rights/changes.json +6 -0
  265. package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
  266. package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
  267. package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
  268. package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
  269. package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
  270. package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
  271. package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
  272. package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
  273. package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
  274. package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
  275. package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
  276. package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
  277. package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
  278. package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
  279. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
  280. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  281. package/packages/bundled-features/src/waitlist/lib.ts +5 -2
  282. package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
  283. package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
  284. package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
  285. package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
  286. package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
  287. package/samples/apps/admin-console/src/run-config.ts +2 -2
  288. package/samples/apps/cap-billing-demo/package.json +3 -0
  289. package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
  290. package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
  291. package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
  292. package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
  293. package/samples/apps/showcase/package.json +3 -0
  294. package/samples/apps/showcase/src/app/seed-items.ts +1 -1
  295. package/samples/apps/styleguide/src/app/seed.ts +2 -2
  296. package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
  297. package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
  298. package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
  299. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
  300. package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +2 -0
  301. package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
  302. package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
  303. package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +12 -0
  304. package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
  305. package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
  306. package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +7 -0
  307. package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +2 -0
  308. package/samples/apps/use-all-bundled/feature-manifest.json +4 -4
  309. package/samples/apps/use-all-bundled/package.json +4 -0
  310. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
  311. package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
  312. package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
  313. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
  314. package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
  315. package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
  316. package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
  317. package/samples/apps/user-data-rights-demo/README.md +2 -2
  318. package/samples/apps/user-data-rights-demo/package.json +3 -0
  319. package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
  320. package/samples/apps/workspaces/package.json +3 -0
  321. package/samples/recipes/access-control/package.json +3 -0
  322. package/samples/recipes/anonymous-access/package.json +3 -0
  323. package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
  324. package/samples/recipes/apex-landing/package.json +1 -0
  325. package/samples/recipes/apex-surface-auth/package.json +3 -0
  326. package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
  327. package/samples/recipes/api-worker-split/package.json +3 -0
  328. package/samples/recipes/api-worker-split/src/feature.ts +1 -2
  329. package/samples/recipes/auth-claims/package.json +3 -0
  330. package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
  331. package/samples/recipes/auth-mfa/package.json +3 -0
  332. package/samples/recipes/basic-entity/package.json +3 -0
  333. package/samples/recipes/chat-channels/package.json +3 -0
  334. package/samples/recipes/compliance-profiles-demo/package.json +3 -0
  335. package/samples/recipes/cross-feature-events/package.json +3 -1
  336. package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
  337. package/samples/recipes/crypto-shredding-hr/package.json +3 -0
  338. package/samples/recipes/currencies-global/package.json +3 -0
  339. package/samples/recipes/currencies-per-tenant/package.json +3 -0
  340. package/samples/recipes/custom-fields-basic/package.json +3 -0
  341. package/samples/recipes/custom-handlers/package.json +3 -0
  342. package/samples/recipes/dashboard-stats/package.json +3 -0
  343. package/samples/recipes/delivery-notifications/package.json +3 -0
  344. package/samples/recipes/e2e-generator/package.json +3 -0
  345. package/samples/recipes/embedded/package.json +3 -0
  346. package/samples/recipes/embedded-entity-form/package.json +1 -0
  347. package/samples/recipes/encrypted-tenant-config/README.md +1 -1
  348. package/samples/recipes/encrypted-tenant-config/package.json +3 -0
  349. package/samples/recipes/error-contract/package.json +3 -0
  350. package/samples/recipes/event-sourcing/package.json +3 -1
  351. package/samples/recipes/event-sourcing/src/feature.ts +16 -20
  352. package/samples/recipes/event-sourcing/tsconfig.json +2 -6
  353. package/samples/recipes/feature-toggles/package.json +3 -0
  354. package/samples/recipes/field-access/package.json +3 -0
  355. package/samples/recipes/files-post-processing/package.json +1 -0
  356. package/samples/recipes/golden-path/README.md +30 -0
  357. package/samples/recipes/golden-path/package.json +11 -0
  358. package/samples/recipes/golden-path/src/feature.ts +70 -0
  359. package/samples/recipes/idempotency/package.json +3 -0
  360. package/samples/recipes/inbound-mail-triage/package.json +3 -0
  361. package/samples/recipes/lane-routing/package.json +3 -0
  362. package/samples/recipes/ledger-banking/package.json +3 -0
  363. package/samples/recipes/ledger-invoicing/package.json +3 -0
  364. package/samples/recipes/legal-pages/package.json +3 -0
  365. package/samples/recipes/lifecycle-hooks/package.json +3 -0
  366. package/samples/recipes/managed-config/package.json +3 -0
  367. package/samples/recipes/managed-pages/package.json +3 -0
  368. package/samples/recipes/notes-history-basic/package.json +3 -0
  369. package/samples/recipes/ownership/package.json +3 -0
  370. package/samples/recipes/pdf-audit-export/package.json +1 -0
  371. package/samples/recipes/pipeline-basics/package.json +3 -0
  372. package/samples/recipes/public-share-token/package.json +3 -0
  373. package/samples/recipes/public-share-token/src/feature.ts +1 -1
  374. package/samples/recipes/rate-limiting/package.json +3 -0
  375. package/samples/recipes/realtime-sse/package.json +3 -0
  376. package/samples/recipes/record-detail-layout/package.json +1 -0
  377. package/samples/recipes/reference-data/package.json +3 -0
  378. package/samples/recipes/relations/package.json +3 -0
  379. package/samples/recipes/screens-nav/package.json +3 -0
  380. package/samples/recipes/search/package.json +3 -0
  381. package/samples/recipes/secrets-demo/package.json +3 -0
  382. package/samples/recipes/security-baseline/src/feature.ts +2 -2
  383. package/samples/recipes/session-revocation/README.md +1 -1
  384. package/samples/recipes/session-revocation/package.json +3 -0
  385. package/samples/recipes/session-revocation/src/feature.ts +1 -1
  386. package/samples/recipes/state-machine/package.json +3 -1
  387. package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
  388. package/samples/recipes/state-machine/src/events.ts +19 -0
  389. package/samples/recipes/state-machine/src/feature.ts +25 -30
  390. package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
  391. package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
  392. package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
  393. package/samples/recipes/state-machine/src/reducer.ts +1 -1
  394. package/samples/recipes/state-machine/tsconfig.json +2 -6
  395. package/samples/recipes/tags-basic/package.json +3 -0
  396. package/samples/recipes/tenant-isolation/package.json +3 -0
  397. package/samples/recipes/tenant-settings/package.json +3 -0
  398. package/samples/recipes/tier-admin/package.json +3 -0
  399. package/samples/recipes/timezones/package.json +3 -0
  400. package/samples/recipes/tsconfig.base.json +1 -1
  401. package/samples/recipes/user-data-rights/package.json +3 -0
  402. package/samples/recipes/user-data-rights/src/feature.ts +6 -2
  403. package/samples/recipes/user-profile/package.json +3 -0
  404. package/samples/recipes/user-profile/src/feature.ts +2 -2
  405. package/samples/recipes/webhook-step/package.json +3 -0
  406. package/samples/recipes/wizard-form/package.json +1 -0
  407. package/samples/recipes/workflow-engine/package.json +3 -0
  408. package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
  409. package/samples/recipes/writeform-section/package.json +1 -0
  410. package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
  411. /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
@@ -63,7 +63,7 @@ function registerNotesHistory(
63
63
  r.translations({ keys: NOTES_HISTORY_FEATURE_I18N });
64
64
  }
65
65
 
66
- export const notesHistoryFeature = defineFeature(NOTES_HISTORY_FEATURE_NAME, (r) =>
66
+ const defaultNotesHistoryFeature = defineFeature(NOTES_HISTORY_FEATURE_NAME, (r) =>
67
67
  registerNotesHistory(r, DEFAULT_NOTES_HISTORY_ACCESS, undefined, undefined),
68
68
  );
69
69
 
@@ -114,14 +114,14 @@ function resolveAccess(opts: NotesHistoryFeatureOptions): AccessRule {
114
114
  // rebuild). access/roles/ownership build a fresh feature-definition.
115
115
  export function createNotesHistoryFeature(
116
116
  opts: NotesHistoryFeatureOptions = {},
117
- ): typeof notesHistoryFeature {
117
+ ): typeof defaultNotesHistoryFeature {
118
118
  if (
119
119
  opts.access === undefined &&
120
120
  opts.roles === undefined &&
121
121
  opts.ownership === undefined &&
122
122
  opts.parents === undefined
123
123
  ) {
124
- return notesHistoryFeature;
124
+ return defaultNotesHistoryFeature;
125
125
  }
126
126
  assertNoWhereRuleInOwnershipWrite("createNotesHistoryFeature", opts.ownership?.write);
127
127
  // A mount that accepts no parents at all can never take a note write —
@@ -138,3 +138,6 @@ export function createNotesHistoryFeature(
138
138
  registerNotesHistory(r, resolveAccess(opts), opts.ownership, opts.parents),
139
139
  );
140
140
  }
141
+
142
+ /** @deprecated Use createNotesHistoryFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
143
+ export const notesHistoryFeature = createNotesHistoryFeature();
@@ -1,4 +1,4 @@
1
- import { fetchOne, runInSavepointIfSupported } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne, runInSavepointIfSupported } from "@cosmicdrift/kumiko-framework/db";
2
2
  import type { AccessRule, WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { ValidationError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { decryptStoredPii, denyUnlessJoinRowParentVisible } from "../../shared/index.js";
@@ -4,9 +4,9 @@
4
4
  // dependency. Mirrors job-run/delivery-attempt (user-data-rights-defaults):
5
5
  // export-only, erasure via crypto-shredding.
6
6
 
7
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
8
7
  import { configuredPiiSubjectKms, type SubjectId } from "@cosmicdrift/kumiko-framework/crypto";
9
8
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
9
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
10
10
  import type {
11
11
  TenantId,
12
12
  UserDataDeleteHook,
@@ -15,22 +15,31 @@ import {
15
15
 
16
16
  export { eraseNoteBodiesReachingSubject } from "./hooks.js";
17
17
 
18
- export const notesHistoryUserDataFeature = defineFeature("notes-history-user-data", (r) => {
19
- r.describe(
20
- "GDPR (Art. 20 export / Art. 17 erasure) coverage for the `notes-history` feature's `note-entry` and `note-mention` entities. Mounts the export hook so a user's authored notes are included in the user-data export bundle; the note-entry delete hook crypto-shreds the row-subject key of each note that structurally @-mentions the forgotten user (`note-mention`) or hangs on the user as host entity (regardless of the host entity's retention strategy: the note text is free PII, the host's anonymize/blockDelete protects the row, not the content), keeping the append-only history intact for all other notes. The manual `crypto-shredding` forget-subject command reaches the same notes for user and record subjects through the exported `eraseNoteBodiesReachingSubject`, and the export lists them under `note-mention`. `note-mention`'s own hooks are a no-op — it is a plain FK pointer, not separately exportable content. Kept separate from `notes-history` so notes consumers without the user-data-rights pipeline don't pull a hard dependency — requires `user-data-rights`, optionalRequires `notes-history`.",
18
+ export function createNotesHistoryUserDataFeature() {
19
+ return defineFeature(
20
+ "notes-history-user-data",
21
+ (r) => {
22
+ r.describe(
23
+ "GDPR (Art. 20 export / Art. 17 erasure) coverage for the `notes-history` feature's `note-entry` and `note-mention` entities. Mounts the export hook so a user's authored notes are included in the user-data export bundle; the note-entry delete hook crypto-shreds the row-subject key of each note that structurally @-mentions the forgotten user (`note-mention`) or hangs on the user as host entity (regardless of the host entity's retention strategy: the note text is free PII, the host's anonymize/blockDelete protects the row, not the content), keeping the append-only history intact for all other notes. The manual `crypto-shredding` forget-subject command reaches the same notes for user and record subjects through the exported `eraseNoteBodiesReachingSubject`, and the export lists them under `note-mention`. `note-mention`'s own hooks are a no-op — it is a plain FK pointer, not separately exportable content. Kept separate from `notes-history` so notes consumers without the user-data-rights pipeline don't pull a hard dependency — requires `user-data-rights`, optionalRequires `notes-history`.",
24
+ );
25
+ // user-data-rights is the hard dependency (EXT_USER_DATA host). notes-history
26
+ // is OPTIONAL: if it's mounted toggleable(default=false), a hard r.requires
27
+ // would throw an "effectively disabled" boot warning even though the
28
+ // note-entry entity exists and the hooks work fine.
29
+ r.requires({ features: ["user-data-rights"] });
30
+ r.optionalRequires("notes-history");
31
+ r.useExtension(EXT_USER_DATA, "note-entry", {
32
+ export: noteEntryExportHook,
33
+ delete: noteEntryDeleteHook,
34
+ });
35
+ r.useExtension(EXT_USER_DATA, "note-mention", {
36
+ export: noteMentionExportHook,
37
+ delete: noteMentionDeleteHook,
38
+ });
39
+ },
40
+ { dedupeOptions: {} },
21
41
  );
22
- // user-data-rights is the hard dependency (EXT_USER_DATA host). notes-history
23
- // is OPTIONAL: if it's mounted toggleable(default=false), a hard r.requires
24
- // would throw an "effectively disabled" boot warning even though the
25
- // note-entry entity exists and the hooks work fine.
26
- r.requires({ features: ["user-data-rights"] });
27
- r.optionalRequires("notes-history");
28
- r.useExtension(EXT_USER_DATA, "note-entry", {
29
- export: noteEntryExportHook,
30
- delete: noteEntryDeleteHook,
31
- });
32
- r.useExtension(EXT_USER_DATA, "note-mention", {
33
- export: noteMentionExportHook,
34
- delete: noteMentionDeleteHook,
35
- });
36
- });
42
+ }
43
+
44
+ /** @deprecated Use createNotesHistoryUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
45
+ export const notesHistoryUserDataFeature = createNotesHistoryUserDataFeature();
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.368.0",
4
+ "type": "improvement",
5
+ "title": "The token list screen takes a description and slots via listScreen",
6
+ "detail": "createPersonalAccessTokensFeature({ listScreen: { description, slots } }) sets the i18n description and the slots (for example a header component) of the api-tokens list, so an app can show instructions above the list and use the bundled screen directly instead of embedding it in its own dashboard. Without the option nothing changes. Both bundled token screens are now marked agent: { expose: false }, since the mint screen reveals the token plaintext."
7
+ },
2
8
  {
3
9
  "version": "0.365.0",
4
10
  "type": "fix",
@@ -4,7 +4,11 @@ import {
4
4
  } from "@cosmicdrift/kumiko-bundled-features/auth-foundation";
5
5
  import { PAT_TOKEN_PREFIX } from "@cosmicdrift/kumiko-framework/api";
6
6
  import { deriveEntityTableMeta } from "@cosmicdrift/kumiko-framework/db";
7
- import { defineFeature, type FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
7
+ import {
8
+ defineFeature,
9
+ type FeatureDefinition,
10
+ type ProjectionListScreenDefinition,
11
+ } from "@cosmicdrift/kumiko-framework/engine";
8
12
  import {
9
13
  API_TOKEN_ENTITY_NAME,
10
14
  PAT_DEFAULT_RATE_LIMIT,
@@ -68,6 +72,9 @@ export type PersonalAccessTokensOptions = {
68
72
  * shown in place of the token screens when the tenant's tier excludes the
69
73
  * feature, e.g. an upgrade notice. Default: the standard "unavailable" notice. */
70
74
  readonly lockedFallbackScreen?: string;
75
+ /** Description (i18n key) and slots rendered on the token list screen, e.g. an
76
+ * explanatory text or a header component above the list. Default: neither. */
77
+ readonly listScreen?: Pick<ProjectionListScreenDefinition, "description" | "slots">;
71
78
  // Opt-in MFA re-auth gate for minting a token — wired via
72
79
  // mfaVerifierFromFeature (auth-mfa/feature.ts) at app-composition time. No
73
80
  // hard dependency on the optional auth-mfa feature.
@@ -176,7 +183,15 @@ export function createPersonalAccessTokensFeature(
176
183
  // places `patListScreen` via r.nav in its logged-in settings area.
177
184
  const lockedFallback =
178
185
  options.lockedFallbackScreen === undefined ? {} : { fallback: options.lockedFallbackScreen };
179
- r.screen({ ...patListScreen, ...lockedFallback });
186
+ // Copy the two fields explicitly: a wider object passed as a variable
187
+ // escapes the Pick check and would override agent/access otherwise.
188
+ const { description, slots } = options.listScreen ?? {};
189
+ r.screen({
190
+ ...patListScreen,
191
+ ...(description === undefined ? {} : { description }),
192
+ ...(slots === undefined ? {} : { slots }),
193
+ ...lockedFallback,
194
+ });
180
195
  r.screen({ ...createPatMintScreen(scopes), ...lockedFallback });
181
196
  r.translations({ keys: { ...PAT_FEATURE_I18N, ...patScopeOptionTranslations(scopes) } });
182
197
 
@@ -1,4 +1,4 @@
1
- import { insertOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { insertOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  createSystemUser,
4
4
  defineWriteHandler,
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { definePagedQueryHandler, MAX_LIST_LIMIT } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
4
4
  import * as z from "zod";
@@ -8,7 +8,7 @@ import { apiTokenTable } from "../schema/api-token.js";
8
8
 
9
9
  // `sort` arrives raw from the client's query string. selectMany's orderBy has
10
10
  // no column-existence check — an unrecognised field just gets snake_cased and
11
- // quoted as-is (bun-db/query.ts columnOf) — so this allowlist is what stops a
11
+ // quoted as-is (db/query.ts columnOf) — so this allowlist is what stops a
12
12
  // client sorting by tokenHash or any other non-exposed column.
13
13
  const SORTABLE_COLUMNS = ["id", "name", "createdAt", "expiresAt", "revokedAt"] as const;
14
14
  type SortableColumn = (typeof SORTABLE_COLUMNS)[number];
@@ -1,4 +1,4 @@
1
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,6 +1,6 @@
1
1
  import type { TokenVerifier } from "@cosmicdrift/kumiko-framework/api";
2
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
3
2
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
3
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
4
4
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
5
5
  import { isExpiredAt } from "./expiry.js";
6
6
  import { hashPatToken } from "./hash.js";
@@ -1,9 +1,9 @@
1
+ import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
1
2
  import {
2
3
  runnerCanBeginTransaction,
3
4
  transaction,
4
5
  updateMany,
5
- } from "@cosmicdrift/kumiko-framework/bun-db";
6
- import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
6
+ } from "@cosmicdrift/kumiko-framework/db";
7
7
  import { SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import { append } from "@cosmicdrift/kumiko-framework/event-store";
9
9
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,11 +1,9 @@
1
- import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { buildSessionRoles } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
5
- // kumiko-lint-ignore cross-feature-import shared lifecycle-status gate with session auth
6
- import { isPrincipalBlocked } from "../sessions/index.js";
7
5
  import { tenantMembershipsTable } from "../tenant/index.js";
8
- import { type UserStatus, userTable } from "../user/index.js";
6
+ import { isPrincipalRowBlocked, type UserStatus, userTable } from "../user/index.js";
9
7
 
10
8
  // Live role resolution for a (userId, tenantId), mirroring login.write.ts:
11
9
  // global roles (users.roles) ∪ tenant-membership roles (forbidden roles
@@ -28,10 +26,14 @@ export async function resolvePatRoles(
28
26
  });
29
27
  const membership = memberships[0];
30
28
  if (!membership) return null;
31
- const userRow = await fetchOne<{ roles: string | null; status: UserStatus }>(db, userTable, {
29
+ const userRow = await fetchOne<{
30
+ roles: string | null;
31
+ status: UserStatus;
32
+ isDeleted: boolean;
33
+ }>(db, userTable, {
32
34
  id: userId,
33
35
  });
34
- if (userRow && isPrincipalBlocked(userRow.status)) return null;
36
+ if (userRow && isPrincipalRowBlocked(userRow)) return null;
35
37
  const globalRoles = parseRoles(userRow?.roles ?? null);
36
38
  return buildSessionRoles(globalRoles, parseRoles(membership.roles));
37
39
  }
@@ -35,6 +35,7 @@ const PAT_SCREEN_VISIBLE_WHEN = {
35
35
  export const patListScreen: ProjectionListScreenDefinition = {
36
36
  id: PAT_SCREEN_ID,
37
37
  type: "projectionList",
38
+ agent: { expose: false },
38
39
  visibleWhen: PAT_SCREEN_VISIBLE_WHEN,
39
40
  query: PatQueries.mine,
40
41
  // The `mine` handler honours `limit` only (no offset/total), so a pager would
@@ -118,6 +119,7 @@ export function createPatMintScreen(scopes: PatScopeConfig): SecretMintScreenDef
118
119
  return {
119
120
  id: PAT_MINT_SCREEN_ID,
120
121
  type: "secretMint",
122
+ agent: { expose: false },
121
123
  visibleWhen: PAT_SCREEN_VISIBLE_WHEN,
122
124
  handler: PatHandlers.create,
123
125
  fields: {
@@ -11,21 +11,30 @@
11
11
  import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
12
12
  import { statusQuery } from "./handlers/status.query.js";
13
13
 
14
- export const readinessFeature = defineFeature("readiness", (r) => {
15
- r.describe(
16
- "One-call tenant-onboarding probe: `readiness:query:status` rolls up every config key and secret declared `required: true` across all mounted features and reports which still lack a usable value for the calling tenant, plus a single `ready` boolean. Provider-features under an `r.extensionSelector`-declared extension point count only while their provider is the selected one — a tenant on the inmemory mail transport is not blocked by unset SMTP keys. Mount it (together with `config` and `secrets`) when an admin UI needs a settings checklist before the first mail-send or file-write; the per-concern lists stay available via `config:query:readiness` and `secrets:query:list`.",
17
- );
18
- r.uiHints({
19
- displayLabel: "Readiness · Onboarding Probe",
20
- category: "operations",
21
- recommended: false,
22
- });
23
- r.requires({ features: ["config"] });
24
- r.requires({ features: ["secrets"] });
14
+ export function createReadinessFeature() {
15
+ return defineFeature(
16
+ "readiness",
17
+ (r) => {
18
+ r.describe(
19
+ "One-call tenant-onboarding probe: `readiness:query:status` rolls up every config key and secret declared `required: true` across all mounted features and reports which still lack a usable value for the calling tenant, plus a single `ready` boolean. Provider-features under an `r.extensionSelector`-declared extension point count only while their provider is the selected one — a tenant on the inmemory mail transport is not blocked by unset SMTP keys. Mount it (together with `config` and `secrets`) when an admin UI needs a settings checklist before the first mail-send or file-write; the per-concern lists stay available via `config:query:readiness` and `secrets:query:list`.",
20
+ );
21
+ r.uiHints({
22
+ displayLabel: "Readiness · Onboarding Probe",
23
+ category: "operations",
24
+ recommended: false,
25
+ });
26
+ r.requires({ features: ["config"] });
27
+ r.requires({ features: ["secrets"] });
28
+
29
+ const queries = {
30
+ status: r.queryHandler(statusQuery),
31
+ };
25
32
 
26
- const queries = {
27
- status: r.queryHandler(statusQuery),
28
- };
33
+ return { queries };
34
+ },
35
+ { dedupeOptions: {} },
36
+ );
37
+ }
29
38
 
30
- return { queries };
31
- });
39
+ /** @deprecated Use createReadinessFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
40
+ export const readinessFeature = createReadinessFeature();
@@ -1,3 +1,3 @@
1
1
  export { READINESS_FEATURE, ReadinessQueries } from "./constants.js";
2
- export { readinessFeature } from "./feature.js";
2
+ export { createReadinessFeature, readinessFeature } from "./feature.js";
3
3
  export type { ReadinessMissingSecret } from "./handlers/status.query.js";
@@ -1,5 +1,5 @@
1
- import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
2
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/db";
3
3
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import type { StoredEnvelope } from "../../table.js";
5
5
 
@@ -72,8 +72,13 @@ export { type StoredEnvelope, type StoredMetadata, tenantSecretsTable } from "./
72
72
  // FileProviderContext-Pfade (S3-Plugin im Worker) liefern dieselben
73
73
  // zwei Felder, also reicht die schmale ctx-shape — kein voller
74
74
  // HandlerContext-Import noetig.
75
+ // Handler contexts carry the caller as ctx.user, provider contexts set _userId (takes precedence).
75
76
  export function requireSecretsContext(
76
- ctx: { readonly secrets?: SecretsContext; readonly _userId?: string | undefined },
77
+ ctx: {
78
+ readonly secrets?: SecretsContext;
79
+ readonly _userId?: string | undefined;
80
+ readonly user?: { readonly id: string };
81
+ },
77
82
  handlerName: string,
78
83
  ): SecretsContext {
79
84
  if (!ctx.secrets) {
@@ -83,10 +88,10 @@ export function requireSecretsContext(
83
88
  "createSecretsContext({db, masterKeyProvider, registry}) via extraContext.secrets at boot.",
84
89
  });
85
90
  }
86
- const userId = ctx._userId;
91
+ const userId = ctx._userId ?? ctx.user?.id;
87
92
  if (!userId) {
88
93
  throw new InternalError({
89
- message: `[${handlerName}] ctx._userId missing — cannot audit secret reads without a caller identity.`,
94
+ message: `[${handlerName}] ctx._userId missing (and no ctx.user) — cannot audit secret reads without a caller identity.`,
90
95
  });
91
96
  }
92
97
  const withAudit = (raw: SecretsContext): SecretsContext => ({
@@ -17,11 +17,11 @@
17
17
  // that landed the row on the new kekVersion first surfaces here as a
18
18
  // version_conflict error (counted as "skipped", not "failed").
19
19
 
20
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
21
20
  import {
22
21
  createEventStoreExecutor,
23
22
  createTenantDb,
24
23
  type DbConnection,
24
+ selectMany,
25
25
  type TenantDb,
26
26
  } from "@cosmicdrift/kumiko-framework/db";
27
27
  import type { JobContext, SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
@@ -81,7 +81,7 @@ export async function rotateJob(
81
81
  function tdbFor(tenantId: TenantId): TenantDb {
82
82
  let existing = tdbCache.get(tenantId);
83
83
  if (!existing) {
84
- existing = createTenantDb(db, tenantId, "system");
84
+ existing = createTenantDb({ db, tenantId, mode: "system" });
85
85
  tdbCache.set(tenantId, existing);
86
86
  }
87
87
  return existing;
@@ -12,12 +12,13 @@
12
12
  // read logged") now sits on the events-table instead of a
13
13
  // dedicated audit-table.
14
14
 
15
- import { fetchOne, transaction } from "@cosmicdrift/kumiko-framework/bun-db";
16
15
  import {
17
16
  createEventStoreExecutor,
18
17
  createTenantDb,
19
18
  type DbConnection,
20
19
  type DbRunner,
20
+ fetchOne,
21
+ transaction,
21
22
  } from "@cosmicdrift/kumiko-framework/db";
22
23
  import type { SessionUser } from "@cosmicdrift/kumiko-framework/engine";
23
24
  import { InternalError, type WriteErrorInfo } from "@cosmicdrift/kumiko-framework/errors";
@@ -205,7 +206,7 @@ function buildSecretsContext(
205
206
  tenantId,
206
207
  roles: SYSTEM_ROLES,
207
208
  };
208
- const tdb = createTenantDb(db, tenantId, "system");
209
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
209
210
 
210
211
  const existing = await lookup(tenantId, key);
211
212
  const commonFields = {
@@ -270,7 +271,7 @@ function buildSecretsContext(
270
271
  tenantId,
271
272
  roles: SYSTEM_ROLES,
272
273
  };
273
- const tdb = createTenantDb(db, tenantId, "system");
274
+ const tdb = createTenantDb({ db, tenantId, mode: "system" });
274
275
  const result = await executor.delete({ id: existing.id }, actor, tdb);
275
276
  return result.isSuccess;
276
277
  },
@@ -1,5 +1,5 @@
1
- import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
2
1
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/db";
3
3
 
4
4
  export async function deleteStaleSessionsBatch(
5
5
  db: DbConnection,
@@ -1,4 +1,4 @@
1
- import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { access, defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { decryptStoredPii } from "../../shared/index.js";
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  access,
4
4
  definePagedQueryHandler,
@@ -11,7 +11,7 @@ import { userSessionTable } from "../schema/user-session.js";
11
11
 
12
12
  // `sort` arrives raw from the client's query string. selectMany's orderBy
13
13
  // has no column-existence check — an unrecognised field just gets
14
- // snake_cased and quoted as-is (bun-db/query.ts columnOf) — so this
14
+ // snake_cased and quoted as-is (db/query.ts columnOf) — so this
15
15
  // allowlist is what stops a client sorting by ip/userAgent or any other
16
16
  // non-exposed column.
17
17
  const SORTABLE_COLUMNS = ["id", "userId", "createdAt", "expiresAt", "revokedAt"] as const;
@@ -1,4 +1,4 @@
1
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { definePagedQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { decryptStoredPii } from "../../shared/index.js";
@@ -1,5 +1,5 @@
1
1
  import { requestContext } from "@cosmicdrift/kumiko-framework/api";
2
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
3
3
  import { access, defineWriteHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
4
4
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
5
5
  import { append } from "@cosmicdrift/kumiko-framework/event-store";
@@ -1,4 +1,4 @@
1
- import { updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -1,4 +1,4 @@
1
- import { fetchOne, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
1
+ import { fetchOne, updateMany } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import { UnprocessableError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
4
4
  import { generateId } from "@cosmicdrift/kumiko-framework/utils";
@@ -9,8 +9,8 @@ import type {
9
9
 
10
10
  export type { SessionMassRevoker } from "@cosmicdrift/kumiko-framework/api";
11
11
 
12
- import { fetchOne, insertOne, transaction, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
13
12
  import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
13
+ import { fetchOne, insertOne, transaction, updateMany } from "@cosmicdrift/kumiko-framework/db";
14
14
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
15
15
  import { buildSessionRoles, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
16
16
  import { append } from "@cosmicdrift/kumiko-framework/event-store";
@@ -18,7 +18,12 @@ import { generateId, parseRoles } from "@cosmicdrift/kumiko-framework/utils";
18
18
  import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
19
19
  import { encryptForDirectWrite } from "../shared/index.js";
20
20
  import { tenantMembershipsTable } from "../tenant/index.js";
21
- import { isPrincipalBlocked, type UserStatus, userTable } from "../user/index.js";
21
+ import {
22
+ isPrincipalBlocked,
23
+ isPrincipalRowBlocked,
24
+ type UserStatus,
25
+ userTable,
26
+ } from "../user/index.js";
22
27
  import {
23
28
  DEFAULT_SESSION_EXPIRY_MS,
24
29
  LAST_SEEN_REFRESH_MS,
@@ -190,16 +195,18 @@ export function createSessionCallbacks(opts: SessionCallbacksOptions): SessionCa
190
195
  // missing row is a legitimate "no tenant roles" outcome. Both branches
191
196
  // return the bare "live" string (no re-derived roles) — the middleware
192
197
  // falls back to the JWT's frozen roles claim.
193
- let user: { status: UserStatus; roles: string | null } | undefined;
198
+ let user: { status: UserStatus; isDeleted: boolean; roles: string | null } | undefined;
194
199
  try {
195
- user = await fetchOne<{ status: UserStatus; roles: string | null }>(db, userTable, {
196
- id: expectedUserId,
197
- });
200
+ user = await fetchOne<{ status: UserStatus; isDeleted: boolean; roles: string | null }>(
201
+ db,
202
+ userTable,
203
+ { id: expectedUserId },
204
+ );
198
205
  } catch {
199
206
  return "live";
200
207
  }
201
208
  if (!user) return "live";
202
- if (isPrincipalBlocked(user.status)) return "blocked";
209
+ if (isPrincipalRowBlocked(user)) return "blocked";
203
210
 
204
211
  // Same fail-open reasoning as the userTable lookup above — a transient
205
212
  // DB error on the membership read must not lock the user out. A
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { AuthRoutesConfig, SessionCreator } from "@cosmicdrift/kumiko-framework/api";
21
21
  import type { SessionUser } from "@cosmicdrift/kumiko-framework/engine";
22
- import type { LateBoundHolder } from "@cosmicdrift/kumiko-framework/testing";
22
+ import type { LateBoundHolder } from "@cosmicdrift/kumiko-testing/helpers";
23
23
  import type { SessionCallbacks, SessionMassRevoker } from "./session-callbacks.js";
24
24
 
25
25
  export type BoundSessionCallbacks = {
@@ -130,7 +130,7 @@ function registerTags(
130
130
  r.translations({ keys: TAGS_FEATURE_I18N });
131
131
  }
132
132
 
133
- export const tagsFeature = defineFeature(TAGS_FEATURE_NAME, (r) =>
133
+ const defaultTagsFeature = defineFeature(TAGS_FEATURE_NAME, (r) =>
134
134
  registerTags(r, DEFAULT_TAG_ACCESS, undefined, undefined, undefined),
135
135
  );
136
136
 
@@ -183,7 +183,7 @@ function resolveAccess(opts: TagsFeatureOptions): AccessRule {
183
183
  // Backwards-compat / options wrapper. Without options returns the module-level
184
184
  // singleton (no rebuild). access/roles/toggleable/ownership build a fresh
185
185
  // feature-definition.
186
- export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof tagsFeature {
186
+ export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof defaultTagsFeature {
187
187
  if (
188
188
  opts.access === undefined &&
189
189
  opts.roles === undefined &&
@@ -191,7 +191,7 @@ export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof tagsFea
191
191
  opts.ownership === undefined &&
192
192
  opts.parents === undefined
193
193
  ) {
194
- return tagsFeature;
194
+ return defaultTagsFeature;
195
195
  }
196
196
  if (opts.parents !== undefined && opts.parents.length === 0) {
197
197
  throw new Error(
@@ -207,3 +207,6 @@ export function createTagsFeature(opts: TagsFeatureOptions = {}): typeof tagsFea
207
207
  registerTags(r, access, opts.toggleable, opts.ownership, opts.parents),
208
208
  );
209
209
  }
210
+
211
+ /** @deprecated Use createTagsFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
212
+ export const tagsFeature = createTagsFeature();
@@ -2,8 +2,8 @@
2
2
  // delivery and apps import types ONLY and take the implementation from
3
3
  // ctx.templateResolver at runtime.
4
4
 
5
- import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
6
5
  import type { DbRunner, TenantDb } from "@cosmicdrift/kumiko-framework/db";
6
+ import { selectMany } from "@cosmicdrift/kumiko-framework/db";
7
7
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
8
8
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
9
9
  import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
@@ -1,4 +1,29 @@
1
1
  [
2
+ {
3
+ "version": "0.367.0",
4
+ "type": "improvement",
5
+ "title": "Notifications can keep their mail template system-only",
6
+ "detail": "r.notification(name, { systemOnly: true }) marks the stored mail template as a platform text. Tenant admins no longer see it in the template overview, list or detail, and creating a tenant version (upsert-tenant, copy-locale, import-bundle, also a SystemAdmin writing for a tenant) is refused with access_denied and templateResolver.errors.systemOnlyTemplate. SystemAdmins edit the system template as before, and the mail renderer always uses it, even if a tenant row exists from before."
7
+ },
8
+ {
9
+ "version": "0.367.0",
10
+ "type": "fix",
11
+ "title": "Rich text placeholders no longer nest paragraphs",
12
+ "detail": "A richText placeholder alone in a paragraph compiles into a div that keeps the paragraph attributes, and one inside other text renders inline with line breaks instead of its own paragraphs. Mails and PDFs no longer contain <p><p>. richText and stepIs are now reserved template variable names, like the other renderer helpers.",
13
+ "migration": "A notification that declares a template variable called richText, stepIs or percent fails at boot; rename the variable."
14
+ },
15
+ {
16
+ "version": "0.367.0",
17
+ "type": "improvement",
18
+ "title": "Template bundles with a logo can be seeded",
19
+ "detail": "seedSystemTemplateBundle(db, bundle, { dispatcher }) now seeds bundles that carry resources such as a logo by running the import-bundle-system write on the given seed dispatcher. With ifExists \"skip\" (default) nothing is written when every locale row already exists; if only some exist, the whole bundle is imported again. Without a dispatcher such a bundle still fails with a message that names the missing option."
20
+ },
21
+ {
22
+ "version": "0.367.0",
23
+ "type": "improvement",
24
+ "title": "Template conditions with data-if and a percent variable type",
25
+ "detail": "A paragraph, heading or table row with data-if=\"name\" renders only when the variable has a value (0 counts as a value); inside a repeat row the name refers to the row field, on the repeat row itself to the root variable. The sanitizer keeps the attribute, and template validation reports a condition on an undeclared variable. New variable type percent (templateVariable.percent()) takes percentage points and renders locale-aware, 12 as \"12 %\" in German and \"12%\" in English; the preview uses its example value. The document designer has no toolbar control for conditions yet; the attribute survives editing."
26
+ },
2
27
  {
3
28
  "version": "0.365.0",
4
29
  "type": "breaking",