@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 +1 @@
1
- {"version":3,"file":"intake.js","names":[],"sources":["../../src/routes/intake.ts"],"sourcesContent":["import type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\nimport { z } from 'zod';\n\nimport type { BoardRegistry } from '../boards/index.js';\nimport { cardLabels, moveCardToBoard } from '../boards/relocate.js';\nimport type { Intake, IntakeItem } from '../capabilities/intake.js';\nimport type { AuditEmitter } from '../storage/domains/audit/domain.js';\nimport { normalizeIntakeLabel, resolveIntakeLabelRoute } from '../storage/domains/intake/base.js';\nimport type { IntakeConfig, IntakeLabelRoute, IntakeStorage } from '../storage/domains/intake/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport type { RouteDependencies } from './route.js';\nimport { Route } from './route.js';\n\nexport interface IntakeIntegration {\n id: string;\n intake: Pick<Intake, 'listSources' | 'listItems'>;\n}\n\ninterface AggregatedIntakeItem extends Omit<IntakeItem, 'source'> {\n integrationId: string;\n externalSource: {\n integrationId: string;\n type: string;\n externalId: string;\n url?: string;\n };\n}\n\nexport interface IntakeRoutesDeps extends RouteDependencies {\n audit: AuditEmitter;\n /** Intake selection domain handle. */\n intake: IntakeStorage;\n /** Factory project domain handle, used to validate binding targets. */\n projects?: { get(input: { orgId: string; id: string }): Promise<unknown | null> };\n integrations?: IntakeIntegration[];\n /** Installed boards, used to validate binding targets. Absent means only legacy routing is accepted. */\n boardRegistry?: BoardRegistry;\n /** Work items domain handle; when present, rebinding a source to another board moves its resting cards. */\n workItems?: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;\n /** GitHub repositories, used to match a card to the repository binding its source id names. */\n githubRepositories?: Pick<SourceControlStorageHandle['repositories'], 'get'>;\n}\n\n/** Upper bound on source pages read while relocating cards, so a huge source cannot stall the request. */\nconst REBIND_MAX_PAGES = 20;\n/**\n * One deadline for the whole rebind read, not one per page: the binding is already saved when we\n * get here, so the caller is only waiting on relocation and a slow provider must not hold the\n * response for pages × timeout.\n */\nconst REBIND_READ_BUDGET_MS = 30_000;\n\n/**\n * Keys under which an intake item may be persisted as a work item. Providers key items by their\n * own id, while materialization uses the human identifier (`linear:MAS-44`), so both are accepted.\n */\nfunction intakeItemSourceKeys(integrationId: string, item: IntakeItem): string[] {\n const identifier = item.metadata?.identifier;\n return typeof identifier === 'string' && identifier.length > 0\n ? [item.source.externalId, `${integrationId}:${identifier}`]\n : [item.source.externalId];\n}\n\n/**\n * Move the cards that came from a rebound source onto its new board's initial phase. Terminal cards\n * stay put (they are history that belongs where it finished), as do cards with a session attached to\n * a current stage (a run owns them). Everything else moves, including cards parked in a working\n * phase that never started a run — auto-ingested issues sit in Work › Triage that way.\n */\nasync function relocateSourceCards({\n workItems,\n integration,\n boardRegistry,\n orgId,\n userId,\n factoryProjectId,\n sourceId,\n targetBoard,\n attributionSourceIds,\n}: {\n workItems: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;\n integration: IntakeIntegration;\n boardRegistry: BoardRegistry;\n orgId: string;\n userId: string;\n factoryProjectId: string;\n sourceId: string;\n targetBoard: string;\n attributionSourceIds: string[];\n}): Promise<{ moved: number; skipped: number }> {\n if (!boardRegistry.has(targetBoard)) return { moved: 0, skipped: 0 };\n\n const sourceKeys = new Set<string>();\n let cursor: string | undefined;\n const deadline = Date.now() + REBIND_READ_BUDGET_MS;\n for (let page = 0; page < REBIND_MAX_PAGES; page += 1) {\n const result = await withTimeout(\n integration.id,\n () =>\n integration.intake.listItems({\n orgId,\n userId,\n sourceIds: [sourceId],\n attributionSourceIds,\n cursor,\n }),\n deadline - Date.now(),\n );\n for (const item of result.items) {\n if (item.sourceId !== sourceId) continue;\n for (const key of intakeItemSourceKeys(integration.id, item)) sourceKeys.add(key);\n }\n if (!result.nextCursor) break;\n cursor = result.nextCursor;\n }\n if (sourceKeys.size === 0) return { moved: 0, skipped: 0 };\n\n let moved = 0;\n let skipped = 0;\n const items = await workItems.list({ orgId, factoryProjectId });\n for (const item of items) {\n const source = item.externalSource;\n if (!source || source.integrationId !== integration.id || !sourceKeys.has(source.externalId)) continue;\n const outcome = await moveCardToBoard({ workItems, boardRegistry, userId, item, targetBoard });\n if (outcome === 'moved') moved += 1;\n else if (outcome === 'skipped') skipped += 1;\n }\n return { moved, skipped };\n}\n\n/**\n * After a label route changes, every issue card in the project that carries `label` is re-routed\n * under the project's current routes: to the board its labels now select, or — when none of them is\n * routed any more — to its GitHub repository binding's board, falling back to Work.\n */\nasync function relocateLabeledCards({\n workItems,\n boardRegistry,\n orgId,\n userId,\n factoryProjectId,\n integrationId,\n label,\n routes,\n intake,\n githubRepositories,\n}: {\n workItems: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;\n boardRegistry: BoardRegistry;\n orgId: string;\n userId: string;\n factoryProjectId: string;\n integrationId: string;\n label: string;\n routes: readonly IntakeLabelRoute[];\n intake: Pick<IntakeStorage, 'listBindings'>;\n githubRepositories?: Pick<SourceControlStorageHandle['repositories'], 'get'>;\n}): Promise<{ moved: number; skipped: number }> {\n const changed = normalizeIntakeLabel(label);\n const repositoryBoards =\n integrationId === 'github'\n ? await githubRepositoryBoards({ intake, githubRepositories, boardRegistry, orgId, factoryProjectId })\n : [];\n let moved = 0;\n let skipped = 0;\n for (const item of await workItems.list({ orgId, factoryProjectId })) {\n const source = item.externalSource;\n if (!source || source.integrationId !== integrationId || source.type !== 'issue') continue;\n const labels = cardLabels(item);\n if (!labels.some(candidate => normalizeIntakeLabel(candidate) === changed)) continue;\n const targetBoard =\n resolveIntakeLabelRoute(routes, labels)?.board ??\n repositoryBoards.find(candidate => cardInRepository(item, candidate))?.board ??\n 'work';\n const outcome = await moveCardToBoard({ workItems, boardRegistry, userId, item, targetBoard });\n if (outcome === 'moved') moved += 1;\n else if (outcome === 'skipped') skipped += 1;\n }\n return { moved, skipped };\n}\n\ninterface GithubRepositoryBoard {\n board: string;\n slug: string;\n externalId?: string;\n}\n\n/**\n * The project's GitHub repository bindings that name an installed board. A binding's source id is\n * the internal repository id or the repository slug, so ids are resolved to the slug and external id\n * a card carries.\n */\nasync function githubRepositoryBoards({\n intake,\n githubRepositories,\n boardRegistry,\n orgId,\n factoryProjectId,\n}: {\n intake: Pick<IntakeStorage, 'listBindings'>;\n githubRepositories?: Pick<SourceControlStorageHandle['repositories'], 'get'>;\n boardRegistry: BoardRegistry;\n orgId: string;\n factoryProjectId: string;\n}): Promise<GithubRepositoryBoard[]> {\n const boards: GithubRepositoryBoard[] = [];\n for (const binding of await intake.listBindings({ orgId, integrationId: 'github' })) {\n if (binding.factoryProjectId !== factoryProjectId || !binding.board || !boardRegistry.has(binding.board)) continue;\n const repository = await githubRepositories?.get({ orgId, id: binding.sourceId });\n boards.push(\n repository\n ? { board: binding.board, slug: repository.slug.toLowerCase(), externalId: repository.externalId }\n : { board: binding.board, slug: binding.sourceId.toLowerCase() },\n );\n }\n return boards;\n}\n\nfunction cardInRepository(\n item: { metadata?: Record<string, unknown> | null; externalSource?: { url?: string } | null },\n repository: GithubRepositoryBoard,\n): boolean {\n const repositoryId = item.metadata?.githubRepositoryId;\n if (\n repository.externalId !== undefined &&\n repositoryId !== undefined &&\n String(repositoryId) === repository.externalId\n )\n return true;\n const match = /^https?:\\/\\/[^/]+\\/(.+)\\/(?:issues|pull)\\/\\d+(?:[/?#]|$)/.exec(item.externalSource?.url ?? '');\n return match?.[1]?.toLowerCase() === repository.slug;\n}\n\n/** One integration that failed while the rest of the aggregation succeeded. */\nexport interface IntakeIntegrationFailure {\n integrationId: string;\n message: string;\n}\n\ntype SettledIntegration<T> = { integrationId: string; value: T } | IntakeIntegrationFailure;\n\nconst PROVIDER_READ_TIMEOUT_MS = 15_000;\n\n/** The Intake contract takes no abort signal, so a slow read is abandoned, not cancelled. */\nfunction withTimeout<T>(\n integrationId: string,\n read: () => Promise<T>,\n timeoutMs: number = PROVIDER_READ_TIMEOUT_MS,\n): Promise<T> {\n return new Promise((resolve, reject) => {\n const budget = Math.max(0, timeoutMs);\n const timer = setTimeout(\n () => reject(new Error(`${integrationId} did not answer within ${Math.round(budget / 1000)}s`)),\n budget,\n );\n read()\n .then(resolve, reject)\n .finally(() => clearTimeout(timer));\n });\n}\n\n/**\n * Read every integration concurrently and isolate the ones that throw or hang, so a single\n * unreachable provider degrades to a per-source error instead of failing the listing.\n */\nasync function settleByIntegration<T>(\n requests: Array<{ integrationId: string; read: () => Promise<T> }>,\n): Promise<{ pages: Array<{ integrationId: string; value: T }>; failures: IntakeIntegrationFailure[] }> {\n const settled = await Promise.all(\n requests.map(async ({ integrationId, read }): Promise<SettledIntegration<T>> => {\n try {\n return { integrationId, value: await withTimeout(integrationId, read) };\n } catch (error) {\n console.error(`[factory] intake integration ${integrationId} is unavailable:`, error);\n return { integrationId, message: error instanceof Error ? error.message : String(error) };\n }\n }),\n );\n const pages: Array<{ integrationId: string; value: T }> = [];\n const failures: IntakeIntegrationFailure[] = [];\n for (const entry of settled) {\n if ('value' in entry) pages.push(entry);\n else failures.push(entry);\n }\n return { pages, failures };\n}\n\nconst MAX_INTAKE_SOURCE_ID_LENGTH = 1024;\n\ninterface ParsedBinding {\n integrationId: string;\n sourceId: string;\n factoryProjectId: string | null;\n /** Installed board target; `null`/omitted keeps legacy source-type routing. */\n board: string | null;\n}\n\n/** Validate a binding request body, rejecting unknown shapes. */\nexport function parseIntakeBinding(body: unknown): ParsedBinding | null {\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return null;\n const { integrationId, sourceId, factoryProjectId, board } = body as Record<string, unknown>;\n const isId = (value: unknown) => typeof value === 'string' && value.length > 0 && value.length <= 256;\n const isSourceId = (value: unknown) =>\n typeof value === 'string' && value.length > 0 && value.length <= MAX_INTAKE_SOURCE_ID_LENGTH;\n if (!isId(integrationId) || !isSourceId(sourceId)) return null;\n if (factoryProjectId !== null && !isId(factoryProjectId)) return null;\n if (board !== undefined && board !== null && !isId(board)) return null;\n return {\n integrationId: integrationId as string,\n sourceId: sourceId as string,\n factoryProjectId: factoryProjectId as string | null,\n board: (board as string | null | undefined) ?? null,\n };\n}\n\nconst identifier = z.string().min(1).max(256);\nconst labelRouteBodySchema = z.object({\n factoryProjectId: identifier,\n integrationId: identifier,\n label: z\n .string()\n .max(256)\n .transform(normalizeIntakeLabel)\n .refine(label => label.length > 0, 'label must not be blank'),\n /** Installed board target; `null` removes the route so the label falls back to Work. */\n board: identifier.nullish().transform(board => board ?? null),\n});\ntype ParsedLabelRoute = z.output<typeof labelRouteBodySchema>;\n\n/** Validate a label-route request body, rejecting unknown shapes. */\nexport function parseIntakeLabelRoute(body: unknown): ParsedLabelRoute | null {\n const parsed = labelRouteBodySchema.safeParse(body);\n return parsed.success ? parsed.data : null;\n}\n\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\nfunction sanitizeIdList(value: unknown): string[] | null | undefined {\n if (value === null) return null;\n if (!Array.isArray(value) || value.length > 200) return undefined;\n const ids = value.filter(\n (item): item is string => typeof item === 'string' && item.length > 0 && item.length <= MAX_INTAKE_SOURCE_ID_LENGTH,\n );\n return ids.length === value.length && new Set(ids).size === ids.length ? ids : undefined;\n}\n\nfunction sanitizeLinearRepositoryMap(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;\n const entries = Object.entries(value);\n if (entries.length > 200) return undefined;\n const mapping: Record<string, string> = Object.create(null);\n for (const [projectId, slug] of entries) {\n if (\n !projectId ||\n projectId.length > MAX_INTAKE_SOURCE_ID_LENGTH ||\n typeof slug !== 'string' ||\n !slug.trim() ||\n slug.length > 512\n ) {\n return undefined;\n }\n mapping[projectId] = slug;\n }\n return mapping;\n}\n\n/** Validate a request body into an intake config, rejecting unknown shapes. */\nexport function parseIntakeConfig(body: unknown): IntakeConfig | null {\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return null;\n const entries = Object.entries(body);\n if (entries.length > 50) return null;\n\n // Null-prototype so an `__proto__` key lands as a real entry instead of silently\n // reassigning the prototype and disappearing from the validation below.\n const config: IntakeConfig = Object.create(null);\n for (const [integrationId, value] of entries) {\n if (\n !integrationId ||\n integrationId.length > 128 ||\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value)\n ) {\n return null;\n }\n const selection = value as { enabled?: unknown; sourceIds?: unknown; repositoryByLinearProject?: unknown };\n if (typeof selection.enabled !== 'boolean') return null;\n const sourceIds = sanitizeIdList(selection.sourceIds ?? null);\n if (sourceIds === undefined) return null;\n const repositoryByLinearProject =\n integrationId === 'linear' ? sanitizeLinearRepositoryMap(selection.repositoryByLinearProject) : undefined;\n if (\n integrationId === 'linear' &&\n selection.repositoryByLinearProject !== undefined &&\n repositoryByLinearProject === undefined\n )\n return null;\n config[integrationId] = {\n enabled: selection.enabled,\n sourceIds,\n ...(repositoryByLinearProject ? { repositoryByLinearProject } : {}),\n };\n }\n return config;\n}\n\nfunction encodeCursor(cursors: Record<string, string>): string | null {\n return Object.keys(cursors).length > 0 ? Buffer.from(JSON.stringify(cursors)).toString('base64url') : null;\n}\n\nfunction decodeCursor(value: string | undefined): Record<string, string> | null {\n if (!value) return {};\n try {\n const parsed = JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return null;\n const entries = Object.entries(parsed);\n if (entries.some(([key, cursor]) => !key || typeof cursor !== 'string')) return null;\n return Object.fromEntries(entries) as Record<string, string>;\n } catch {\n return null;\n }\n}\n\nexport class IntakeRoutes extends Route<IntakeRoutesDeps> {\n async #resolveTenant(c: Context): Promise<{ orgId: string; userId: string } | { response: Response }> {\n await this.deps.auth.ensureUser(c);\n const tenant = this.deps.auth.tenant(c);\n if (!tenant) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (!tenant.orgId) {\n return {\n response: c.json(\n { error: 'organization_required', message: 'Intake configuration requires an organization.' },\n 403,\n ),\n };\n }\n return { orgId: tenant.orgId, userId: tenant.userId };\n }\n\n routes(): ApiRoute[] {\n const { audit, intake, projects, integrations = [], boardRegistry, workItems, githubRepositories } = this.deps;\n const integrationIds = integrations.map(integration => integration.id);\n\n return [\n registerApiRoute('/web/intake/config', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n await intake.ensureReady();\n const config = await intake.getConfig({ orgId: tenant.orgId, integrationIds });\n return c.json({ config });\n },\n }),\n registerApiRoute('/web/intake/config', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const config = parseIntakeConfig(body);\n if (!config) {\n return c.json({ error: 'invalid_config' }, 400);\n }\n\n const registeredConfig: IntakeConfig = Object.create(null);\n for (const [integrationId, selection] of Object.entries(config)) {\n if (integrationIds.includes(integrationId)) {\n registeredConfig[integrationId] = selection;\n continue;\n }\n if (selection.enabled || selection.sourceIds?.length) {\n return c.json({ error: 'invalid_config' }, 400);\n }\n }\n\n await intake.ensureReady();\n await intake.saveConfig({ orgId: tenant.orgId, config: registeredConfig });\n await audit.emit({\n context: loose(c),\n input: {\n action: 'factory.intake.config_updated',\n targets: [{ type: 'intake_config', id: tenant.orgId }],\n metadata: Object.fromEntries(\n Object.entries(registeredConfig).map(([integrationId, selection]) => [\n integrationId,\n { enabled: selection.enabled, sources: selection.sourceIds?.length ?? null },\n ]),\n ),\n },\n });\n return c.json({ config: registeredConfig });\n },\n }),\n registerApiRoute('/web/intake/bindings', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n await intake.ensureReady();\n return c.json({ bindings: await intake.listBindings({ orgId: tenant.orgId }) });\n },\n }),\n registerApiRoute('/web/intake/bindings', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const binding = parseIntakeBinding(body);\n if (!binding || !integrationIds.includes(binding.integrationId)) {\n return c.json({ error: 'invalid_binding' }, 400);\n }\n if (binding.factoryProjectId && projects) {\n const project = await projects.get({ orgId: tenant.orgId, id: binding.factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n }\n if (binding.board !== null && !boardRegistry?.has(binding.board)) {\n return c.json({ error: 'invalid_board', message: `Board '${binding.board}' is not installed.` }, 422);\n }\n\n await intake.ensureReady();\n let auditFactoryProjectId = binding.factoryProjectId;\n let relocated: { moved: number; skipped: number } | null = null;\n if (binding.factoryProjectId === null) {\n const previousBinding = await intake.clearBinding({\n orgId: tenant.orgId,\n integrationId: binding.integrationId,\n sourceId: binding.sourceId,\n });\n auditFactoryProjectId = previousBinding?.factoryProjectId ?? null;\n } else {\n const previousBinding = await intake.getBinding({\n orgId: tenant.orgId,\n integrationId: binding.integrationId,\n sourceId: binding.sourceId,\n });\n await intake.setBinding({\n orgId: tenant.orgId,\n userId: tenant.userId,\n integrationId: binding.integrationId,\n sourceId: binding.sourceId,\n factoryProjectId: binding.factoryProjectId,\n board: binding.board,\n });\n // A source that stays in the same project but is pointed at a different board\n // takes its resting cards along. Bindings that predate persisted boards have a\n // null board yet still fed Work/Review, so relocation compares each card's\n // effective board rather than trusting the previous binding value.\n const nextBoard = binding.board;\n const integration = integrations.find(candidate => candidate.id === binding.integrationId);\n if (\n workItems &&\n boardRegistry &&\n integration &&\n previousBinding?.factoryProjectId === binding.factoryProjectId &&\n nextBoard !== null &&\n previousBinding.board !== nextBoard\n ) {\n try {\n const config = await intake.getConfig({\n orgId: tenant.orgId,\n integrationIds: [binding.integrationId],\n });\n const configuredSourceIds = config[binding.integrationId]?.sourceIds ?? [];\n const attributionSourceIds = configuredSourceIds.includes(binding.sourceId)\n ? configuredSourceIds\n : [...configuredSourceIds, binding.sourceId];\n relocated = await relocateSourceCards({\n workItems,\n integration,\n boardRegistry,\n orgId: tenant.orgId,\n userId: tenant.userId,\n factoryProjectId: binding.factoryProjectId,\n sourceId: binding.sourceId,\n attributionSourceIds,\n targetBoard: nextBoard,\n });\n } catch (error) {\n // The binding is saved; the cards can be moved by hand if the provider was unreachable.\n console.error(`[factory] intake rebind could not relocate ${binding.integrationId} cards:`, error);\n }\n }\n }\n await audit.emit({\n context: loose(c),\n input: {\n action: 'factory.intake.binding_updated',\n ...(auditFactoryProjectId ? { factoryProjectId: auditFactoryProjectId } : {}),\n targets: [{ type: 'intake_source', id: `${binding.integrationId}:${binding.sourceId}` }],\n metadata: {\n factoryProjectId: binding.factoryProjectId,\n board: binding.board,\n ...(relocated ? { relocated } : {}),\n },\n },\n });\n return c.json({\n bindings: await intake.listBindings({ orgId: tenant.orgId }),\n ...(relocated ? { relocated } : {}),\n });\n },\n }),\n registerApiRoute('/web/intake/label-routes', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n const factoryProjectId = c.req.query('factoryProjectId');\n await intake.ensureReady();\n return c.json({\n routes: await intake.listLabelRoutes({\n orgId: tenant.orgId,\n ...(factoryProjectId ? { factoryProjectId } : {}),\n }),\n });\n },\n }),\n registerApiRoute('/web/intake/label-routes', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const route = parseIntakeLabelRoute(body);\n if (!route || !integrationIds.includes(route.integrationId)) {\n return c.json({ error: 'invalid_label_route' }, 400);\n }\n if (projects) {\n const project = await projects.get({ orgId: tenant.orgId, id: route.factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n }\n if (route.board !== null && !boardRegistry?.has(route.board)) {\n return c.json({ error: 'invalid_board', message: `Board '${route.board}' is not installed.` }, 422);\n }\n\n await intake.ensureReady();\n const scope = {\n orgId: tenant.orgId,\n factoryProjectId: route.factoryProjectId,\n integrationId: route.integrationId,\n };\n const previous = (await intake.listLabelRoutes(scope)).find(existing => existing.label === route.label);\n if (route.board === null) {\n await intake.clearLabelRoute({ ...scope, label: route.label });\n } else {\n await intake.setLabelRoute({ ...scope, label: route.label, board: route.board, userId: tenant.userId });\n }\n\n // Cards already carrying the label follow the route: onto the new board, or — when the\n // label is no longer routed anywhere — to the repository binding's board or Work.\n let relocated: { moved: number; skipped: number } | null = null;\n if (workItems && boardRegistry && (previous?.board ?? null) !== route.board) {\n try {\n relocated = await relocateLabeledCards({\n workItems,\n boardRegistry,\n orgId: tenant.orgId,\n userId: tenant.userId,\n factoryProjectId: route.factoryProjectId,\n integrationId: route.integrationId,\n label: route.label,\n routes: await intake.listLabelRoutes(scope),\n intake,\n githubRepositories,\n });\n } catch (error) {\n // The route is saved; the cards can be moved by hand.\n console.error(`[factory] intake label route could not relocate ${route.integrationId} cards:`, error);\n }\n }\n await audit.emit({\n context: loose(c),\n input: {\n action: 'factory.intake.label_route_updated',\n factoryProjectId: route.factoryProjectId,\n targets: [{ type: 'intake_label_route', id: `${route.integrationId}:${route.label}` }],\n metadata: { board: route.board, ...(relocated ? { relocated } : {}) },\n },\n });\n return c.json({\n routes: await intake.listLabelRoutes({ orgId: tenant.orgId, factoryProjectId: route.factoryProjectId }),\n ...(relocated ? { relocated } : {}),\n });\n },\n }),\n registerApiRoute('/web/intake/sources', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n const { pages, failures } = await settleByIntegration(\n integrations.map(integration => ({\n integrationId: integration.id,\n read: () => integration.intake.listSources(tenant),\n })),\n );\n return c.json({\n sources: pages.flatMap(({ integrationId, value }) => value.map(source => ({ integrationId, ...source }))),\n failures,\n });\n },\n }),\n registerApiRoute('/web/intake/items', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n const cursors = decodeCursor(c.req.query('cursor'));\n if (!cursors) return c.json({ error: 'invalid_cursor' }, 400);\n\n await intake.ensureReady();\n const config = await intake.getConfig({ orgId: tenant.orgId, integrationIds });\n const { pages, failures } = await settleByIntegration(\n integrations.flatMap(integration => {\n const selection = config[integration.id];\n if (!selection?.enabled || !selection.sourceIds?.length) return [];\n const sourceIds = selection.sourceIds;\n const cursor = cursors[integration.id];\n return [\n {\n integrationId: integration.id,\n read: () => integration.intake.listItems({ ...tenant, sourceIds, ...(cursor ? { cursor } : {}) }),\n },\n ];\n }),\n );\n\n const items: AggregatedIntakeItem[] = [];\n const nextCursors: Record<string, string> = {};\n for (const { integrationId, value } of pages) {\n items.push(\n ...value.items.map(item => {\n const { source, ...candidate } = item;\n return { ...candidate, integrationId, externalSource: { integrationId, ...source } };\n }),\n );\n if (value.nextCursor) nextCursors[integrationId] = value.nextCursor;\n }\n // Keep the cursor an unavailable integration came in with, so the next page resumes there instead of replaying it.\n for (const { integrationId } of failures) {\n const cursor = cursors[integrationId];\n if (cursor) nextCursors[integrationId] = cursor;\n }\n return c.json({ items, nextCursor: encodeCursor(nextCursors), failures });\n },\n }),\n ];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"intake.js","names":[],"sources":["../../src/routes/intake.ts"],"sourcesContent":["import type { ApiRoute } from '@mastra/core/server';\nimport { registerApiRoute } from '@mastra/core/server';\nimport type { Context } from 'hono';\nimport { z } from 'zod';\n\nimport type { BoardRegistry } from '../boards/index.js';\nimport { cardLabels, moveCardToBoard } from '../boards/relocate.js';\nimport type { Intake, IntakeItem } from '../capabilities/intake.js';\nimport type { AuditEmitter } from '../storage/domains/audit/domain.js';\nimport { normalizeIntakeLabel, resolveIntakeLabelRoute } from '../storage/domains/intake/base.js';\nimport type { IntakeConfig, IntakeLabelRoute, IntakeStorage } from '../storage/domains/intake/base.js';\nimport type { SourceControlStorageHandle } from '../storage/domains/source-control/base.js';\nimport type { WorkItemsStorage } from '../storage/domains/work-items/base.js';\nimport type { RouteDependencies } from './route.js';\nimport { Route } from './route.js';\n\nexport interface IntakeIntegration {\n id: string;\n intake: Pick<Intake, 'listSources' | 'listItems'>;\n}\n\ninterface AggregatedIntakeItem extends Omit<IntakeItem, 'source'> {\n integrationId: string;\n externalSource: {\n integrationId: string;\n type: string;\n externalId: string;\n url?: string;\n };\n}\n\nexport interface IntakeRoutesDeps extends RouteDependencies {\n audit: AuditEmitter;\n /** Intake selection domain handle. */\n intake: IntakeStorage;\n /** Factory project domain handle, used to validate binding targets. */\n projects?: { get(input: { orgId: string; id: string }): Promise<unknown | null> };\n integrations?: IntakeIntegration[];\n /** Installed boards, used to validate binding targets. Absent means only legacy routing is accepted. */\n boardRegistry?: BoardRegistry;\n /** Work items domain handle; when present, rebinding a source to another board moves its resting cards. */\n workItems?: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;\n /** GitHub repositories, used to match a card to the repository binding its source id names. */\n githubRepositories?: Pick<SourceControlStorageHandle['repositories'], 'get'>;\n}\n\n/** Upper bound on source pages read while relocating cards, so a huge source cannot stall the request. */\nconst REBIND_MAX_PAGES = 20;\n/**\n * One deadline for the whole rebind read, not one per page: the binding is already saved when we\n * get here, so the caller is only waiting on relocation and a slow provider must not hold the\n * response for pages × timeout.\n */\nconst REBIND_READ_BUDGET_MS = 30_000;\n\n/**\n * Keys under which an intake item may be persisted as a work item. Providers key items by their\n * own id, while materialization uses the human identifier (`linear:MAS-44`), so both are accepted.\n */\nfunction intakeItemSourceKeys(integrationId: string, item: IntakeItem): string[] {\n const identifier = item.metadata?.identifier;\n return typeof identifier === 'string' && identifier.length > 0\n ? [item.source.externalId, `${integrationId}:${identifier}`]\n : [item.source.externalId];\n}\n\n/**\n * Move the cards that came from a rebound source onto its new board's initial phase. Terminal cards\n * stay put (they are history that belongs where it finished), as do cards with a session attached to\n * a current stage (a run owns them). Everything else moves, including cards parked in a working\n * phase that never started a run — auto-ingested issues sit in Work › Triage that way.\n */\nasync function relocateSourceCards({\n workItems,\n integration,\n boardRegistry,\n orgId,\n userId,\n factoryProjectId,\n sourceId,\n targetBoard,\n attributionSourceIds,\n}: {\n workItems: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;\n integration: IntakeIntegration;\n boardRegistry: BoardRegistry;\n orgId: string;\n userId: string;\n factoryProjectId: string;\n sourceId: string;\n targetBoard: string;\n attributionSourceIds: string[];\n}): Promise<{ moved: number; skipped: number }> {\n if (!boardRegistry.has(targetBoard)) return { moved: 0, skipped: 0 };\n\n const sourceKeys = new Set<string>();\n let cursor: string | undefined;\n const deadline = Date.now() + REBIND_READ_BUDGET_MS;\n for (let page = 0; page < REBIND_MAX_PAGES; page += 1) {\n const result = await withTimeout(\n integration.id,\n () =>\n integration.intake.listItems({\n orgId,\n userId,\n sourceIds: [sourceId],\n attributionSourceIds,\n cursor,\n }),\n deadline - Date.now(),\n );\n for (const item of result.items) {\n if (item.sourceId !== sourceId) continue;\n for (const key of intakeItemSourceKeys(integration.id, item)) sourceKeys.add(key);\n }\n if (!result.nextCursor) break;\n cursor = result.nextCursor;\n }\n if (sourceKeys.size === 0) return { moved: 0, skipped: 0 };\n\n let moved = 0;\n let skipped = 0;\n const items = await workItems.list({ orgId, factoryProjectId });\n for (const item of items) {\n const source = item.externalSource;\n if (!source || source.integrationId !== integration.id || !sourceKeys.has(source.externalId)) continue;\n const outcome = await moveCardToBoard({ workItems, boardRegistry, userId, item, targetBoard });\n if (outcome === 'moved') moved += 1;\n else if (outcome === 'skipped') skipped += 1;\n }\n return { moved, skipped };\n}\n\n/**\n * After a label route changes, every issue card in the project that carries `label` is re-routed\n * under the project's current routes: to the board its labels now select, or — when none of them is\n * routed any more — to its GitHub repository binding's board, falling back to Work.\n */\nasync function relocateLabeledCards({\n workItems,\n boardRegistry,\n orgId,\n userId,\n factoryProjectId,\n integrationId,\n label,\n routes,\n intake,\n githubRepositories,\n}: {\n workItems: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;\n boardRegistry: BoardRegistry;\n orgId: string;\n userId: string;\n factoryProjectId: string;\n integrationId: string;\n label: string;\n routes: readonly IntakeLabelRoute[];\n intake: Pick<IntakeStorage, 'listBindings'>;\n githubRepositories?: Pick<SourceControlStorageHandle['repositories'], 'get'>;\n}): Promise<{ moved: number; skipped: number }> {\n const changed = normalizeIntakeLabel(label);\n const repositoryBoards =\n integrationId === 'github'\n ? await githubRepositoryBoards({ intake, githubRepositories, boardRegistry, orgId, factoryProjectId })\n : [];\n let moved = 0;\n let skipped = 0;\n for (const item of await workItems.list({ orgId, factoryProjectId })) {\n const source = item.externalSource;\n if (!source || source.integrationId !== integrationId || source.type !== 'issue') continue;\n const labels = cardLabels(item);\n if (!labels.some(candidate => normalizeIntakeLabel(candidate) === changed)) continue;\n const targetBoard =\n resolveIntakeLabelRoute(routes, labels)?.board ??\n repositoryBoards.find(candidate => cardInRepository(item, candidate))?.board ??\n 'work';\n const outcome = await moveCardToBoard({ workItems, boardRegistry, userId, item, targetBoard });\n if (outcome === 'moved') moved += 1;\n else if (outcome === 'skipped') skipped += 1;\n }\n return { moved, skipped };\n}\n\ninterface GithubRepositoryBoard {\n board: string;\n slug: string;\n externalId?: string;\n}\n\n/**\n * The project's GitHub repository bindings that name an installed board. A binding's source id is\n * the internal repository id or the repository slug, so ids are resolved to the slug and external id\n * a card carries.\n */\nasync function githubRepositoryBoards({\n intake,\n githubRepositories,\n boardRegistry,\n orgId,\n factoryProjectId,\n}: {\n intake: Pick<IntakeStorage, 'listBindings'>;\n githubRepositories?: Pick<SourceControlStorageHandle['repositories'], 'get'>;\n boardRegistry: BoardRegistry;\n orgId: string;\n factoryProjectId: string;\n}): Promise<GithubRepositoryBoard[]> {\n const boards: GithubRepositoryBoard[] = [];\n for (const binding of await intake.listBindings({ orgId, integrationId: 'github' })) {\n if (binding.factoryProjectId !== factoryProjectId || !binding.board || !boardRegistry.has(binding.board)) continue;\n const repository = await githubRepositories?.get({ orgId, id: binding.sourceId });\n boards.push(\n repository\n ? { board: binding.board, slug: repository.slug.toLowerCase(), externalId: repository.externalId }\n : { board: binding.board, slug: binding.sourceId.toLowerCase() },\n );\n }\n return boards;\n}\n\nfunction cardInRepository(\n item: { metadata?: Record<string, unknown> | null; externalSource?: { url?: string } | null },\n repository: GithubRepositoryBoard,\n): boolean {\n const repositoryId = item.metadata?.githubRepositoryId;\n if (\n repository.externalId !== undefined &&\n repositoryId !== undefined &&\n String(repositoryId) === repository.externalId\n )\n return true;\n const match = /^https?:\\/\\/[^/]+\\/(.+)\\/(?:issues|pull)\\/\\d+(?:[/?#]|$)/.exec(item.externalSource?.url ?? '');\n return match?.[1]?.toLowerCase() === repository.slug;\n}\n\n/** One integration that failed while the rest of the aggregation succeeded. */\nexport interface IntakeIntegrationFailure {\n integrationId: string;\n message: string;\n}\n\ntype SettledIntegration<T> = { integrationId: string; value: T } | IntakeIntegrationFailure;\n\nconst PROVIDER_READ_TIMEOUT_MS = 15_000;\n\n/** The Intake contract takes no abort signal, so a slow read is abandoned, not cancelled. */\nfunction withTimeout<T>(\n integrationId: string,\n read: () => Promise<T>,\n timeoutMs: number = PROVIDER_READ_TIMEOUT_MS,\n): Promise<T> {\n return new Promise((resolve, reject) => {\n const budget = Math.max(0, timeoutMs);\n const timer = setTimeout(\n () => reject(new Error(`${integrationId} did not answer within ${Math.round(budget / 1000)}s`)),\n budget,\n );\n read()\n .then(resolve, reject)\n .finally(() => clearTimeout(timer));\n });\n}\n\n/**\n * Read every integration concurrently and isolate the ones that throw or hang, so a single\n * unreachable provider degrades to a per-source error instead of failing the listing.\n */\nasync function settleByIntegration<T>(\n requests: Array<{ integrationId: string; read: () => Promise<T> }>,\n): Promise<{ pages: Array<{ integrationId: string; value: T }>; failures: IntakeIntegrationFailure[] }> {\n const settled = await Promise.all(\n requests.map(async ({ integrationId, read }): Promise<SettledIntegration<T>> => {\n try {\n return { integrationId, value: await withTimeout(integrationId, read) };\n } catch (error) {\n console.error(`[factory] intake integration ${integrationId} is unavailable:`, error);\n return { integrationId, message: error instanceof Error ? error.message : String(error) };\n }\n }),\n );\n const pages: Array<{ integrationId: string; value: T }> = [];\n const failures: IntakeIntegrationFailure[] = [];\n for (const entry of settled) {\n if ('value' in entry) pages.push(entry);\n else failures.push(entry);\n }\n return { pages, failures };\n}\n\nconst MAX_INTAKE_SOURCE_ID_LENGTH = 1024;\n\ninterface ParsedBinding {\n integrationId: string;\n sourceId: string;\n factoryProjectId: string | null;\n /** Installed board target; `null`/omitted keeps legacy source-type routing. */\n board: string | null;\n}\n\n/** Validate a binding request body, rejecting unknown shapes. */\nexport function parseIntakeBinding(body: unknown): ParsedBinding | null {\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return null;\n const { integrationId, sourceId, factoryProjectId, board } = body as Record<string, unknown>;\n const isId = (value: unknown) => typeof value === 'string' && value.length > 0 && value.length <= 256;\n const isSourceId = (value: unknown) =>\n typeof value === 'string' && value.length > 0 && value.length <= MAX_INTAKE_SOURCE_ID_LENGTH;\n if (!isId(integrationId) || !isSourceId(sourceId)) return null;\n if (factoryProjectId !== null && !isId(factoryProjectId)) return null;\n if (board !== undefined && board !== null && !isId(board)) return null;\n return {\n integrationId: integrationId as string,\n sourceId: sourceId as string,\n factoryProjectId: factoryProjectId as string | null,\n board: (board as string | null | undefined) ?? null,\n };\n}\n\nconst identifier = z.string().min(1).max(256);\nconst labelRouteBodySchema = z.object({\n factoryProjectId: identifier,\n integrationId: identifier,\n label: z\n .string()\n .max(256)\n .transform(normalizeIntakeLabel)\n .refine(label => label.length > 0, 'label must not be blank'),\n /** Installed board target; `null` removes the route so the label falls back to Work. */\n board: identifier.nullish().transform(board => board ?? null),\n});\ntype ParsedLabelRoute = z.output<typeof labelRouteBodySchema>;\n\n/** Validate a label-route request body, rejecting unknown shapes. */\nexport function parseIntakeLabelRoute(body: unknown): ParsedLabelRoute | null {\n const parsed = labelRouteBodySchema.safeParse(body);\n return parsed.success ? parsed.data : null;\n}\n\nfunction loose(c: unknown): Context {\n return c as Context;\n}\n\nfunction sanitizeIdList(value: unknown): string[] | null | undefined {\n if (value === null) return null;\n if (!Array.isArray(value) || value.length > 200) return undefined;\n const ids = value.filter(\n (item): item is string => typeof item === 'string' && item.length > 0 && item.length <= MAX_INTAKE_SOURCE_ID_LENGTH,\n );\n return ids.length === value.length && new Set(ids).size === ids.length ? ids : undefined;\n}\n\nfunction sanitizeLinearRepositoryMap(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined;\n const entries = Object.entries(value);\n if (entries.length > 200) return undefined;\n const mapping: Record<string, string> = Object.create(null);\n for (const [projectId, slug] of entries) {\n if (\n !projectId ||\n projectId.length > MAX_INTAKE_SOURCE_ID_LENGTH ||\n typeof slug !== 'string' ||\n !slug.trim() ||\n slug.length > 512\n ) {\n return undefined;\n }\n mapping[projectId] = slug;\n }\n return mapping;\n}\n\n/** Validate a request body into an intake config, rejecting unknown shapes. */\nexport function parseIntakeConfig(body: unknown): IntakeConfig | null {\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return null;\n const entries = Object.entries(body);\n if (entries.length > 50) return null;\n\n // Null-prototype so an `__proto__` key lands as a real entry instead of silently\n // reassigning the prototype and disappearing from the validation below.\n const config: IntakeConfig = Object.create(null);\n for (const [integrationId, value] of entries) {\n if (\n !integrationId ||\n integrationId.length > 128 ||\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value)\n ) {\n return null;\n }\n const selection = value as { enabled?: unknown; sourceIds?: unknown; repositoryByLinearProject?: unknown };\n if (typeof selection.enabled !== 'boolean') return null;\n const sourceIds = sanitizeIdList(selection.sourceIds ?? null);\n if (sourceIds === undefined) return null;\n const repositoryByLinearProject =\n integrationId === 'linear' ? sanitizeLinearRepositoryMap(selection.repositoryByLinearProject) : undefined;\n if (\n integrationId === 'linear' &&\n selection.repositoryByLinearProject !== undefined &&\n repositoryByLinearProject === undefined\n )\n return null;\n config[integrationId] = {\n enabled: selection.enabled,\n sourceIds,\n ...(repositoryByLinearProject ? { repositoryByLinearProject } : {}),\n };\n }\n return config;\n}\n\nfunction encodeCursor(cursors: Record<string, string>): string | null {\n return Object.keys(cursors).length > 0 ? Buffer.from(JSON.stringify(cursors)).toString('base64url') : null;\n}\n\nfunction decodeCursor(value: string | undefined): Record<string, string> | null {\n if (!value) return {};\n try {\n const parsed = JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return null;\n const entries = Object.entries(parsed);\n if (entries.some(([key, cursor]) => !key || typeof cursor !== 'string')) return null;\n return Object.fromEntries(entries) as Record<string, string>;\n } catch {\n return null;\n }\n}\n\nexport class IntakeRoutes extends Route<IntakeRoutesDeps> {\n async #resolveTenant(c: Context): Promise<{ orgId: string; userId: string } | { response: Response }> {\n await this.deps.auth.ensureUser(c);\n const tenant = this.deps.auth.tenant(c);\n if (!tenant) return { response: c.json({ error: 'unauthorized' }, 401) };\n if (!tenant.orgId) {\n return {\n response: c.json(\n { error: 'organization_required', message: 'Intake configuration requires an organization.' },\n 403,\n ),\n };\n }\n return { orgId: tenant.orgId, userId: tenant.userId };\n }\n\n routes(): ApiRoute[] {\n const { audit, intake, projects, integrations = [], boardRegistry, workItems, githubRepositories } = this.deps;\n const integrationIds = integrations.map(integration => integration.id);\n\n return [\n registerApiRoute('/web/intake/config', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n await intake.ensureReady();\n const config = await intake.getConfig({ orgId: tenant.orgId, integrationIds });\n return c.json({ config });\n },\n }),\n registerApiRoute('/web/intake/config', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const config = parseIntakeConfig(body);\n if (!config) {\n return c.json({ error: 'invalid_config' }, 400);\n }\n\n const registeredConfig: IntakeConfig = Object.create(null);\n for (const [integrationId, selection] of Object.entries(config)) {\n if (integrationIds.includes(integrationId)) {\n registeredConfig[integrationId] = selection;\n continue;\n }\n if (selection.enabled || selection.sourceIds?.length) {\n return c.json({ error: 'invalid_config' }, 400);\n }\n }\n\n await intake.ensureReady();\n await intake.mergeConfig({ orgId: tenant.orgId, config: registeredConfig });\n await audit.emit({\n context: loose(c),\n input: {\n action: 'factory.intake.config_updated',\n targets: [{ type: 'intake_config', id: tenant.orgId }],\n metadata: Object.fromEntries(\n Object.entries(registeredConfig).map(([integrationId, selection]) => [\n integrationId,\n { enabled: selection.enabled, sources: selection.sourceIds?.length ?? null },\n ]),\n ),\n },\n });\n return c.json({ config: await intake.getConfig({ orgId: tenant.orgId, integrationIds }) });\n },\n }),\n registerApiRoute('/web/intake/bindings', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n await intake.ensureReady();\n return c.json({ bindings: await intake.listBindings({ orgId: tenant.orgId }) });\n },\n }),\n registerApiRoute('/web/intake/bindings', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const binding = parseIntakeBinding(body);\n if (!binding || !integrationIds.includes(binding.integrationId)) {\n return c.json({ error: 'invalid_binding' }, 400);\n }\n if (binding.factoryProjectId && projects) {\n const project = await projects.get({ orgId: tenant.orgId, id: binding.factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n }\n if (binding.board !== null && !boardRegistry?.has(binding.board)) {\n return c.json({ error: 'invalid_board', message: `Board '${binding.board}' is not installed.` }, 422);\n }\n\n await intake.ensureReady();\n let auditFactoryProjectId = binding.factoryProjectId;\n let relocated: { moved: number; skipped: number } | null = null;\n if (binding.factoryProjectId === null) {\n const previousBinding = await intake.clearBinding({\n orgId: tenant.orgId,\n integrationId: binding.integrationId,\n sourceId: binding.sourceId,\n });\n auditFactoryProjectId = previousBinding?.factoryProjectId ?? null;\n } else {\n const previousBinding = await intake.getBinding({\n orgId: tenant.orgId,\n integrationId: binding.integrationId,\n sourceId: binding.sourceId,\n });\n await intake.setBinding({\n orgId: tenant.orgId,\n userId: tenant.userId,\n integrationId: binding.integrationId,\n sourceId: binding.sourceId,\n factoryProjectId: binding.factoryProjectId,\n board: binding.board,\n });\n // A source that stays in the same project but is pointed at a different board\n // takes its resting cards along. Bindings that predate persisted boards have a\n // null board yet still fed Work/Review, so relocation compares each card's\n // effective board rather than trusting the previous binding value.\n const nextBoard = binding.board;\n const integration = integrations.find(candidate => candidate.id === binding.integrationId);\n if (\n workItems &&\n boardRegistry &&\n integration &&\n previousBinding?.factoryProjectId === binding.factoryProjectId &&\n nextBoard !== null &&\n previousBinding.board !== nextBoard\n ) {\n try {\n const config = await intake.getConfig({\n orgId: tenant.orgId,\n integrationIds: [binding.integrationId],\n });\n const configuredSourceIds = config[binding.integrationId]?.sourceIds ?? [];\n const attributionSourceIds = configuredSourceIds.includes(binding.sourceId)\n ? configuredSourceIds\n : [...configuredSourceIds, binding.sourceId];\n relocated = await relocateSourceCards({\n workItems,\n integration,\n boardRegistry,\n orgId: tenant.orgId,\n userId: tenant.userId,\n factoryProjectId: binding.factoryProjectId,\n sourceId: binding.sourceId,\n attributionSourceIds,\n targetBoard: nextBoard,\n });\n } catch (error) {\n // The binding is saved; the cards can be moved by hand if the provider was unreachable.\n console.error(`[factory] intake rebind could not relocate ${binding.integrationId} cards:`, error);\n }\n }\n }\n await audit.emit({\n context: loose(c),\n input: {\n action: 'factory.intake.binding_updated',\n ...(auditFactoryProjectId ? { factoryProjectId: auditFactoryProjectId } : {}),\n targets: [{ type: 'intake_source', id: `${binding.integrationId}:${binding.sourceId}` }],\n metadata: {\n factoryProjectId: binding.factoryProjectId,\n board: binding.board,\n ...(relocated ? { relocated } : {}),\n },\n },\n });\n return c.json({\n bindings: await intake.listBindings({ orgId: tenant.orgId }),\n ...(relocated ? { relocated } : {}),\n });\n },\n }),\n registerApiRoute('/web/intake/label-routes', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n const factoryProjectId = c.req.query('factoryProjectId');\n await intake.ensureReady();\n return c.json({\n routes: await intake.listLabelRoutes({\n orgId: tenant.orgId,\n ...(factoryProjectId ? { factoryProjectId } : {}),\n }),\n });\n },\n }),\n registerApiRoute('/web/intake/label-routes', {\n method: 'PUT',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n return c.json({ error: 'Invalid JSON body' }, 400);\n }\n const route = parseIntakeLabelRoute(body);\n if (!route || !integrationIds.includes(route.integrationId)) {\n return c.json({ error: 'invalid_label_route' }, 400);\n }\n if (projects) {\n const project = await projects.get({ orgId: tenant.orgId, id: route.factoryProjectId });\n if (!project) return c.json({ error: 'factory_project_not_found' }, 404);\n }\n if (route.board !== null && !boardRegistry?.has(route.board)) {\n return c.json({ error: 'invalid_board', message: `Board '${route.board}' is not installed.` }, 422);\n }\n\n await intake.ensureReady();\n const scope = {\n orgId: tenant.orgId,\n factoryProjectId: route.factoryProjectId,\n integrationId: route.integrationId,\n };\n const previous = (await intake.listLabelRoutes(scope)).find(existing => existing.label === route.label);\n if (route.board === null) {\n await intake.clearLabelRoute({ ...scope, label: route.label });\n } else {\n await intake.setLabelRoute({ ...scope, label: route.label, board: route.board, userId: tenant.userId });\n }\n\n // Cards already carrying the label follow the route: onto the new board, or — when the\n // label is no longer routed anywhere — to the repository binding's board or Work.\n let relocated: { moved: number; skipped: number } | null = null;\n if (workItems && boardRegistry && (previous?.board ?? null) !== route.board) {\n try {\n relocated = await relocateLabeledCards({\n workItems,\n boardRegistry,\n orgId: tenant.orgId,\n userId: tenant.userId,\n factoryProjectId: route.factoryProjectId,\n integrationId: route.integrationId,\n label: route.label,\n routes: await intake.listLabelRoutes(scope),\n intake,\n githubRepositories,\n });\n } catch (error) {\n // The route is saved; the cards can be moved by hand.\n console.error(`[factory] intake label route could not relocate ${route.integrationId} cards:`, error);\n }\n }\n await audit.emit({\n context: loose(c),\n input: {\n action: 'factory.intake.label_route_updated',\n factoryProjectId: route.factoryProjectId,\n targets: [{ type: 'intake_label_route', id: `${route.integrationId}:${route.label}` }],\n metadata: { board: route.board, ...(relocated ? { relocated } : {}) },\n },\n });\n return c.json({\n routes: await intake.listLabelRoutes({ orgId: tenant.orgId, factoryProjectId: route.factoryProjectId }),\n ...(relocated ? { relocated } : {}),\n });\n },\n }),\n registerApiRoute('/web/intake/sources', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n const { pages, failures } = await settleByIntegration(\n integrations.map(integration => ({\n integrationId: integration.id,\n read: () => integration.intake.listSources(tenant),\n })),\n );\n return c.json({\n sources: pages.flatMap(({ integrationId, value }) => value.map(source => ({ integrationId, ...source }))),\n failures,\n });\n },\n }),\n registerApiRoute('/web/intake/items', {\n method: 'GET',\n requiresAuth: false,\n handler: async c => {\n const tenant = await this.#resolveTenant(loose(c));\n if ('response' in tenant) return tenant.response;\n const cursors = decodeCursor(c.req.query('cursor'));\n if (!cursors) return c.json({ error: 'invalid_cursor' }, 400);\n\n await intake.ensureReady();\n const config = await intake.getConfig({ orgId: tenant.orgId, integrationIds });\n const { pages, failures } = await settleByIntegration(\n integrations.flatMap(integration => {\n const selection = config[integration.id];\n if (!selection?.enabled || !selection.sourceIds?.length) return [];\n const sourceIds = selection.sourceIds;\n const cursor = cursors[integration.id];\n return [\n {\n integrationId: integration.id,\n read: () => integration.intake.listItems({ ...tenant, sourceIds, ...(cursor ? { cursor } : {}) }),\n },\n ];\n }),\n );\n\n const items: AggregatedIntakeItem[] = [];\n const nextCursors: Record<string, string> = {};\n for (const { integrationId, value } of pages) {\n items.push(\n ...value.items.map(item => {\n const { source, ...candidate } = item;\n return { ...candidate, integrationId, externalSource: { integrationId, ...source } };\n }),\n );\n if (value.nextCursor) nextCursors[integrationId] = value.nextCursor;\n }\n // Keep the cursor an unavailable integration came in with, so the next page resumes there instead of replaying it.\n for (const { integrationId } of failures) {\n const cursor = cursors[integrationId];\n if (cursor) nextCursors[integrationId] = cursor;\n }\n return c.json({ items, nextCursor: encodeCursor(nextCursors), failures });\n },\n }),\n ];\n }\n}\n"],"mappings":";;;;;;;AA+CA,MAAM,mBAAmB;;;;;;AAMzB,MAAM,wBAAwB;;;;;AAM9B,SAAS,qBAAqB,eAAuB,MAA4B;CAC/E,MAAM,aAAa,KAAK,UAAU;CAClC,OAAO,OAAO,eAAe,YAAY,WAAW,SAAS,IACzD,CAAC,KAAK,OAAO,YAAY,GAAG,cAAc,GAAG,YAAY,IACzD,CAAC,KAAK,OAAO,UAAU;AAC7B;;;;;;;AAQA,eAAe,oBAAoB,EACjC,WACA,aACA,eACA,OACA,QACA,kBACA,UACA,aACA,wBAW8C;CAC9C,IAAI,CAAC,cAAc,IAAI,WAAW,GAAG,OAAO;EAAE,OAAO;EAAG,SAAS;CAAE;CAEnE,MAAM,6BAAa,IAAI,IAAY;CACnC,IAAI;CACJ,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,KAAK,IAAI,OAAO,GAAG,OAAO,kBAAkB,QAAQ,GAAG;EACrD,MAAM,SAAS,MAAM,YACnB,YAAY,UAEV,YAAY,OAAO,UAAU;GAC3B;GACA;GACA,WAAW,CAAC,QAAQ;GACpB;GACA;EACF,CAAC,GACH,WAAW,KAAK,IAAI,CACtB;EACA,KAAK,MAAM,QAAQ,OAAO,OAAO;GAC/B,IAAI,KAAK,aAAa,UAAU;GAChC,KAAK,MAAM,OAAO,qBAAqB,YAAY,IAAI,IAAI,GAAG,WAAW,IAAI,GAAG;EAClF;EACA,IAAI,CAAC,OAAO,YAAY;EACxB,SAAS,OAAO;CAClB;CACA,IAAI,WAAW,SAAS,GAAG,OAAO;EAAE,OAAO;EAAG,SAAS;CAAE;CAEzD,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,MAAM,QAAQ,MAAM,UAAU,KAAK;EAAE;EAAO;CAAiB,CAAC;CAC9D,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,UAAU,OAAO,kBAAkB,YAAY,MAAM,CAAC,WAAW,IAAI,OAAO,UAAU,GAAG;EAC9F,MAAM,UAAU,MAAM,gBAAgB;GAAE;GAAW;GAAe;GAAQ;GAAM;EAAY,CAAC;EAC7F,IAAI,YAAY,SAAS,SAAS;OAC7B,IAAI,YAAY,WAAW,WAAW;CAC7C;CACA,OAAO;EAAE;EAAO;CAAQ;AAC1B;;;;;;AAOA,eAAe,qBAAqB,EAClC,WACA,eACA,OACA,QACA,kBACA,eACA,OACA,QACA,QACA,sBAY8C;CAC9C,MAAM,UAAU,qBAAqB,KAAK;CAC1C,MAAM,mBACJ,kBAAkB,WACd,MAAM,uBAAuB;EAAE;EAAQ;EAAoB;EAAe;EAAO;CAAiB,CAAC,IACnG,CAAC;CACP,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,MAAM,UAAU,KAAK;EAAE;EAAO;CAAiB,CAAC,GAAG;EACpE,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,UAAU,OAAO,kBAAkB,iBAAiB,OAAO,SAAS,SAAS;EAClF,MAAM,SAAS,WAAW,IAAI;EAC9B,IAAI,CAAC,OAAO,MAAK,cAAa,qBAAqB,SAAS,MAAM,OAAO,GAAG;EAC5E,MAAM,cACJ,wBAAwB,QAAQ,MAAM,CAAC,EAAE,SACzC,iBAAiB,MAAK,cAAa,iBAAiB,MAAM,SAAS,CAAC,CAAC,EAAE,SACvE;EACF,MAAM,UAAU,MAAM,gBAAgB;GAAE;GAAW;GAAe;GAAQ;GAAM;EAAY,CAAC;EAC7F,IAAI,YAAY,SAAS,SAAS;OAC7B,IAAI,YAAY,WAAW,WAAW;CAC7C;CACA,OAAO;EAAE;EAAO;CAAQ;AAC1B;;;;;;AAaA,eAAe,uBAAuB,EACpC,QACA,oBACA,eACA,OACA,oBAOmC;CACnC,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,WAAW,MAAM,OAAO,aAAa;EAAE;EAAO,eAAe;CAAS,CAAC,GAAG;EACnF,IAAI,QAAQ,qBAAqB,oBAAoB,CAAC,QAAQ,SAAS,CAAC,cAAc,IAAI,QAAQ,KAAK,GAAG;EAC1G,MAAM,aAAa,MAAM,oBAAoB,IAAI;GAAE;GAAO,IAAI,QAAQ;EAAS,CAAC;EAChF,OAAO,KACL,aACI;GAAE,OAAO,QAAQ;GAAO,MAAM,WAAW,KAAK,YAAY;GAAG,YAAY,WAAW;EAAW,IAC/F;GAAE,OAAO,QAAQ;GAAO,MAAM,QAAQ,SAAS,YAAY;EAAE,CACnE;CACF;CACA,OAAO;AACT;AAEA,SAAS,iBACP,MACA,YACS;CACT,MAAM,eAAe,KAAK,UAAU;CACpC,IACE,WAAW,eAAe,KAAA,KAC1B,iBAAiB,KAAA,KACjB,OAAO,YAAY,MAAM,WAAW,YAEpC,OAAO;CAET,OADc,2DAA2D,KAAK,KAAK,gBAAgB,OAAO,EAC/F,CAAC,GAAG,EAAE,EAAE,YAAY,MAAM,WAAW;AAClD;AAUA,MAAM,2BAA2B;;AAGjC,SAAS,YACP,eACA,MACA,YAAoB,0BACR;CACZ,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,SAAS,KAAK,IAAI,GAAG,SAAS;EACpC,MAAM,QAAQ,iBACN,uBAAO,IAAI,MAAM,GAAG,cAAc,yBAAyB,KAAK,MAAM,SAAS,GAAI,EAAE,EAAE,CAAC,GAC9F,MACF;EACA,KAAK,CAAC,CACH,KAAK,SAAS,MAAM,CAAC,CACrB,cAAc,aAAa,KAAK,CAAC;CACtC,CAAC;AACH;;;;;AAMA,eAAe,oBACb,UACsG;CACtG,MAAM,UAAU,MAAM,QAAQ,IAC5B,SAAS,IAAI,OAAO,EAAE,eAAe,WAA2C;EAC9E,IAAI;GACF,OAAO;IAAE;IAAe,OAAO,MAAM,YAAY,eAAe,IAAI;GAAE;EACxE,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,cAAc,mBAAmB,KAAK;GACpF,OAAO;IAAE;IAAe,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAAE;EAC1F;CACF,CAAC,CACH;CACA,MAAM,QAAoD,CAAC;CAC3D,MAAM,WAAuC,CAAC;CAC9C,KAAK,MAAM,SAAS,SAClB,IAAI,WAAW,OAAO,MAAM,KAAK,KAAK;MACjC,SAAS,KAAK,KAAK;CAE1B,OAAO;EAAE;EAAO;CAAS;AAC3B;AAEA,MAAM,8BAA8B;;AAWpC,SAAgB,mBAAmB,MAAqC;CACtE,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG,OAAO;CAC7E,MAAM,EAAE,eAAe,UAAU,kBAAkB,UAAU;CAC7D,MAAM,QAAQ,UAAmB,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,MAAM,UAAU;CAClG,MAAM,cAAc,UAClB,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,MAAM,UAAU;CACnE,IAAI,CAAC,KAAK,aAAa,KAAK,CAAC,WAAW,QAAQ,GAAG,OAAO;CAC1D,IAAI,qBAAqB,QAAQ,CAAC,KAAK,gBAAgB,GAAG,OAAO;CACjE,IAAI,UAAU,KAAA,KAAa,UAAU,QAAQ,CAAC,KAAK,KAAK,GAAG,OAAO;CAClE,OAAO;EACU;EACL;EACQ;EAClB,OAAQ,SAAuC;CACjD;AACF;AAEA,MAAM,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG;AAC5C,MAAM,uBAAuB,EAAE,OAAO;CACpC,kBAAkB;CAClB,eAAe;CACf,OAAO,EACJ,OAAO,CAAC,CACR,IAAI,GAAG,CAAC,CACR,UAAU,oBAAoB,CAAC,CAC/B,QAAO,UAAS,MAAM,SAAS,GAAG,yBAAyB;;CAE9D,OAAO,WAAW,QAAQ,CAAC,CAAC,WAAU,UAAS,SAAS,IAAI;AAC9D,CAAC;;AAID,SAAgB,sBAAsB,MAAwC;CAC5E,MAAM,SAAS,qBAAqB,UAAU,IAAI;CAClD,OAAO,OAAO,UAAU,OAAO,OAAO;AACxC;AAEA,SAAS,MAAM,GAAqB;CAClC,OAAO;AACT;AAEA,SAAS,eAAe,OAA6C;CACnE,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,KAAK,OAAO,KAAA;CACxD,MAAM,MAAM,MAAM,QACf,SAAyB,OAAO,SAAS,YAAY,KAAK,SAAS,KAAK,KAAK,UAAU,2BAC1F;CACA,OAAO,IAAI,WAAW,MAAM,UAAU,IAAI,IAAI,GAAG,CAAC,CAAC,SAAS,IAAI,SAAS,MAAM,KAAA;AACjF;AAEA,SAAS,4BAA4B,OAAoD;CACvF,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;CAChF,MAAM,UAAU,OAAO,QAAQ,KAAK;CACpC,IAAI,QAAQ,SAAS,KAAK,OAAO,KAAA;CACjC,MAAM,UAAkC,OAAO,OAAO,IAAI;CAC1D,KAAK,MAAM,CAAC,WAAW,SAAS,SAAS;EACvC,IACE,CAAC,aACD,UAAU,SAAS,+BACnB,OAAO,SAAS,YAChB,CAAC,KAAK,KAAK,KACX,KAAK,SAAS,KAEd;EAEF,QAAQ,aAAa;CACvB;CACA,OAAO;AACT;;AAGA,SAAgB,kBAAkB,MAAoC;CACpE,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG,OAAO;CAC7E,MAAM,UAAU,OAAO,QAAQ,IAAI;CACnC,IAAI,QAAQ,SAAS,IAAI,OAAO;CAIhC,MAAM,SAAuB,OAAO,OAAO,IAAI;CAC/C,KAAK,MAAM,CAAC,eAAe,UAAU,SAAS;EAC5C,IACE,CAAC,iBACD,cAAc,SAAS,OACvB,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,GAEnB,OAAO;EAET,MAAM,YAAY;EAClB,IAAI,OAAO,UAAU,YAAY,WAAW,OAAO;EACnD,MAAM,YAAY,eAAe,UAAU,aAAa,IAAI;EAC5D,IAAI,cAAc,KAAA,GAAW,OAAO;EACpC,MAAM,4BACJ,kBAAkB,WAAW,4BAA4B,UAAU,yBAAyB,IAAI,KAAA;EAClG,IACE,kBAAkB,YAClB,UAAU,8BAA8B,KAAA,KACxC,8BAA8B,KAAA,GAE9B,OAAO;EACT,OAAO,iBAAiB;GACtB,SAAS,UAAU;GACnB;GACA,GAAI,4BAA4B,EAAE,0BAA0B,IAAI,CAAC;EACnE;CACF;CACA,OAAO;AACT;AAEA,SAAS,aAAa,SAAgD;CACpE,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,OAAO,KAAK,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,SAAS,WAAW,IAAI;AACxG;AAEA,SAAS,aAAa,OAA0D;CAC9E,IAAI,CAAC,OAAO,OAAO,CAAC;CACpB,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,OAAO,KAAK,OAAO,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC;EAC1E,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG,OAAO;EACnF,MAAM,UAAU,OAAO,QAAQ,MAAM;EACrC,IAAI,QAAQ,MAAM,CAAC,KAAK,YAAY,CAAC,OAAO,OAAO,WAAW,QAAQ,GAAG,OAAO;EAChF,OAAO,OAAO,YAAY,OAAO;CACnC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,IAAa,eAAb,cAAkC,MAAwB;CACxD,MAAM,eAAe,GAAiF;EACpG,MAAM,KAAK,KAAK,KAAK,WAAW,CAAC;EACjC,MAAM,SAAS,KAAK,KAAK,KAAK,OAAO,CAAC;EACtC,IAAI,CAAC,QAAQ,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,eAAe,GAAG,GAAG,EAAE;EACvE,IAAI,CAAC,OAAO,OACV,OAAO,EACL,UAAU,EAAE,KACV;GAAE,OAAO;GAAyB,SAAS;EAAiD,GAC5F,GACF,EACF;EAEF,OAAO;GAAE,OAAO,OAAO;GAAO,QAAQ,OAAO;EAAO;CACtD;CAEA,SAAqB;EACnB,MAAM,EAAE,OAAO,QAAQ,UAAU,eAAe,CAAC,GAAG,eAAe,WAAW,uBAAuB,KAAK;EAC1G,MAAM,iBAAiB,aAAa,KAAI,gBAAe,YAAY,EAAE;EAErE,OAAO;GACL,iBAAiB,sBAAsB;IACrC,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KACxC,MAAM,OAAO,YAAY;KACzB,MAAM,SAAS,MAAM,OAAO,UAAU;MAAE,OAAO,OAAO;MAAO;KAAe,CAAC;KAC7E,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;IAC1B;GACF,CAAC;GACD,iBAAiB,sBAAsB;IACrC,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KAExC,IAAI;KACJ,IAAI;MACF,OAAO,MAAM,EAAE,IAAI,KAAK;KAC1B,QAAQ;MACN,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;KACnD;KACA,MAAM,SAAS,kBAAkB,IAAI;KACrC,IAAI,CAAC,QACH,OAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG;KAGhD,MAAM,mBAAiC,OAAO,OAAO,IAAI;KACzD,KAAK,MAAM,CAAC,eAAe,cAAc,OAAO,QAAQ,MAAM,GAAG;MAC/D,IAAI,eAAe,SAAS,aAAa,GAAG;OAC1C,iBAAiB,iBAAiB;OAClC;MACF;MACA,IAAI,UAAU,WAAW,UAAU,WAAW,QAC5C,OAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG;KAElD;KAEA,MAAM,OAAO,YAAY;KACzB,MAAM,OAAO,YAAY;MAAE,OAAO,OAAO;MAAO,QAAQ;KAAiB,CAAC;KAC1E,MAAM,MAAM,KAAK;MACf,SAAS,MAAM,CAAC;MAChB,OAAO;OACL,QAAQ;OACR,SAAS,CAAC;QAAE,MAAM;QAAiB,IAAI,OAAO;OAAM,CAAC;OACrD,UAAU,OAAO,YACf,OAAO,QAAQ,gBAAgB,CAAC,CAAC,KAAK,CAAC,eAAe,eAAe,CACnE,eACA;QAAE,SAAS,UAAU;QAAS,SAAS,UAAU,WAAW,UAAU;OAAK,CAC7E,CAAC,CACH;MACF;KACF,CAAC;KACD,OAAO,EAAE,KAAK,EAAE,QAAQ,MAAM,OAAO,UAAU;MAAE,OAAO,OAAO;MAAO;KAAe,CAAC,EAAE,CAAC;IAC3F;GACF,CAAC;GACD,iBAAiB,wBAAwB;IACvC,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KACxC,MAAM,OAAO,YAAY;KACzB,OAAO,EAAE,KAAK,EAAE,UAAU,MAAM,OAAO,aAAa,EAAE,OAAO,OAAO,MAAM,CAAC,EAAE,CAAC;IAChF;GACF,CAAC;GACD,iBAAiB,wBAAwB;IACvC,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KAExC,IAAI;KACJ,IAAI;MACF,OAAO,MAAM,EAAE,IAAI,KAAK;KAC1B,QAAQ;MACN,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;KACnD;KACA,MAAM,UAAU,mBAAmB,IAAI;KACvC,IAAI,CAAC,WAAW,CAAC,eAAe,SAAS,QAAQ,aAAa,GAC5D,OAAO,EAAE,KAAK,EAAE,OAAO,kBAAkB,GAAG,GAAG;KAEjD,IAAI,QAAQ,oBAAoB,UAE1B;UAAA,CAAC,MADiB,SAAS,IAAI;OAAE,OAAO,OAAO;OAAO,IAAI,QAAQ;MAAiB,CAAC,GAC1E,OAAO,EAAE,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;KAAA;KAEzE,IAAI,QAAQ,UAAU,QAAQ,CAAC,eAAe,IAAI,QAAQ,KAAK,GAC7D,OAAO,EAAE,KAAK;MAAE,OAAO;MAAiB,SAAS,UAAU,QAAQ,MAAM;KAAqB,GAAG,GAAG;KAGtG,MAAM,OAAO,YAAY;KACzB,IAAI,wBAAwB,QAAQ;KACpC,IAAI,YAAuD;KAC3D,IAAI,QAAQ,qBAAqB,MAM/B,yBAAwB,MALM,OAAO,aAAa;MAChD,OAAO,OAAO;MACd,eAAe,QAAQ;MACvB,UAAU,QAAQ;KACpB,CAAC,EAAA,EACwC,oBAAoB;UACxD;MACL,MAAM,kBAAkB,MAAM,OAAO,WAAW;OAC9C,OAAO,OAAO;OACd,eAAe,QAAQ;OACvB,UAAU,QAAQ;MACpB,CAAC;MACD,MAAM,OAAO,WAAW;OACtB,OAAO,OAAO;OACd,QAAQ,OAAO;OACf,eAAe,QAAQ;OACvB,UAAU,QAAQ;OAClB,kBAAkB,QAAQ;OAC1B,OAAO,QAAQ;MACjB,CAAC;MAKD,MAAM,YAAY,QAAQ;MAC1B,MAAM,cAAc,aAAa,MAAK,cAAa,UAAU,OAAO,QAAQ,aAAa;MACzF,IACE,aACA,iBACA,eACA,iBAAiB,qBAAqB,QAAQ,oBAC9C,cAAc,QACd,gBAAgB,UAAU,WAE1B,IAAI;OAKF,MAAM,uBAAsB,MAJP,OAAO,UAAU;QACpC,OAAO,OAAO;QACd,gBAAgB,CAAC,QAAQ,aAAa;OACxC,CAAC,EAAA,CACkC,QAAQ,cAAc,EAAE,aAAa,CAAC;OACzE,MAAM,uBAAuB,oBAAoB,SAAS,QAAQ,QAAQ,IACtE,sBACA,CAAC,GAAG,qBAAqB,QAAQ,QAAQ;OAC7C,YAAY,MAAM,oBAAoB;QACpC;QACA;QACA;QACA,OAAO,OAAO;QACd,QAAQ,OAAO;QACf,kBAAkB,QAAQ;QAC1B,UAAU,QAAQ;QAClB;QACA,aAAa;OACf,CAAC;MACH,SAAS,OAAO;OAEd,QAAQ,MAAM,8CAA8C,QAAQ,cAAc,UAAU,KAAK;MACnG;KAEJ;KACA,MAAM,MAAM,KAAK;MACf,SAAS,MAAM,CAAC;MAChB,OAAO;OACL,QAAQ;OACR,GAAI,wBAAwB,EAAE,kBAAkB,sBAAsB,IAAI,CAAC;OAC3E,SAAS,CAAC;QAAE,MAAM;QAAiB,IAAI,GAAG,QAAQ,cAAc,GAAG,QAAQ;OAAW,CAAC;OACvF,UAAU;QACR,kBAAkB,QAAQ;QAC1B,OAAO,QAAQ;QACf,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;OACnC;MACF;KACF,CAAC;KACD,OAAO,EAAE,KAAK;MACZ,UAAU,MAAM,OAAO,aAAa,EAAE,OAAO,OAAO,MAAM,CAAC;MAC3D,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;KACnC,CAAC;IACH;GACF,CAAC;GACD,iBAAiB,4BAA4B;IAC3C,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KACxC,MAAM,mBAAmB,EAAE,IAAI,MAAM,kBAAkB;KACvD,MAAM,OAAO,YAAY;KACzB,OAAO,EAAE,KAAK,EACZ,QAAQ,MAAM,OAAO,gBAAgB;MACnC,OAAO,OAAO;MACd,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;KACjD,CAAC,EACH,CAAC;IACH;GACF,CAAC;GACD,iBAAiB,4BAA4B;IAC3C,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KAExC,IAAI;KACJ,IAAI;MACF,OAAO,MAAM,EAAE,IAAI,KAAK;KAC1B,QAAQ;MACN,OAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,GAAG,GAAG;KACnD;KACA,MAAM,QAAQ,sBAAsB,IAAI;KACxC,IAAI,CAAC,SAAS,CAAC,eAAe,SAAS,MAAM,aAAa,GACxD,OAAO,EAAE,KAAK,EAAE,OAAO,sBAAsB,GAAG,GAAG;KAErD,IAAI,UAEE;UAAA,CAAC,MADiB,SAAS,IAAI;OAAE,OAAO,OAAO;OAAO,IAAI,MAAM;MAAiB,CAAC,GACxE,OAAO,EAAE,KAAK,EAAE,OAAO,4BAA4B,GAAG,GAAG;KAAA;KAEzE,IAAI,MAAM,UAAU,QAAQ,CAAC,eAAe,IAAI,MAAM,KAAK,GACzD,OAAO,EAAE,KAAK;MAAE,OAAO;MAAiB,SAAS,UAAU,MAAM,MAAM;KAAqB,GAAG,GAAG;KAGpG,MAAM,OAAO,YAAY;KACzB,MAAM,QAAQ;MACZ,OAAO,OAAO;MACd,kBAAkB,MAAM;MACxB,eAAe,MAAM;KACvB;KACA,MAAM,YAAY,MAAM,OAAO,gBAAgB,KAAK,EAAA,CAAG,MAAK,aAAY,SAAS,UAAU,MAAM,KAAK;KACtG,IAAI,MAAM,UAAU,MAClB,MAAM,OAAO,gBAAgB;MAAE,GAAG;MAAO,OAAO,MAAM;KAAM,CAAC;UAE7D,MAAM,OAAO,cAAc;MAAE,GAAG;MAAO,OAAO,MAAM;MAAO,OAAO,MAAM;MAAO,QAAQ,OAAO;KAAO,CAAC;KAKxG,IAAI,YAAuD;KAC3D,IAAI,aAAa,kBAAkB,UAAU,SAAS,UAAU,MAAM,OACpE,IAAI;MACF,YAAY,MAAM,qBAAqB;OACrC;OACA;OACA,OAAO,OAAO;OACd,QAAQ,OAAO;OACf,kBAAkB,MAAM;OACxB,eAAe,MAAM;OACrB,OAAO,MAAM;OACb,QAAQ,MAAM,OAAO,gBAAgB,KAAK;OAC1C;OACA;MACF,CAAC;KACH,SAAS,OAAO;MAEd,QAAQ,MAAM,mDAAmD,MAAM,cAAc,UAAU,KAAK;KACtG;KAEF,MAAM,MAAM,KAAK;MACf,SAAS,MAAM,CAAC;MAChB,OAAO;OACL,QAAQ;OACR,kBAAkB,MAAM;OACxB,SAAS,CAAC;QAAE,MAAM;QAAsB,IAAI,GAAG,MAAM,cAAc,GAAG,MAAM;OAAQ,CAAC;OACrF,UAAU;QAAE,OAAO,MAAM;QAAO,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;OAAG;MACtE;KACF,CAAC;KACD,OAAO,EAAE,KAAK;MACZ,QAAQ,MAAM,OAAO,gBAAgB;OAAE,OAAO,OAAO;OAAO,kBAAkB,MAAM;MAAiB,CAAC;MACtG,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;KACnC,CAAC;IACH;GACF,CAAC;GACD,iBAAiB,uBAAuB;IACtC,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KACxC,MAAM,EAAE,OAAO,aAAa,MAAM,oBAChC,aAAa,KAAI,iBAAgB;MAC/B,eAAe,YAAY;MAC3B,YAAY,YAAY,OAAO,YAAY,MAAM;KACnD,EAAE,CACJ;KACA,OAAO,EAAE,KAAK;MACZ,SAAS,MAAM,SAAS,EAAE,eAAe,YAAY,MAAM,KAAI,YAAW;OAAE;OAAe,GAAG;MAAO,EAAE,CAAC;MACxG;KACF,CAAC;IACH;GACF,CAAC;GACD,iBAAiB,qBAAqB;IACpC,QAAQ;IACR,cAAc;IACd,SAAS,OAAM,MAAK;KAClB,MAAM,SAAS,MAAM,KAAK,eAAe,MAAM,CAAC,CAAC;KACjD,IAAI,cAAc,QAAQ,OAAO,OAAO;KACxC,MAAM,UAAU,aAAa,EAAE,IAAI,MAAM,QAAQ,CAAC;KAClD,IAAI,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,OAAO,iBAAiB,GAAG,GAAG;KAE5D,MAAM,OAAO,YAAY;KACzB,MAAM,SAAS,MAAM,OAAO,UAAU;MAAE,OAAO,OAAO;MAAO;KAAe,CAAC;KAC7E,MAAM,EAAE,OAAO,aAAa,MAAM,oBAChC,aAAa,SAAQ,gBAAe;MAClC,MAAM,YAAY,OAAO,YAAY;MACrC,IAAI,CAAC,WAAW,WAAW,CAAC,UAAU,WAAW,QAAQ,OAAO,CAAC;MACjE,MAAM,YAAY,UAAU;MAC5B,MAAM,SAAS,QAAQ,YAAY;MACnC,OAAO,CACL;OACE,eAAe,YAAY;OAC3B,YAAY,YAAY,OAAO,UAAU;QAAE,GAAG;QAAQ;QAAW,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;OAAG,CAAC;MAClG,CACF;KACF,CAAC,CACH;KAEA,MAAM,QAAgC,CAAC;KACvC,MAAM,cAAsC,CAAC;KAC7C,KAAK,MAAM,EAAE,eAAe,WAAW,OAAO;MAC5C,MAAM,KACJ,GAAG,MAAM,MAAM,KAAI,SAAQ;OACzB,MAAM,EAAE,QAAQ,GAAG,cAAc;OACjC,OAAO;QAAE,GAAG;QAAW;QAAe,gBAAgB;SAAE;SAAe,GAAG;QAAO;OAAE;MACrF,CAAC,CACH;MACA,IAAI,MAAM,YAAY,YAAY,iBAAiB,MAAM;KAC3D;KAEA,KAAK,MAAM,EAAE,mBAAmB,UAAU;MACxC,MAAM,SAAS,QAAQ;MACvB,IAAI,QAAQ,YAAY,iBAAiB;KAC3C;KACA,OAAO,EAAE,KAAK;MAAE;MAAO,YAAY,aAAa,WAAW;MAAG;KAAS,CAAC;IAC1E;GACF,CAAC;EACH;CACF;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { Route } from "./route.js";
2
2
  import { registerApiRoute } from "@mastra/core/server";
3
3
  import { KnowledgeUnsupportedCapabilityError, canonicalizeKnowledgeScope, isKnowledgeScopeVisible, knowledgeScopeKey, parseKnowledgeWikilinks } from "@mastra/core/storage";
4
- //#region src/routes/knowledge.ts
4
+ // src/routes/knowledge.ts
5
5
  /** Reserved node that anchors pinned records (see subconscious/pinned.ts). */
6
6
  const PINNED_NODE_NAME = "pinned";
7
7
  /** Hover-card budget for record text shipped in the graph payload. */
@@ -1122,7 +1122,6 @@ var KnowledgeRoutes = class extends Route {
1122
1122
  };
1123
1123
  }
1124
1124
  };
1125
- //#endregion
1126
1125
  export { KnowledgeRoutes };
1127
1126
 
1128
1127
  //# sourceMappingURL=knowledge.js.map
@@ -7,7 +7,7 @@ import { completeAnthropicLogin, startAnthropicLogin } from "@mastra/code-sdk/au
7
7
  import { copilotNextPollDelayMs, pollGitHubCopilotDeviceLogin, startGitHubCopilotDeviceLogin } from "@mastra/code-sdk/auth/providers/github-copilot";
8
8
  import { pollCodexDeviceLogin, startCodexDeviceLogin } from "@mastra/code-sdk/auth/providers/openai-codex";
9
9
  import { pollXAIDeviceLogin, startXAIDeviceLogin } from "@mastra/code-sdk/auth/providers/xai";
10
- //#region src/routes/oauth.ts
10
+ // src/routes/oauth.ts
11
11
  /**
12
12
  * Web OAuth sign-in routes for model providers (Settings › Providers).
13
13
  *
@@ -472,7 +472,6 @@ var OAuthRoutes = class extends Route {
472
472
  ];
473
473
  }
474
474
  };
475
- //#endregion
476
475
  export { OAuthRoutes };
477
476
 
478
477
  //# sourceMappingURL=oauth.js.map
@@ -6,7 +6,7 @@ import { Route } from "./route.js";
6
6
  import { registerApiRoute } from "@mastra/core/server";
7
7
  import { describeFactorySandbox, normalizeFactorySandboxSettings } from "@mastra/core/workspace";
8
8
  import { MastraError } from "@mastra/core/error";
9
- //#region src/routes/projects.ts
9
+ // src/routes/projects.ts
10
10
  const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11
11
  const MAX_NAME_LENGTH = 200;
12
12
  const MAX_REPOSITORY_COMMAND_LENGTH = 2e3;
@@ -916,7 +916,6 @@ var ProjectRoutes = class extends Route {
916
916
  ];
917
917
  }
918
918
  };
919
- //#endregion
920
919
  export { ProjectRoutes };
921
920
 
922
921
  //# sourceMappingURL=projects.js.map
@@ -1,7 +1,7 @@
1
1
  import { factoryUserOrgId } from "../auth.js";
2
2
  import { providerDisplayName } from "../provider-display-name.js";
3
3
  import { getCredentialProviderId as getAuthProviderId } from "@mastra/code-sdk/providers/model-ids";
4
- //#region src/routes/provider-credentials.ts
4
+ // src/routes/provider-credentials.ts
5
5
  /**
6
6
  * Providers that support a browser-driven OAuth sign-in flow, keyed by
7
7
  * *catalog* provider id (what the routes and settings UI use). All flows need
@@ -96,7 +96,6 @@ async function listTenantCredentialsForRequest({ c, auth, credentials }) {
96
96
  if (!storage) return [];
97
97
  return storage.listCredentials(tenantOrgId(tenant), tenant.userId);
98
98
  }
99
- //#endregion
100
99
  export { WEB_OAUTH_PROVIDERS, credentialLabel, getAuthProviderId, getTenantCredentialsStorage, listTenantCredentialsForRequest, resolveCredentialContext, tenantOrgId };
101
100
 
102
101
  //# sourceMappingURL=provider-credentials.js.map
@@ -1,4 +1,4 @@
1
- //#region src/routes/route.ts
1
+ // src/routes/route.ts
2
2
  /**
3
3
  * A route module: constructed once at boot with its dependencies, then asked
4
4
  * for the `ApiRoute[]` it serves.
@@ -9,7 +9,6 @@ var Route = class {
9
9
  this.deps = deps;
10
10
  }
11
11
  };
12
- //#endregion
13
12
  export { Route };
14
13
 
15
14
  //# sourceMappingURL=route.js.map
@@ -1,5 +1,5 @@
1
1
  import { MASTRA_RESOURCE_ID_KEY } from "@mastra/core/request-context";
2
- //#region src/routes/session-access.ts
2
+ // src/routes/session-access.ts
3
3
  /**
4
4
  * Whether the viewer may read a visible session's conversation. A session on its owner's memory is
5
5
  * the owner's alone, whatever its row says.
@@ -196,7 +196,6 @@ async function filterActiveRuns(c, canReach) {
196
196
  headers
197
197
  });
198
198
  }
199
- //#endregion
200
199
  export { canReadSessionResource, canSwitchSessionModel, canViewSourceControlSession, createSessionAccessGuard };
201
200
 
202
201
  //# sourceMappingURL=session-access.js.map
@@ -2,7 +2,7 @@ import { Route } from "./route.js";
2
2
  import { listFactorySkills } from "../skills/catalog.js";
3
3
  import { SkillInvocationError, formatSkillMessage, resolveSkillInvocation } from "../skills/service.js";
4
4
  import { registerApiRoute } from "@mastra/core/server";
5
- //#region src/routes/skills.ts
5
+ // src/routes/skills.ts
6
6
  const MAX_SESSION_ID_LENGTH = 512;
7
7
  const MAX_ARGUMENTS_LENGTH = 16384;
8
8
  const SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
@@ -147,7 +147,6 @@ var SkillRoutes = class extends Route {
147
147
  ];
148
148
  }
149
149
  };
150
- //#endregion
151
150
  export { SkillRoutes };
152
151
 
153
152
  //# sourceMappingURL=skills.js.map
@@ -1,17 +1,17 @@
1
1
  import { isValidGitRef } from "../sandbox/git-ref.js";
2
- import { canReadSessionResource, canSwitchSessionModel, canViewSourceControlSession } from "./session-access.js";
3
- import { waitForPendingFilesystemCapture } from "../session/filesystem-capture.js";
2
+ import { seedSessionOrg } from "../session/org-seed.js";
4
3
  import { isRunBound, isWorkerSession, listFactorySessionThreads, sessionMemoryResourceId, sessionThreadsToMove, userSessionResourceFor } from "../session/session-threads.js";
5
- import { normalizeSessionTitle } from "../session/session-title.js";
6
4
  import { reclaimDeletedSessionSandbox } from "../integrations/github/sandbox-release.js";
7
- import { seedSessionOrg } from "../session/org-seed.js";
5
+ import { waitForPendingFilesystemCapture } from "../session/filesystem-capture.js";
6
+ import { normalizeSessionTitle } from "../session/session-title.js";
8
7
  import { SESSION_OWNER_SIGNAL_TAG } from "../session-owner-signal.js";
8
+ import { canReadSessionResource, canSwitchSessionModel, canViewSourceControlSession } from "./session-access.js";
9
9
  import { RequestContext } from "@mastra/core/request-context";
10
10
  import { registerApiRoute } from "@mastra/core/server";
11
11
  import { UniqueViolationError } from "@mastra/core/storage";
12
12
  import { resolveModel } from "@mastra/code-sdk/agents/model";
13
13
  import { createSignal } from "@mastra/core/signals";
14
- //#region src/routes/source-control-sessions.ts
14
+ // src/routes/source-control-sessions.ts
15
15
  function loose(c) {
16
16
  return c;
17
17
  }
@@ -688,7 +688,6 @@ function buildSourceControlSessionRoutes(options) {
688
688
  })
689
689
  ];
690
690
  }
691
- //#endregion
692
691
  export { USER_SESSION_BRANCH_PREFIX, buildSourceControlSessionRoutes };
693
692
 
694
693
  //# sourceMappingURL=source-control-sessions.js.map
@@ -1,5 +1,5 @@
1
1
  import { registerApiRoute } from "@mastra/core/server";
2
- //#region src/routes/source-control-settings.ts
2
+ // src/routes/source-control-settings.ts
3
3
  async function loadRepository(c, options) {
4
4
  await options.auth.ensureUser(c);
5
5
  const tenant = options.auth.tenant(c);
@@ -81,7 +81,6 @@ function buildSourceControlSettingsRoutes(options) {
81
81
  }
82
82
  })];
83
83
  }
84
- //#endregion
85
84
  export { buildSourceControlSettingsRoutes };
86
85
 
87
86
  //# sourceMappingURL=source-control-settings.js.map
@@ -4,7 +4,6 @@ import "../boards/index.js";
4
4
  import { MaterializeError } from "../integrations/github/sandbox.js";
5
5
  import { FactoryDispatchError } from "../rules/dispatch-errors.js";
6
6
  import { isAgentActor } from "../storage/domains/work-items/base.js";
7
- import { getGithubFeatureDiagnostics } from "../integrations/github/config.js";
8
7
  import { invalidateTenantCredentialSnapshots } from "./tenant-credentials.js";
9
8
  import { effectiveModelScope } from "../storage/domains/projects/base.js";
10
9
  import { SessionBranchHeldError, SessionOwnershipMismatchError, SourceControlConnectionNotFoundError } from "../storage/domains/source-control/base.js";
@@ -14,6 +13,7 @@ import { buildSourceControlSessionRoutes } from "./source-control-sessions.js";
14
13
  import { resolveWorkItemRepository } from "../session/work-item-repository.js";
15
14
  import { FactoryStartCoordinator } from "../rules/start-coordinator.js";
16
15
  import { invalidateCustomProvidersSnapshots } from "./custom-provider-source.js";
16
+ import { getGithubFeatureDiagnostics } from "../integrations/github/config.js";
17
17
  import { FactoryTransitionService } from "../rules/transition-service.js";
18
18
  import { buildAutomationRunRoutes } from "./automation-runs.js";
19
19
  import { buildFsRoutes } from "./fs.js";
@@ -24,7 +24,7 @@ import { SkillRoutes } from "./skills.js";
24
24
  import { buildSourceControlSettingsRoutes } from "./source-control-settings.js";
25
25
  import { WorkItemRoutes } from "./work-items.js";
26
26
  import { registerApiRoute } from "@mastra/core/server";
27
- //#region src/routes/surface.ts
27
+ // src/routes/surface.ts
28
28
  const MATERIALIZE_FAILURE_CODE = {
29
29
  "git-missing": "repository_git_missing",
30
30
  "egress-blocked": "repository_egress_blocked",
@@ -183,7 +183,7 @@ async function prepareFactoryRuleBinding(sourceControlProvider, coordinator, pro
183
183
  branch,
184
184
  attributeToUserId: isAgentActor(approver) ? void 0 : approver
185
185
  }).catch((error) => {
186
- if (error instanceof FactorySourceSessionResolutionError && error.reason === "repository") throw new FactoryDispatchError("source_repository_missing", `Repository ${repository.slug} is linked but not in this Factory's environment. Turn it on under Settings → Environment, then retry.`, { cause: error });
186
+ if (error instanceof FactorySourceSessionResolutionError && error.reason === "repository") throw new FactoryDispatchError("source_repository_missing", `Repository ${repository.slug} is linked but not pre-cloned for this Factory. Turn on Pre-clone under Settings → Repositories, then retry.`, { cause: error });
187
187
  if (error instanceof SessionBranchHeldError) throw new FactoryDispatchError("session_unavailable", `${error.message} The run cannot start until branch ${branch} is free for this repository.`, { cause: error });
188
188
  if (!(error instanceof SessionOwnershipMismatchError)) throw error;
189
189
  throw new FactoryDispatchError("session_unavailable", `Session ${error.sessionId} on branch ${branch} predates factory ownership and cannot be reused. Delete that session, then retry.`, { cause: error });
@@ -527,7 +527,6 @@ function assembleFactoryApiRoutes(deps) {
527
527
  }) : []
528
528
  ];
529
529
  }
530
- //#endregion
531
530
  export { assembleFactoryApiRoutes, buildIntegrationContext, prepareFactoryRuleBinding };
532
531
 
533
532
  //# sourceMappingURL=surface.js.map