@agent-relay/cloud 2.0.23 → 6.0.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 (289) hide show
  1. package/dist/api-client.d.ts +33 -0
  2. package/dist/api-client.d.ts.map +1 -0
  3. package/dist/api-client.js +123 -0
  4. package/dist/api-client.js.map +1 -0
  5. package/dist/auth.d.ts +13 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +299 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/index.d.ts +4 -10
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +4 -37
  12. package/dist/index.js.map +1 -1
  13. package/dist/types.d.ts +73 -0
  14. package/dist/types.d.ts.map +1 -0
  15. package/dist/types.js +12 -0
  16. package/dist/types.js.map +1 -0
  17. package/dist/workflows.d.ts +46 -0
  18. package/dist/workflows.d.ts.map +1 -0
  19. package/dist/workflows.js +464 -0
  20. package/dist/workflows.js.map +1 -0
  21. package/package.json +8 -25
  22. package/dist/api/admin.d.ts +0 -8
  23. package/dist/api/admin.d.ts.map +0 -1
  24. package/dist/api/admin.js +0 -225
  25. package/dist/api/admin.js.map +0 -1
  26. package/dist/api/auth.d.ts +0 -20
  27. package/dist/api/auth.d.ts.map +0 -1
  28. package/dist/api/auth.js +0 -138
  29. package/dist/api/auth.js.map +0 -1
  30. package/dist/api/billing.d.ts +0 -7
  31. package/dist/api/billing.d.ts.map +0 -1
  32. package/dist/api/billing.js +0 -564
  33. package/dist/api/billing.js.map +0 -1
  34. package/dist/api/cli-pty-runner.d.ts +0 -53
  35. package/dist/api/cli-pty-runner.d.ts.map +0 -1
  36. package/dist/api/cli-pty-runner.js +0 -175
  37. package/dist/api/cli-pty-runner.js.map +0 -1
  38. package/dist/api/codex-auth-helper.d.ts +0 -21
  39. package/dist/api/codex-auth-helper.d.ts.map +0 -1
  40. package/dist/api/codex-auth-helper.js +0 -327
  41. package/dist/api/codex-auth-helper.js.map +0 -1
  42. package/dist/api/consensus.d.ts +0 -13
  43. package/dist/api/consensus.d.ts.map +0 -1
  44. package/dist/api/consensus.js +0 -261
  45. package/dist/api/consensus.js.map +0 -1
  46. package/dist/api/coordinators.d.ts +0 -8
  47. package/dist/api/coordinators.d.ts.map +0 -1
  48. package/dist/api/coordinators.js +0 -750
  49. package/dist/api/coordinators.js.map +0 -1
  50. package/dist/api/daemons.d.ts +0 -12
  51. package/dist/api/daemons.d.ts.map +0 -1
  52. package/dist/api/daemons.js +0 -535
  53. package/dist/api/daemons.js.map +0 -1
  54. package/dist/api/email-auth.d.ts +0 -11
  55. package/dist/api/email-auth.d.ts.map +0 -1
  56. package/dist/api/email-auth.js +0 -347
  57. package/dist/api/email-auth.js.map +0 -1
  58. package/dist/api/generic-webhooks.d.ts +0 -8
  59. package/dist/api/generic-webhooks.d.ts.map +0 -1
  60. package/dist/api/generic-webhooks.js +0 -129
  61. package/dist/api/generic-webhooks.js.map +0 -1
  62. package/dist/api/git.d.ts +0 -8
  63. package/dist/api/git.d.ts.map +0 -1
  64. package/dist/api/git.js +0 -269
  65. package/dist/api/git.js.map +0 -1
  66. package/dist/api/github-app.d.ts +0 -11
  67. package/dist/api/github-app.d.ts.map +0 -1
  68. package/dist/api/github-app.js +0 -223
  69. package/dist/api/github-app.js.map +0 -1
  70. package/dist/api/middleware/planLimits.d.ts +0 -43
  71. package/dist/api/middleware/planLimits.d.ts.map +0 -1
  72. package/dist/api/middleware/planLimits.js +0 -202
  73. package/dist/api/middleware/planLimits.js.map +0 -1
  74. package/dist/api/monitoring.d.ts +0 -11
  75. package/dist/api/monitoring.d.ts.map +0 -1
  76. package/dist/api/monitoring.js +0 -578
  77. package/dist/api/monitoring.js.map +0 -1
  78. package/dist/api/nango-auth.d.ts +0 -9
  79. package/dist/api/nango-auth.d.ts.map +0 -1
  80. package/dist/api/nango-auth.js +0 -741
  81. package/dist/api/nango-auth.js.map +0 -1
  82. package/dist/api/onboarding.d.ts +0 -15
  83. package/dist/api/onboarding.d.ts.map +0 -1
  84. package/dist/api/onboarding.js +0 -679
  85. package/dist/api/onboarding.js.map +0 -1
  86. package/dist/api/policy.d.ts +0 -8
  87. package/dist/api/policy.d.ts.map +0 -1
  88. package/dist/api/policy.js +0 -229
  89. package/dist/api/policy.js.map +0 -1
  90. package/dist/api/provider-env.d.ts +0 -26
  91. package/dist/api/provider-env.d.ts.map +0 -1
  92. package/dist/api/provider-env.js +0 -141
  93. package/dist/api/provider-env.js.map +0 -1
  94. package/dist/api/providers.d.ts +0 -7
  95. package/dist/api/providers.d.ts.map +0 -1
  96. package/dist/api/providers.js +0 -574
  97. package/dist/api/providers.js.map +0 -1
  98. package/dist/api/repos.d.ts +0 -8
  99. package/dist/api/repos.d.ts.map +0 -1
  100. package/dist/api/repos.js +0 -577
  101. package/dist/api/repos.js.map +0 -1
  102. package/dist/api/sessions.d.ts +0 -11
  103. package/dist/api/sessions.d.ts.map +0 -1
  104. package/dist/api/sessions.js +0 -302
  105. package/dist/api/sessions.js.map +0 -1
  106. package/dist/api/teams.d.ts +0 -7
  107. package/dist/api/teams.d.ts.map +0 -1
  108. package/dist/api/teams.js +0 -281
  109. package/dist/api/teams.js.map +0 -1
  110. package/dist/api/test-helpers.d.ts +0 -10
  111. package/dist/api/test-helpers.d.ts.map +0 -1
  112. package/dist/api/test-helpers.js +0 -745
  113. package/dist/api/test-helpers.js.map +0 -1
  114. package/dist/api/usage.d.ts +0 -7
  115. package/dist/api/usage.d.ts.map +0 -1
  116. package/dist/api/usage.js +0 -111
  117. package/dist/api/usage.js.map +0 -1
  118. package/dist/api/webhooks.d.ts +0 -8
  119. package/dist/api/webhooks.d.ts.map +0 -1
  120. package/dist/api/webhooks.js +0 -645
  121. package/dist/api/webhooks.js.map +0 -1
  122. package/dist/api/workspaces.d.ts +0 -25
  123. package/dist/api/workspaces.d.ts.map +0 -1
  124. package/dist/api/workspaces.js +0 -1799
  125. package/dist/api/workspaces.js.map +0 -1
  126. package/dist/billing/index.d.ts +0 -9
  127. package/dist/billing/index.d.ts.map +0 -1
  128. package/dist/billing/index.js +0 -9
  129. package/dist/billing/index.js.map +0 -1
  130. package/dist/billing/plans.d.ts +0 -39
  131. package/dist/billing/plans.d.ts.map +0 -1
  132. package/dist/billing/plans.js +0 -245
  133. package/dist/billing/plans.js.map +0 -1
  134. package/dist/billing/service.d.ts +0 -80
  135. package/dist/billing/service.d.ts.map +0 -1
  136. package/dist/billing/service.js +0 -388
  137. package/dist/billing/service.js.map +0 -1
  138. package/dist/billing/types.d.ts +0 -141
  139. package/dist/billing/types.d.ts.map +0 -1
  140. package/dist/billing/types.js +0 -7
  141. package/dist/billing/types.js.map +0 -1
  142. package/dist/config.d.ts +0 -5
  143. package/dist/config.d.ts.map +0 -1
  144. package/dist/config.js +0 -5
  145. package/dist/config.js.map +0 -1
  146. package/dist/db/bulk-ingest.d.ts +0 -89
  147. package/dist/db/bulk-ingest.d.ts.map +0 -1
  148. package/dist/db/bulk-ingest.js +0 -268
  149. package/dist/db/bulk-ingest.js.map +0 -1
  150. package/dist/db/drizzle.d.ts +0 -290
  151. package/dist/db/drizzle.d.ts.map +0 -1
  152. package/dist/db/drizzle.js +0 -1422
  153. package/dist/db/drizzle.js.map +0 -1
  154. package/dist/db/index.d.ts +0 -56
  155. package/dist/db/index.d.ts.map +0 -1
  156. package/dist/db/index.js +0 -70
  157. package/dist/db/index.js.map +0 -1
  158. package/dist/db/schema.d.ts +0 -5117
  159. package/dist/db/schema.d.ts.map +0 -1
  160. package/dist/db/schema.js +0 -656
  161. package/dist/db/schema.js.map +0 -1
  162. package/dist/provisioner/index.d.ts +0 -207
  163. package/dist/provisioner/index.d.ts.map +0 -1
  164. package/dist/provisioner/index.js +0 -2118
  165. package/dist/provisioner/index.js.map +0 -1
  166. package/dist/server.d.ts +0 -17
  167. package/dist/server.d.ts.map +0 -1
  168. package/dist/server.js +0 -2055
  169. package/dist/server.js.map +0 -1
  170. package/dist/services/auto-scaler.d.ts +0 -152
  171. package/dist/services/auto-scaler.d.ts.map +0 -1
  172. package/dist/services/auto-scaler.js +0 -439
  173. package/dist/services/auto-scaler.js.map +0 -1
  174. package/dist/services/capacity-manager.d.ts +0 -148
  175. package/dist/services/capacity-manager.d.ts.map +0 -1
  176. package/dist/services/capacity-manager.js +0 -449
  177. package/dist/services/capacity-manager.js.map +0 -1
  178. package/dist/services/ci-agent-spawner.d.ts +0 -49
  179. package/dist/services/ci-agent-spawner.d.ts.map +0 -1
  180. package/dist/services/ci-agent-spawner.js +0 -373
  181. package/dist/services/ci-agent-spawner.js.map +0 -1
  182. package/dist/services/cloud-message-bus.d.ts +0 -28
  183. package/dist/services/cloud-message-bus.d.ts.map +0 -1
  184. package/dist/services/cloud-message-bus.js +0 -19
  185. package/dist/services/cloud-message-bus.js.map +0 -1
  186. package/dist/services/compute-enforcement.d.ts +0 -57
  187. package/dist/services/compute-enforcement.d.ts.map +0 -1
  188. package/dist/services/compute-enforcement.js +0 -175
  189. package/dist/services/compute-enforcement.js.map +0 -1
  190. package/dist/services/coordinator.d.ts +0 -62
  191. package/dist/services/coordinator.d.ts.map +0 -1
  192. package/dist/services/coordinator.js +0 -389
  193. package/dist/services/coordinator.js.map +0 -1
  194. package/dist/services/index.d.ts +0 -17
  195. package/dist/services/index.d.ts.map +0 -1
  196. package/dist/services/index.js +0 -25
  197. package/dist/services/index.js.map +0 -1
  198. package/dist/services/intro-expiration.d.ts +0 -60
  199. package/dist/services/intro-expiration.d.ts.map +0 -1
  200. package/dist/services/intro-expiration.js +0 -252
  201. package/dist/services/intro-expiration.js.map +0 -1
  202. package/dist/services/mention-handler.d.ts +0 -65
  203. package/dist/services/mention-handler.d.ts.map +0 -1
  204. package/dist/services/mention-handler.js +0 -405
  205. package/dist/services/mention-handler.js.map +0 -1
  206. package/dist/services/nango.d.ts +0 -219
  207. package/dist/services/nango.d.ts.map +0 -1
  208. package/dist/services/nango.js +0 -424
  209. package/dist/services/nango.js.map +0 -1
  210. package/dist/services/persistence.d.ts +0 -131
  211. package/dist/services/persistence.d.ts.map +0 -1
  212. package/dist/services/persistence.js +0 -200
  213. package/dist/services/persistence.js.map +0 -1
  214. package/dist/services/planLimits.d.ts +0 -147
  215. package/dist/services/planLimits.d.ts.map +0 -1
  216. package/dist/services/planLimits.js +0 -335
  217. package/dist/services/planLimits.js.map +0 -1
  218. package/dist/services/presence-registry.d.ts +0 -56
  219. package/dist/services/presence-registry.d.ts.map +0 -1
  220. package/dist/services/presence-registry.js +0 -91
  221. package/dist/services/presence-registry.js.map +0 -1
  222. package/dist/services/scaling-orchestrator.d.ts +0 -159
  223. package/dist/services/scaling-orchestrator.d.ts.map +0 -1
  224. package/dist/services/scaling-orchestrator.js +0 -502
  225. package/dist/services/scaling-orchestrator.js.map +0 -1
  226. package/dist/services/scaling-policy.d.ts +0 -121
  227. package/dist/services/scaling-policy.d.ts.map +0 -1
  228. package/dist/services/scaling-policy.js +0 -415
  229. package/dist/services/scaling-policy.js.map +0 -1
  230. package/dist/services/ssh-security.d.ts +0 -31
  231. package/dist/services/ssh-security.d.ts.map +0 -1
  232. package/dist/services/ssh-security.js +0 -63
  233. package/dist/services/ssh-security.js.map +0 -1
  234. package/dist/services/workspace-keepalive.d.ts +0 -76
  235. package/dist/services/workspace-keepalive.d.ts.map +0 -1
  236. package/dist/services/workspace-keepalive.js +0 -234
  237. package/dist/services/workspace-keepalive.js.map +0 -1
  238. package/dist/shims/consensus.d.ts +0 -23
  239. package/dist/shims/consensus.d.ts.map +0 -1
  240. package/dist/shims/consensus.js +0 -5
  241. package/dist/shims/consensus.js.map +0 -1
  242. package/dist/webhooks/index.d.ts +0 -24
  243. package/dist/webhooks/index.d.ts.map +0 -1
  244. package/dist/webhooks/index.js +0 -29
  245. package/dist/webhooks/index.js.map +0 -1
  246. package/dist/webhooks/parsers/github.d.ts +0 -8
  247. package/dist/webhooks/parsers/github.d.ts.map +0 -1
  248. package/dist/webhooks/parsers/github.js +0 -234
  249. package/dist/webhooks/parsers/github.js.map +0 -1
  250. package/dist/webhooks/parsers/index.d.ts +0 -23
  251. package/dist/webhooks/parsers/index.d.ts.map +0 -1
  252. package/dist/webhooks/parsers/index.js +0 -30
  253. package/dist/webhooks/parsers/index.js.map +0 -1
  254. package/dist/webhooks/parsers/linear.d.ts +0 -9
  255. package/dist/webhooks/parsers/linear.d.ts.map +0 -1
  256. package/dist/webhooks/parsers/linear.js +0 -258
  257. package/dist/webhooks/parsers/linear.js.map +0 -1
  258. package/dist/webhooks/parsers/slack.d.ts +0 -9
  259. package/dist/webhooks/parsers/slack.d.ts.map +0 -1
  260. package/dist/webhooks/parsers/slack.js +0 -214
  261. package/dist/webhooks/parsers/slack.js.map +0 -1
  262. package/dist/webhooks/responders/github.d.ts +0 -8
  263. package/dist/webhooks/responders/github.d.ts.map +0 -1
  264. package/dist/webhooks/responders/github.js +0 -73
  265. package/dist/webhooks/responders/github.js.map +0 -1
  266. package/dist/webhooks/responders/index.d.ts +0 -23
  267. package/dist/webhooks/responders/index.d.ts.map +0 -1
  268. package/dist/webhooks/responders/index.js +0 -30
  269. package/dist/webhooks/responders/index.js.map +0 -1
  270. package/dist/webhooks/responders/linear.d.ts +0 -9
  271. package/dist/webhooks/responders/linear.d.ts.map +0 -1
  272. package/dist/webhooks/responders/linear.js +0 -149
  273. package/dist/webhooks/responders/linear.js.map +0 -1
  274. package/dist/webhooks/responders/slack.d.ts +0 -20
  275. package/dist/webhooks/responders/slack.d.ts.map +0 -1
  276. package/dist/webhooks/responders/slack.js +0 -178
  277. package/dist/webhooks/responders/slack.js.map +0 -1
  278. package/dist/webhooks/router.d.ts +0 -25
  279. package/dist/webhooks/router.d.ts.map +0 -1
  280. package/dist/webhooks/router.js +0 -504
  281. package/dist/webhooks/router.js.map +0 -1
  282. package/dist/webhooks/rules-engine.d.ts +0 -24
  283. package/dist/webhooks/rules-engine.d.ts.map +0 -1
  284. package/dist/webhooks/rules-engine.js +0 -287
  285. package/dist/webhooks/rules-engine.js.map +0 -1
  286. package/dist/webhooks/types.d.ts +0 -186
  287. package/dist/webhooks/types.d.ts.map +0 -1
  288. package/dist/webhooks/types.js +0 -8
  289. package/dist/webhooks/types.js.map +0 -1
