@mastra/factory 0.2.2-alpha.0 → 0.2.2-alpha.2

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 (174) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/auth.d.ts +2 -2
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +401 -314
  5. package/dist/auth.js.map +1 -1
  6. package/dist/capabilities/connection.js +1 -1
  7. package/dist/capabilities/intake.js +1 -1
  8. package/dist/capabilities/version-control.js +1 -1
  9. package/dist/factory.d.ts.map +1 -1
  10. package/dist/factory.js +441 -39455
  11. package/dist/factory.js.map +1 -1
  12. package/dist/index.js +2 -39466
  13. package/dist/integrations/base.js +1 -1
  14. package/dist/integrations/github/config.js +36 -22
  15. package/dist/integrations/github/config.js.map +1 -1
  16. package/dist/integrations/github/factory-session.js +33 -37
  17. package/dist/integrations/github/factory-session.js.map +1 -1
  18. package/dist/integrations/github/integration.js +1037 -3624
  19. package/dist/integrations/github/integration.js.map +1 -1
  20. package/dist/integrations/github/issue-triage.js +71 -71
  21. package/dist/integrations/github/issue-triage.js.map +1 -1
  22. package/dist/integrations/github/pat.js +47 -36
  23. package/dist/integrations/github/pat.js.map +1 -1
  24. package/dist/integrations/github/provenance.js +72 -101
  25. package/dist/integrations/github/provenance.js.map +1 -1
  26. package/dist/integrations/github/routes.d.ts.map +1 -1
  27. package/dist/integrations/github/routes.js +1272 -1833
  28. package/dist/integrations/github/routes.js.map +1 -1
  29. package/dist/integrations/github/rules.js +203 -471
  30. package/dist/integrations/github/rules.js.map +1 -1
  31. package/dist/integrations/github/sandbox.d.ts +2 -0
  32. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  33. package/dist/integrations/github/sandbox.js +401 -326
  34. package/dist/integrations/github/sandbox.js.map +1 -1
  35. package/dist/integrations/github/session-subscriptions.js +165 -223
  36. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  37. package/dist/integrations/github/subscriptions.js +43 -51
  38. package/dist/integrations/github/subscriptions.js.map +1 -1
  39. package/dist/integrations/github/token-refresh.js +15 -18
  40. package/dist/integrations/github/token-refresh.js.map +1 -1
  41. package/dist/integrations/github/webhook.js +359 -343
  42. package/dist/integrations/github/webhook.js.map +1 -1
  43. package/dist/integrations/linear/agent-tools.js +77 -100
  44. package/dist/integrations/linear/agent-tools.js.map +1 -1
  45. package/dist/integrations/linear/integration.js +611 -1309
  46. package/dist/integrations/linear/integration.js.map +1 -1
  47. package/dist/integrations/linear/routes.js +227 -230
  48. package/dist/integrations/linear/routes.js.map +1 -1
  49. package/dist/integrations/linear/rules.js +126 -346
  50. package/dist/integrations/linear/rules.js.map +1 -1
  51. package/dist/integrations/linear/storage.js +1 -1
  52. package/dist/integrations/platform/api-client.js +131 -135
  53. package/dist/integrations/platform/api-client.js.map +1 -1
  54. package/dist/integrations/platform/github/event-worker.js +275 -573
  55. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  56. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  57. package/dist/integrations/platform/github/integration.js +845 -3942
  58. package/dist/integrations/platform/github/integration.js.map +1 -1
  59. package/dist/integrations/platform/linear/integration.js +457 -1309
  60. package/dist/integrations/platform/linear/integration.js.map +1 -1
  61. package/dist/integrations/workos/integration.js +80 -85
  62. package/dist/integrations/workos/integration.js.map +1 -1
  63. package/dist/routes/config.d.ts.map +1 -1
  64. package/dist/routes/config.js +933 -915
  65. package/dist/routes/config.js.map +1 -1
  66. package/dist/routes/custom-provider-source.js +110 -93
  67. package/dist/routes/custom-provider-source.js.map +1 -1
  68. package/dist/routes/fs.js +401 -349
  69. package/dist/routes/fs.js.map +1 -1
  70. package/dist/routes/intake.js +165 -165
  71. package/dist/routes/intake.js.map +1 -1
  72. package/dist/routes/oauth.js +447 -25166
  73. package/dist/routes/oauth.js.map +1 -1
  74. package/dist/routes/projects.js +437 -376
  75. package/dist/routes/projects.js.map +1 -1
  76. package/dist/routes/provider-credentials.js +76 -58
  77. package/dist/routes/provider-credentials.js.map +1 -1
  78. package/dist/routes/route.js +12 -8
  79. package/dist/routes/route.js.map +1 -1
  80. package/dist/routes/skills.js +160 -173
  81. package/dist/routes/skills.js.map +1 -1
  82. package/dist/routes/surface.js +250 -28618
  83. package/dist/routes/surface.js.map +1 -1
  84. package/dist/routes/tenant-credentials.js +141 -166
  85. package/dist/routes/tenant-credentials.js.map +1 -1
  86. package/dist/routes/work-items.js +654 -862
  87. package/dist/routes/work-items.js.map +1 -1
  88. package/dist/rules/binding-context.js +23 -35
  89. package/dist/rules/binding-context.js.map +1 -1
  90. package/dist/rules/defaults.js +200 -309
  91. package/dist/rules/defaults.js.map +1 -1
  92. package/dist/rules/dispatcher.d.ts.map +1 -1
  93. package/dist/rules/dispatcher.js +438 -677
  94. package/dist/rules/dispatcher.js.map +1 -1
  95. package/dist/rules/index.js +5 -599
  96. package/dist/rules/processor.js +344 -596
  97. package/dist/rules/processor.js.map +1 -1
  98. package/dist/rules/resolve.js +21 -18
  99. package/dist/rules/resolve.js.map +1 -1
  100. package/dist/rules/start-coordinator.js +168 -157
  101. package/dist/rules/start-coordinator.js.map +1 -1
  102. package/dist/rules/tools.js +50 -85
  103. package/dist/rules/tools.js.map +1 -1
  104. package/dist/rules/transition-service.js +183 -454
  105. package/dist/rules/transition-service.js.map +1 -1
  106. package/dist/rules/types.js +33 -29
  107. package/dist/rules/types.js.map +1 -1
  108. package/dist/rules/validation.js +266 -281
  109. package/dist/rules/validation.js.map +1 -1
  110. package/dist/sandbox/fleet.js +272 -250
  111. package/dist/sandbox/fleet.js.map +1 -1
  112. package/dist/sandbox/reattach.js +13 -6
  113. package/dist/sandbox/reattach.js.map +1 -1
  114. package/dist/server-error.js +12 -16
  115. package/dist/server-error.js.map +1 -1
  116. package/dist/skills/service.js +30 -35
  117. package/dist/skills/service.js.map +1 -1
  118. package/dist/spa-static.d.ts.map +1 -1
  119. package/dist/spa-static.js +91 -64
  120. package/dist/spa-static.js.map +1 -1
  121. package/dist/state-signing.js +73 -44
  122. package/dist/state-signing.js.map +1 -1
  123. package/dist/storage/domains/audit/agent-audit.js +60 -59
  124. package/dist/storage/domains/audit/agent-audit.js.map +1 -1
  125. package/dist/storage/domains/audit/base.js +169 -112
  126. package/dist/storage/domains/audit/base.js.map +1 -1
  127. package/dist/storage/domains/audit/domain.js +155 -153
  128. package/dist/storage/domains/audit/domain.js.map +1 -1
  129. package/dist/storage/domains/credentials/base.js +259 -243
  130. package/dist/storage/domains/credentials/base.js.map +1 -1
  131. package/dist/storage/domains/custom-providers/base.js +138 -143
  132. package/dist/storage/domains/custom-providers/base.js.map +1 -1
  133. package/dist/storage/domains/intake/base.js +75 -57
  134. package/dist/storage/domains/intake/base.js.map +1 -1
  135. package/dist/storage/domains/integrations/base.js +310 -245
  136. package/dist/storage/domains/integrations/base.js.map +1 -1
  137. package/dist/storage/domains/memory-settings/base.js +117 -102
  138. package/dist/storage/domains/memory-settings/base.js.map +1 -1
  139. package/dist/storage/domains/model-packs/base.js +89 -88
  140. package/dist/storage/domains/model-packs/base.js.map +1 -1
  141. package/dist/storage/domains/projects/base.js +97 -92
  142. package/dist/storage/domains/projects/base.js.map +1 -1
  143. package/dist/storage/domains/queue-health/base.js +111 -76
  144. package/dist/storage/domains/queue-health/base.js.map +1 -1
  145. package/dist/storage/domains/source-control/base.d.ts +9 -0
  146. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  147. package/dist/storage/domains/source-control/base.js +777 -702
  148. package/dist/storage/domains/source-control/base.js.map +1 -1
  149. package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
  150. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  151. package/dist/storage/domains/source-control/inmemory.js +322 -344
  152. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  153. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  154. package/dist/storage/domains/work-items/base.js +1266 -1132
  155. package/dist/storage/domains/work-items/base.js.map +1 -1
  156. package/dist/storage/domains/work-items/metrics.js +202 -184
  157. package/dist/storage/domains/work-items/metrics.js.map +1 -1
  158. package/dist/timing.d.ts +15 -0
  159. package/dist/timing.d.ts.map +1 -0
  160. package/dist/timing.js +34 -0
  161. package/dist/timing.js.map +1 -0
  162. package/dist/workspace.d.ts +2 -3
  163. package/dist/workspace.d.ts.map +1 -1
  164. package/dist/workspace.js +236 -438
  165. package/dist/workspace.js.map +1 -1
  166. package/factory-skills/factory-review/SKILL.md +9 -2
  167. package/package.json +9 -9
  168. package/dist/capabilities/connection.js.map +0 -1
  169. package/dist/capabilities/intake.js.map +0 -1
  170. package/dist/capabilities/version-control.js.map +0 -1
  171. package/dist/index.js.map +0 -1
  172. package/dist/integrations/base.js.map +0 -1
  173. package/dist/integrations/linear/storage.js.map +0 -1
  174. package/dist/rules/index.js.map +0 -1
