@mastra/factory 0.25.0-alpha.4 → 0.25.0-alpha.6

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 (358) hide show
  1. package/README.md +3 -1
  2. package/dist/auth.js +1 -2
  3. package/dist/boards/define-board.js +1 -2
  4. package/dist/boards/index.js +1 -2
  5. package/dist/boards/registry.js +1 -2
  6. package/dist/boards/relocate.js +1 -2
  7. package/dist/boards/review.js +1 -2
  8. package/dist/boards/semantics.js +1 -2
  9. package/dist/boards/transition-policy.js +1 -2
  10. package/dist/boards/work-tool-rules.js +1 -2
  11. package/dist/boards/work-transition-policy.js +1 -2
  12. package/dist/boards/work.js +1 -2
  13. package/dist/default-thinking-level.d.ts +3 -0
  14. package/dist/default-thinking-level.d.ts.map +1 -0
  15. package/dist/default-thinking-level.js +5 -0
  16. package/dist/default-thinking-level.js.map +1 -0
  17. package/dist/environment/build-runner.js +1 -2
  18. package/dist/environment/build-schedule.js +1 -2
  19. package/dist/environment/build-workflow.js +1 -2
  20. package/dist/environment/build.js +1 -2
  21. package/dist/environment/heads.js +1 -2
  22. package/dist/factory.d.ts +4 -2
  23. package/dist/factory.d.ts.map +1 -1
  24. package/dist/factory.js +62 -21
  25. package/dist/factory.js.map +1 -1
  26. package/dist/feed-events.js +1 -2
  27. package/dist/index.js +2 -2
  28. package/dist/integrations/channel-thread-announcements.d.ts +8 -0
  29. package/dist/integrations/channel-thread-announcements.d.ts.map +1 -0
  30. package/dist/integrations/channel-thread-announcements.js +16 -0
  31. package/dist/integrations/channel-thread-announcements.js.map +1 -0
  32. package/dist/integrations/github/acceptance-labels.js +1 -2
  33. package/dist/integrations/github/app-identity.js +1 -2
  34. package/dist/integrations/github/commits.js +1 -2
  35. package/dist/integrations/github/config.js +1 -2
  36. package/dist/integrations/github/default-rules.js +2 -3
  37. package/dist/integrations/github/integration.js +3 -4
  38. package/dist/integrations/github/issue-reconciler.js +1 -2
  39. package/dist/integrations/github/pat.js +1 -2
  40. package/dist/integrations/github/provenance.d.ts.map +1 -1
  41. package/dist/integrations/github/provenance.js +2 -5
  42. package/dist/integrations/github/provenance.js.map +1 -1
  43. package/dist/integrations/github/reconcile-worker.js +1 -2
  44. package/dist/integrations/github/reconciliation-config.js +1 -2
  45. package/dist/integrations/github/routes.js +4 -5
  46. package/dist/integrations/github/rules.d.ts.map +1 -1
  47. package/dist/integrations/github/rules.js +14 -3
  48. package/dist/integrations/github/rules.js.map +1 -1
  49. package/dist/integrations/github/sandbox-release.js +1 -2
  50. package/dist/integrations/github/sandbox.js +1 -2
  51. package/dist/integrations/github/session-subscriptions.js +1 -2
  52. package/dist/integrations/github/settle-or-abort.js +1 -2
  53. package/dist/integrations/github/stale-reviews.js +1 -2
  54. package/dist/integrations/github/subscriptions.js +1 -2
  55. package/dist/integrations/github/token-refresh.js +1 -2
  56. package/dist/integrations/github/webhook.d.ts.map +1 -1
  57. package/dist/integrations/github/webhook.js +17 -3
  58. package/dist/integrations/github/webhook.js.map +1 -1
  59. package/dist/integrations/gitlab/agent-tools.js +1 -2
  60. package/dist/integrations/gitlab/api.js +1 -2
  61. package/dist/integrations/gitlab/default-rules.js +1 -2
  62. package/dist/integrations/gitlab/integration.d.ts +4 -0
  63. package/dist/integrations/gitlab/integration.d.ts.map +1 -1
  64. package/dist/integrations/gitlab/integration.js +12 -4
  65. package/dist/integrations/gitlab/integration.js.map +1 -1
  66. package/dist/integrations/gitlab/issue-reconciler.js +1 -2
  67. package/dist/integrations/gitlab/merge-request-reconciler.js +1 -2
  68. package/dist/integrations/gitlab/reconciler.js +1 -2
  69. package/dist/integrations/gitlab/reconciliation-config.js +1 -2
  70. package/dist/integrations/gitlab/routes.d.ts +6 -0
  71. package/dist/integrations/gitlab/routes.d.ts.map +1 -1
  72. package/dist/integrations/gitlab/routes.js +154 -3
  73. package/dist/integrations/gitlab/routes.js.map +1 -1
  74. package/dist/integrations/gitlab/rules.d.ts.map +1 -1
  75. package/dist/integrations/gitlab/rules.js +5 -3
  76. package/dist/integrations/gitlab/rules.js.map +1 -1
  77. package/dist/integrations/gitlab/session-subscriptions.js +1 -2
  78. package/dist/integrations/gitlab/subscriptions.js +1 -2
  79. package/dist/integrations/gitlab/version-control.js +1 -2
  80. package/dist/integrations/gitlab/webhook-dispatch.js +1 -2
  81. package/dist/integrations/gitlab/webhook.js +1 -2
  82. package/dist/integrations/incidentio/agent-tools.js +1 -2
  83. package/dist/integrations/incidentio/api.js +1 -2
  84. package/dist/integrations/incidentio/claim.js +1 -2
  85. package/dist/integrations/incidentio/default-rules.js +1 -2
  86. package/dist/integrations/incidentio/intake.js +1 -2
  87. package/dist/integrations/incidentio/integration.js +1 -2
  88. package/dist/integrations/incidentio/issue-reconciler.js +1 -2
  89. package/dist/integrations/incidentio/reconciliation-config.js +1 -2
  90. package/dist/integrations/incidentio/routes.js +1 -2
  91. package/dist/integrations/incidentio/rules.js +1 -2
  92. package/dist/integrations/issue-reconcile-worker.js +1 -2
  93. package/dist/integrations/issue-reconciler.js +1 -2
  94. package/dist/integrations/jira/adf.js +1 -2
  95. package/dist/integrations/jira/agent-tools.js +1 -2
  96. package/dist/integrations/jira/api.d.ts +1 -1
  97. package/dist/integrations/jira/api.d.ts.map +1 -1
  98. package/dist/integrations/jira/api.js +2 -3
  99. package/dist/integrations/jira/api.js.map +1 -1
  100. package/dist/integrations/jira/claim.js +1 -2
  101. package/dist/integrations/jira/default-rules.js +1 -2
  102. package/dist/integrations/jira/integration.d.ts +3 -1
  103. package/dist/integrations/jira/integration.d.ts.map +1 -1
  104. package/dist/integrations/jira/integration.js +18 -4
  105. package/dist/integrations/jira/integration.js.map +1 -1
  106. package/dist/integrations/jira/issue-reconciler.js +1 -2
  107. package/dist/integrations/jira/reconciliation-config.js +1 -2
  108. package/dist/integrations/jira/routes.js +1 -2
  109. package/dist/integrations/jira/rules.js +1 -2
  110. package/dist/integrations/linear/agent-tools.d.ts +1 -1
  111. package/dist/integrations/linear/agent-tools.d.ts.map +1 -1
  112. package/dist/integrations/linear/agent-tools.js +5 -5
  113. package/dist/integrations/linear/agent-tools.js.map +1 -1
  114. package/dist/integrations/linear/claim.js +1 -2
  115. package/dist/integrations/linear/default-rules.js +1 -2
  116. package/dist/integrations/linear/integration.d.ts +2 -0
  117. package/dist/integrations/linear/integration.d.ts.map +1 -1
  118. package/dist/integrations/linear/integration.js +2 -2
  119. package/dist/integrations/linear/integration.js.map +1 -1
  120. package/dist/integrations/linear/issue-reconciler.js +1 -2
  121. package/dist/integrations/linear/reconciliation-config.js +1 -2
  122. package/dist/integrations/linear/routes.js +1 -2
  123. package/dist/integrations/linear/rules.js +1 -2
  124. package/dist/integrations/platform/api-client.js +1 -2
  125. package/dist/integrations/platform/connect/routes.js +1 -2
  126. package/dist/integrations/platform/github/event-worker.js +6 -2
  127. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  128. package/dist/integrations/platform/github/integration.js +1 -2
  129. package/dist/integrations/platform/gitlab/event-worker.js +1 -2
  130. package/dist/integrations/platform/gitlab/integration.js +1 -2
  131. package/dist/integrations/platform/incidentio/integration.js +1 -2
  132. package/dist/integrations/platform/jira/agent-tools.js +1 -2
  133. package/dist/integrations/platform/jira/integration.js +1 -2
  134. package/dist/integrations/platform/jira/routes.js +1 -2
  135. package/dist/integrations/platform/linear/event-worker.js +1 -2
  136. package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
  137. package/dist/integrations/platform/linear/integration.js +2 -2
  138. package/dist/integrations/platform/linear/integration.js.map +1 -1
  139. package/dist/integrations/pull-request-head.d.ts +1 -0
  140. package/dist/integrations/pull-request-head.d.ts.map +1 -1
  141. package/dist/integrations/pull-request-head.js +3 -3
  142. package/dist/integrations/pull-request-head.js.map +1 -1
  143. package/dist/integrations/reconciliation-config.js +1 -2
  144. package/dist/integrations/slack/channel-reply-processor.d.ts +1 -0
  145. package/dist/integrations/slack/channel-reply-processor.d.ts.map +1 -1
  146. package/dist/integrations/slack/channel-reply-processor.js +16 -6
  147. package/dist/integrations/slack/channel-reply-processor.js.map +1 -1
  148. package/dist/integrations/slack/channel-session-link-processor.d.ts +1 -0
  149. package/dist/integrations/slack/channel-session-link-processor.d.ts.map +1 -1
  150. package/dist/integrations/slack/channel-session-link-processor.js +2 -3
  151. package/dist/integrations/slack/channel-session-link-processor.js.map +1 -1
  152. package/dist/integrations/slack/connect-route.js +1 -2
  153. package/dist/integrations/slack/emoji-shortcodes.generated.js +1 -2
  154. package/dist/integrations/slack/emoji.js +1 -2
  155. package/dist/integrations/slack/feed-publisher.js +1 -2
  156. package/dist/integrations/slack/integration.d.ts +5 -0
  157. package/dist/integrations/slack/integration.d.ts.map +1 -1
  158. package/dist/integrations/slack/integration.js +13 -2
  159. package/dist/integrations/slack/integration.js.map +1 -1
  160. package/dist/integrations/slack/reply-reminder-processor.js +1 -2
  161. package/dist/integrations/slack/reply-tool.d.ts.map +1 -1
  162. package/dist/integrations/slack/reply-tool.js +4 -13
  163. package/dist/integrations/slack/reply-tool.js.map +1 -1
  164. package/dist/integrations/slack/run-error-card.d.ts +3 -0
  165. package/dist/integrations/slack/run-error-card.d.ts.map +1 -0
  166. package/dist/integrations/slack/run-error-card.js +44 -0
  167. package/dist/integrations/slack/run-error-card.js.map +1 -0
  168. package/dist/integrations/slack/share-file-tool.js +1 -2
  169. package/dist/integrations/slack/slack.d.ts.map +1 -1
  170. package/dist/integrations/slack/slack.js +7 -4
  171. package/dist/integrations/slack/slack.js.map +1 -1
  172. package/dist/integrations/subscription-session.js +1 -2
  173. package/dist/integrations/workos/integration.js +1 -2
  174. package/dist/mcp/disconnect.js +1 -2
  175. package/dist/mcp/events.js +2 -3
  176. package/dist/mcp/routes.js +1 -2
  177. package/dist/packages/_internals/workspace/dist/index.js +1 -2
  178. package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
  179. package/dist/platform-auth-host.js +1 -2
  180. package/dist/provider-display-name.js +1 -2
  181. package/dist/review-verdict.d.ts +1 -0
  182. package/dist/review-verdict.d.ts.map +1 -1
  183. package/dist/review-verdict.js +9 -3
  184. package/dist/review-verdict.js.map +1 -1
  185. package/dist/routes/attention-activity.js +1 -2
  186. package/dist/routes/attention-parked.js +1 -2
  187. package/dist/routes/attention-proposed.js +1 -2
  188. package/dist/routes/attention-providers.js +1 -2
  189. package/dist/routes/attention.js +1 -2
  190. package/dist/routes/automation-runs.js +1 -2
  191. package/dist/routes/config.d.ts +7 -0
  192. package/dist/routes/config.d.ts.map +1 -1
  193. package/dist/routes/config.js +29 -3
  194. package/dist/routes/config.js.map +1 -1
  195. package/dist/routes/contracts.js +1 -2
  196. package/dist/routes/custom-provider-source.js +1 -2
  197. package/dist/routes/fs.js +1 -2
  198. package/dist/routes/intake.js +6 -4
  199. package/dist/routes/intake.js.map +1 -1
  200. package/dist/routes/knowledge.js +1 -2
  201. package/dist/routes/oauth.js +1 -2
  202. package/dist/routes/projects.js +1 -2
  203. package/dist/routes/provider-credentials.js +1 -2
  204. package/dist/routes/route.js +1 -2
  205. package/dist/routes/session-access.js +1 -2
  206. package/dist/routes/skills.js +1 -2
  207. package/dist/routes/source-control-sessions.js +5 -6
  208. package/dist/routes/source-control-settings.js +1 -2
  209. package/dist/routes/surface.js +3 -4
  210. package/dist/routes/surface.js.map +1 -1
  211. package/dist/routes/telemetry.js +1 -2
  212. package/dist/routes/tenant-credentials.js +1 -2
  213. package/dist/routes/work-items.js +2 -3
  214. package/dist/rules/binding-context.js +1 -2
  215. package/dist/rules/decision-applicability.js +1 -2
  216. package/dist/rules/dispatch-errors.js +1 -2
  217. package/dist/rules/dispatcher.d.ts.map +1 -1
  218. package/dist/rules/dispatcher.js +9 -3
  219. package/dist/rules/dispatcher.js.map +1 -1
  220. package/dist/rules/event-rules.js +1 -2
  221. package/dist/rules/processor.js +1 -2
  222. package/dist/rules/resolve.js +1 -2
  223. package/dist/rules/review-source-tool.js +1 -2
  224. package/dist/rules/start-coordinator.js +1 -2
  225. package/dist/rules/terminal-cleanup.js +1 -2
  226. package/dist/rules/tools.js +1 -2
  227. package/dist/rules/transition-service.js +1 -2
  228. package/dist/rules/types.d.ts +4 -1
  229. package/dist/rules/types.d.ts.map +1 -1
  230. package/dist/rules/types.js +1 -2
  231. package/dist/rules/types.js.map +1 -1
  232. package/dist/rules/validation.js +1 -2
  233. package/dist/run-error.d.ts +13 -0
  234. package/dist/run-error.d.ts.map +1 -0
  235. package/dist/run-error.js +81 -0
  236. package/dist/run-error.js.map +1 -0
  237. package/dist/sandbox/callback-factory-sandbox.js +1 -2
  238. package/dist/sandbox/git-ref.js +1 -2
  239. package/dist/sandbox/local-factory-sandbox.d.ts +12 -4
  240. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -1
  241. package/dist/sandbox/local-factory-sandbox.js +32 -7
  242. package/dist/sandbox/local-factory-sandbox.js.map +1 -1
  243. package/dist/sandbox/materialization.js +1 -2
  244. package/dist/sandbox/session-retirement.js +1 -2
  245. package/dist/sandbox/session-sandbox.js +1 -2
  246. package/dist/sandbox/workdir.js +1 -2
  247. package/dist/secret-encryption.js +1 -2
  248. package/dist/server-error.js +1 -2
  249. package/dist/session/credential-policy.js +1 -2
  250. package/dist/session/default-model-hydration.js +1 -2
  251. package/dist/session/environment-repositories.js +1 -2
  252. package/dist/session/environment-state-processor.d.ts +0 -1
  253. package/dist/session/environment-state-processor.d.ts.map +1 -1
  254. package/dist/session/environment-state-processor.js +2 -3
  255. package/dist/session/environment-state-processor.js.map +1 -1
  256. package/dist/session/factory-session.js +1 -2
  257. package/dist/session/filesystem-capture.js +2 -3
  258. package/dist/session/filesystem-capture.js.map +1 -1
  259. package/dist/session/first-exec-capture.js +2 -3
  260. package/dist/session/first-exec-capture.js.map +1 -1
  261. package/dist/session/first-message-capture.js +1 -2
  262. package/dist/session/live-sessions.js +1 -2
  263. package/dist/session/memory-settings-hydration.js +1 -2
  264. package/dist/session/org-seed.js +1 -2
  265. package/dist/session/reply-credential-processor.js +1 -2
  266. package/dist/session/resource-migration.js +1 -2
  267. package/dist/session/run-audit.js +1 -2
  268. package/dist/session/session-threads.js +1 -2
  269. package/dist/session/session-title.js +1 -2
  270. package/dist/session/shell-commands.js +1 -2
  271. package/dist/session/source-control-tools.js +2 -3
  272. package/dist/session/thinking-default.d.ts +1 -1
  273. package/dist/session/thinking-default.d.ts.map +1 -1
  274. package/dist/session/thinking-default.js +11 -13
  275. package/dist/session/thinking-default.js.map +1 -1
  276. package/dist/session/thread-session-stamp.js +1 -2
  277. package/dist/session/thread-title-mirror.js +1 -2
  278. package/dist/session/thread-title-mirror.js.map +1 -1
  279. package/dist/session/work-item-repository.js +1 -2
  280. package/dist/session-owner-signal.js +1 -2
  281. package/dist/skills/catalog.js +1 -2
  282. package/dist/skills/service.js +1 -2
  283. package/dist/spa-static.js +1 -2
  284. package/dist/state-signing.js +1 -2
  285. package/dist/storage/domains/audit/actions.js +1 -2
  286. package/dist/storage/domains/audit/actors.js +1 -2
  287. package/dist/storage/domains/audit/agent-audit.js +1 -2
  288. package/dist/storage/domains/audit/base.js +1 -2
  289. package/dist/storage/domains/audit/domain.js +1 -2
  290. package/dist/storage/domains/audit/wire.js +1 -2
  291. package/dist/storage/domains/channel-identity/base.js +1 -2
  292. package/dist/storage/domains/comments/activity.js +1 -2
  293. package/dist/storage/domains/comments/actor.js +1 -2
  294. package/dist/storage/domains/comments/base.js +1 -2
  295. package/dist/storage/domains/comments/domain.js +1 -2
  296. package/dist/storage/domains/comments/feed-context.js +1 -2
  297. package/dist/storage/domains/comments/parse.js +1 -2
  298. package/dist/storage/domains/comments/routes.js +1 -2
  299. package/dist/storage/domains/comments/schema.js +1 -2
  300. package/dist/storage/domains/comments/wire.js +1 -2
  301. package/dist/storage/domains/credentials/base.d.ts +4 -1
  302. package/dist/storage/domains/credentials/base.d.ts.map +1 -1
  303. package/dist/storage/domains/credentials/base.js +40 -44
  304. package/dist/storage/domains/credentials/base.js.map +1 -1
  305. package/dist/storage/domains/custom-providers/base.js +1 -2
  306. package/dist/storage/domains/filesystem/base.js +1 -2
  307. package/dist/storage/domains/intake/base.d.ts +5 -0
  308. package/dist/storage/domains/intake/base.d.ts.map +1 -1
  309. package/dist/storage/domains/intake/base.js +10 -2
  310. package/dist/storage/domains/intake/base.js.map +1 -1
  311. package/dist/storage/domains/integrations/base.js +1 -2
  312. package/dist/storage/domains/memory-settings/base.js +1 -2
  313. package/dist/storage/domains/model-defaults/base.js +1 -2
  314. package/dist/storage/domains/projects/base.d.ts +0 -1
  315. package/dist/storage/domains/projects/base.d.ts.map +1 -1
  316. package/dist/storage/domains/projects/base.js +5 -6
  317. package/dist/storage/domains/projects/base.js.map +1 -1
  318. package/dist/storage/domains/queue-health/base.js +1 -2
  319. package/dist/storage/domains/source-control/base.js +1 -2
  320. package/dist/storage/domains/source-control/inmemory.js +1 -2
  321. package/dist/storage/domains/work-items/base.js +1 -2
  322. package/dist/storage/domains/work-items/board-version.js +1 -2
  323. package/dist/storage/domains/work-items/metrics.js +1 -2
  324. package/dist/telemetry-types.js +1 -2
  325. package/dist/telemetry.js +1 -2
  326. package/dist/timing.js +1 -2
  327. package/dist/tools/annotations.js +1 -2
  328. package/dist/tools/approval-tools.js +1 -2
  329. package/dist/tools/deliver.js +2 -3
  330. package/dist/tools/index.js +1 -2
  331. package/dist/tools/messaging-tools.js +1 -2
  332. package/dist/tools/permissions.js +1 -2
  333. package/dist/tools/read-tools.js +1 -2
  334. package/dist/tools/reports.js +1 -2
  335. package/dist/tools/run-watch.d.ts +0 -2
  336. package/dist/tools/run-watch.d.ts.map +1 -1
  337. package/dist/tools/run-watch.js +4 -44
  338. package/dist/tools/run-watch.js.map +1 -1
  339. package/dist/tools/sandbox-tools.js +1 -2
  340. package/dist/tools/scope.js +2 -3
  341. package/dist/tools/session-tools.js +1 -2
  342. package/dist/tools/sessions-state-processor.js +1 -2
  343. package/dist/tools/side-sessions.js +1 -2
  344. package/dist/tools/work-item-tools.js +1 -2
  345. package/dist/work-item-branch.js +1 -2
  346. package/dist/work-item-branch.js.map +1 -1
  347. package/dist/work-items/create-work-item.js +1 -2
  348. package/dist/work-items/decision-actions.js +1 -2
  349. package/dist/workspace.d.ts.map +1 -1
  350. package/dist/workspace.js +1 -3
  351. package/dist/workspace.js.map +1 -1
  352. package/factory-skills/factory-gitlab-review/SKILL.md +1 -1
  353. package/factory-skills/factory-plan/SKILL.md +1 -1
  354. package/factory-skills/factory-rereview/SKILL.md +14 -3
  355. package/factory-skills/factory-review/SKILL.md +14 -3
  356. package/factory-skills/factory-self-review/SKILL.md +1 -1
  357. package/factory-skills/factory-triage/SKILL.md +52 -29
  358. package/package.json +19 -17