package/dist/db/schema.js DELETED
@@ -1,656 +0,0 @@
1
- /**
2
- * Agent Relay Cloud - Drizzle Schema
3
- *
4
- * Type-safe database schema with PostgreSQL support.
5
- * Generate migrations: npm run db:generate
6
- * Run migrations: npm run db:migrate
7
- */
8
- import { pgTable, uuid, varchar, text, timestamp, boolean, bigint, jsonb, unique, index, } from 'drizzle-orm/pg-core';
9
- import { relations } from 'drizzle-orm';
10
- // ============================================================================
11
- // Users
12
- // ============================================================================
13
- export const users = pgTable('users', {
14
- id: uuid('id').primaryKey().defaultRandom(),
15
- // GitHub OAuth fields (nullable for email-only users)
16
- githubId: varchar('github_id', { length: 255 }).unique(),
17
- githubUsername: varchar('github_username', { length: 255 }),
18
- // Email authentication fields
19
- email: varchar('email', { length: 255 }).unique(),
20
- passwordHash: varchar('password_hash', { length: 255 }), // For email login
21
- emailVerified: boolean('email_verified').notNull().default(false),
22
- emailVerificationToken: varchar('email_verification_token', { length: 255 }),
23
- emailVerificationExpires: timestamp('email_verification_expires'),
24
- // Profile
25
- displayName: varchar('display_name', { length: 255 }), // User-provided name for email users
26
- avatarUrl: varchar('avatar_url', { length: 512 }),
27
- plan: varchar('plan', { length: 50 }).notNull().default('free'),
28
- // Stripe billing
29
- stripeCustomerId: varchar('stripe_customer_id', { length: 255 }),
30
- // Nango OAuth connections
31
- nangoConnectionId: varchar('nango_connection_id', { length: 255 }), // Permanent login connection
32
- incomingConnectionId: varchar('incoming_connection_id', { length: 255 }), // Temp polling connection
33
- pendingInstallationRequest: timestamp('pending_installation_request'), // Org approval wait
34
- onboardingCompletedAt: timestamp('onboarding_completed_at'),
35
- createdAt: timestamp('created_at').defaultNow().notNull(),
36
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
37
- }, (table) => ({
38
- nangoConnectionIdx: index('idx_users_nango_connection').on(table.nangoConnectionId),
39
- incomingConnectionIdx: index('idx_users_incoming_connection').on(table.incomingConnectionId),
40
- emailIdx: index('idx_users_email').on(table.email),
41
- }));
42
- export const usersRelations = relations(users, ({ many }) => ({
43
- credentials: many(credentials),
44
- workspaces: many(workspaces),
45
- projectGroups: many(projectGroups),
46
- repositories: many(repositories),
47
- linkedDaemons: many(linkedDaemons),
48
- installedGitHubApps: many(githubInstallations),
49
- emails: many(userEmails),
50
- }));
51
- // ============================================================================
52
- // User Emails (GitHub-linked email addresses for account reconciliation)
53
- // ============================================================================
54
- export const userEmails = pgTable('user_emails', {
55
- id: uuid('id').primaryKey().defaultRandom(),
56
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
57
- email: varchar('email', { length: 255 }).notNull(),
58
- /** Whether this email is verified on GitHub */
59
- verified: boolean('verified').notNull().default(false),
60
- /** Whether this is the primary email on GitHub */
61
- primary: boolean('primary').notNull().default(false),
62
- /** Source of this email: 'github', 'manual', etc. */
63
- source: varchar('source', { length: 50 }).notNull().default('github'),
64
- createdAt: timestamp('created_at').defaultNow().notNull(),
65
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
66
- }, (table) => ({
67
- userEmailIdx: unique('user_emails_user_email_unique').on(table.userId, table.email),
68
- emailIdx: index('idx_user_emails_email').on(table.email),
69
- userIdIdx: index('idx_user_emails_user_id').on(table.userId),
70
- }));
71
- export const userEmailsRelations = relations(userEmails, ({ one }) => ({
72
- user: one(users, {
73
- fields: [userEmails.userId],
74
- references: [users.id],
75
- }),
76
- }));
77
- // ============================================================================
78
- // GitHub App Installations
79
- // ============================================================================
80
- export const githubInstallations = pgTable('github_installations', {
81
- id: uuid('id').primaryKey().defaultRandom(),
82
- installationId: varchar('installation_id', { length: 255 }).unique().notNull(),
83
- accountType: varchar('account_type', { length: 50 }).notNull(), // 'user' | 'organization'
84
- accountLogin: varchar('account_login', { length: 255 }).notNull(),
85
- accountId: varchar('account_id', { length: 255 }).notNull(),
86
- installedById: uuid('installed_by_id').references(() => users.id, { onDelete: 'set null' }),
87
- // Permissions granted to the installation
88
- permissions: jsonb('permissions').$type().default({}),
89
- // Events the installation is subscribed to
90
- events: text('events').array(),
91
- // Installation state
92
- suspended: boolean('suspended').notNull().default(false),
93
- suspendedAt: timestamp('suspended_at'),
94
- suspendedBy: varchar('suspended_by', { length: 255 }),
95
- createdAt: timestamp('created_at').defaultNow().notNull(),
96
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
97
- }, (table) => ({
98
- accountLoginIdx: index('idx_github_installations_account_login').on(table.accountLogin),
99
- installedByIdx: index('idx_github_installations_installed_by').on(table.installedById),
100
- }));
101
- export const githubInstallationsRelations = relations(githubInstallations, ({ one, many }) => ({
102
- installedBy: one(users, {
103
- fields: [githubInstallations.installedById],
104
- references: [users.id],
105
- }),
106
- repositories: many(repositories),
107
- }));
108
- // ============================================================================
109
- // Credentials (connected provider registry - no token storage)
110
- // Note: Tokens are not stored centrally. CLI tools authenticate directly
111
- // on workspace instances. This table tracks which providers a user has connected.
112
- // ============================================================================
113
- export const credentials = pgTable('credentials', {
114
- id: uuid('id').primaryKey().defaultRandom(),
115
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
116
- // Workspace-specific credentials - tokens are stored on the workspace daemon
117
- // Note: workspaceId uses a raw SQL reference to avoid circular dependency with workspaces table
118
- workspaceId: uuid('workspace_id').references(() => workspaces.id, { onDelete: 'cascade' }),
119
- provider: varchar('provider', { length: 50 }).notNull(),
120
- scopes: text('scopes').array(),
121
- providerAccountId: varchar('provider_account_id', { length: 255 }),
122
- providerAccountEmail: varchar('provider_account_email', { length: 255 }),
123
- createdAt: timestamp('created_at').defaultNow().notNull(),
124
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
125
- }, (table) => ({
126
- // Unique constraint: one credential per provider per workspace per user
127
- userProviderWorkspaceIdx: unique('credentials_user_provider_workspace_unique').on(table.userId, table.provider, table.workspaceId),
128
- userIdIdx: index('idx_credentials_user_id').on(table.userId),
129
- workspaceIdIdx: index('idx_credentials_workspace_id').on(table.workspaceId),
130
- }));
131
- export const credentialsRelations = relations(credentials, ({ one }) => ({
132
- user: one(users, {
133
- fields: [credentials.userId],
134
- references: [users.id],
135
- }),
136
- workspace: one(workspaces, {
137
- fields: [credentials.workspaceId],
138
- references: [workspaces.id],
139
- }),
140
- }));
141
- export const workspaces = pgTable('workspaces', {
142
- id: uuid('id').primaryKey().defaultRandom(),
143
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
144
- name: varchar('name', { length: 255 }).notNull(),
145
- status: varchar('status', { length: 50 }).notNull().default('provisioning'),
146
- computeProvider: varchar('compute_provider', { length: 50 }).notNull(),
147
- computeId: varchar('compute_id', { length: 255 }),
148
- publicUrl: varchar('public_url', { length: 255 }),
149
- customDomain: varchar('custom_domain', { length: 255 }),
150
- customDomainStatus: varchar('custom_domain_status', { length: 50 }),
151
- config: jsonb('config').$type().notNull().default({}),
152
- errorMessage: text('error_message'),
153
- createdAt: timestamp('created_at').defaultNow().notNull(),
154
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
155
- }, (table) => ({
156
- userIdIdx: index('idx_workspaces_user_id').on(table.userId),
157
- customDomainIdx: index('idx_workspaces_custom_domain').on(table.customDomain),
158
- }));
159
- export const workspacesRelations = relations(workspaces, ({ one, many }) => ({
160
- user: one(users, {
161
- fields: [workspaces.userId],
162
- references: [users.id],
163
- }),
164
- members: many(workspaceMembers),
165
- repositories: many(repositories),
166
- credentials: many(credentials),
167
- }));
168
- // ============================================================================
169
- // Workspace Members
170
- // ============================================================================
171
- export const workspaceMembers = pgTable('workspace_members', {
172
- id: uuid('id').primaryKey().defaultRandom(),
173
- workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }),
174
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
175
- role: varchar('role', { length: 50 }).notNull().default('member'),
176
- invitedBy: uuid('invited_by').references(() => users.id),
177
- invitedAt: timestamp('invited_at').defaultNow(),
178
- acceptedAt: timestamp('accepted_at'),
179
- }, (table) => ({
180
- workspaceUserIdx: unique('workspace_members_workspace_user_unique').on(table.workspaceId, table.userId),
181
- workspaceIdIdx: index('idx_workspace_members_workspace_id').on(table.workspaceId),
182
- userIdIdx: index('idx_workspace_members_user_id').on(table.userId),
183
- }));
184
- export const workspaceMembersRelations = relations(workspaceMembers, ({ one }) => ({
185
- workspace: one(workspaces, {
186
- fields: [workspaceMembers.workspaceId],
187
- references: [workspaces.id],
188
- }),
189
- user: one(users, {
190
- fields: [workspaceMembers.userId],
191
- references: [users.id],
192
- }),
193
- inviter: one(users, {
194
- fields: [workspaceMembers.invitedBy],
195
- references: [users.id],
196
- }),
197
- }));
198
- // ============================================================================
199
- // Project Groups (grouping of related repositories)
200
- // ============================================================================
201
- export const projectGroups = pgTable('project_groups', {
202
- id: uuid('id').primaryKey().defaultRandom(),
203
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
204
- name: varchar('name', { length: 255 }).notNull(),
205
- description: text('description'),
206
- color: varchar('color', { length: 7 }), // Hex color for UI (e.g., "#3B82F6")
207
- icon: varchar('icon', { length: 50 }), // Icon name for UI
208
- // Coordinator agent configuration - this agent oversees all repos in the group
209
- coordinatorAgent: jsonb('coordinator_agent').$type().default({ enabled: false }),
210
- // Display order for user's groups
211
- sortOrder: bigint('sort_order', { mode: 'number' }).notNull().default(0),
212
- createdAt: timestamp('created_at').defaultNow().notNull(),
213
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
214
- }, (table) => ({
215
- userIdIdx: index('idx_project_groups_user_id').on(table.userId),
216
- userNameIdx: unique('project_groups_user_name_unique').on(table.userId, table.name),
217
- }));
218
- export const projectGroupsRelations = relations(projectGroups, ({ one, many }) => ({
219
- user: one(users, {
220
- fields: [projectGroups.userId],
221
- references: [users.id],
222
- }),
223
- repositories: many(repositories),
224
- }));
225
- // ============================================================================
226
- // Repositories
227
- // ============================================================================
228
- export const repositories = pgTable('repositories', {
229
- id: uuid('id').primaryKey().defaultRandom(),
230
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
231
- workspaceId: uuid('workspace_id').references(() => workspaces.id, { onDelete: 'set null' }),
232
- projectGroupId: uuid('project_group_id').references(() => projectGroups.id, { onDelete: 'set null' }),
233
- // GitHub App installation that provides access to this repo
234
- installationId: uuid('installation_id').references(() => githubInstallations.id, { onDelete: 'set null' }),
235
- nangoConnectionId: varchar('nango_connection_id', { length: 255 }),
236
- githubFullName: varchar('github_full_name', { length: 255 }).notNull(),
237
- githubId: bigint('github_id', { mode: 'number' }).notNull(),
238
- defaultBranch: varchar('default_branch', { length: 255 }).notNull().default('main'),
239
- isPrivate: boolean('is_private').notNull().default(false),
240
- syncStatus: varchar('sync_status', { length: 50 }).notNull().default('pending'),
241
- lastSyncedAt: timestamp('last_synced_at'),
242
- // Project-level agent configuration (optional)
243
- projectAgent: jsonb('project_agent').$type().default({ enabled: false }),
244
- createdAt: timestamp('created_at').defaultNow().notNull(),
245
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
246
- }, (table) => ({
247
- userGithubIdx: unique('repositories_user_github_unique').on(table.userId, table.githubFullName),
248
- userIdIdx: index('idx_repositories_user_id').on(table.userId),
249
- workspaceIdIdx: index('idx_repositories_workspace_id').on(table.workspaceId),
250
- projectGroupIdIdx: index('idx_repositories_project_group_id').on(table.projectGroupId),
251
- installationIdIdx: index('idx_repositories_installation_id').on(table.installationId),
252
- nangoConnectionIdx: index('idx_repositories_nango_connection').on(table.nangoConnectionId),
253
- }));
254
- export const repositoriesRelations = relations(repositories, ({ one }) => ({
255
- user: one(users, {
256
- fields: [repositories.userId],
257
- references: [users.id],
258
- }),
259
- workspace: one(workspaces, {
260
- fields: [repositories.workspaceId],
261
- references: [workspaces.id],
262
- }),
263
- projectGroup: one(projectGroups, {
264
- fields: [repositories.projectGroupId],
265
- references: [projectGroups.id],
266
- }),
267
- installation: one(githubInstallations, {
268
- fields: [repositories.installationId],
269
- references: [githubInstallations.id],
270
- }),
271
- }));
272
- // ============================================================================
273
- // Linked Daemons (local agent-relay instances)
274
- // ============================================================================
275
- export const linkedDaemons = pgTable('linked_daemons', {
276
- id: uuid('id').primaryKey().defaultRandom(),
277
- userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
278
- name: varchar('name', { length: 255 }).notNull(),
279
- machineId: varchar('machine_id', { length: 255 }).notNull(),
280
- apiKeyHash: varchar('api_key_hash', { length: 255 }).notNull(),
281
- status: varchar('status', { length: 50 }).notNull().default('offline'),
282
- lastSeenAt: timestamp('last_seen_at'),
283
- metadata: jsonb('metadata').notNull().default({}),
284
- pendingUpdates: jsonb('pending_updates').notNull().default([]),
285
- messageQueue: jsonb('message_queue').notNull().default([]),
286
- workspaceId: uuid('workspace_id').references(() => workspaces.id, { onDelete: 'set null' }),
287
- createdAt: timestamp('created_at').defaultNow().notNull(),
288
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
289
- }, (table) => ({
290
- userMachineIdx: unique('linked_daemons_user_machine_unique').on(table.userId, table.machineId),
291
- userIdIdx: index('idx_linked_daemons_user_id').on(table.userId),
292
- apiKeyHashIdx: index('idx_linked_daemons_api_key_hash').on(table.apiKeyHash),
293
- statusIdx: index('idx_linked_daemons_status').on(table.status),
294
- workspaceIdIdx: index('idx_linked_daemons_workspace_id').on(table.workspaceId),
295
- }));
296
- export const linkedDaemonsRelations = relations(linkedDaemons, ({ one }) => ({
297
- user: one(users, {
298
- fields: [linkedDaemons.userId],
299
- references: [users.id],
300
- }),
301
- workspace: one(workspaces, {
302
- fields: [linkedDaemons.workspaceId],
303
- references: [workspaces.id],
304
- }),
305
- }));
306
- // ============================================================================
307
- // Subscriptions (billing)
308
- // ============================================================================
309
- export const subscriptions = pgTable('subscriptions', {
310
- id: uuid('id').primaryKey().defaultRandom(),
311
- userId: uuid('user_id').references(() => users.id, { onDelete: 'cascade' }),
312
- stripeSubscriptionId: varchar('stripe_subscription_id', { length: 255 }).unique(),
313
- stripeCustomerId: varchar('stripe_customer_id', { length: 255 }),
314
- plan: varchar('plan', { length: 50 }).notNull(),
315
- status: varchar('status', { length: 50 }).notNull().default('active'),
316
- currentPeriodStart: timestamp('current_period_start'),
317
- currentPeriodEnd: timestamp('current_period_end'),
318
- createdAt: timestamp('created_at').defaultNow().notNull(),
319
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
320
- });
321
- // ============================================================================
322
- // Usage Records
323
- // ============================================================================
324
- export const usageRecords = pgTable('usage_records', {
325
- id: uuid('id').primaryKey().defaultRandom(),
326
- userId: uuid('user_id').references(() => users.id, { onDelete: 'cascade' }),
327
- workspaceId: uuid('workspace_id').references(() => workspaces.id, { onDelete: 'set null' }),
328
- metric: varchar('metric', { length: 100 }).notNull(),
329
- value: bigint('value', { mode: 'number' }).notNull(),
330
- recordedAt: timestamp('recorded_at').defaultNow().notNull(),
331
- }, (table) => ({
332
- userIdIdx: index('idx_usage_records_user_id').on(table.userId),
333
- recordedAtIdx: index('idx_usage_records_recorded_at').on(table.recordedAt),
334
- }));
335
- // ============================================================================
336
- // Channels (workspace-scoped messaging channels)
337
- // ============================================================================
338
- export const channels = pgTable('channels', {
339
- id: uuid('id').primaryKey().defaultRandom(),
340
- workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }),
341
- /** Channel identifier (e.g., '#general', '#random', 'dm:user1:user2') */
342
- channelId: varchar('channel_id', { length: 255 }).notNull(),
343
- /** Display name (without # prefix) */
344
- name: varchar('name', { length: 255 }).notNull(),
345
- description: text('description'),
346
- /** Channel type: 'public', 'private', 'dm' */
347
- visibility: varchar('visibility', { length: 50 }).notNull().default('public'),
348
- /** Channel status: 'active', 'archived' */
349
- status: varchar('status', { length: 50 }).notNull().default('active'),
350
- createdBy: varchar('created_by', { length: 255 }),
351
- createdAt: timestamp('created_at').defaultNow().notNull(),
352
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
353
- lastActivityAt: timestamp('last_activity_at'),
354
- }, (table) => ({
355
- workspaceChannelIdx: unique('channels_workspace_channel_unique').on(table.workspaceId, table.channelId),
356
- workspaceIdIdx: index('idx_channels_workspace_id').on(table.workspaceId),
357
- statusIdx: index('idx_channels_status').on(table.status),
358
- }));
359
- export const channelsRelations = relations(channels, ({ one, many }) => ({
360
- workspace: one(workspaces, {
361
- fields: [channels.workspaceId],
362
- references: [workspaces.id],
363
- }),
364
- members: many(channelMembers),
365
- }));
366
- // ============================================================================
367
- // Channel Members (who's in each channel)
368
- // ============================================================================
369
- export const channelMembers = pgTable('channel_members', {
370
- id: uuid('id').primaryKey().defaultRandom(),
371
- channelId: uuid('channel_id').notNull().references(() => channels.id, { onDelete: 'cascade' }),
372
- /** Member identifier (username or agent name) */
373
- memberId: varchar('member_id', { length: 255 }).notNull(),
374
- /** Member type: 'user' or 'agent' */
375
- memberType: varchar('member_type', { length: 50 }).notNull().default('user'),
376
- /** Role in channel: 'owner', 'admin', 'member' */
377
- role: varchar('role', { length: 50 }).notNull().default('member'),
378
- joinedAt: timestamp('joined_at').defaultNow().notNull(),
379
- invitedBy: varchar('invited_by', { length: 255 }),
380
- }, (table) => ({
381
- channelMemberIdx: unique('channel_members_channel_member_unique').on(table.channelId, table.memberId),
382
- channelIdIdx: index('idx_channel_members_channel_id').on(table.channelId),
383
- memberIdIdx: index('idx_channel_members_member_id').on(table.memberId),
384
- }));
385
- export const channelMembersRelations = relations(channelMembers, ({ one }) => ({
386
- channel: one(channels, {
387
- fields: [channelMembers.channelId],
388
- references: [channels.id],
389
- }),
390
- }));
391
- // ============================================================================
392
- // Agent Sessions (cloud persistence for PtyWrapper agents)
393
- // ============================================================================
394
- export const agentSessions = pgTable('agent_sessions', {
395
- id: uuid('id').primaryKey().defaultRandom(),
396
- workspaceId: uuid('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }),
397
- agentName: varchar('agent_name', { length: 255 }).notNull(),
398
- status: varchar('status', { length: 50 }).notNull().default('active'),
399
- startedAt: timestamp('started_at').defaultNow().notNull(),
400
- endedAt: timestamp('ended_at'),
401
- endMarker: jsonb('end_marker').$type(),
402
- metadata: jsonb('metadata').notNull().default({}),
403
- }, (table) => ({
404
- workspaceIdIdx: index('idx_agent_sessions_workspace_id').on(table.workspaceId),
405
- agentNameIdx: index('idx_agent_sessions_agent_name').on(table.agentName),
406
- statusIdx: index('idx_agent_sessions_status').on(table.status),
407
- }));
408
- // ============================================================================
409
- // Agent Summaries (cloud persistence for [[SUMMARY]] blocks)
410
- // ============================================================================
411
- export const agentSummaries = pgTable('agent_summaries', {
412
- id: uuid('id').primaryKey().defaultRandom(),
413
- sessionId: uuid('session_id').notNull().references(() => agentSessions.id, { onDelete: 'cascade' }),
414
- agentName: varchar('agent_name', { length: 255 }).notNull(),
415
- summary: jsonb('summary').$type().notNull(),
416
- createdAt: timestamp('created_at').defaultNow().notNull(),
417
- }, (table) => ({
418
- sessionIdIdx: index('idx_agent_summaries_session_id').on(table.sessionId),
419
- agentNameIdx: index('idx_agent_summaries_agent_name').on(table.agentName),
420
- }));
421
- export const agentMetrics = pgTable('agent_metrics', {
422
- id: uuid('id').primaryKey().defaultRandom(),
423
- daemonId: uuid('daemon_id').notNull().references(() => linkedDaemons.id, { onDelete: 'cascade' }),
424
- agentName: varchar('agent_name', { length: 255 }).notNull(),
425
- pid: bigint('pid', { mode: 'number' }),
426
- status: varchar('status', { length: 50 }).notNull().default('unknown'),
427
- // Current memory snapshot
428
- rssBytes: bigint('rss_bytes', { mode: 'number' }),
429
- heapUsedBytes: bigint('heap_used_bytes', { mode: 'number' }),
430
- cpuPercent: bigint('cpu_percent', { mode: 'number' }),
431
- // Trend data
432
- trend: varchar('trend', { length: 20 }),
433
- trendRatePerMinute: bigint('trend_rate_per_minute', { mode: 'number' }),
434
- alertLevel: varchar('alert_level', { length: 20 }).default('normal'),
435
- // Watermarks
436
- highWatermark: bigint('high_watermark', { mode: 'number' }),
437
- averageRss: bigint('average_rss', { mode: 'number' }),
438
- // Full metrics JSON for detailed data
439
- metricsData: jsonb('metrics_data').$type(),
440
- // Timestamps
441
- uptimeMs: bigint('uptime_ms', { mode: 'number' }),
442
- startedAt: timestamp('started_at'),
443
- recordedAt: timestamp('recorded_at').defaultNow().notNull(),
444
- }, (table) => ({
445
- daemonIdIdx: index('idx_agent_metrics_daemon_id').on(table.daemonId),
446
- agentNameIdx: index('idx_agent_metrics_agent_name').on(table.agentName),
447
- recordedAtIdx: index('idx_agent_metrics_recorded_at').on(table.recordedAt),
448
- alertLevelIdx: index('idx_agent_metrics_alert_level').on(table.alertLevel),
449
- }));
450
- export const agentMetricsRelations = relations(agentMetrics, ({ one }) => ({
451
- daemon: one(linkedDaemons, {
452
- fields: [agentMetrics.daemonId],
453
- references: [linkedDaemons.id],
454
- }),
455
- }));
456
- // ============================================================================
457
- // Agent Crashes (crash history with insights)
458
- // ============================================================================
459
- export const agentCrashes = pgTable('agent_crashes', {
460
- id: uuid('id').primaryKey().defaultRandom(),
461
- daemonId: uuid('daemon_id').notNull().references(() => linkedDaemons.id, { onDelete: 'cascade' }),
462
- agentName: varchar('agent_name', { length: 255 }).notNull(),
463
- pid: bigint('pid', { mode: 'number' }),
464
- exitCode: bigint('exit_code', { mode: 'number' }),
465
- signal: varchar('signal', { length: 50 }),
466
- reason: text('reason'),
467
- // Crash analysis
468
- likelyCause: varchar('likely_cause', { length: 50 }),
469
- confidence: varchar('confidence', { length: 20 }),
470
- summary: text('summary'),
471
- // Memory state at crash
472
- peakMemory: bigint('peak_memory', { mode: 'number' }),
473
- lastKnownMemory: bigint('last_known_memory', { mode: 'number' }),
474
- memoryTrend: varchar('memory_trend', { length: 20 }),
475
- // Full insight data
476
- insightData: jsonb('insight_data').$type(),
477
- // Last output (truncated)
478
- lastOutput: text('last_output'),
479
- crashedAt: timestamp('crashed_at').defaultNow().notNull(),
480
- }, (table) => ({
481
- daemonIdIdx: index('idx_agent_crashes_daemon_id').on(table.daemonId),
482
- agentNameIdx: index('idx_agent_crashes_agent_name').on(table.agentName),
483
- crashedAtIdx: index('idx_agent_crashes_crashed_at').on(table.crashedAt),
484
- likelyCauseIdx: index('idx_agent_crashes_likely_cause').on(table.likelyCause),
485
- }));
486
- export const agentCrashesRelations = relations(agentCrashes, ({ one }) => ({
487
- daemon: one(linkedDaemons, {
488
- fields: [agentCrashes.daemonId],
489
- references: [linkedDaemons.id],
490
- }),
491
- }));
492
- // ============================================================================
493
- // Memory Alerts (proactive alerting history)
494
- // ============================================================================
495
- export const memoryAlerts = pgTable('memory_alerts', {
496
- id: uuid('id').primaryKey().defaultRandom(),
497
- daemonId: uuid('daemon_id').notNull().references(() => linkedDaemons.id, { onDelete: 'cascade' }),
498
- agentName: varchar('agent_name', { length: 255 }).notNull(),
499
- alertType: varchar('alert_type', { length: 50 }).notNull(), // warning, critical, oom_imminent, trend_warning, recovered
500
- currentRss: bigint('current_rss', { mode: 'number' }),
501
- threshold: bigint('threshold', { mode: 'number' }),
502
- message: text('message'),
503
- recommendation: text('recommendation'),
504
- acknowledged: boolean('acknowledged').default(false),
505
- acknowledgedAt: timestamp('acknowledged_at'),
506
- createdAt: timestamp('created_at').defaultNow().notNull(),
507
- }, (table) => ({
508
- daemonIdIdx: index('idx_memory_alerts_daemon_id').on(table.daemonId),
509
- agentNameIdx: index('idx_memory_alerts_agent_name').on(table.agentName),
510
- alertTypeIdx: index('idx_memory_alerts_alert_type').on(table.alertType),
511
- createdAtIdx: index('idx_memory_alerts_created_at').on(table.createdAt),
512
- }));
513
- export const memoryAlertsRelations = relations(memoryAlerts, ({ one }) => ({
514
- daemon: one(linkedDaemons, {
515
- fields: [memoryAlerts.daemonId],
516
- references: [linkedDaemons.id],
517
- }),
518
- }));
519
- export const ciFailureEvents = pgTable('ci_failure_events', {
520
- id: uuid('id').primaryKey().defaultRandom(),
521
- repositoryId: uuid('repository_id').references(() => repositories.id, { onDelete: 'cascade' }),
522
- repository: varchar('repository', { length: 255 }).notNull(), // org/repo format
523
- prNumber: bigint('pr_number', { mode: 'number' }),
524
- branch: varchar('branch', { length: 255 }),
525
- commitSha: varchar('commit_sha', { length: 40 }),
526
- checkName: varchar('check_name', { length: 255 }).notNull(),
527
- checkId: bigint('check_id', { mode: 'number' }).notNull(),
528
- conclusion: varchar('conclusion', { length: 50 }).notNull(), // failure, cancelled, timed_out, etc.
529
- failureTitle: text('failure_title'),
530
- failureSummary: text('failure_summary'),
531
- failureDetails: text('failure_details'),
532
- annotations: jsonb('annotations').$type().default([]),
533
- workflowName: varchar('workflow_name', { length: 255 }),
534
- workflowRunId: bigint('workflow_run_id', { mode: 'number' }),
535
- // Processing state
536
- processedAt: timestamp('processed_at'),
537
- agentSpawned: boolean('agent_spawned').default(false),
538
- createdAt: timestamp('created_at').defaultNow().notNull(),
539
- }, (table) => ({
540
- repositoryIdx: index('idx_ci_failure_events_repository').on(table.repository),
541
- prNumberIdx: index('idx_ci_failure_events_pr_number').on(table.prNumber),
542
- checkNameIdx: index('idx_ci_failure_events_check_name').on(table.checkName),
543
- createdAtIdx: index('idx_ci_failure_events_created_at').on(table.createdAt),
544
- repoPrIdx: index('idx_ci_failure_events_repo_pr').on(table.repository, table.prNumber),
545
- }));
546
- export const ciFailureEventsRelations = relations(ciFailureEvents, ({ one, many }) => ({
547
- repositoryRef: one(repositories, {
548
- fields: [ciFailureEvents.repositoryId],
549
- references: [repositories.id],
550
- }),
551
- fixAttempts: many(ciFixAttempts),
552
- }));
553
- // ============================================================================
554
- // CI Fix Attempts (agent responses to failures)
555
- // ============================================================================
556
- export const ciFixAttempts = pgTable('ci_fix_attempts', {
557
- id: uuid('id').primaryKey().defaultRandom(),
558
- failureEventId: uuid('failure_event_id').notNull().references(() => ciFailureEvents.id, { onDelete: 'cascade' }),
559
- agentId: varchar('agent_id', { length: 255 }).notNull(),
560
- agentName: varchar('agent_name', { length: 255 }).notNull(),
561
- status: varchar('status', { length: 50 }).notNull().default('pending'), // pending, in_progress, success, failed
562
- commitSha: varchar('commit_sha', { length: 40 }),
563
- errorMessage: text('error_message'),
564
- // Timing
565
- startedAt: timestamp('started_at').defaultNow().notNull(),
566
- completedAt: timestamp('completed_at'),
567
- }, (table) => ({
568
- failureEventIdx: index('idx_ci_fix_attempts_failure_event').on(table.failureEventId),
569
- statusIdx: index('idx_ci_fix_attempts_status').on(table.status),
570
- agentIdIdx: index('idx_ci_fix_attempts_agent_id').on(table.agentId),
571
- }));
572
- export const ciFixAttemptsRelations = relations(ciFixAttempts, ({ one }) => ({
573
- failureEvent: one(ciFailureEvents, {
574
- fields: [ciFixAttempts.failureEventId],
575
- references: [ciFailureEvents.id],
576
- }),
577
- }));
578
- // ============================================================================
579
- // GitHub Issue Assignments (agent handling of issues)
580
- // ============================================================================
581
- export const issueAssignments = pgTable('issue_assignments', {
582
- id: uuid('id').primaryKey().defaultRandom(),
583
- repositoryId: uuid('repository_id').references(() => repositories.id, { onDelete: 'cascade' }),
584
- repository: varchar('repository', { length: 255 }).notNull(), // org/repo format
585
- issueNumber: bigint('issue_number', { mode: 'number' }).notNull(),
586
- issueTitle: text('issue_title').notNull(),
587
- issueBody: text('issue_body'),
588
- issueUrl: varchar('issue_url', { length: 512 }),
589
- // Assignment details
590
- agentId: varchar('agent_id', { length: 255 }),
591
- agentName: varchar('agent_name', { length: 255 }),
592
- assignedAt: timestamp('assigned_at'),
593
- // Status tracking
594
- status: varchar('status', { length: 50 }).notNull().default('pending'), // pending, assigned, in_progress, resolved, closed
595
- resolution: text('resolution'),
596
- // PR created to fix the issue
597
- linkedPrNumber: bigint('linked_pr_number', { mode: 'number' }),
598
- // Metadata
599
- labels: text('labels').array(),
600
- priority: varchar('priority', { length: 20 }), // low, medium, high, critical
601
- createdAt: timestamp('created_at').defaultNow().notNull(),
602
- updatedAt: timestamp('updated_at').defaultNow().notNull(),
603
- }, (table) => ({
604
- repositoryIdx: index('idx_issue_assignments_repository').on(table.repository),
605
- issueNumberIdx: index('idx_issue_assignments_issue_number').on(table.issueNumber),
606
- statusIdx: index('idx_issue_assignments_status').on(table.status),
607
- agentIdIdx: index('idx_issue_assignments_agent_id').on(table.agentId),
608
- repoIssueIdx: unique('issue_assignments_repo_issue_unique').on(table.repository, table.issueNumber),
609
- }));
610
- export const issueAssignmentsRelations = relations(issueAssignments, ({ one }) => ({
611
- repositoryRef: one(repositories, {
612
- fields: [issueAssignments.repositoryId],
613
- references: [repositories.id],
614
- }),
615
- }));
616
- // ============================================================================
617
- // Comment Mentions (tracking @mentions to agents)
618
- // ============================================================================
619
- export const commentMentions = pgTable('comment_mentions', {
620
- id: uuid('id').primaryKey().defaultRandom(),
621
- repositoryId: uuid('repository_id').references(() => repositories.id, { onDelete: 'cascade' }),
622
- repository: varchar('repository', { length: 255 }).notNull(),
623
- // Source of the mention
624
- sourceType: varchar('source_type', { length: 50 }).notNull(), // issue_comment, pr_comment, pr_review
625
- sourceId: bigint('source_id', { mode: 'number' }).notNull(), // GitHub comment ID
626
- issueOrPrNumber: bigint('issue_or_pr_number', { mode: 'number' }).notNull(),
627
- // Comment details
628
- commentBody: text('comment_body').notNull(),
629
- commentUrl: varchar('comment_url', { length: 512 }),
630
- authorLogin: varchar('author_login', { length: 255 }).notNull(),
631
- authorId: bigint('author_id', { mode: 'number' }),
632
- // Mention details
633
- mentionedAgent: varchar('mentioned_agent', { length: 255 }).notNull(), // e.g., "agent-relay", "ci-fix", "lead"
634
- mentionContext: text('mention_context'), // Text surrounding the mention
635
- // Response tracking
636
- agentId: varchar('agent_id', { length: 255 }),
637
- agentName: varchar('agent_name', { length: 255 }),
638
- status: varchar('status', { length: 50 }).notNull().default('pending'), // pending, processing, responded, ignored
639
- responseCommentId: bigint('response_comment_id', { mode: 'number' }),
640
- responseBody: text('response_body'),
641
- respondedAt: timestamp('responded_at'),
642
- // Metadata
643
- createdAt: timestamp('created_at').defaultNow().notNull(),
644
- }, (table) => ({
645
- repositoryIdx: index('idx_comment_mentions_repository').on(table.repository),
646
- sourceIdx: index('idx_comment_mentions_source').on(table.sourceType, table.sourceId),
647
- statusIdx: index('idx_comment_mentions_status').on(table.status),
648
- mentionedAgentIdx: index('idx_comment_mentions_mentioned_agent').on(table.mentionedAgent),
649
- }));
650
- export const commentMentionsRelations = relations(commentMentions, ({ one }) => ({
651
- repositoryRef: one(repositories, {
652
- fields: [commentMentions.repositoryId],
653
- references: [repositories.id],
654
- }),
655
- }));
656
- //# sourceMappingURL=schema.js.map