@@ -1,348 +1,326 @@
1
- // src/storage/domains/source-control/inmemory.ts
2
1
  import { randomUUID } from "crypto";
2
+ //#region src/storage/domains/source-control/inmemory.ts
3
+ /** In-memory provider-scoped source-control handle for route tests. */
3
4
  var SourceControlStorageInMemory = class {
4
- integrationId;
5
- installationsRows = [];
6
- repositoriesRows = [];
7
- connectionsRows = [];
8
- projectRepositoriesRows = [];
9
- sandboxesRows = [];
10
- worktreesRows = [];
11
- sessionsRows = [];
12
- constructor(integrationId = "github") {
13
- this.integrationId = integrationId;
14
- }
15
- installations = {
16
- list: async ({ orgId }) => this.installationsRows.filter((row) => row.orgId === orgId),
17
- get: async ({ orgId, id }) => this.installationsRows.find((row) => row.orgId === orgId && row.id === id) ?? null,
18
- findByExternalId: async ({
19
- orgId,
20
- externalId
21
- }) => this.installationsRows.find((row) => row.orgId === orgId && row.externalId === externalId) ?? null,
22
- upsert: async (input) => {
23
- const existing = this.installationsRows.find(
24
- (row) => row.orgId === input.orgId && row.externalId === input.externalId
25
- );
26
- if (existing) {
27
- Object.assign(existing, {
28
- connectedByUserId: input.connectedByUserId,
29
- accountName: input.accountName ?? null,
30
- accountType: input.accountType ?? null,
31
- providerMetadata: input.providerMetadata ?? {}
32
- });
33
- return existing;
34
- }
35
- const created = {
36
- id: randomUUID(),
37
- integrationId: this.integrationId,
38
- orgId: input.orgId,
39
- connectedByUserId: input.connectedByUserId,
40
- externalId: input.externalId,
41
- accountName: input.accountName ?? null,
42
- accountType: input.accountType ?? null,
43
- providerMetadata: input.providerMetadata ?? {},
44
- createdAt: /* @__PURE__ */ new Date()
45
- };
46
- this.installationsRows.push(created);
47
- return created;
48
- },
49
- delete: async ({ orgId, id }) => {
50
- const index = this.installationsRows.findIndex((row) => row.orgId === orgId && row.id === id);
51
- if (index < 0) return false;
52
- this.installationsRows.splice(index, 1);
53
- return true;
54
- }
55
- };
56
- repositories = {
57
- list: async ({ orgId, installationId }) => {
58
- const installation = await this.installations.get({ orgId, id: installationId });
59
- return installation ? this.repositoriesRows.filter((row) => row.installationId === installationId) : [];
60
- },
61
- get: async ({ orgId, id }) => {
62
- const row = this.repositoriesRows.find((candidate) => candidate.id === id);
63
- if (!row) return null;
64
- return await this.installations.get({ orgId, id: row.installationId }) ? row : null;
65
- },
66
- findByExternalId: async ({
67
- orgId,
68
- installationId,
69
- externalId
70
- }) => {
71
- const rows = await this.repositories.list({ orgId, installationId });
72
- return rows.find((row) => row.externalId === externalId) ?? null;
73
- },
74
- findBySlug: async ({ orgId, installationId, slug }) => {
75
- const rows = await this.repositories.list({ orgId, installationId });
76
- return rows.find((row) => row.slug === slug) ?? null;
77
- },
78
- upsert: async ({
79
- orgId,
80
- input
81
- }) => {
82
- if (!await this.installations.get({ orgId, id: input.installationId })) {
83
- throw new Error("Source-control installation not found");
84
- }
85
- const existing = this.repositoriesRows.find(
86
- (row) => row.installationId === input.installationId && row.externalId === input.externalId
87
- );
88
- const now = /* @__PURE__ */ new Date();
89
- if (existing) {
90
- Object.assign(existing, {
91
- slug: input.slug,
92
- defaultBranch: input.defaultBranch,
93
- providerMetadata: input.providerMetadata ?? {},
94
- updatedAt: now
95
- });
96
- return existing;
97
- }
98
- const created = {
99
- id: randomUUID(),
100
- installationId: input.installationId,
101
- externalId: input.externalId,
102
- slug: input.slug,
103
- defaultBranch: input.defaultBranch,
104
- providerMetadata: input.providerMetadata ?? {},
105
- createdAt: now,
106
- updatedAt: now
107
- };
108
- this.repositoriesRows.push(created);
109
- return created;
110
- }
111
- };
112
- connections = {
113
- list: async ({ factoryProjectId }) => this.connectionsRows.filter((row) => row.factoryProjectId === factoryProjectId),
114
- get: async ({ orgId, id }) => {
115
- const row = this.connectionsRows.find((candidate) => candidate.id === id);
116
- if (!row) return null;
117
- return await this.installations.get({ orgId, id: row.installationId }) ? row : null;
118
- },
119
- create: async (input) => {
120
- if (!await this.installations.get({ orgId: input.orgId, id: input.installationId })) {
121
- throw new Error("Source-control installation not found");
122
- }
123
- const existing = this.connectionsRows.find(
124
- (row) => row.factoryProjectId === input.factoryProjectId && row.integrationId === this.integrationId && row.installationId === input.installationId
125
- );
126
- if (existing) return existing;
127
- const created = {
128
- id: randomUUID(),
129
- factoryProjectId: input.factoryProjectId,
130
- integrationId: this.integrationId,
131
- installationId: input.installationId,
132
- createdByUserId: input.createdByUserId,
133
- createdAt: /* @__PURE__ */ new Date()
134
- };
135
- this.connectionsRows.push(created);
136
- return created;
137
- },
138
- delete: async ({ orgId, id }) => {
139
- if (!await this.connections.get({ orgId, id })) return false;
140
- this.connectionsRows.splice(0, this.connectionsRows.length, ...this.connectionsRows.filter((row) => row.id !== id));
141
- return true;
142
- }
143
- };
144
- projectRepositories = {
145
- list: async ({ orgId, connectionId }) => await this.connections.get({ orgId, id: connectionId }) ? this.projectRepositoriesRows.filter((row) => row.connectionId === connectionId) : [],
146
- listByExternalRepository: async ({
147
- installationExternalId,
148
- repositoryExternalId
149
- }) => {
150
- const targets = [];
151
- for (const installation of this.installationsRows.filter((row) => row.externalId === installationExternalId)) {
152
- const repository = this.repositoriesRows.find(
153
- (row) => row.installationId === installation.id && row.externalId === repositoryExternalId
154
- );
155
- if (!repository) continue;
156
- for (const projectRepository of this.projectRepositoriesRows.filter(
157
- (row) => row.repositoryId === repository.id
158
- )) {
159
- const connection = this.connectionsRows.find(
160
- (row) => row.id === projectRepository.connectionId && row.installationId === installation.id && row.integrationId === this.integrationId
161
- );
162
- if (!connection) continue;
163
- targets.push({
164
- orgId: installation.orgId,
165
- factoryProjectId: connection.factoryProjectId,
166
- projectRepository
167
- });
168
- }
169
- }
170
- return targets;
171
- },
172
- get: async ({ orgId, id }) => {
173
- const row = this.projectRepositoriesRows.find((candidate) => candidate.id === id);
174
- if (!row) return null;
175
- return await this.connections.get({ orgId, id: row.connectionId }) ? row : null;
176
- },
177
- link: async (input) => {
178
- const connection = await this.connections.get({ orgId: input.orgId, id: input.connectionId });
179
- const repository = await this.repositories.get({ orgId: input.orgId, id: input.repositoryId });
180
- if (!connection || !repository || repository.installationId !== connection.installationId) {
181
- throw new Error("Source-control connection or repository not found");
182
- }
183
- const existing = this.projectRepositoriesRows.find(
184
- (row) => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId
185
- );
186
- if (existing) return existing;
187
- const now = /* @__PURE__ */ new Date();
188
- const created = {
189
- id: randomUUID(),
190
- connectionId: input.connectionId,
191
- repositoryId: input.repositoryId,
192
- createdByUserId: input.createdByUserId,
193
- branch: input.branch ?? null,
194
- sandboxProvider: input.sandboxProvider,
195
- sandboxWorkdir: input.sandboxWorkdir,
196
- setupCommand: input.setupCommand ?? null,
197
- createdAt: now,
198
- updatedAt: now
199
- };
200
- this.projectRepositoriesRows.push(created);
201
- return created;
202
- },
203
- update: async ({
204
- orgId,
205
- id,
206
- input
207
- }) => {
208
- const row = await this.projectRepositories.get({ orgId, id });
209
- if (!row) return null;
210
- Object.assign(row, input, { updatedAt: /* @__PURE__ */ new Date() });
211
- return row;
212
- },
213
- unlink: async ({ orgId, id }) => {
214
- if (!await this.projectRepositories.get({ orgId, id })) return false;
215
- this.projectRepositoriesRows.splice(
216
- 0,
217
- this.projectRepositoriesRows.length,
218
- ...this.projectRepositoriesRows.filter((row) => row.id !== id)
219
- );
220
- return true;
221
- }
222
- };
223
- sandboxes = {
224
- getOrCreate: async ({
225
- projectRepository,
226
- userId
227
- }) => {
228
- const existing = this.sandboxesRows.find(
229
- (row) => row.projectRepositoryId === projectRepository.id && row.userId === userId
230
- );
231
- if (existing) return existing;
232
- const created = {
233
- id: randomUUID(),
234
- projectRepositoryId: projectRepository.id,
235
- userId,
236
- sandboxId: null,
237
- sandboxWorkdir: projectRepository.sandboxWorkdir,
238
- materializedAt: null,
239
- createdAt: /* @__PURE__ */ new Date()
240
- };
241
- this.sandboxesRows.push(created);
242
- return created;
243
- },
244
- getById: async ({ id }) => this.sandboxesRows.find((row) => row.id === id) ?? null,
245
- setSandboxId: async ({ id, sandboxId }) => {
246
- const row = this.sandboxesRows.find((candidate) => candidate.id === id);
247
- if (row) row.sandboxId = sandboxId;
248
- },
249
- clearBinding: async ({ id }) => {
250
- const row = this.sandboxesRows.find((candidate) => candidate.id === id);
251
- if (row) Object.assign(row, { sandboxId: null, materializedAt: null });
252
- },
253
- markMaterialized: async ({ id }) => {
254
- const row = this.sandboxesRows.find((candidate) => candidate.id === id);
255
- if (row) row.materializedAt = /* @__PURE__ */ new Date();
256
- }
257
- };
258
- worktrees = {
259
- upsert: async (input) => {
260
- const existing = this.worktreesRows.find(
261
- (row) => row.projectRepositoryId === input.projectRepositoryId && row.userId === input.userId && row.branch === input.branch
262
- );
263
- if (existing) {
264
- existing.baseBranch = input.baseBranch;
265
- existing.worktreePath = input.worktreePath;
266
- return;
267
- }
268
- this.worktreesRows.push({ id: randomUUID(), createdAt: /* @__PURE__ */ new Date(), ...input });
269
- },
270
- list: async ({
271
- projectRepositoryId,
272
- userId
273
- }) => this.worktreesRows.filter((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId),
274
- get: async ({
275
- projectRepositoryId,
276
- userId,
277
- branch
278
- }) => this.worktreesRows.find(
279
- (row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch
280
- ) ?? null,
281
- findByPath: async ({
282
- projectRepositoryId,
283
- userId,
284
- worktreePath
285
- }) => this.worktreesRows.find(
286
- (row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.worktreePath === worktreePath
287
- ) ?? null,
288
- delete: async ({
289
- projectRepositoryId,
290
- userId,
291
- branch
292
- }) => {
293
- this.worktreesRows.splice(
294
- 0,
295
- this.worktreesRows.length,
296
- ...this.worktreesRows.filter(
297
- (row) => !(row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch)
298
- )
299
- );
300
- }
301
- };
302
- sessions = {
303
- list: async ({ projectRepositoryId, userId }) => this.sessionsRows.filter((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId),
304
- getBySessionId: async (sessionId) => this.sessionsRows.find((row) => row.sessionId === sessionId) ?? null,
305
- getForBranch: async ({
306
- projectRepositoryId,
307
- userId,
308
- branch
309
- }) => this.sessionsRows.find(
310
- (row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch
311
- ) ?? null,
312
- create: async (input) => {
313
- const existing = await this.sessions.getForBranch(input);
314
- if (existing) return existing;
315
- const now = /* @__PURE__ */ new Date();
316
- const session = {
317
- id: randomUUID(),
318
- ...input,
319
- sandboxId: null,
320
- sandboxWorkdir: null,
321
- materializedAt: null,
322
- createdAt: now,
323
- updatedAt: now
324
- };
325
- this.sessionsRows.push(session);
326
- return session;
327
- },
328
- setSandbox: async ({
329
- id,
330
- sandboxId,
331
- sandboxWorkdir
332
- }) => {
333
- const row = this.sessionsRows.find((candidate) => candidate.id === id);
334
- if (row) Object.assign(row, { sandboxId, sandboxWorkdir, updatedAt: /* @__PURE__ */ new Date() });
335
- },
336
- markMaterialized: async ({ id }) => {
337
- const row = this.sessionsRows.find((candidate) => candidate.id === id);
338
- if (row) Object.assign(row, { materializedAt: /* @__PURE__ */ new Date(), updatedAt: /* @__PURE__ */ new Date() });
339
- },
340
- delete: async (id) => {
341
- this.sessionsRows.splice(0, this.sessionsRows.length, ...this.sessionsRows.filter((row) => row.id !== id));
342
- }
343
- };
344
- };
345
- export {
346
- SourceControlStorageInMemory
5
+ integrationId;
6
+ installationsRows = [];
7
+ repositoriesRows = [];
8
+ connectionsRows = [];
9
+ projectRepositoriesRows = [];
10
+ sandboxesRows = [];
11
+ worktreesRows = [];
12
+ sessionsRows = [];
13
+ constructor(integrationId = "github") {
14
+ this.integrationId = integrationId;
15
+ }
16
+ installations = {
17
+ list: async ({ orgId }) => this.installationsRows.filter((row) => row.orgId === orgId),
18
+ get: async ({ orgId, id }) => this.installationsRows.find((row) => row.orgId === orgId && row.id === id) ?? null,
19
+ findByExternalId: async ({ orgId, externalId }) => this.installationsRows.find((row) => row.orgId === orgId && row.externalId === externalId) ?? null,
20
+ upsert: async (input) => {
21
+ const existing = this.installationsRows.find((row) => row.orgId === input.orgId && row.externalId === input.externalId);
22
+ if (existing) {
23
+ Object.assign(existing, {
24
+ connectedByUserId: input.connectedByUserId,
25
+ accountName: input.accountName ?? null,
26
+ accountType: input.accountType ?? null,
27
+ providerMetadata: input.providerMetadata ?? {}
28
+ });
29
+ return existing;
30
+ }
31
+ const created = {
32
+ id: randomUUID(),
33
+ integrationId: this.integrationId,
34
+ orgId: input.orgId,
35
+ connectedByUserId: input.connectedByUserId,
36
+ externalId: input.externalId,
37
+ accountName: input.accountName ?? null,
38
+ accountType: input.accountType ?? null,
39
+ providerMetadata: input.providerMetadata ?? {},
40
+ createdAt: /* @__PURE__ */ new Date()
41
+ };
42
+ this.installationsRows.push(created);
43
+ return created;
44
+ },
45
+ delete: async ({ orgId, id }) => {
46
+ const index = this.installationsRows.findIndex((row) => row.orgId === orgId && row.id === id);
47
+ if (index < 0) return false;
48
+ this.installationsRows.splice(index, 1);
49
+ return true;
50
+ }
51
+ };
52
+ repositories = {
53
+ list: async ({ orgId, installationId }) => {
54
+ return await this.installations.get({
55
+ orgId,
56
+ id: installationId
57
+ }) ? this.repositoriesRows.filter((row) => row.installationId === installationId) : [];
58
+ },
59
+ get: async ({ orgId, id }) => {
60
+ const row = this.repositoriesRows.find((candidate) => candidate.id === id);
61
+ if (!row) return null;
62
+ return await this.installations.get({
63
+ orgId,
64
+ id: row.installationId
65
+ }) ? row : null;
66
+ },
67
+ findByExternalId: async ({ orgId, installationId, externalId }) => {
68
+ return (await this.repositories.list({
69
+ orgId,
70
+ installationId
71
+ })).find((row) => row.externalId === externalId) ?? null;
72
+ },
73
+ findBySlug: async ({ orgId, installationId, slug }) => {
74
+ return (await this.repositories.list({
75
+ orgId,
76
+ installationId
77
+ })).find((row) => row.slug === slug) ?? null;
78
+ },
79
+ upsert: async ({ orgId, input }) => {
80
+ if (!await this.installations.get({
81
+ orgId,
82
+ id: input.installationId
83
+ })) throw new Error("Source-control installation not found");
84
+ const existing = this.repositoriesRows.find((row) => row.installationId === input.installationId && row.externalId === input.externalId);
85
+ const now = /* @__PURE__ */ new Date();
86
+ if (existing) {
87
+ Object.assign(existing, {
88
+ slug: input.slug,
89
+ defaultBranch: input.defaultBranch,
90
+ providerMetadata: input.providerMetadata ?? {},
91
+ updatedAt: now
92
+ });
93
+ return existing;
94
+ }
95
+ const created = {
96
+ id: randomUUID(),
97
+ installationId: input.installationId,
98
+ externalId: input.externalId,
99
+ slug: input.slug,
100
+ defaultBranch: input.defaultBranch,
101
+ providerMetadata: input.providerMetadata ?? {},
102
+ createdAt: now,
103
+ updatedAt: now
104
+ };
105
+ this.repositoriesRows.push(created);
106
+ return created;
107
+ }
108
+ };
109
+ connections = {
110
+ list: async ({ factoryProjectId }) => this.connectionsRows.filter((row) => row.factoryProjectId === factoryProjectId),
111
+ get: async ({ orgId, id }) => {
112
+ const row = this.connectionsRows.find((candidate) => candidate.id === id);
113
+ if (!row) return null;
114
+ return await this.installations.get({
115
+ orgId,
116
+ id: row.installationId
117
+ }) ? row : null;
118
+ },
119
+ create: async (input) => {
120
+ if (!await this.installations.get({
121
+ orgId: input.orgId,
122
+ id: input.installationId
123
+ })) throw new Error("Source-control installation not found");
124
+ const existing = this.connectionsRows.find((row) => row.factoryProjectId === input.factoryProjectId && row.integrationId === this.integrationId && row.installationId === input.installationId);
125
+ if (existing) return existing;
126
+ const created = {
127
+ id: randomUUID(),
128
+ factoryProjectId: input.factoryProjectId,
129
+ integrationId: this.integrationId,
130
+ installationId: input.installationId,
131
+ createdByUserId: input.createdByUserId,
132
+ createdAt: /* @__PURE__ */ new Date()
133
+ };
134
+ this.connectionsRows.push(created);
135
+ return created;
136
+ },
137
+ delete: async ({ orgId, id }) => {
138
+ if (!await this.connections.get({
139
+ orgId,
140
+ id
141
+ })) return false;
142
+ this.connectionsRows.splice(0, this.connectionsRows.length, ...this.connectionsRows.filter((row) => row.id !== id));
143
+ return true;
144
+ }
145
+ };
146
+ projectRepositories = {
147
+ list: async ({ orgId, connectionId }) => await this.connections.get({
148
+ orgId,
149
+ id: connectionId
150
+ }) ? this.projectRepositoriesRows.filter((row) => row.connectionId === connectionId) : [],
151
+ listByExternalRepository: async ({ installationExternalId, repositoryExternalId }) => {
152
+ const targets = [];
153
+ for (const installation of this.installationsRows.filter((row) => row.externalId === installationExternalId)) {
154
+ const repository = this.repositoriesRows.find((row) => row.installationId === installation.id && row.externalId === repositoryExternalId);
155
+ if (!repository) continue;
156
+ for (const projectRepository of this.projectRepositoriesRows.filter((row) => row.repositoryId === repository.id)) {
157
+ const connection = this.connectionsRows.find((row) => row.id === projectRepository.connectionId && row.installationId === installation.id && row.integrationId === this.integrationId);
158
+ if (!connection) continue;
159
+ targets.push({
160
+ orgId: installation.orgId,
161
+ factoryProjectId: connection.factoryProjectId,
162
+ projectRepository
163
+ });
164
+ }
165
+ }
166
+ return targets;
167
+ },
168
+ get: async ({ orgId, id }) => {
169
+ const row = this.projectRepositoriesRows.find((candidate) => candidate.id === id);
170
+ if (!row) return null;
171
+ return await this.connections.get({
172
+ orgId,
173
+ id: row.connectionId
174
+ }) ? row : null;
175
+ },
176
+ link: async (input) => {
177
+ const connection = await this.connections.get({
178
+ orgId: input.orgId,
179
+ id: input.connectionId
180
+ });
181
+ const repository = await this.repositories.get({
182
+ orgId: input.orgId,
183
+ id: input.repositoryId
184
+ });
185
+ if (!connection || !repository || repository.installationId !== connection.installationId) throw new Error("Source-control connection or repository not found");
186
+ const existing = this.projectRepositoriesRows.find((row) => row.connectionId === input.connectionId && row.repositoryId === input.repositoryId);
187
+ if (existing) return existing;
188
+ const now = /* @__PURE__ */ new Date();
189
+ const created = {
190
+ id: randomUUID(),
191
+ connectionId: input.connectionId,
192
+ repositoryId: input.repositoryId,
193
+ createdByUserId: input.createdByUserId,
194
+ branch: input.branch ?? null,
195
+ sandboxProvider: input.sandboxProvider,
196
+ sandboxWorkdir: input.sandboxWorkdir,
197
+ setupCommand: input.setupCommand ?? null,
198
+ createdAt: now,
199
+ updatedAt: now
200
+ };
201
+ this.projectRepositoriesRows.push(created);
202
+ return created;
203
+ },
204
+ update: async ({ orgId, id, input }) => {
205
+ const row = await this.projectRepositories.get({
206
+ orgId,
207
+ id
208
+ });
209
+ if (!row) return null;
210
+ Object.assign(row, input, { updatedAt: /* @__PURE__ */ new Date() });
211
+ return row;
212
+ },
213
+ unlink: async ({ orgId, id }) => {
214
+ if (!await this.projectRepositories.get({
215
+ orgId,
216
+ id
217
+ })) return false;
218
+ this.projectRepositoriesRows.splice(0, this.projectRepositoriesRows.length, ...this.projectRepositoriesRows.filter((row) => row.id !== id));
219
+ return true;
220
+ }
221
+ };
222
+ sandboxes = {
223
+ getOrCreate: async ({ projectRepository, userId }) => {
224
+ const existing = this.sandboxesRows.find((row) => row.projectRepositoryId === projectRepository.id && row.userId === userId);
225
+ if (existing) return existing;
226
+ const created = {
227
+ id: randomUUID(),
228
+ projectRepositoryId: projectRepository.id,
229
+ userId,
230
+ sandboxId: null,
231
+ sandboxWorkdir: projectRepository.sandboxWorkdir,
232
+ materializedAt: null,
233
+ createdAt: /* @__PURE__ */ new Date()
234
+ };
235
+ this.sandboxesRows.push(created);
236
+ return created;
237
+ },
238
+ getById: async ({ id }) => this.sandboxesRows.find((row) => row.id === id) ?? null,
239
+ setWorkdir: async ({ id, sandboxWorkdir }) => {
240
+ const row = this.sandboxesRows.find((candidate) => candidate.id === id);
241
+ if (row) Object.assign(row, {
242
+ sandboxWorkdir,
243
+ materializedAt: null
244
+ });
245
+ },
246
+ setSandboxId: async ({ id, sandboxId }) => {
247
+ const row = this.sandboxesRows.find((candidate) => candidate.id === id);
248
+ if (row) row.sandboxId = sandboxId;
249
+ },
250
+ clearBinding: async ({ id }) => {
251
+ const row = this.sandboxesRows.find((candidate) => candidate.id === id);
252
+ if (row) Object.assign(row, {
253
+ sandboxId: null,
254
+ materializedAt: null
255
+ });
256
+ },
257
+ markMaterialized: async ({ id }) => {
258
+ const row = this.sandboxesRows.find((candidate) => candidate.id === id);
259
+ if (row) row.materializedAt = /* @__PURE__ */ new Date();
260
+ }
261
+ };
262
+ worktrees = {
263
+ upsert: async (input) => {
264
+ const existing = this.worktreesRows.find((row) => row.projectRepositoryId === input.projectRepositoryId && row.userId === input.userId && row.branch === input.branch);
265
+ if (existing) {
266
+ existing.baseBranch = input.baseBranch;
267
+ existing.worktreePath = input.worktreePath;
268
+ return;
269
+ }
270
+ this.worktreesRows.push({
271
+ id: randomUUID(),
272
+ createdAt: /* @__PURE__ */ new Date(),
273
+ ...input
274
+ });
275
+ },
276
+ list: async ({ projectRepositoryId, userId }) => this.worktreesRows.filter((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId),
277
+ get: async ({ projectRepositoryId, userId, branch }) => this.worktreesRows.find((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch) ?? null,
278
+ findByPath: async ({ projectRepositoryId, userId, worktreePath }) => this.worktreesRows.find((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.worktreePath === worktreePath) ?? null,
279
+ delete: async ({ projectRepositoryId, userId, branch }) => {
280
+ this.worktreesRows.splice(0, this.worktreesRows.length, ...this.worktreesRows.filter((row) => !(row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch)));
281
+ }
282
+ };
283
+ sessions = {
284
+ list: async ({ projectRepositoryId, userId }) => this.sessionsRows.filter((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId),
285
+ getBySessionId: async (sessionId) => this.sessionsRows.find((row) => row.sessionId === sessionId) ?? null,
286
+ getForBranch: async ({ projectRepositoryId, userId, branch }) => this.sessionsRows.find((row) => row.projectRepositoryId === projectRepositoryId && row.userId === userId && row.branch === branch) ?? null,
287
+ create: async (input) => {
288
+ const existing = await this.sessions.getForBranch(input);
289
+ if (existing) return existing;
290
+ const now = /* @__PURE__ */ new Date();
291
+ const session = {
292
+ id: randomUUID(),
293
+ ...input,
294
+ sandboxId: null,
295
+ sandboxWorkdir: null,
296
+ materializedAt: null,
297
+ createdAt: now,
298
+ updatedAt: now
299
+ };
300
+ this.sessionsRows.push(session);
301
+ return session;
302
+ },
303
+ setSandbox: async ({ id, sandboxId, sandboxWorkdir }) => {
304
+ const row = this.sessionsRows.find((candidate) => candidate.id === id);
305
+ if (row) Object.assign(row, {
306
+ sandboxId,
307
+ sandboxWorkdir,
308
+ updatedAt: /* @__PURE__ */ new Date()
309
+ });
310
+ },
311
+ markMaterialized: async ({ id }) => {
312
+ const row = this.sessionsRows.find((candidate) => candidate.id === id);
313
+ if (row) Object.assign(row, {
314
+ materializedAt: /* @__PURE__ */ new Date(),
315
+ updatedAt: /* @__PURE__ */ new Date()
316
+ });
317
+ },
318
+ delete: async (id) => {
319
+ this.sessionsRows.splice(0, this.sessionsRows.length, ...this.sessionsRows.filter((row) => row.id !== id));
320
+ }
321
+ };
347
322
  };
323
+ //#endregion
324
+ export { SourceControlStorageInMemory };
325
+
348
326
  //# sourceMappingURL=inmemory.js.map