@@ -1,6 +1,6 @@
1
1
  import { createPlaintextFactorySecretEncryption } from "../../../secret-encryption.js";
2
2
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
3
- //#region src/storage/domains/credentials/base.ts
3
+ // src/storage/domains/credentials/base.ts
4
4
  /** Mirror of `AuthStorage.getApiKey()`'s expiry check. */
5
5
  function isOAuthCredentialExpired(credential, now = Date.now()) {
6
6
  return now >= credential.expires;
@@ -18,7 +18,11 @@ const MODEL_CREDENTIALS_SCHEMA = {
18
18
  type: { type: "text" },
19
19
  data: { type: "json" },
20
20
  created_at: { type: "timestamp" },
21
- updated_at: { type: "timestamp" }
21
+ updated_at: { type: "timestamp" },
22
+ refresh_failed_at: {
23
+ type: "timestamp",
24
+ nullable: true
25
+ }
22
26
  },
23
27
  uniqueIndexes: [{
24
28
  name: "model_provider_credentials_user_unique",
@@ -107,6 +111,15 @@ var ModelCredentialsStorage = class extends FactoryStorageDomain {
107
111
  async #decryptCredential(value) {
108
112
  return (await this.encryption.decrypt(value)).value;
109
113
  }
114
+ async #toRecord(row, scope) {
115
+ return {
116
+ provider: row.provider,
117
+ scope,
118
+ credential: await this.#decryptCredential(row.data),
119
+ updatedAt: row.updated_at,
120
+ refreshFailedAt: row.refresh_failed_at ?? void 0
121
+ };
122
+ }
110
123
  async #migrateCredential(id) {
111
124
  await this.#db.updateAtomic("model_provider_credentials", { id }, async (row) => {
112
125
  const decrypted = await this.encryption.decrypt(row.data);
@@ -126,7 +139,8 @@ var ModelCredentialsStorage = class extends FactoryStorageDomain {
126
139
  const update = async () => this.#db.updateMany("model_provider_credentials", where, {
127
140
  type: credential.type,
128
141
  data: encrypted,
129
- updated_at: /* @__PURE__ */ new Date()
142
+ updated_at: /* @__PURE__ */ new Date(),
143
+ refresh_failed_at: null
130
144
  });
131
145
  let lastError;
132
146
  for (let attempt = 0; attempt < 2; attempt++) {
@@ -163,45 +177,20 @@ var ModelCredentialsStorage = class extends FactoryStorageDomain {
163
177
  org_id: orgId,
164
178
  user_id: null
165
179
  })]);
166
- return Promise.all([...userRows.map(async (row) => ({
167
- provider: row.provider,
168
- scope: "user",
169
- credential: await this.#decryptCredential(row.data),
170
- updatedAt: row.updated_at
171
- })), ...orgRows.map(async (row) => ({
172
- provider: row.provider,
173
- scope: "org",
174
- credential: await this.#decryptCredential(row.data),
175
- updatedAt: row.updated_at
176
- }))]);
180
+ return Promise.all([...userRows.map((row) => this.#toRecord(row, "user")), ...orgRows.map((row) => this.#toRecord(row, "org"))]);
177
181
  }
178
182
  /** Resolve a provider credential from exactly one tenancy scope. */
179
183
  async resolveCredential(orgId, userId, provider, scope) {
180
- const readUser = async () => {
181
- const row = await this.#db.findOne("model_provider_credentials", {
182
- org_id: orgId,
183
- provider,
184
- user_id: userId
185
- });
186
- return row ? {
187
- provider: row.provider,
188
- scope: "user",
189
- credential: await this.#decryptCredential(row.data)
190
- } : void 0;
184
+ const tenant = scope === "org" ? { orgId } : {
185
+ orgId,
186
+ userId
191
187
  };
192
- const readOrg = async () => {
193
- const row = await this.#db.findOne("model_provider_credentials", {
194
- org_id: orgId,
195
- provider,
196
- user_id: null
197
- });
198
- return row ? {
199
- provider: row.provider,
200
- scope: "org",
201
- credential: await this.#decryptCredential(row.data)
202
- } : void 0;
203
- };
204
- return scope === "org" ? readOrg() : readUser();
188
+ const row = await this.#db.findOne("model_provider_credentials", tenantWhere(tenant, provider));
189
+ return row ? {
190
+ provider: row.provider,
191
+ scope,
192
+ credential: await this.#decryptCredential(row.data)
193
+ } : void 0;
205
194
  }
206
195
  /**
207
196
  * Refresh the tenant's OAuth credential under the backend's atomic
@@ -209,10 +198,12 @@ var ModelCredentialsStorage = class extends FactoryStorageDomain {
209
198
  * rotating refresh tokens. The expiry is re-checked under the lock —
210
199
  * another replica may have refreshed already, in which case `refreshFn` is
211
200
  * skipped and the fresh credential is returned. Returns `undefined` when no
212
- * OAuth row exists for the tenant.
201
+ * OAuth row exists for the tenant. A failed `refreshFn` is recorded on the
202
+ * row (surfaced as `CredentialRecord.refreshFailedAt`) and rethrown.
213
203
  */
214
204
  async refreshOAuth(tenant, provider, refreshFn) {
215
205
  let result;
206
+ let failure;
216
207
  await this.#db.updateAtomic("model_provider_credentials", tenantWhere(tenant, provider), async (row) => {
217
208
  const decrypted = await this.encryption.decrypt(row.data);
218
209
  if (decrypted.value.type !== "oauth") return null;
@@ -221,13 +212,19 @@ var ModelCredentialsStorage = class extends FactoryStorageDomain {
221
212
  result = current;
222
213
  return decrypted.needsReencryption ? { data: await this.encryption.encrypt(current) } : null;
223
214
  }
224
- const next = await refreshFn(current);
225
- result = next;
215
+ try {
216
+ result = await refreshFn(current);
217
+ } catch (error) {
218
+ failure = { error };
219
+ return { refresh_failed_at: /* @__PURE__ */ new Date() };
220
+ }
226
221
  return {
227
- data: await this.encryption.encrypt(next),
228
- updated_at: /* @__PURE__ */ new Date()
222
+ data: await this.encryption.encrypt(result),
223
+ updated_at: /* @__PURE__ */ new Date(),
224
+ refresh_failed_at: null
229
225
  };
230
226
  });
227
+ if (failure) throw failure.error;
231
228
  return result;
232
229
  }
233
230
  /** Persist a pending login flow started by a web route. */
@@ -288,7 +285,6 @@ var ModelCredentialsStorage = class extends FactoryStorageDomain {
288
285
  await this.#db.deleteMany("oauth_login_sessions", { session_id: sessionId });
289
286
  }
290
287
  };
291
- //#endregion
292
288
  export { MODEL_CREDENTIALS_SCHEMA, ModelCredentialsStorage, OAUTH_LOGIN_SESSIONS_SCHEMA, isOAuthCredentialExpired };
293
289
 
294
290
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/credentials/base.ts"],"sourcesContent":["/**\n * Model provider credentials domain — tenant-scoped OAuth tokens and API keys\n * for model providers (Anthropic/Claude Max, OpenAI Codex, GitHub Copilot,\n * xAI, plus plain API-key providers).\n *\n * Tenancy is two-level:\n * - **user-scoped** rows (`userId` present): personal plan OAuth tokens and\n * personal API keys. OAuth plan tokens are ONLY ever user-scoped — they are\n * personal subscriptions, and sharing one would bill/rate-limit a single\n * account for the whole org.\n * - **org-scoped** rows (`userId` absent): shared API keys set by an org\n * admin, inherited by every member.\n *\n * Model calls resolve exactly one scope: user or org. Deployed tenant stores\n * never fall back to the other scope or implicitly borrow server environment keys.\n *\n * Secrets posture: credentials are stored server-side only and never returned\n * to the client (same as `linear_connections.access_token`). Encryption at\n * rest is out of scope, matching the existing posture.\n *\n * The domain also owns `oauth_login_sessions`: pending web login flows\n * (paste-code PKCE verifiers, device-code poll state) persisted server-side so\n * any replica can complete or poll a flow started on another.\n */\n\nimport type { AuthCredential, OAuthCredential } from '@mastra/code-sdk/auth/types';\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, CollectionWhere, FactoryStorageOps } from '@mastra/core/storage';\nimport { createPlaintextFactorySecretEncryption } from '../../../secret-encryption.js';\nimport type { FactorySecretEncryption } from '../../../secret-encryption.js';\n\n/** Owning tenant of a credential row. `userId` absent = org-scoped row. */\nexport interface CredentialTenant {\n orgId: string;\n userId?: string;\n}\n\n/** Which tenancy level a credential row lives at. */\nexport type CredentialScope = 'user' | 'org';\n\n/** One stored credential, annotated with its scope. */\nexport interface CredentialRecord {\n provider: string;\n scope: CredentialScope;\n credential: AuthCredential;\n updatedAt: Date;\n}\n\n/** Result of per-caller resolution: the winning credential and its scope. */\nexport interface ResolvedCredential {\n provider: string;\n scope: CredentialScope;\n credential: AuthCredential;\n}\n\n/** Kind of pending web login flow a session row tracks. */\nexport type LoginSessionKind = 'paste-code' | 'device-code';\n\n/** Scope the completed credential should be written to. */\nexport type LoginCredentialScope = 'user' | 'org';\n\n/** One pending OAuth login flow, persisted so any replica can continue it. */\nexport interface LoginSessionRow {\n sessionId: string;\n orgId: string;\n userId: string;\n provider: string;\n kind: LoginSessionKind;\n /** Where the completed credential lands; absent rows default to `'user'`. */\n credentialScope?: LoginCredentialScope;\n /** Serialized flow state (PKCE verifier, device-code pending state, ...). */\n pending: Record<string, unknown>;\n expiresAt: Date;\n /** Earliest time the next upstream poll is allowed (device-code flows). */\n nextPollAt: Date | null;\n createdAt: Date;\n}\n\nexport interface CreateLoginSessionInput {\n sessionId: string;\n orgId: string;\n userId: string;\n provider: string;\n kind: LoginSessionKind;\n credentialScope?: LoginCredentialScope;\n pending: Record<string, unknown>;\n expiresAt: Date;\n nextPollAt?: Date | null;\n}\n\n/** Mirror of `AuthStorage.getApiKey()`'s expiry check. */\nexport function isOAuthCredentialExpired(credential: OAuthCredential, now = Date.now()): boolean {\n return now >= credential.expires;\n}\n\nexport const MODEL_CREDENTIALS_SCHEMA: CollectionSchema = {\n name: 'model_provider_credentials',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text', nullable: true },\n provider: { type: 'text' },\n type: { type: 'text' },\n data: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n // Scope is encoded in `user_id` nullability (NULL = org-scoped shared\n // row), enforced by two partial unique indexes.\n {\n name: 'model_provider_credentials_user_unique',\n columns: ['org_id', 'user_id', 'provider'],\n whereNotNull: 'user_id',\n },\n { name: 'model_provider_credentials_org_unique', columns: ['org_id', 'provider'], whereNull: 'user_id' },\n ],\n};\n\nexport const OAUTH_LOGIN_SESSIONS_SCHEMA: CollectionSchema = {\n name: 'oauth_login_sessions',\n columns: {\n session_id: { type: 'text', primaryKey: true },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n provider: { type: 'text' },\n kind: { type: 'text' },\n credential_scope: { type: 'text', nullable: true },\n pending: { type: 'json' },\n expires_at: { type: 'timestamp' },\n next_poll_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n },\n};\n\n/** Column shape of one `model_provider_credentials` row as returned by ops. */\ninterface CredentialDbRow extends Record<string, unknown> {\n id: string;\n provider: string;\n user_id: string | null;\n data: unknown;\n updated_at: Date;\n}\n\n/** Column shape of one `oauth_login_sessions` row as returned by ops. */\ninterface LoginSessionDbRow extends Record<string, unknown> {\n session_id: string;\n org_id: string;\n user_id: string;\n provider: string;\n kind: LoginSessionKind;\n credential_scope: LoginCredentialScope | null;\n pending: Record<string, unknown>;\n expires_at: Date;\n next_poll_at: Date | null;\n created_at: Date;\n}\n\nfunction toSessionRow(db: LoginSessionDbRow): LoginSessionRow {\n return {\n sessionId: db.session_id,\n orgId: db.org_id,\n userId: db.user_id,\n provider: db.provider,\n kind: db.kind,\n ...(db.credential_scope ? { credentialScope: db.credential_scope } : {}),\n pending: db.pending,\n expiresAt: db.expires_at,\n nextPollAt: db.next_poll_at,\n createdAt: db.created_at,\n };\n}\n\n/** Filter selecting exactly the tenant's row for a provider (`null` = org row). */\nfunction tenantWhere(tenant: CredentialTenant, provider: string): CollectionWhere {\n return { org_id: tenant.orgId, provider, user_id: tenant.userId ?? null };\n}\n\n/**\n * Model-credentials storage, written once against the generic\n * `FactoryStorageOps` surface. `refreshOAuth()` and `claimLoginSession()`\n * ride `updateAtomic` so concurrent replicas serialize instead of\n * invalidating each other's rotating tokens / double-claiming a flow.\n */\nexport class ModelCredentialsStorage extends FactoryStorageDomain {\n constructor(private readonly encryption: FactorySecretEncryption = createPlaintextFactorySecretEncryption()) {\n super('model-credentials');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MODEL_CREDENTIALS_SCHEMA, OAUTH_LOGIN_SESSIONS_SCHEMA]);\n const rows = await this.ops.findMany<CredentialDbRow>('model_provider_credentials', {});\n await Promise.all(rows.map(row => this.#migrateCredential(row.id)));\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('oauth_login_sessions', {});\n await this.ops.deleteMany('model_provider_credentials', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async #decryptCredential(value: unknown): Promise<AuthCredential> {\n return (await this.encryption.decrypt<AuthCredential>(value)).value;\n }\n\n async #migrateCredential(id: string): Promise<void> {\n await this.#db.updateAtomic<CredentialDbRow>('model_provider_credentials', { id }, async row => {\n const decrypted = await this.encryption.decrypt<AuthCredential>(row.data);\n if (!decrypted.needsReencryption) return null;\n return { data: await this.encryption.encrypt(decrypted.value) };\n });\n }\n\n /** Read the tenant's credential for a provider at exactly that scope. */\n async getCredential(tenant: CredentialTenant, provider: string): Promise<AuthCredential | undefined> {\n const row = await this.#db.findOne<CredentialDbRow>('model_provider_credentials', tenantWhere(tenant, provider));\n return row ? this.#decryptCredential(row.data) : undefined;\n }\n\n /** Upsert the tenant's credential (`created_at` is preserved on update). */\n async setCredential(tenant: CredentialTenant, provider: string, credential: AuthCredential): Promise<void> {\n const where = tenantWhere(tenant, provider);\n const encrypted = await this.encryption.encrypt(credential);\n const update = async () =>\n this.#db.updateMany('model_provider_credentials', where, {\n type: credential.type,\n data: encrypted,\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await this.#db.insertOne<CredentialDbRow>('model_provider_credentials', {\n org_id: tenant.orgId,\n user_id: tenant.userId ?? null,\n provider,\n type: credential.type,\n data: encrypted,\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n }\n\n /** Delete the tenant's credential at exactly that scope. True when a row was removed. */\n async removeCredential(tenant: CredentialTenant, provider: string): Promise<boolean> {\n const deleted = await this.#db.deleteMany('model_provider_credentials', tenantWhere(tenant, provider));\n return deleted > 0;\n }\n\n /** All credentials visible to a user: their own rows plus the org's shared rows. */\n async listCredentials(orgId: string, userId: string): Promise<CredentialRecord[]> {\n // SQL `IN` never matches NULL, so the org rows need their own query.\n const [userRows, orgRows] = await Promise.all([\n this.#db.findMany<CredentialDbRow>('model_provider_credentials', { org_id: orgId, user_id: userId }),\n this.#db.findMany<CredentialDbRow>('model_provider_credentials', { org_id: orgId, user_id: null }),\n ]);\n return Promise.all([\n ...userRows.map(async row => ({\n provider: row.provider,\n scope: 'user' as const,\n credential: await this.#decryptCredential(row.data),\n updatedAt: row.updated_at,\n })),\n ...orgRows.map(async row => ({\n provider: row.provider,\n scope: 'org' as const,\n credential: await this.#decryptCredential(row.data),\n updatedAt: row.updated_at,\n })),\n ]);\n }\n\n /** Resolve a provider credential from exactly one tenancy scope. */\n async resolveCredential(\n orgId: string,\n userId: string,\n provider: string,\n scope: CredentialScope,\n ): Promise<ResolvedCredential | undefined> {\n const readUser = async (): Promise<ResolvedCredential | undefined> => {\n const row = await this.#db.findOne<CredentialDbRow>('model_provider_credentials', {\n org_id: orgId,\n provider,\n user_id: userId,\n });\n return row\n ? { provider: row.provider, scope: 'user', credential: await this.#decryptCredential(row.data) }\n : undefined;\n };\n const readOrg = async (): Promise<ResolvedCredential | undefined> => {\n const row = await this.#db.findOne<CredentialDbRow>('model_provider_credentials', {\n org_id: orgId,\n provider,\n user_id: null,\n });\n return row\n ? { provider: row.provider, scope: 'org', credential: await this.#decryptCredential(row.data) }\n : undefined;\n };\n return scope === 'org' ? readOrg() : readUser();\n }\n\n /**\n * Refresh the tenant's OAuth credential under the backend's atomic\n * read-modify-write so concurrent replicas don't invalidate each other's\n * rotating refresh tokens. The expiry is re-checked under the lock —\n * another replica may have refreshed already, in which case `refreshFn` is\n * skipped and the fresh credential is returned. Returns `undefined` when no\n * OAuth row exists for the tenant.\n */\n async refreshOAuth(\n tenant: CredentialTenant,\n provider: string,\n refreshFn: (current: OAuthCredential) => Promise<OAuthCredential>,\n ): Promise<OAuthCredential | undefined> {\n let result: OAuthCredential | undefined;\n await this.#db.updateAtomic<CredentialDbRow>(\n 'model_provider_credentials',\n tenantWhere(tenant, provider),\n async row => {\n const decrypted = await this.encryption.decrypt<AuthCredential>(row.data);\n if (decrypted.value.type !== 'oauth') return null;\n const current = decrypted.value;\n // Re-check under the lock: another replica may have refreshed while we waited.\n if (!isOAuthCredentialExpired(current)) {\n result = current;\n return decrypted.needsReencryption ? { data: await this.encryption.encrypt(current) } : null;\n }\n const next = await refreshFn(current);\n result = next;\n return { data: await this.encryption.encrypt(next), updated_at: new Date() };\n },\n );\n return result;\n }\n\n /** Persist a pending login flow started by a web route. */\n async createLoginSession(input: CreateLoginSessionInput): Promise<LoginSessionRow> {\n const inserted = await this.#db.insertOne<LoginSessionDbRow>('oauth_login_sessions', {\n session_id: input.sessionId,\n org_id: input.orgId,\n user_id: input.userId,\n provider: input.provider,\n kind: input.kind,\n credential_scope: input.credentialScope ?? null,\n pending: input.pending,\n expires_at: input.expiresAt,\n next_poll_at: input.nextPollAt ?? null,\n created_at: new Date(),\n });\n return toSessionRow(inserted);\n }\n\n /**\n * Read a pending login flow. An expired session is deleted on read (TTL\n * cleanup) and reported as absent.\n */\n async getLoginSession(sessionId: string): Promise<LoginSessionRow | undefined> {\n const row = await this.#db.findOne<LoginSessionDbRow>('oauth_login_sessions', { session_id: sessionId });\n if (!row) return undefined;\n if (row.expires_at.getTime() <= Date.now()) {\n await this.#db.deleteMany('oauth_login_sessions', { session_id: sessionId });\n return undefined;\n }\n return toSessionRow(row);\n }\n\n /**\n * Atomically claim a due login session for one upstream completion/poll attempt.\n * Returns undefined when the session is missing, expired, owned by another\n * tenant/provider, or already claimed by a concurrent request.\n */\n async claimLoginSession(\n sessionId: string,\n owner: Pick<LoginSessionRow, 'orgId' | 'userId' | 'provider' | 'kind'>,\n ): Promise<LoginSessionRow | undefined> {\n const now = Date.now();\n let claimed = false;\n const updated = await this.#db.updateAtomic<LoginSessionDbRow>(\n 'oauth_login_sessions',\n { session_id: sessionId },\n row => {\n if (\n row.org_id !== owner.orgId ||\n row.user_id !== owner.userId ||\n row.provider !== owner.provider ||\n row.kind !== owner.kind\n ) {\n return null;\n }\n if (row.expires_at.getTime() <= now) return null;\n if (row.next_poll_at && row.next_poll_at.getTime() > now) return null;\n claimed = true;\n // Park the next poll at expiry so a concurrent claim loses until the\n // claimer either touches the session forward or deletes it.\n return { next_poll_at: row.expires_at };\n },\n );\n return claimed && updated ? toSessionRow(updated) : undefined;\n }\n\n /** Update a pending flow's serialized state and/or next allowed poll time. */\n async touchLoginSession(\n sessionId: string,\n updates: { pending?: Record<string, unknown>; nextPollAt?: Date | null },\n ): Promise<void> {\n const set: Record<string, unknown> = {};\n if (updates.pending !== undefined) set.pending = updates.pending;\n if (updates.nextPollAt !== undefined) set.next_poll_at = updates.nextPollAt;\n if (Object.keys(set).length === 0) return;\n await this.#db.updateMany('oauth_login_sessions', { session_id: sessionId }, set);\n }\n\n /** Remove a pending login flow (completed, cancelled, or failed). */\n async deleteLoginSession(sessionId: string): Promise<void> {\n await this.#db.deleteMany('oauth_login_sessions', { session_id: sessionId });\n }\n}\n"],"mappings":";;;;AA2FA,SAAgB,yBAAyB,YAA6B,MAAM,KAAK,IAAI,GAAY;CAC/F,OAAO,OAAO,WAAW;AAC3B;AAEA,MAAa,2BAA6C;CACxD,MAAM;CACN,SAAS;EACP,IAAI,EAAE,MAAM,UAAU;EACtB,QAAQ,EAAE,MAAM,OAAO;EACvB,SAAS;GAAE,MAAM;GAAQ,UAAU;EAAK;EACxC,UAAU,EAAE,MAAM,OAAO;EACzB,MAAM,EAAE,MAAM,OAAO;EACrB,MAAM,EAAE,MAAM,OAAO;EACrB,YAAY,EAAE,MAAM,YAAY;EAChC,YAAY,EAAE,MAAM,YAAY;CAClC;CACA,eAAe,CAGb;EACE,MAAM;EACN,SAAS;GAAC;GAAU;GAAW;EAAU;EACzC,cAAc;CAChB,GACA;EAAE,MAAM;EAAyC,SAAS,CAAC,UAAU,UAAU;EAAG,WAAW;CAAU,CACzG;AACF;AAEA,MAAa,8BAAgD;CAC3D,MAAM;CACN,SAAS;EACP,YAAY;GAAE,MAAM;GAAQ,YAAY;EAAK;EAC7C,QAAQ,EAAE,MAAM,OAAO;EACvB,SAAS,EAAE,MAAM,OAAO;EACxB,UAAU,EAAE,MAAM,OAAO;EACzB,MAAM,EAAE,MAAM,OAAO;EACrB,kBAAkB;GAAE,MAAM;GAAQ,UAAU;EAAK;EACjD,SAAS,EAAE,MAAM,OAAO;EACxB,YAAY,EAAE,MAAM,YAAY;EAChC,cAAc;GAAE,MAAM;GAAa,UAAU;EAAK;EAClD,YAAY,EAAE,MAAM,YAAY;CAClC;AACF;AAyBA,SAAS,aAAa,IAAwC;CAC5D,OAAO;EACL,WAAW,GAAG;EACd,OAAO,GAAG;EACV,QAAQ,GAAG;EACX,UAAU,GAAG;EACb,MAAM,GAAG;EACT,GAAI,GAAG,mBAAmB,EAAE,iBAAiB,GAAG,iBAAiB,IAAI,CAAC;EACtE,SAAS,GAAG;EACZ,WAAW,GAAG;EACd,YAAY,GAAG;EACf,WAAW,GAAG;CAChB;AACF;;AAGA,SAAS,YAAY,QAA0B,UAAmC;CAChF,OAAO;EAAE,QAAQ,OAAO;EAAO;EAAU,SAAS,OAAO,UAAU;CAAK;AAC1E;;;;;;;AAQA,IAAa,0BAAb,cAA6C,qBAAqB;CACnC;CAA7B,YAAY,aAAuD,uCAAuC,GAAG;EAC3G,MAAM,mBAAmB;EADE,KAAA,aAAA;CAE7B;CAEA,MAAM,OAAsB;EAC1B,MAAM,KAAK,kBAAkB,CAAC,0BAA0B,2BAA2B,CAAC;EACpF,MAAM,OAAO,MAAM,KAAK,IAAI,SAA0B,8BAA8B,CAAC,CAAC;EACtF,MAAM,QAAQ,IAAI,KAAK,KAAI,QAAO,KAAK,mBAAmB,IAAI,EAAE,CAAC,CAAC;CACpE;CAEA,MAAM,sBAAqC;EACzC,MAAM,KAAK,IAAI,WAAW,wBAAwB,CAAC,CAAC;EACpD,MAAM,KAAK,IAAI,WAAW,8BAA8B,CAAC,CAAC;CAC5D;CAEA,IAAI,MAAyB;EAC3B,OAAO,KAAK;CACd;CAEA,MAAM,mBAAmB,OAAyC;EAChE,QAAQ,MAAM,KAAK,WAAW,QAAwB,KAAK,EAAA,CAAG;CAChE;CAEA,MAAM,mBAAmB,IAA2B;EAClD,MAAM,KAAK,IAAI,aAA8B,8BAA8B,EAAE,GAAG,GAAG,OAAM,QAAO;GAC9F,MAAM,YAAY,MAAM,KAAK,WAAW,QAAwB,IAAI,IAAI;GACxE,IAAI,CAAC,UAAU,mBAAmB,OAAO;GACzC,OAAO,EAAE,MAAM,MAAM,KAAK,WAAW,QAAQ,UAAU,KAAK,EAAE;EAChE,CAAC;CACH;;CAGA,MAAM,cAAc,QAA0B,UAAuD;EACnG,MAAM,MAAM,MAAM,KAAK,IAAI,QAAyB,8BAA8B,YAAY,QAAQ,QAAQ,CAAC;EAC/G,OAAO,MAAM,KAAK,mBAAmB,IAAI,IAAI,IAAI,KAAA;CACnD;;CAGA,MAAM,cAAc,QAA0B,UAAkB,YAA2C;EACzG,MAAM,QAAQ,YAAY,QAAQ,QAAQ;EAC1C,MAAM,YAAY,MAAM,KAAK,WAAW,QAAQ,UAAU;EAC1D,MAAM,SAAS,YACb,KAAK,IAAI,WAAW,8BAA8B,OAAO;GACvD,MAAM,WAAW;GACjB,MAAM;GACN,4BAAY,IAAI,KAAK;EACvB,CAAC;EAEH,IAAI;EACJ,KAAK,IAAI,UAAU,GAAG,UAAU,GAAG,WAAW;GAC5C,IAAK,MAAM,OAAO,IAAK,GAAG;GAE1B,MAAM,sBAAM,IAAI,KAAK;GACrB,IAAI;IACF,MAAM,KAAK,IAAI,UAA2B,8BAA8B;KACtE,QAAQ,OAAO;KACf,SAAS,OAAO,UAAU;KAC1B;KACA,MAAM,WAAW;KACjB,MAAM;KACN,YAAY;KACZ,YAAY;IACd,CAAC;IACD;GACF,SAAS,OAAO;IACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;IACpD,YAAY;GACd;EACF;EACA,MAAM;CACR;;CAGA,MAAM,iBAAiB,QAA0B,UAAoC;EAEnF,OAAO,MADe,KAAK,IAAI,WAAW,8BAA8B,YAAY,QAAQ,QAAQ,CAAC,IACpF;CACnB;;CAGA,MAAM,gBAAgB,OAAe,QAA6C;EAEhF,MAAM,CAAC,UAAU,WAAW,MAAM,QAAQ,IAAI,CAC5C,KAAK,IAAI,SAA0B,8BAA8B;GAAE,QAAQ;GAAO,SAAS;EAAO,CAAC,GACnG,KAAK,IAAI,SAA0B,8BAA8B;GAAE,QAAQ;GAAO,SAAS;EAAK,CAAC,CACnG,CAAC;EACD,OAAO,QAAQ,IAAI,CACjB,GAAG,SAAS,IAAI,OAAM,SAAQ;GAC5B,UAAU,IAAI;GACd,OAAO;GACP,YAAY,MAAM,KAAK,mBAAmB,IAAI,IAAI;GAClD,WAAW,IAAI;EACjB,EAAE,GACF,GAAG,QAAQ,IAAI,OAAM,SAAQ;GAC3B,UAAU,IAAI;GACd,OAAO;GACP,YAAY,MAAM,KAAK,mBAAmB,IAAI,IAAI;GAClD,WAAW,IAAI;EACjB,EAAE,CACJ,CAAC;CACH;;CAGA,MAAM,kBACJ,OACA,QACA,UACA,OACyC;EACzC,MAAM,WAAW,YAAqD;GACpE,MAAM,MAAM,MAAM,KAAK,IAAI,QAAyB,8BAA8B;IAChF,QAAQ;IACR;IACA,SAAS;GACX,CAAC;GACD,OAAO,MACH;IAAE,UAAU,IAAI;IAAU,OAAO;IAAQ,YAAY,MAAM,KAAK,mBAAmB,IAAI,IAAI;GAAE,IAC7F,KAAA;EACN;EACA,MAAM,UAAU,YAAqD;GACnE,MAAM,MAAM,MAAM,KAAK,IAAI,QAAyB,8BAA8B;IAChF,QAAQ;IACR;IACA,SAAS;GACX,CAAC;GACD,OAAO,MACH;IAAE,UAAU,IAAI;IAAU,OAAO;IAAO,YAAY,MAAM,KAAK,mBAAmB,IAAI,IAAI;GAAE,IAC5F,KAAA;EACN;EACA,OAAO,UAAU,QAAQ,QAAQ,IAAI,SAAS;CAChD;;;;;;;;;CAUA,MAAM,aACJ,QACA,UACA,WACsC;EACtC,IAAI;EACJ,MAAM,KAAK,IAAI,aACb,8BACA,YAAY,QAAQ,QAAQ,GAC5B,OAAM,QAAO;GACX,MAAM,YAAY,MAAM,KAAK,WAAW,QAAwB,IAAI,IAAI;GACxE,IAAI,UAAU,MAAM,SAAS,SAAS,OAAO;GAC7C,MAAM,UAAU,UAAU;GAE1B,IAAI,CAAC,yBAAyB,OAAO,GAAG;IACtC,SAAS;IACT,OAAO,UAAU,oBAAoB,EAAE,MAAM,MAAM,KAAK,WAAW,QAAQ,OAAO,EAAE,IAAI;GAC1F;GACA,MAAM,OAAO,MAAM,UAAU,OAAO;GACpC,SAAS;GACT,OAAO;IAAE,MAAM,MAAM,KAAK,WAAW,QAAQ,IAAI;IAAG,4BAAY,IAAI,KAAK;GAAE;EAC7E,CACF;EACA,OAAO;CACT;;CAGA,MAAM,mBAAmB,OAA0D;EAajF,OAAO,aAAa,MAZG,KAAK,IAAI,UAA6B,wBAAwB;GACnF,YAAY,MAAM;GAClB,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,UAAU,MAAM;GAChB,MAAM,MAAM;GACZ,kBAAkB,MAAM,mBAAmB;GAC3C,SAAS,MAAM;GACf,YAAY,MAAM;GAClB,cAAc,MAAM,cAAc;GAClC,4BAAY,IAAI,KAAK;EACvB,CAAC,CAC2B;CAC9B;;;;;CAMA,MAAM,gBAAgB,WAAyD;EAC7E,MAAM,MAAM,MAAM,KAAK,IAAI,QAA2B,wBAAwB,EAAE,YAAY,UAAU,CAAC;EACvG,IAAI,CAAC,KAAK,OAAO,KAAA;EACjB,IAAI,IAAI,WAAW,QAAQ,KAAK,KAAK,IAAI,GAAG;GAC1C,MAAM,KAAK,IAAI,WAAW,wBAAwB,EAAE,YAAY,UAAU,CAAC;GAC3E;EACF;EACA,OAAO,aAAa,GAAG;CACzB;;;;;;CAOA,MAAM,kBACJ,WACA,OACsC;EACtC,MAAM,MAAM,KAAK,IAAI;EACrB,IAAI,UAAU;EACd,MAAM,UAAU,MAAM,KAAK,IAAI,aAC7B,wBACA,EAAE,YAAY,UAAU,IACxB,QAAO;GACL,IACE,IAAI,WAAW,MAAM,SACrB,IAAI,YAAY,MAAM,UACtB,IAAI,aAAa,MAAM,YACvB,IAAI,SAAS,MAAM,MAEnB,OAAO;GAET,IAAI,IAAI,WAAW,QAAQ,KAAK,KAAK,OAAO;GAC5C,IAAI,IAAI,gBAAgB,IAAI,aAAa,QAAQ,IAAI,KAAK,OAAO;GACjE,UAAU;GAGV,OAAO,EAAE,cAAc,IAAI,WAAW;EACxC,CACF;EACA,OAAO,WAAW,UAAU,aAAa,OAAO,IAAI,KAAA;CACtD;;CAGA,MAAM,kBACJ,WACA,SACe;EACf,MAAM,MAA+B,CAAC;EACtC,IAAI,QAAQ,YAAY,KAAA,GAAW,IAAI,UAAU,QAAQ;EACzD,IAAI,QAAQ,eAAe,KAAA,GAAW,IAAI,eAAe,QAAQ;EACjE,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC,WAAW,GAAG;EACnC,MAAM,KAAK,IAAI,WAAW,wBAAwB,EAAE,YAAY,UAAU,GAAG,GAAG;CAClF;;CAGA,MAAM,mBAAmB,WAAkC;EACzD,MAAM,KAAK,IAAI,WAAW,wBAAwB,EAAE,YAAY,UAAU,CAAC;CAC7E;AACF"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/credentials/base.ts"],"sourcesContent":["/**\n * Model provider credentials domain — tenant-scoped OAuth tokens and API keys\n * for model providers (Anthropic/Claude Max, OpenAI Codex, GitHub Copilot,\n * xAI, plus plain API-key providers).\n *\n * Tenancy is two-level:\n * - **user-scoped** rows (`userId` present): personal plan OAuth tokens and\n * personal API keys. OAuth plan tokens are ONLY ever user-scoped — they are\n * personal subscriptions, and sharing one would bill/rate-limit a single\n * account for the whole org.\n * - **org-scoped** rows (`userId` absent): shared API keys set by an org\n * admin, inherited by every member.\n *\n * Model calls resolve exactly one scope: user or org. Deployed tenant stores\n * never fall back to the other scope or implicitly borrow server environment keys.\n *\n * Secrets posture: credentials are stored server-side only and never returned\n * to the client (same as `linear_connections.access_token`). Encryption at\n * rest is out of scope, matching the existing posture.\n *\n * The domain also owns `oauth_login_sessions`: pending web login flows\n * (paste-code PKCE verifiers, device-code poll state) persisted server-side so\n * any replica can complete or poll a flow started on another.\n */\n\nimport type { AuthCredential, OAuthCredential } from '@mastra/code-sdk/auth/types';\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, CollectionWhere, FactoryStorageOps } from '@mastra/core/storage';\nimport { createPlaintextFactorySecretEncryption } from '../../../secret-encryption.js';\nimport type { FactorySecretEncryption } from '../../../secret-encryption.js';\n\n/** Owning tenant of a credential row. `userId` absent = org-scoped row. */\nexport interface CredentialTenant {\n orgId: string;\n userId?: string;\n}\n\n/** Which tenancy level a credential row lives at. */\nexport type CredentialScope = 'user' | 'org';\n\n/** One stored credential, annotated with its scope. */\nexport interface CredentialRecord {\n provider: string;\n scope: CredentialScope;\n credential: AuthCredential;\n updatedAt: Date;\n /** When the last OAuth token refresh failed; cleared by the next successful refresh or a new sign-in. */\n refreshFailedAt?: Date;\n}\n\n/** Result of per-caller resolution: the winning credential and its scope. */\nexport interface ResolvedCredential {\n provider: string;\n scope: CredentialScope;\n credential: AuthCredential;\n}\n\n/** Kind of pending web login flow a session row tracks. */\nexport type LoginSessionKind = 'paste-code' | 'device-code';\n\n/** Scope the completed credential should be written to. */\nexport type LoginCredentialScope = 'user' | 'org';\n\n/** One pending OAuth login flow, persisted so any replica can continue it. */\nexport interface LoginSessionRow {\n sessionId: string;\n orgId: string;\n userId: string;\n provider: string;\n kind: LoginSessionKind;\n /** Where the completed credential lands; absent rows default to `'user'`. */\n credentialScope?: LoginCredentialScope;\n /** Serialized flow state (PKCE verifier, device-code pending state, ...). */\n pending: Record<string, unknown>;\n expiresAt: Date;\n /** Earliest time the next upstream poll is allowed (device-code flows). */\n nextPollAt: Date | null;\n createdAt: Date;\n}\n\nexport interface CreateLoginSessionInput {\n sessionId: string;\n orgId: string;\n userId: string;\n provider: string;\n kind: LoginSessionKind;\n credentialScope?: LoginCredentialScope;\n pending: Record<string, unknown>;\n expiresAt: Date;\n nextPollAt?: Date | null;\n}\n\n/** Mirror of `AuthStorage.getApiKey()`'s expiry check. */\nexport function isOAuthCredentialExpired(credential: OAuthCredential, now = Date.now()): boolean {\n return now >= credential.expires;\n}\n\nexport const MODEL_CREDENTIALS_SCHEMA: CollectionSchema = {\n name: 'model_provider_credentials',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text', nullable: true },\n provider: { type: 'text' },\n type: { type: 'text' },\n data: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n refresh_failed_at: { type: 'timestamp', nullable: true },\n },\n uniqueIndexes: [\n // Scope is encoded in `user_id` nullability (NULL = org-scoped shared\n // row), enforced by two partial unique indexes.\n {\n name: 'model_provider_credentials_user_unique',\n columns: ['org_id', 'user_id', 'provider'],\n whereNotNull: 'user_id',\n },\n { name: 'model_provider_credentials_org_unique', columns: ['org_id', 'provider'], whereNull: 'user_id' },\n ],\n};\n\nexport const OAUTH_LOGIN_SESSIONS_SCHEMA: CollectionSchema = {\n name: 'oauth_login_sessions',\n columns: {\n session_id: { type: 'text', primaryKey: true },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n provider: { type: 'text' },\n kind: { type: 'text' },\n credential_scope: { type: 'text', nullable: true },\n pending: { type: 'json' },\n expires_at: { type: 'timestamp' },\n next_poll_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n },\n};\n\n/** Column shape of one `model_provider_credentials` row as returned by ops. */\ninterface CredentialDbRow extends Record<string, unknown> {\n id: string;\n provider: string;\n user_id: string | null;\n data: unknown;\n updated_at: Date;\n refresh_failed_at: Date | null;\n}\n\n/** Column shape of one `oauth_login_sessions` row as returned by ops. */\ninterface LoginSessionDbRow extends Record<string, unknown> {\n session_id: string;\n org_id: string;\n user_id: string;\n provider: string;\n kind: LoginSessionKind;\n credential_scope: LoginCredentialScope | null;\n pending: Record<string, unknown>;\n expires_at: Date;\n next_poll_at: Date | null;\n created_at: Date;\n}\n\nfunction toSessionRow(db: LoginSessionDbRow): LoginSessionRow {\n return {\n sessionId: db.session_id,\n orgId: db.org_id,\n userId: db.user_id,\n provider: db.provider,\n kind: db.kind,\n ...(db.credential_scope ? { credentialScope: db.credential_scope } : {}),\n pending: db.pending,\n expiresAt: db.expires_at,\n nextPollAt: db.next_poll_at,\n createdAt: db.created_at,\n };\n}\n\n/** Filter selecting exactly the tenant's row for a provider (`null` = org row). */\nfunction tenantWhere(tenant: CredentialTenant, provider: string): CollectionWhere {\n return { org_id: tenant.orgId, provider, user_id: tenant.userId ?? null };\n}\n\n/**\n * Model-credentials storage, written once against the generic\n * `FactoryStorageOps` surface. `refreshOAuth()` and `claimLoginSession()`\n * ride `updateAtomic` so concurrent replicas serialize instead of\n * invalidating each other's rotating tokens / double-claiming a flow.\n */\nexport class ModelCredentialsStorage extends FactoryStorageDomain {\n constructor(private readonly encryption: FactorySecretEncryption = createPlaintextFactorySecretEncryption()) {\n super('model-credentials');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MODEL_CREDENTIALS_SCHEMA, OAUTH_LOGIN_SESSIONS_SCHEMA]);\n const rows = await this.ops.findMany<CredentialDbRow>('model_provider_credentials', {});\n await Promise.all(rows.map(row => this.#migrateCredential(row.id)));\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('oauth_login_sessions', {});\n await this.ops.deleteMany('model_provider_credentials', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async #decryptCredential(value: unknown): Promise<AuthCredential> {\n return (await this.encryption.decrypt<AuthCredential>(value)).value;\n }\n\n async #toRecord(row: CredentialDbRow, scope: CredentialScope): Promise<CredentialRecord> {\n return {\n provider: row.provider,\n scope,\n credential: await this.#decryptCredential(row.data),\n updatedAt: row.updated_at,\n refreshFailedAt: row.refresh_failed_at ?? undefined,\n };\n }\n\n async #migrateCredential(id: string): Promise<void> {\n await this.#db.updateAtomic<CredentialDbRow>('model_provider_credentials', { id }, async row => {\n const decrypted = await this.encryption.decrypt<AuthCredential>(row.data);\n if (!decrypted.needsReencryption) return null;\n return { data: await this.encryption.encrypt(decrypted.value) };\n });\n }\n\n /** Read the tenant's credential for a provider at exactly that scope. */\n async getCredential(tenant: CredentialTenant, provider: string): Promise<AuthCredential | undefined> {\n const row = await this.#db.findOne<CredentialDbRow>('model_provider_credentials', tenantWhere(tenant, provider));\n return row ? this.#decryptCredential(row.data) : undefined;\n }\n\n /** Upsert the tenant's credential (`created_at` is preserved on update). */\n async setCredential(tenant: CredentialTenant, provider: string, credential: AuthCredential): Promise<void> {\n const where = tenantWhere(tenant, provider);\n const encrypted = await this.encryption.encrypt(credential);\n const update = async () =>\n this.#db.updateMany('model_provider_credentials', where, {\n type: credential.type,\n data: encrypted,\n updated_at: new Date(),\n refresh_failed_at: null,\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await this.#db.insertOne<CredentialDbRow>('model_provider_credentials', {\n org_id: tenant.orgId,\n user_id: tenant.userId ?? null,\n provider,\n type: credential.type,\n data: encrypted,\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n }\n\n /** Delete the tenant's credential at exactly that scope. True when a row was removed. */\n async removeCredential(tenant: CredentialTenant, provider: string): Promise<boolean> {\n const deleted = await this.#db.deleteMany('model_provider_credentials', tenantWhere(tenant, provider));\n return deleted > 0;\n }\n\n /** All credentials visible to a user: their own rows plus the org's shared rows. */\n async listCredentials(orgId: string, userId: string): Promise<CredentialRecord[]> {\n // SQL `IN` never matches NULL, so the org rows need their own query.\n const [userRows, orgRows] = await Promise.all([\n this.#db.findMany<CredentialDbRow>('model_provider_credentials', { org_id: orgId, user_id: userId }),\n this.#db.findMany<CredentialDbRow>('model_provider_credentials', { org_id: orgId, user_id: null }),\n ]);\n return Promise.all([\n ...userRows.map(row => this.#toRecord(row, 'user')),\n ...orgRows.map(row => this.#toRecord(row, 'org')),\n ]);\n }\n\n /** Resolve a provider credential from exactly one tenancy scope. */\n async resolveCredential(\n orgId: string,\n userId: string,\n provider: string,\n scope: CredentialScope,\n ): Promise<ResolvedCredential | undefined> {\n const tenant = scope === 'org' ? { orgId } : { orgId, userId };\n const row = await this.#db.findOne<CredentialDbRow>('model_provider_credentials', tenantWhere(tenant, provider));\n return row ? { provider: row.provider, scope, credential: await this.#decryptCredential(row.data) } : undefined;\n }\n\n /**\n * Refresh the tenant's OAuth credential under the backend's atomic\n * read-modify-write so concurrent replicas don't invalidate each other's\n * rotating refresh tokens. The expiry is re-checked under the lock —\n * another replica may have refreshed already, in which case `refreshFn` is\n * skipped and the fresh credential is returned. Returns `undefined` when no\n * OAuth row exists for the tenant. A failed `refreshFn` is recorded on the\n * row (surfaced as `CredentialRecord.refreshFailedAt`) and rethrown.\n */\n async refreshOAuth(\n tenant: CredentialTenant,\n provider: string,\n refreshFn: (current: OAuthCredential) => Promise<OAuthCredential>,\n ): Promise<OAuthCredential | undefined> {\n let result: OAuthCredential | undefined;\n let failure: { error: unknown } | undefined;\n await this.#db.updateAtomic<CredentialDbRow>(\n 'model_provider_credentials',\n tenantWhere(tenant, provider),\n async row => {\n const decrypted = await this.encryption.decrypt<AuthCredential>(row.data);\n if (decrypted.value.type !== 'oauth') return null;\n const current = decrypted.value;\n // Re-check under the lock: another replica may have refreshed while we waited.\n if (!isOAuthCredentialExpired(current)) {\n result = current;\n return decrypted.needsReencryption ? { data: await this.encryption.encrypt(current) } : null;\n }\n try {\n result = await refreshFn(current);\n } catch (error) {\n failure = { error };\n return { refresh_failed_at: new Date() };\n }\n return { data: await this.encryption.encrypt(result), updated_at: new Date(), refresh_failed_at: null };\n },\n );\n if (failure) throw failure.error;\n return result;\n }\n\n /** Persist a pending login flow started by a web route. */\n async createLoginSession(input: CreateLoginSessionInput): Promise<LoginSessionRow> {\n const inserted = await this.#db.insertOne<LoginSessionDbRow>('oauth_login_sessions', {\n session_id: input.sessionId,\n org_id: input.orgId,\n user_id: input.userId,\n provider: input.provider,\n kind: input.kind,\n credential_scope: input.credentialScope ?? null,\n pending: input.pending,\n expires_at: input.expiresAt,\n next_poll_at: input.nextPollAt ?? null,\n created_at: new Date(),\n });\n return toSessionRow(inserted);\n }\n\n /**\n * Read a pending login flow. An expired session is deleted on read (TTL\n * cleanup) and reported as absent.\n */\n async getLoginSession(sessionId: string): Promise<LoginSessionRow | undefined> {\n const row = await this.#db.findOne<LoginSessionDbRow>('oauth_login_sessions', { session_id: sessionId });\n if (!row) return undefined;\n if (row.expires_at.getTime() <= Date.now()) {\n await this.#db.deleteMany('oauth_login_sessions', { session_id: sessionId });\n return undefined;\n }\n return toSessionRow(row);\n }\n\n /**\n * Atomically claim a due login session for one upstream completion/poll attempt.\n * Returns undefined when the session is missing, expired, owned by another\n * tenant/provider, or already claimed by a concurrent request.\n */\n async claimLoginSession(\n sessionId: string,\n owner: Pick<LoginSessionRow, 'orgId' | 'userId' | 'provider' | 'kind'>,\n ): Promise<LoginSessionRow | undefined> {\n const now = Date.now();\n let claimed = false;\n const updated = await this.#db.updateAtomic<LoginSessionDbRow>(\n 'oauth_login_sessions',\n { session_id: sessionId },\n row => {\n if (\n row.org_id !== owner.orgId ||\n row.user_id !== owner.userId ||\n row.provider !== owner.provider ||\n row.kind !== owner.kind\n ) {\n return null;\n }\n if (row.expires_at.getTime() <= now) return null;\n if (row.next_poll_at && row.next_poll_at.getTime() > now) return null;\n claimed = true;\n // Park the next poll at expiry so a concurrent claim loses until the\n // claimer either touches the session forward or deletes it.\n return { next_poll_at: row.expires_at };\n },\n );\n return claimed && updated ? toSessionRow(updated) : undefined;\n }\n\n /** Update a pending flow's serialized state and/or next allowed poll time. */\n async touchLoginSession(\n sessionId: string,\n updates: { pending?: Record<string, unknown>; nextPollAt?: Date | null },\n ): Promise<void> {\n const set: Record<string, unknown> = {};\n if (updates.pending !== undefined) set.pending = updates.pending;\n if (updates.nextPollAt !== undefined) set.next_poll_at = updates.nextPollAt;\n if (Object.keys(set).length === 0) return;\n await this.#db.updateMany('oauth_login_sessions', { session_id: sessionId }, set);\n }\n\n /** Remove a pending login flow (completed, cancelled, or failed). */\n async deleteLoginSession(sessionId: string): Promise<void> {\n await this.#db.deleteMany('oauth_login_sessions', { session_id: sessionId });\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createPlaintextFactorySecretEncryption } from "../../../secret-encryption.js";
2
2
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
3
- //#region src/storage/domains/custom-providers/base.ts
3
+ // src/storage/domains/custom-providers/base.ts
4
4
  const CUSTOM_PROVIDERS_SCHEMA = {
5
5
  name: "custom_providers",
6
6
  columns: {
@@ -170,7 +170,6 @@ var CustomProvidersStorage = class extends FactoryStorageDomain {
170
170
  }) > 0;
171
171
  }
172
172
  };
173
- //#endregion
174
173
  export { CUSTOM_PROVIDERS_SCHEMA, CustomProvidersStorage };
175
174
 
176
175
  //# sourceMappingURL=base.js.map
@@ -1,5 +1,5 @@
1
1
  import { FactoryStorageDomain } from "@mastra/core/storage";
2
- //#region src/storage/domains/filesystem/base.ts
2
+ // src/storage/domains/filesystem/base.ts
3
3
  const SNAPSHOTS = "filesystem_snapshots";
4
4
  const FILESYSTEM_SCHEMAS = [{
5
5
  name: SNAPSHOTS,
@@ -73,7 +73,6 @@ var FilesystemStorage = class extends FactoryStorageDomain {
73
73
  return this.ops.deleteMany(SNAPSHOTS, { resource_id: args.resourceId });
74
74
  }
75
75
  };
76
- //#endregion
77
76
  export { FILESYSTEM_SCHEMAS, FilesystemStorage };
78
77
 
79
78
  //# sourceMappingURL=base.js.map
@@ -77,6 +77,11 @@ export declare class IntakeStorage extends FactoryStorageDomain {
77
77
  orgId: string;
78
78
  config: IntakeConfig;
79
79
  }): Promise<void>;
80
+ /** Overlay `config` onto the stored selections; integrations it omits keep their stored value. */
81
+ mergeConfig({ orgId, config }: {
82
+ orgId: string;
83
+ config: IntakeConfig;
84
+ }): Promise<IntakeConfig>;
80
85
  /** Every source binding in the org, optionally narrowed to one integration. */
81
86
  listBindings({ orgId, integrationId, }: {
82
87
  orgId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/intake/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/intake/base.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
2
- //#region src/storage/domains/intake/base.ts
2
+ // src/storage/domains/intake/base.ts
3
3
  /**
4
4
  * Org-wide intake selections for every configured intake integration.
5
5
  *
@@ -219,6 +219,15 @@ var IntakeStorage = class extends FactoryStorageDomain {
219
219
  updated_at: now
220
220
  });
221
221
  }
222
+ /** Overlay `config` onto the stored selections; integrations it omits keep their stored value. */
223
+ async mergeConfig({ orgId, config }) {
224
+ const merged = Object.assign(Object.create(null), await this.getConfig({ orgId }), config);
225
+ await this.saveConfig({
226
+ orgId,
227
+ config: merged
228
+ });
229
+ return merged;
230
+ }
222
231
  async #insertConfigIfAbsent(orgId, config) {
223
232
  const now = /* @__PURE__ */ new Date();
224
233
  try {
@@ -425,7 +434,6 @@ var IntakeStorage = class extends FactoryStorageDomain {
425
434
  }, { isolationLevel: "serializable" });
426
435
  }
427
436
  };
428
- //#endregion
429
437
  export { DEFAULT_INTAKE_CONFIG, INTAKE_LABEL_ROUTES_SCHEMA, INTAKE_ORG_SETTINGS_SCHEMA, INTAKE_SOURCE_BINDINGS_SCHEMA, IntakeStorage, LEGACY_INTAKE_USER_SETTINGS_SCHEMA, mergeIntakeSelections, normalizeIntakeLabel, resolveIntakeLabelRoute };
430
438
 
431
439
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/intake/base.ts"],"sourcesContent":["/**\n * Org-wide intake selections for every configured intake integration.\n *\n * Integration ids are dynamic. Each integration contributes provider-neutral\n * sources through `FactoryIntegration.intake`; this domain only persists which\n * source ids the organization selected. The selection feeds shared boards, so\n * every member reads the same one.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport interface IntakeSelection {\n enabled: boolean;\n /** Provider-owned source ids; `null` means nothing is selected. */\n sourceIds: string[] | null;\n repositoryByLinearProject?: Record<string, string>;\n}\n\nexport type IntakeConfig = Record<string, IntakeSelection>;\n\nexport const DEFAULT_INTAKE_CONFIG: IntakeConfig = {};\n\nexport const INTAKE_ORG_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'intake_org_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'intake_org_settings_org_unique', columns: ['org_id'] }],\n};\n\n/** Collection evolution is additive, so the per-member unique index cannot be narrowed: rows stay and are folded at boot. */\nexport const LEGACY_INTAKE_USER_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'intake_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'intake_settings_org_user_unique', columns: ['org_id', 'user_id'] }],\n};\n\n/** What the org effectively saw while selections were personal: a member's sources fed the shared board only while their switch was on. */\nexport function mergeIntakeSelections(configs: readonly IntakeConfig[]): IntakeConfig {\n const merged: IntakeConfig = Object.create(null);\n for (const config of configs) {\n for (const [integrationId, selection] of Object.entries(config)) {\n const current = merged[integrationId] ?? { enabled: false, sourceIds: null };\n const syncing = selection.enabled ? (selection.sourceIds ?? []) : [];\n const sourceIds = [...new Set([...(current.sourceIds ?? []), ...syncing])];\n merged[integrationId] = {\n enabled: current.enabled || selection.enabled,\n sourceIds: sourceIds.length ? sourceIds : null,\n };\n }\n }\n return merged;\n}\n\n/**\n * Binds an intake source to the Factory project its items belong to.\n *\n * Intake selections are org-wide, so they cannot say *where* an\n * ingested item should land. GitHub items are naturally scoped by their linked\n * repository; providers without that link (Linear) need this explicit binding\n * so viewing one project's board cannot materialize another project's items.\n */\nexport const INTAKE_SOURCE_BINDINGS_SCHEMA: CollectionSchema = {\n name: 'intake_source_bindings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n integration_id: { type: 'text' },\n source_id: { type: 'text' },\n factory_project_id: { type: 'text' },\n /** Installed board the source feeds; `null` keeps the legacy source-type routing (issues → work, PRs → review). */\n board: { type: 'text', nullable: true },\n created_by_user_id: { type: 'text', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'intake_source_bindings_project_idx', columns: ['org_id', 'factory_project_id'] }],\n uniqueIndexes: [\n {\n name: 'intake_source_bindings_org_integration_source_unique',\n columns: ['org_id', 'integration_id', 'source_id'],\n },\n ],\n};\n\nexport interface IntakeSourceBinding {\n integrationId: string;\n sourceId: string;\n factoryProjectId: string;\n /** Installed board the source feeds, or `null` for legacy source-type routing. */\n board: string | null;\n}\n\n/**\n * Routes items carrying a label to an installed board, per Factory project.\n *\n * Repository-scoped providers (GitHub) already know which project an item\n * belongs to, but one repository can feed several boards: an issue labelled\n * `release` belongs on a release board while the rest stay on Work. Labels\n * without a route fall back to the provider's built-in board.\n */\nexport const INTAKE_LABEL_ROUTES_SCHEMA: CollectionSchema = {\n name: 'intake_label_routes',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n factory_project_id: { type: 'text' },\n integration_id: { type: 'text' },\n /** Label as the provider reports it; matched case-insensitively. */\n label: { type: 'text' },\n board: { type: 'text' },\n created_by_user_id: { type: 'text', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'intake_label_routes_project_idx', columns: ['org_id', 'factory_project_id'] }],\n uniqueIndexes: [\n {\n name: 'intake_label_routes_org_project_integration_label_unique',\n columns: ['org_id', 'factory_project_id', 'integration_id', 'label'],\n },\n ],\n};\n\nexport interface IntakeLabelRoute {\n factoryProjectId: string;\n integrationId: string;\n label: string;\n board: string;\n}\n\ntype IntakeLabelRouteRow = {\n factory_project_id: string;\n integration_id: string;\n label: string;\n board: string;\n};\nfunction toIntakeLabelRoute(row: IntakeLabelRouteRow): IntakeLabelRoute {\n return {\n factoryProjectId: row.factory_project_id,\n integrationId: row.integration_id,\n label: row.label,\n board: row.board,\n };\n}\n\n/** Labels are matched the way GitHub treats them: case-insensitively. */\nexport function normalizeIntakeLabel(label: string): string {\n return label.trim().toLowerCase();\n}\n\n/**\n * The board a labelled item should land on under `routes`, or `undefined` when\n * none of its labels is routed. Ties resolve to the first route in `routes`\n * order, so callers should pass a deterministically ordered list.\n */\nexport function resolveIntakeLabelRoute(\n routes: readonly IntakeLabelRoute[],\n labels: readonly string[] | undefined,\n): IntakeLabelRoute | undefined {\n if (!labels?.length) return undefined;\n const normalized = new Set(labels.map(normalizeIntakeLabel));\n return routes.find(route => normalized.has(normalizeIntakeLabel(route.label)));\n}\n\ntype IntakeSourceBindingRow = {\n integration_id: string;\n source_id: string;\n factory_project_id: string;\n board?: string | null;\n};\nfunction toIntakeSourceBinding(row: IntakeSourceBindingRow): IntakeSourceBinding {\n return {\n integrationId: row.integration_id,\n sourceId: row.source_id,\n factoryProjectId: row.factory_project_id,\n board: row.board ?? null,\n };\n}\n\nexport class IntakeStorage extends FactoryStorageDomain {\n constructor() {\n super('intake');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([\n INTAKE_ORG_SETTINGS_SCHEMA,\n LEGACY_INTAKE_USER_SETTINGS_SCHEMA,\n INTAKE_SOURCE_BINDINGS_SCHEMA,\n INTAKE_LABEL_ROUTES_SCHEMA,\n ]);\n await this.#foldLegacyUserSelections();\n }\n\n async #foldLegacyUserSelections(): Promise<void> {\n const legacyRows = await this.ops.findMany<{ org_id: string; config: IntakeConfig }>('intake_settings', {});\n const byOrg = new Map<string, IntakeConfig[]>();\n for (const row of legacyRows) {\n byOrg.set(row.org_id, [...(byOrg.get(row.org_id) ?? []), row.config]);\n }\n for (const [orgId, configs] of byOrg) {\n const folded = await this.ops.findOne('intake_org_settings', { org_id: orgId });\n if (folded) continue;\n await this.#insertConfigIfAbsent(orgId, mergeIntakeSelections(configs));\n }\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('intake_org_settings', {});\n await this.ops.deleteMany('intake_settings', {});\n await this.ops.deleteMany('intake_source_bindings', {});\n await this.ops.deleteMany('intake_label_routes', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async getConfig({\n orgId,\n integrationIds,\n }: {\n orgId: string;\n /**\n * When provided, the result contains exactly these integration ids, with\n * unset integrations defaulting to `{ enabled: true, sourceIds: null }`.\n */\n integrationIds?: string[];\n }): Promise<IntakeConfig> {\n const row = await this.#db.findOne<{ config: IntakeConfig }>('intake_org_settings', { org_id: orgId });\n const saved = structuredClone(row?.config ?? DEFAULT_INTAKE_CONFIG);\n if (!integrationIds) return saved;\n return Object.fromEntries(\n integrationIds.map(integrationId => [integrationId, saved[integrationId] ?? { enabled: true, sourceIds: null }]),\n );\n }\n\n async saveConfig({ orgId, config }: { orgId: string; config: IntakeConfig }): Promise<void> {\n const now = new Date();\n const where = { org_id: orgId };\n const updated = await this.#db.updateMany('intake_org_settings', where, { config, updated_at: now });\n if (updated > 0) return;\n if (await this.#insertConfigIfAbsent(orgId, config)) return;\n await this.#db.updateMany('intake_org_settings', where, { config, updated_at: now });\n }\n\n async #insertConfigIfAbsent(orgId: string, config: IntakeConfig): Promise<boolean> {\n const now = new Date();\n try {\n await this.#db.insertOne('intake_org_settings', { org_id: orgId, config, created_at: now, updated_at: now });\n return true;\n } catch (error) {\n if (error instanceof UniqueViolationError) return false;\n throw error;\n }\n }\n\n /** Every source binding in the org, optionally narrowed to one integration. */\n async listBindings({\n orgId,\n integrationId,\n }: {\n orgId: string;\n integrationId?: string;\n }): Promise<IntakeSourceBinding[]> {\n const rows = await this.#db.findMany<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n ...(integrationId ? { integration_id: integrationId } : {}),\n });\n return rows.map(toIntakeSourceBinding);\n }\n\n /** Source ids bound to one Factory project. Empty means \"nothing bound\". */\n async listBoundSourceIds({\n orgId,\n integrationId,\n factoryProjectId,\n }: {\n orgId: string;\n integrationId: string;\n factoryProjectId: string;\n }): Promise<string[]> {\n const rows = await this.#db.findMany<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n factory_project_id: factoryProjectId,\n });\n return rows.map(row => row.source_id);\n }\n\n /** The binding for one source, or `null` when it is unbound. */\n async getBinding({\n orgId,\n integrationId,\n sourceId,\n }: {\n orgId: string;\n integrationId: string;\n sourceId: string;\n }): Promise<IntakeSourceBinding | null> {\n const row = await this.#db.findOne<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n source_id: sourceId,\n });\n return row ? toIntakeSourceBinding(row) : null;\n }\n\n async clearBinding({\n orgId,\n integrationId,\n sourceId,\n }: {\n orgId: string;\n integrationId: string;\n sourceId: string;\n }): Promise<IntakeSourceBinding | null> {\n const where = { org_id: orgId, integration_id: integrationId, source_id: sourceId };\n return this.storage.withTransaction(\n async ops => {\n const row = await ops.findOne<IntakeSourceBindingRow>('intake_source_bindings', where);\n if (!row) return null;\n await ops.deleteMany('intake_source_bindings', where);\n return toIntakeSourceBinding(row);\n },\n { isolationLevel: 'serializable' },\n );\n }\n\n async setBinding({\n orgId,\n integrationId,\n sourceId,\n factoryProjectId,\n board = null,\n userId,\n }: {\n orgId: string;\n integrationId: string;\n sourceId: string;\n factoryProjectId: string;\n board?: string | null;\n userId?: string;\n }): Promise<void> {\n const where = { org_id: orgId, integration_id: integrationId, source_id: sourceId };\n const now = new Date();\n const patch = { factory_project_id: factoryProjectId, board, updated_at: now };\n const updated = await this.#db.updateMany('intake_source_bindings', where, patch);\n if (updated > 0) return;\n try {\n await this.#db.insertOne('intake_source_bindings', {\n ...where,\n factory_project_id: factoryProjectId,\n board,\n created_by_user_id: userId ?? null,\n created_at: now,\n updated_at: now,\n });\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n await this.#db.updateMany('intake_source_bindings', where, patch);\n }\n }\n /** Atomically replace legacy provider source ids in both selection and routing state. */\n async migrateSourceIds({\n orgId,\n integrationId,\n migrations,\n }: {\n orgId: string;\n integrationId: string;\n migrations: Array<{ from: string; to: string }>;\n }): Promise<{ migrations: Array<{ from: string; to: string }>; conflicts: Array<{ from: string; to: string }> }> {\n if (migrations.length === 0) return { migrations: [], conflicts: [] };\n return this.storage.withTransaction(\n async ops => {\n const bindings = await ops.findMany<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n });\n const bindingBySource = new Map(bindings.map(binding => [binding.source_id, binding] as const));\n const grouped = new Map<string, Array<{ from: string; to: string }>>();\n for (const migration of migrations) {\n grouped.set(migration.to, [...(grouped.get(migration.to) ?? []), migration]);\n }\n const conflicts: Array<{ from: string; to: string }> = [];\n for (const [to, group] of grouped) {\n const candidates = [bindingBySource.get(to), ...group.map(({ from }) => bindingBySource.get(from))].filter(\n (binding): binding is IntakeSourceBindingRow => binding !== undefined,\n );\n const destinations = new Set(\n candidates.map(binding => `${binding.factory_project_id}\\0${binding.board ?? ''}`),\n );\n if (destinations.size > 1) conflicts.push(...group);\n }\n if (conflicts.length > 0) return { migrations: [], conflicts };\n\n const now = new Date();\n for (const [to, group] of grouped) {\n const canonical = bindingBySource.get(to);\n const legacy = group.flatMap(({ from }) => {\n const binding = bindingBySource.get(from);\n return binding ? [{ from, binding }] : [];\n });\n if (!canonical && legacy.length > 0) {\n const [first, ...duplicates] = legacy;\n await ops.updateMany(\n 'intake_source_bindings',\n { org_id: orgId, integration_id: integrationId, source_id: first!.from },\n { source_id: to, updated_at: now },\n );\n for (const duplicate of duplicates) {\n await ops.deleteMany('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n source_id: duplicate.from,\n });\n }\n } else if (canonical) {\n for (const entry of legacy) {\n await ops.deleteMany('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n source_id: entry.from,\n });\n }\n }\n }\n\n const configRow = await ops.findOne<{ config: IntakeConfig }>('intake_org_settings', { org_id: orgId });\n if (configRow) {\n const replacements = new Map(migrations.map(({ from, to }) => [from, to] as const));\n const selected = configRow.config[integrationId]?.sourceIds ?? [];\n const nextSelected = [...new Set(selected.map(sourceId => replacements.get(sourceId) ?? sourceId))];\n if (\n nextSelected.length !== selected.length ||\n nextSelected.some((sourceId, index) => sourceId !== selected[index])\n ) {\n const config = structuredClone(configRow.config);\n config[integrationId] = {\n ...(config[integrationId] ?? { enabled: true }),\n sourceIds: nextSelected.length > 0 ? nextSelected : null,\n };\n await ops.updateMany('intake_org_settings', { org_id: orgId }, { config, updated_at: now });\n }\n }\n return { migrations, conflicts: [] };\n },\n { isolationLevel: 'serializable' },\n );\n }\n\n /** Label routes in the org, optionally narrowed to one project and/or integration. Sorted by label. */\n async listLabelRoutes({\n orgId,\n factoryProjectId,\n integrationId,\n }: {\n orgId: string;\n factoryProjectId?: string;\n integrationId?: string;\n }): Promise<IntakeLabelRoute[]> {\n const rows = await this.#db.findMany<IntakeLabelRouteRow>('intake_label_routes', {\n org_id: orgId,\n ...(factoryProjectId ? { factory_project_id: factoryProjectId } : {}),\n ...(integrationId ? { integration_id: integrationId } : {}),\n });\n return rows.map(toIntakeLabelRoute).sort((a, b) => a.label.localeCompare(b.label));\n }\n\n async setLabelRoute({\n orgId,\n factoryProjectId,\n integrationId,\n label,\n board,\n userId,\n }: {\n orgId: string;\n factoryProjectId: string;\n integrationId: string;\n label: string;\n board: string;\n userId?: string;\n }): Promise<void> {\n const where = {\n org_id: orgId,\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n label: normalizeIntakeLabel(label),\n };\n const now = new Date();\n const patch = { board, updated_at: now };\n const updated = await this.#db.updateMany('intake_label_routes', where, patch);\n if (updated > 0) return;\n try {\n await this.#db.insertOne('intake_label_routes', {\n ...where,\n board,\n created_by_user_id: userId ?? null,\n created_at: now,\n updated_at: now,\n });\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n await this.#db.updateMany('intake_label_routes', where, patch);\n }\n }\n\n /** Remove a label route; returns the route that was removed, or `null` when none existed. */\n async clearLabelRoute({\n orgId,\n factoryProjectId,\n integrationId,\n label,\n }: {\n orgId: string;\n factoryProjectId: string;\n integrationId: string;\n label: string;\n }): Promise<IntakeLabelRoute | null> {\n const where = {\n org_id: orgId,\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n label: normalizeIntakeLabel(label),\n };\n return this.storage.withTransaction(\n async ops => {\n const row = await ops.findOne<IntakeLabelRouteRow>('intake_label_routes', where);\n if (!row) return null;\n await ops.deleteMany('intake_label_routes', where);\n return toIntakeLabelRoute(row);\n },\n { isolationLevel: 'serializable' },\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/intake/base.ts"],"sourcesContent":["/**\n * Org-wide intake selections for every configured intake integration.\n *\n * Integration ids are dynamic. Each integration contributes provider-neutral\n * sources through `FactoryIntegration.intake`; this domain only persists which\n * source ids the organization selected. The selection feeds shared boards, so\n * every member reads the same one.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport interface IntakeSelection {\n enabled: boolean;\n /** Provider-owned source ids; `null` means nothing is selected. */\n sourceIds: string[] | null;\n repositoryByLinearProject?: Record<string, string>;\n}\n\nexport type IntakeConfig = Record<string, IntakeSelection>;\n\nexport const DEFAULT_INTAKE_CONFIG: IntakeConfig = {};\n\nexport const INTAKE_ORG_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'intake_org_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'intake_org_settings_org_unique', columns: ['org_id'] }],\n};\n\n/** Collection evolution is additive, so the per-member unique index cannot be narrowed: rows stay and are folded at boot. */\nexport const LEGACY_INTAKE_USER_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'intake_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'intake_settings_org_user_unique', columns: ['org_id', 'user_id'] }],\n};\n\n/** What the org effectively saw while selections were personal: a member's sources fed the shared board only while their switch was on. */\nexport function mergeIntakeSelections(configs: readonly IntakeConfig[]): IntakeConfig {\n const merged: IntakeConfig = Object.create(null);\n for (const config of configs) {\n for (const [integrationId, selection] of Object.entries(config)) {\n const current = merged[integrationId] ?? { enabled: false, sourceIds: null };\n const syncing = selection.enabled ? (selection.sourceIds ?? []) : [];\n const sourceIds = [...new Set([...(current.sourceIds ?? []), ...syncing])];\n merged[integrationId] = {\n enabled: current.enabled || selection.enabled,\n sourceIds: sourceIds.length ? sourceIds : null,\n };\n }\n }\n return merged;\n}\n\n/**\n * Binds an intake source to the Factory project its items belong to.\n *\n * Intake selections are org-wide, so they cannot say *where* an\n * ingested item should land. GitHub items are naturally scoped by their linked\n * repository; providers without that link (Linear) need this explicit binding\n * so viewing one project's board cannot materialize another project's items.\n */\nexport const INTAKE_SOURCE_BINDINGS_SCHEMA: CollectionSchema = {\n name: 'intake_source_bindings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n integration_id: { type: 'text' },\n source_id: { type: 'text' },\n factory_project_id: { type: 'text' },\n /** Installed board the source feeds; `null` keeps the legacy source-type routing (issues → work, PRs → review). */\n board: { type: 'text', nullable: true },\n created_by_user_id: { type: 'text', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'intake_source_bindings_project_idx', columns: ['org_id', 'factory_project_id'] }],\n uniqueIndexes: [\n {\n name: 'intake_source_bindings_org_integration_source_unique',\n columns: ['org_id', 'integration_id', 'source_id'],\n },\n ],\n};\n\nexport interface IntakeSourceBinding {\n integrationId: string;\n sourceId: string;\n factoryProjectId: string;\n /** Installed board the source feeds, or `null` for legacy source-type routing. */\n board: string | null;\n}\n\n/**\n * Routes items carrying a label to an installed board, per Factory project.\n *\n * Repository-scoped providers (GitHub) already know which project an item\n * belongs to, but one repository can feed several boards: an issue labelled\n * `release` belongs on a release board while the rest stay on Work. Labels\n * without a route fall back to the provider's built-in board.\n */\nexport const INTAKE_LABEL_ROUTES_SCHEMA: CollectionSchema = {\n name: 'intake_label_routes',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n factory_project_id: { type: 'text' },\n integration_id: { type: 'text' },\n /** Label as the provider reports it; matched case-insensitively. */\n label: { type: 'text' },\n board: { type: 'text' },\n created_by_user_id: { type: 'text', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'intake_label_routes_project_idx', columns: ['org_id', 'factory_project_id'] }],\n uniqueIndexes: [\n {\n name: 'intake_label_routes_org_project_integration_label_unique',\n columns: ['org_id', 'factory_project_id', 'integration_id', 'label'],\n },\n ],\n};\n\nexport interface IntakeLabelRoute {\n factoryProjectId: string;\n integrationId: string;\n label: string;\n board: string;\n}\n\ntype IntakeLabelRouteRow = {\n factory_project_id: string;\n integration_id: string;\n label: string;\n board: string;\n};\nfunction toIntakeLabelRoute(row: IntakeLabelRouteRow): IntakeLabelRoute {\n return {\n factoryProjectId: row.factory_project_id,\n integrationId: row.integration_id,\n label: row.label,\n board: row.board,\n };\n}\n\n/** Labels are matched the way GitHub treats them: case-insensitively. */\nexport function normalizeIntakeLabel(label: string): string {\n return label.trim().toLowerCase();\n}\n\n/**\n * The board a labelled item should land on under `routes`, or `undefined` when\n * none of its labels is routed. Ties resolve to the first route in `routes`\n * order, so callers should pass a deterministically ordered list.\n */\nexport function resolveIntakeLabelRoute(\n routes: readonly IntakeLabelRoute[],\n labels: readonly string[] | undefined,\n): IntakeLabelRoute | undefined {\n if (!labels?.length) return undefined;\n const normalized = new Set(labels.map(normalizeIntakeLabel));\n return routes.find(route => normalized.has(normalizeIntakeLabel(route.label)));\n}\n\ntype IntakeSourceBindingRow = {\n integration_id: string;\n source_id: string;\n factory_project_id: string;\n board?: string | null;\n};\nfunction toIntakeSourceBinding(row: IntakeSourceBindingRow): IntakeSourceBinding {\n return {\n integrationId: row.integration_id,\n sourceId: row.source_id,\n factoryProjectId: row.factory_project_id,\n board: row.board ?? null,\n };\n}\n\nexport class IntakeStorage extends FactoryStorageDomain {\n constructor() {\n super('intake');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([\n INTAKE_ORG_SETTINGS_SCHEMA,\n LEGACY_INTAKE_USER_SETTINGS_SCHEMA,\n INTAKE_SOURCE_BINDINGS_SCHEMA,\n INTAKE_LABEL_ROUTES_SCHEMA,\n ]);\n await this.#foldLegacyUserSelections();\n }\n\n async #foldLegacyUserSelections(): Promise<void> {\n const legacyRows = await this.ops.findMany<{ org_id: string; config: IntakeConfig }>('intake_settings', {});\n const byOrg = new Map<string, IntakeConfig[]>();\n for (const row of legacyRows) {\n byOrg.set(row.org_id, [...(byOrg.get(row.org_id) ?? []), row.config]);\n }\n for (const [orgId, configs] of byOrg) {\n const folded = await this.ops.findOne('intake_org_settings', { org_id: orgId });\n if (folded) continue;\n await this.#insertConfigIfAbsent(orgId, mergeIntakeSelections(configs));\n }\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('intake_org_settings', {});\n await this.ops.deleteMany('intake_settings', {});\n await this.ops.deleteMany('intake_source_bindings', {});\n await this.ops.deleteMany('intake_label_routes', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async getConfig({\n orgId,\n integrationIds,\n }: {\n orgId: string;\n /**\n * When provided, the result contains exactly these integration ids, with\n * unset integrations defaulting to `{ enabled: true, sourceIds: null }`.\n */\n integrationIds?: string[];\n }): Promise<IntakeConfig> {\n const row = await this.#db.findOne<{ config: IntakeConfig }>('intake_org_settings', { org_id: orgId });\n const saved = structuredClone(row?.config ?? DEFAULT_INTAKE_CONFIG);\n if (!integrationIds) return saved;\n return Object.fromEntries(\n integrationIds.map(integrationId => [integrationId, saved[integrationId] ?? { enabled: true, sourceIds: null }]),\n );\n }\n\n async saveConfig({ orgId, config }: { orgId: string; config: IntakeConfig }): Promise<void> {\n const now = new Date();\n const where = { org_id: orgId };\n const updated = await this.#db.updateMany('intake_org_settings', where, { config, updated_at: now });\n if (updated > 0) return;\n if (await this.#insertConfigIfAbsent(orgId, config)) return;\n await this.#db.updateMany('intake_org_settings', where, { config, updated_at: now });\n }\n\n /** Overlay `config` onto the stored selections; integrations it omits keep their stored value. */\n async mergeConfig({ orgId, config }: { orgId: string; config: IntakeConfig }): Promise<IntakeConfig> {\n const merged: IntakeConfig = Object.assign(Object.create(null), await this.getConfig({ orgId }), config);\n await this.saveConfig({ orgId, config: merged });\n return merged;\n }\n\n async #insertConfigIfAbsent(orgId: string, config: IntakeConfig): Promise<boolean> {\n const now = new Date();\n try {\n await this.#db.insertOne('intake_org_settings', { org_id: orgId, config, created_at: now, updated_at: now });\n return true;\n } catch (error) {\n if (error instanceof UniqueViolationError) return false;\n throw error;\n }\n }\n\n /** Every source binding in the org, optionally narrowed to one integration. */\n async listBindings({\n orgId,\n integrationId,\n }: {\n orgId: string;\n integrationId?: string;\n }): Promise<IntakeSourceBinding[]> {\n const rows = await this.#db.findMany<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n ...(integrationId ? { integration_id: integrationId } : {}),\n });\n return rows.map(toIntakeSourceBinding);\n }\n\n /** Source ids bound to one Factory project. Empty means \"nothing bound\". */\n async listBoundSourceIds({\n orgId,\n integrationId,\n factoryProjectId,\n }: {\n orgId: string;\n integrationId: string;\n factoryProjectId: string;\n }): Promise<string[]> {\n const rows = await this.#db.findMany<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n factory_project_id: factoryProjectId,\n });\n return rows.map(row => row.source_id);\n }\n\n /** The binding for one source, or `null` when it is unbound. */\n async getBinding({\n orgId,\n integrationId,\n sourceId,\n }: {\n orgId: string;\n integrationId: string;\n sourceId: string;\n }): Promise<IntakeSourceBinding | null> {\n const row = await this.#db.findOne<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n source_id: sourceId,\n });\n return row ? toIntakeSourceBinding(row) : null;\n }\n\n async clearBinding({\n orgId,\n integrationId,\n sourceId,\n }: {\n orgId: string;\n integrationId: string;\n sourceId: string;\n }): Promise<IntakeSourceBinding | null> {\n const where = { org_id: orgId, integration_id: integrationId, source_id: sourceId };\n return this.storage.withTransaction(\n async ops => {\n const row = await ops.findOne<IntakeSourceBindingRow>('intake_source_bindings', where);\n if (!row) return null;\n await ops.deleteMany('intake_source_bindings', where);\n return toIntakeSourceBinding(row);\n },\n { isolationLevel: 'serializable' },\n );\n }\n\n async setBinding({\n orgId,\n integrationId,\n sourceId,\n factoryProjectId,\n board = null,\n userId,\n }: {\n orgId: string;\n integrationId: string;\n sourceId: string;\n factoryProjectId: string;\n board?: string | null;\n userId?: string;\n }): Promise<void> {\n const where = { org_id: orgId, integration_id: integrationId, source_id: sourceId };\n const now = new Date();\n const patch = { factory_project_id: factoryProjectId, board, updated_at: now };\n const updated = await this.#db.updateMany('intake_source_bindings', where, patch);\n if (updated > 0) return;\n try {\n await this.#db.insertOne('intake_source_bindings', {\n ...where,\n factory_project_id: factoryProjectId,\n board,\n created_by_user_id: userId ?? null,\n created_at: now,\n updated_at: now,\n });\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n await this.#db.updateMany('intake_source_bindings', where, patch);\n }\n }\n /** Atomically replace legacy provider source ids in both selection and routing state. */\n async migrateSourceIds({\n orgId,\n integrationId,\n migrations,\n }: {\n orgId: string;\n integrationId: string;\n migrations: Array<{ from: string; to: string }>;\n }): Promise<{ migrations: Array<{ from: string; to: string }>; conflicts: Array<{ from: string; to: string }> }> {\n if (migrations.length === 0) return { migrations: [], conflicts: [] };\n return this.storage.withTransaction(\n async ops => {\n const bindings = await ops.findMany<IntakeSourceBindingRow>('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n });\n const bindingBySource = new Map(bindings.map(binding => [binding.source_id, binding] as const));\n const grouped = new Map<string, Array<{ from: string; to: string }>>();\n for (const migration of migrations) {\n grouped.set(migration.to, [...(grouped.get(migration.to) ?? []), migration]);\n }\n const conflicts: Array<{ from: string; to: string }> = [];\n for (const [to, group] of grouped) {\n const candidates = [bindingBySource.get(to), ...group.map(({ from }) => bindingBySource.get(from))].filter(\n (binding): binding is IntakeSourceBindingRow => binding !== undefined,\n );\n const destinations = new Set(\n candidates.map(binding => `${binding.factory_project_id}\\0${binding.board ?? ''}`),\n );\n if (destinations.size > 1) conflicts.push(...group);\n }\n if (conflicts.length > 0) return { migrations: [], conflicts };\n\n const now = new Date();\n for (const [to, group] of grouped) {\n const canonical = bindingBySource.get(to);\n const legacy = group.flatMap(({ from }) => {\n const binding = bindingBySource.get(from);\n return binding ? [{ from, binding }] : [];\n });\n if (!canonical && legacy.length > 0) {\n const [first, ...duplicates] = legacy;\n await ops.updateMany(\n 'intake_source_bindings',\n { org_id: orgId, integration_id: integrationId, source_id: first!.from },\n { source_id: to, updated_at: now },\n );\n for (const duplicate of duplicates) {\n await ops.deleteMany('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n source_id: duplicate.from,\n });\n }\n } else if (canonical) {\n for (const entry of legacy) {\n await ops.deleteMany('intake_source_bindings', {\n org_id: orgId,\n integration_id: integrationId,\n source_id: entry.from,\n });\n }\n }\n }\n\n const configRow = await ops.findOne<{ config: IntakeConfig }>('intake_org_settings', { org_id: orgId });\n if (configRow) {\n const replacements = new Map(migrations.map(({ from, to }) => [from, to] as const));\n const selected = configRow.config[integrationId]?.sourceIds ?? [];\n const nextSelected = [...new Set(selected.map(sourceId => replacements.get(sourceId) ?? sourceId))];\n if (\n nextSelected.length !== selected.length ||\n nextSelected.some((sourceId, index) => sourceId !== selected[index])\n ) {\n const config = structuredClone(configRow.config);\n config[integrationId] = {\n ...(config[integrationId] ?? { enabled: true }),\n sourceIds: nextSelected.length > 0 ? nextSelected : null,\n };\n await ops.updateMany('intake_org_settings', { org_id: orgId }, { config, updated_at: now });\n }\n }\n return { migrations, conflicts: [] };\n },\n { isolationLevel: 'serializable' },\n );\n }\n\n /** Label routes in the org, optionally narrowed to one project and/or integration. Sorted by label. */\n async listLabelRoutes({\n orgId,\n factoryProjectId,\n integrationId,\n }: {\n orgId: string;\n factoryProjectId?: string;\n integrationId?: string;\n }): Promise<IntakeLabelRoute[]> {\n const rows = await this.#db.findMany<IntakeLabelRouteRow>('intake_label_routes', {\n org_id: orgId,\n ...(factoryProjectId ? { factory_project_id: factoryProjectId } : {}),\n ...(integrationId ? { integration_id: integrationId } : {}),\n });\n return rows.map(toIntakeLabelRoute).sort((a, b) => a.label.localeCompare(b.label));\n }\n\n async setLabelRoute({\n orgId,\n factoryProjectId,\n integrationId,\n label,\n board,\n userId,\n }: {\n orgId: string;\n factoryProjectId: string;\n integrationId: string;\n label: string;\n board: string;\n userId?: string;\n }): Promise<void> {\n const where = {\n org_id: orgId,\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n label: normalizeIntakeLabel(label),\n };\n const now = new Date();\n const patch = { board, updated_at: now };\n const updated = await this.#db.updateMany('intake_label_routes', where, patch);\n if (updated > 0) return;\n try {\n await this.#db.insertOne('intake_label_routes', {\n ...where,\n board,\n created_by_user_id: userId ?? null,\n created_at: now,\n updated_at: now,\n });\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n await this.#db.updateMany('intake_label_routes', where, patch);\n }\n }\n\n /** Remove a label route; returns the route that was removed, or `null` when none existed. */\n async clearLabelRoute({\n orgId,\n factoryProjectId,\n integrationId,\n label,\n }: {\n orgId: string;\n factoryProjectId: string;\n integrationId: string;\n label: string;\n }): Promise<IntakeLabelRoute | null> {\n const where = {\n org_id: orgId,\n factory_project_id: factoryProjectId,\n integration_id: integrationId,\n label: normalizeIntakeLabel(label),\n };\n return this.storage.withTransaction(\n async ops => {\n const row = await ops.findOne<IntakeLabelRouteRow>('intake_label_routes', where);\n if (!row) return null;\n await ops.deleteMany('intake_label_routes', where);\n return toIntakeLabelRoute(row);\n },\n { isolationLevel: 'serializable' },\n );\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createPlaintextFactorySecretEncryption } from "../../../secret-encryption.js";
2
2
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
3
- //#region src/storage/domains/integrations/base.ts
3
+ // src/storage/domains/integrations/base.ts
4
4
  /**
5
5
  * Generic integration storage — the default persistence surface for
6
6
  * `FactoryIntegration`s.
@@ -334,7 +334,6 @@ var IntegrationStorage = class extends FactoryStorageDomain {
334
334
  };
335
335
  }
336
336
  };
337
- //#endregion
338
337
  export { INTEGRATION_CONNECTIONS_SCHEMA, INTEGRATION_SETTINGS_SCHEMA, INTEGRATION_SUBSCRIPTIONS_SCHEMA, IntegrationStorage };
339
338
 
340
339
  //# sourceMappingURL=base.js.map
@@ -1,5 +1,5 @@
1
1
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
2
- //#region src/storage/domains/memory-settings/base.ts
2
+ // src/storage/domains/memory-settings/base.ts
3
3
  /**
4
4
  * Sentinel `user_id` for a factory project's shared memory settings. Factory
5
5
  * runs are org-shared, so their OM configuration lives on the project — this
@@ -123,7 +123,6 @@ var MemorySettingsStorage = class extends FactoryStorageDomain {
123
123
  }
124
124
  }
125
125
  };
126
- //#endregion
127
126
  export { MEMORY_SETTINGS_SCHEMA, MemorySettingsStorage, factoryMemorySettingsUserId };
128
127
 
129
128
  //# sourceMappingURL=base.js.map
@@ -1,6 +1,6 @@
1
1
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
2
2
  import { isThinkingLevelSetting } from "@mastra/code-sdk/thinking";
3
- //#region src/storage/domains/model-defaults/base.ts
3
+ // src/storage/domains/model-defaults/base.ts
4
4
  const USER_DEFAULT_MODELS_SCHEMA = {
5
5
  name: "user_default_models",
6
6
  columns: {
@@ -91,7 +91,6 @@ var ModelDefaultsStorage = class extends FactoryStorageDomain {
91
91
  }) > 0;
92
92
  }
93
93
  };
94
- //#endregion
95
94
  export { ModelDefaultsStorage, USER_DEFAULT_MODELS_SCHEMA };
96
95
 
97
96
  //# sourceMappingURL=base.js.map
@@ -2,7 +2,6 @@ import type { ThinkingLevelSetting } from '@mastra/code-sdk/thinking';
2
2
  import { FactoryStorageDomain } from '@mastra/core/storage';
3
3
  import type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';
4
4
  export declare const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;
5
- export declare const DEFAULT_FACTORY_THINKING_LEVEL: ThinkingLevelSetting;
6
5
  export declare const FACTORY_MODEL_SCOPES: readonly ["factory", "user", "hybrid"];
7
6
  export type FactoryModelScope = (typeof FACTORY_MODEL_SCOPES)[number];
8
7
  /** The single credential scope one session or run resolves from; `hybrid` is never effective. */
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/projects/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/projects/base.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
+ import { DEFAULT_THINKING_LEVEL } from "../../../default-thinking-level.js";
1
2
  import { FactoryStorageDomain } from "@mastra/core/storage";
2
3
  import { isThinkingLevelSetting } from "@mastra/code-sdk/thinking";
3
- //#region src/storage/domains/projects/base.ts
4
+ // src/storage/domains/projects/base.ts
4
5
  const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;
5
- const DEFAULT_FACTORY_THINKING_LEVEL = "medium";
6
6
  const FACTORY_MODEL_SCOPES = [
7
7
  "factory",
8
8
  "user",
@@ -37,7 +37,7 @@ const FACTORY_PROJECTS_SCHEMA = {
37
37
  },
38
38
  default_thinking_level: {
39
39
  type: "text",
40
- default: DEFAULT_FACTORY_THINKING_LEVEL
40
+ default: DEFAULT_THINKING_LEVEL
41
41
  },
42
42
  slack_work_items_enabled: {
43
43
  type: "boolean",
@@ -141,7 +141,7 @@ function toFactoryProject(row) {
141
141
  description: row.description,
142
142
  defaultModelId: row.default_model_id,
143
143
  modelScope: row.model_scope === "factory" || row.model_scope === "user" ? row.model_scope : "hybrid",
144
- defaultThinkingLevel: isThinkingLevelSetting(row.default_thinking_level) ? row.default_thinking_level : DEFAULT_FACTORY_THINKING_LEVEL,
144
+ defaultThinkingLevel: isThinkingLevelSetting(row.default_thinking_level) ? row.default_thinking_level : DEFAULT_THINKING_LEVEL,
145
145
  autoRunEnabled: row.auto_run_enabled,
146
146
  autoApprovePlans: row.auto_approve_plans ?? false,
147
147
  sandboxWorkingDirectory: row.sandbox_working_directory ?? null,
@@ -366,7 +366,6 @@ var FactoryProjectsStorage = class extends FactoryStorageDomain {
366
366
  }) > 0 ? project : null;
367
367
  }
368
368
  };
369
- //#endregion
370
- export { DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES, DEFAULT_FACTORY_THINKING_LEVEL, FACTORY_MODEL_SCOPES, FACTORY_PROJECTS_SCHEMA, FactoryProjectsStorage, effectiveModelScope };
369
+ export { DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES, FACTORY_MODEL_SCOPES, FACTORY_PROJECTS_SCHEMA, FactoryProjectsStorage, effectiveModelScope };
371
370
 
372
371
  //# sourceMappingURL=base.js.map