agent-relay 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.trajectories/agent-relay-322-324.md +17 -0
- package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json +49 -0
- package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.md +31 -0
- package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json +125 -0
- package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.md +62 -0
- package/.trajectories/completed/2026-01/traj_33iuy72sezbk.json +49 -0
- package/.trajectories/completed/2026-01/traj_33iuy72sezbk.md +31 -0
- package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.json +77 -0
- package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.md +42 -0
- package/.trajectories/completed/2026-01/traj_6mieijqyvaag.json +77 -0
- package/.trajectories/completed/2026-01/traj_6mieijqyvaag.md +42 -0
- package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json +77 -0
- package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.md +42 -0
- package/.trajectories/completed/2026-01/traj_94gnp3k30goq.json +66 -0
- package/.trajectories/completed/2026-01/traj_94gnp3k30goq.md +36 -0
- package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.json +40 -0
- package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.md +22 -0
- package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.json +121 -0
- package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.md +29 -0
- package/.trajectories/completed/2026-01/traj_fhx9irlckht6.json +53 -0
- package/.trajectories/completed/2026-01/traj_fhx9irlckht6.md +32 -0
- package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json +101 -0
- package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.md +52 -0
- package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.json +49 -0
- package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.md +31 -0
- package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json +65 -0
- package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.md +37 -0
- package/.trajectories/completed/2026-01/traj_lq450ly148uw.json +49 -0
- package/.trajectories/completed/2026-01/traj_lq450ly148uw.md +31 -0
- package/.trajectories/completed/2026-01/traj_multi_server_arch.md +101 -0
- package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.json +27 -0
- package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.md +14 -0
- package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.json +53 -0
- package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.md +32 -0
- package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json +186 -0
- package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.md +86 -0
- package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json +77 -0
- package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.md +42 -0
- package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.json +89 -0
- package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.md +47 -0
- package/.trajectories/completed/2026-01/traj_xy9vifpqet80.json +65 -0
- package/.trajectories/completed/2026-01/traj_xy9vifpqet80.md +37 -0
- package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json +49 -0
- package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.md +31 -0
- package/.trajectories/consolidate-settings-panel.md +24 -0
- package/.trajectories/gh-cli-user-token.md +26 -0
- package/.trajectories/index.json +155 -1
- package/deploy/workspace/codex.config.toml +15 -0
- package/deploy/workspace/entrypoint.sh +167 -7
- package/deploy/workspace/git-credential-relay +17 -2
- package/dist/bridge/spawner.d.ts +7 -0
- package/dist/bridge/spawner.js +40 -9
- package/dist/bridge/types.d.ts +2 -0
- package/dist/cli/index.js +210 -168
- package/dist/cloud/api/admin.d.ts +8 -0
- package/dist/cloud/api/admin.js +212 -0
- package/dist/cloud/api/auth.js +8 -0
- package/dist/cloud/api/billing.d.ts +0 -10
- package/dist/cloud/api/billing.js +248 -58
- package/dist/cloud/api/codex-auth-helper.d.ts +10 -4
- package/dist/cloud/api/codex-auth-helper.js +215 -8
- package/dist/cloud/api/coordinators.js +402 -0
- package/dist/cloud/api/daemons.js +15 -11
- package/dist/cloud/api/git.js +104 -17
- package/dist/cloud/api/github-app.js +42 -8
- package/dist/cloud/api/nango-auth.js +297 -16
- package/dist/cloud/api/onboarding.js +97 -33
- package/dist/cloud/api/providers.js +12 -16
- package/dist/cloud/api/repos.js +200 -124
- package/dist/cloud/api/test-helpers.js +40 -0
- package/dist/cloud/api/usage.js +13 -0
- package/dist/cloud/api/webhooks.js +1 -1
- package/dist/cloud/api/workspaces.d.ts +18 -0
- package/dist/cloud/api/workspaces.js +945 -15
- package/dist/cloud/config.d.ts +8 -0
- package/dist/cloud/config.js +15 -0
- package/dist/cloud/db/drizzle.d.ts +5 -2
- package/dist/cloud/db/drizzle.js +27 -20
- package/dist/cloud/db/schema.d.ts +19 -51
- package/dist/cloud/db/schema.js +5 -4
- package/dist/cloud/index.d.ts +0 -1
- package/dist/cloud/index.js +0 -1
- package/dist/cloud/provisioner/index.d.ts +93 -1
- package/dist/cloud/provisioner/index.js +608 -63
- package/dist/cloud/server.js +156 -16
- package/dist/cloud/services/compute-enforcement.d.ts +57 -0
- package/dist/cloud/services/compute-enforcement.js +175 -0
- package/dist/cloud/services/index.d.ts +2 -0
- package/dist/cloud/services/index.js +4 -0
- package/dist/cloud/services/intro-expiration.d.ts +55 -0
- package/dist/cloud/services/intro-expiration.js +211 -0
- package/dist/cloud/services/nango.d.ts +14 -0
- package/dist/cloud/services/nango.js +74 -14
- package/dist/cloud/services/ssh-security.d.ts +31 -0
- package/dist/cloud/services/ssh-security.js +63 -0
- package/dist/continuity/manager.d.ts +5 -0
- package/dist/continuity/manager.js +56 -2
- package/dist/daemon/api.d.ts +2 -0
- package/dist/daemon/api.js +214 -5
- package/dist/daemon/cli-auth.d.ts +13 -1
- package/dist/daemon/cli-auth.js +166 -47
- package/dist/daemon/connection.d.ts +7 -1
- package/dist/daemon/connection.js +15 -0
- package/dist/daemon/orchestrator.d.ts +2 -0
- package/dist/daemon/orchestrator.js +26 -0
- package/dist/daemon/repo-manager.d.ts +116 -0
- package/dist/daemon/repo-manager.js +384 -0
- package/dist/daemon/router.d.ts +60 -1
- package/dist/daemon/router.js +281 -20
- package/dist/daemon/user-directory.d.ts +111 -0
- package/dist/daemon/user-directory.js +233 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/T1tgCqVWHFIkV7ClEtzD7/_ssgManifest.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +9 -0
- package/dist/dashboard/out/_next/static/chunks/766-b54f0853794b78c3.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/83-b51836037078006c.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/891-6cd50de1224f70bb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/899-bb19a9b3d9b39ea6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-8939b0fc700f7eca.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/page-5af1b6b439858aa6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-f45ecbc3e06134fc.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/history/{page-abb9ab2d329f56e9.js → page-8c8bed33beb2bf1c.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/{page-c22d080201cbd9fb.js → page-16f3b49e55b1e0ed.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-ac39dc0cc3c26fa7.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/{page-77e9c65420a06cfb.js → page-4a5938c18a11a654.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-982a7000fee44014.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-ac3a6ac433fd6001.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-09f9caae98a18c09.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/signup/{page-68d34f50baa8ab6b.js → page-547dd0ca55ecd0ba.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-ed4e1fb6f29c34cf.js → main-2ee6beb2ae96d210.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-app-6e8e8d3ef4e0192a.js → main-app-5d692157a8eb1fd9.js} +1 -1
- package/dist/dashboard/out/_next/static/css/85d2af9c7ac74d62.css +1 -0
- package/dist/dashboard/out/_next/static/css/fe4b28883eeff359.css +1 -0
- package/dist/dashboard/out/app/onboarding.html +1 -1
- package/dist/dashboard/out/app/onboarding.txt +3 -3
- package/dist/dashboard/out/app.html +1 -1
- package/dist/dashboard/out/app.txt +3 -3
- package/dist/dashboard/out/apple-icon.png +0 -0
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +3 -3
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +3 -3
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +3 -3
- package/dist/dashboard/out/login.html +2 -2
- package/dist/dashboard/out/login.txt +3 -3
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +3 -3
- package/dist/dashboard/out/pricing.html +2 -2
- package/dist/dashboard/out/pricing.txt +3 -3
- package/dist/dashboard/out/providers/setup/claude.html +1 -0
- package/dist/dashboard/out/providers/setup/claude.txt +8 -0
- package/dist/dashboard/out/providers/setup/codex.html +1 -0
- package/dist/dashboard/out/providers/setup/codex.txt +8 -0
- package/dist/dashboard/out/providers.html +1 -1
- package/dist/dashboard/out/providers.txt +3 -3
- package/dist/dashboard/out/signup.html +2 -2
- package/dist/dashboard/out/signup.txt +3 -3
- package/dist/dashboard-server/server.js +316 -12
- package/dist/dashboard-server/user-bridge.d.ts +103 -0
- package/dist/dashboard-server/user-bridge.js +189 -0
- package/dist/protocol/channels.d.ts +205 -0
- package/dist/protocol/channels.js +154 -0
- package/dist/protocol/types.d.ts +13 -1
- package/dist/resiliency/provider-context.js +2 -0
- package/dist/shared/cli-auth-config.d.ts +19 -0
- package/dist/shared/cli-auth-config.js +58 -2
- package/dist/utils/agent-config.js +1 -1
- package/dist/wrapper/auth-detection.d.ts +49 -0
- package/dist/wrapper/auth-detection.js +192 -0
- package/dist/wrapper/base-wrapper.d.ts +153 -0
- package/dist/wrapper/base-wrapper.js +393 -0
- package/dist/wrapper/client.d.ts +7 -1
- package/dist/wrapper/client.js +3 -0
- package/dist/wrapper/index.d.ts +1 -0
- package/dist/wrapper/index.js +4 -3
- package/dist/wrapper/pty-wrapper.d.ts +62 -84
- package/dist/wrapper/pty-wrapper.js +154 -180
- package/dist/wrapper/tmux-wrapper.d.ts +41 -66
- package/dist/wrapper/tmux-wrapper.js +90 -134
- package/package.json +4 -2
- package/scripts/postinstall.js +11 -155
- package/scripts/test-interactive-terminal.sh +248 -0
- package/dist/cloud/vault/index.d.ts +0 -76
- package/dist/cloud/vault/index.js +0 -219
- package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/724-2dae7627550ab88f.js +0 -9
- package/dist/dashboard/out/_next/static/chunks/766-1f2dd8cb7f766b0b.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-3fdfa60e53f2810d.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-e6381e5a6e1fbcfd.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-3538dfe0ffe984b8.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-67a3e98d9a43a6ed.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-b08ed1c34d14434a.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-e88bc117ef7671c3.js +0 -1
- package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +0 -1
- package/dist/dashboard/out/_next/static/css/7c3ae9e8617d42a5.css +0 -1
- package/dist/dashboard/out/_next/static/wPgKJtcOmTFLpUncDg16A/_ssgManifest.js +0 -1
- /package/dist/dashboard/out/_next/static/{wPgKJtcOmTFLpUncDg16A → T1tgCqVWHFIkV7ClEtzD7}/_buildManifest.js +0 -0
package/dist/cloud/config.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export interface CloudConfig {
|
|
5
5
|
port: number;
|
|
6
6
|
publicUrl: string;
|
|
7
|
+
appUrl: string;
|
|
7
8
|
sessionSecret: string;
|
|
8
9
|
databaseUrl: string;
|
|
9
10
|
redisUrl: string;
|
|
@@ -38,6 +39,8 @@ export interface CloudConfig {
|
|
|
38
39
|
username: string;
|
|
39
40
|
password: string;
|
|
40
41
|
};
|
|
42
|
+
snapshotRetentionDays?: number;
|
|
43
|
+
volumeSizeGb?: number;
|
|
41
44
|
};
|
|
42
45
|
railway?: {
|
|
43
46
|
apiToken: string;
|
|
@@ -60,7 +63,12 @@ export interface CloudConfig {
|
|
|
60
63
|
enterpriseYearly?: string;
|
|
61
64
|
};
|
|
62
65
|
};
|
|
66
|
+
adminUsers: string[];
|
|
63
67
|
}
|
|
64
68
|
export declare function loadConfig(): CloudConfig;
|
|
69
|
+
/**
|
|
70
|
+
* Check if a GitHub username is an admin user
|
|
71
|
+
*/
|
|
72
|
+
export declare function isAdminUser(githubUsername: string): boolean;
|
|
65
73
|
export declare function getConfig(): CloudConfig;
|
|
66
74
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/cloud/config.js
CHANGED
|
@@ -15,6 +15,7 @@ export function loadConfig() {
|
|
|
15
15
|
return {
|
|
16
16
|
port: parseInt(process.env.PORT || '4567', 10),
|
|
17
17
|
publicUrl: process.env.PUBLIC_URL || 'http://localhost:4567',
|
|
18
|
+
appUrl: process.env.APP_URL || process.env.PUBLIC_URL || 'http://localhost:4567',
|
|
18
19
|
sessionSecret: requireEnv('SESSION_SECRET'),
|
|
19
20
|
databaseUrl: requireEnv('DATABASE_URL'),
|
|
20
21
|
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
|
|
@@ -54,6 +55,8 @@ export function loadConfig() {
|
|
|
54
55
|
password: optionalEnv('GHCR_TOKEN'),
|
|
55
56
|
}
|
|
56
57
|
: undefined,
|
|
58
|
+
snapshotRetentionDays: parseInt(optionalEnv('FLY_SNAPSHOT_RETENTION_DAYS') || '14', 10),
|
|
59
|
+
volumeSizeGb: parseInt(optionalEnv('FLY_VOLUME_SIZE_GB') || '10', 10),
|
|
57
60
|
}
|
|
58
61
|
: undefined,
|
|
59
62
|
railway: optionalEnv('RAILWAY_API_TOKEN')
|
|
@@ -79,8 +82,20 @@ export function loadConfig() {
|
|
|
79
82
|
enterpriseYearly: optionalEnv('STRIPE_ENTERPRISE_YEARLY_PRICE_ID'),
|
|
80
83
|
},
|
|
81
84
|
},
|
|
85
|
+
// Admin users - comma-separated GitHub usernames (e.g., "khaliqgant,admin2")
|
|
86
|
+
adminUsers: (optionalEnv('ADMIN_USERS') || '')
|
|
87
|
+
.split(',')
|
|
88
|
+
.map((u) => u.trim().toLowerCase())
|
|
89
|
+
.filter(Boolean),
|
|
82
90
|
};
|
|
83
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if a GitHub username is an admin user
|
|
94
|
+
*/
|
|
95
|
+
export function isAdminUser(githubUsername) {
|
|
96
|
+
const config = getConfig();
|
|
97
|
+
return config.adminUsers.includes(githubUsername.toLowerCase());
|
|
98
|
+
}
|
|
84
99
|
// Singleton config instance
|
|
85
100
|
let _config = null;
|
|
86
101
|
export function getConfig() {
|
|
@@ -18,6 +18,7 @@ export interface UserQueries {
|
|
|
18
18
|
findByEmail(email: string): Promise<schema.User | null>;
|
|
19
19
|
findByNangoConnectionId(connectionId: string): Promise<schema.User | null>;
|
|
20
20
|
findByIncomingConnectionId(connectionId: string): Promise<schema.User | null>;
|
|
21
|
+
findByPlan(plan: string): Promise<schema.User[]>;
|
|
21
22
|
upsert(data: schema.NewUser): Promise<schema.User>;
|
|
22
23
|
update(id: string, data: Partial<Omit<schema.User, 'id' | 'createdAt'>>): Promise<void>;
|
|
23
24
|
completeOnboarding(userId: string): Promise<void>;
|
|
@@ -43,7 +44,6 @@ export interface CredentialQueries {
|
|
|
43
44
|
findByUserId(userId: string): Promise<schema.Credential[]>;
|
|
44
45
|
findByUserAndProvider(userId: string, provider: string): Promise<schema.Credential | null>;
|
|
45
46
|
upsert(data: schema.NewCredential): Promise<schema.Credential>;
|
|
46
|
-
updateTokens(userId: string, provider: string, accessToken: string, refreshToken?: string, expiresAt?: Date): Promise<void>;
|
|
47
47
|
delete(userId: string, provider: string): Promise<void>;
|
|
48
48
|
}
|
|
49
49
|
export declare const credentialQueries: CredentialQueries;
|
|
@@ -51,7 +51,9 @@ export interface WorkspaceQueries {
|
|
|
51
51
|
findById(id: string): Promise<schema.Workspace | null>;
|
|
52
52
|
findByUserId(userId: string): Promise<schema.Workspace[]>;
|
|
53
53
|
findByCustomDomain(domain: string): Promise<schema.Workspace | null>;
|
|
54
|
+
findAll(): Promise<schema.Workspace[]>;
|
|
54
55
|
create(data: schema.NewWorkspace): Promise<schema.Workspace>;
|
|
56
|
+
update(id: string, data: Partial<Pick<schema.Workspace, 'name' | 'config'>>): Promise<void>;
|
|
55
57
|
updateStatus(id: string, status: string, options?: {
|
|
56
58
|
computeId?: string;
|
|
57
59
|
publicUrl?: string;
|
|
@@ -137,11 +139,12 @@ export declare const projectGroupQueries: ProjectGroupQueries;
|
|
|
137
139
|
export interface RepositoryQueries {
|
|
138
140
|
findById(id: string): Promise<schema.Repository | null>;
|
|
139
141
|
findByFullName(fullName: string): Promise<schema.Repository | null>;
|
|
142
|
+
findByGithubFullName(fullName: string): Promise<schema.Repository[]>;
|
|
140
143
|
findByUserId(userId: string): Promise<schema.Repository[]>;
|
|
141
144
|
findByWorkspaceId(workspaceId: string): Promise<schema.Repository[]>;
|
|
142
145
|
findByProjectGroupId(projectGroupId: string): Promise<schema.Repository[]>;
|
|
143
146
|
upsert(data: schema.NewRepository): Promise<schema.Repository>;
|
|
144
|
-
assignToWorkspace(repoId: string, workspaceId: string): Promise<void>;
|
|
147
|
+
assignToWorkspace(repoId: string, workspaceId: string | null): Promise<void>;
|
|
145
148
|
assignToGroup(repoId: string, projectGroupId: string | null): Promise<void>;
|
|
146
149
|
updateProjectAgent(id: string, config: schema.ProjectAgentConfig): Promise<void>;
|
|
147
150
|
updateSyncStatus(id: string, status: string, lastSyncedAt?: Date): Promise<void>;
|
package/dist/cloud/db/drizzle.js
CHANGED
|
@@ -61,6 +61,11 @@ export const userQueries = {
|
|
|
61
61
|
const result = await db.select().from(schema.users).where(eq(schema.users.incomingConnectionId, connectionId));
|
|
62
62
|
return result[0] ?? null;
|
|
63
63
|
},
|
|
64
|
+
async findByPlan(plan) {
|
|
65
|
+
const db = getDb();
|
|
66
|
+
const result = await db.select().from(schema.users).where(eq(schema.users.plan, plan));
|
|
67
|
+
return result;
|
|
68
|
+
},
|
|
64
69
|
async upsert(data) {
|
|
65
70
|
const db = getDb();
|
|
66
71
|
const result = await db
|
|
@@ -214,9 +219,6 @@ export const credentialQueries = {
|
|
|
214
219
|
.onConflictDoUpdate({
|
|
215
220
|
target: [schema.credentials.userId, schema.credentials.provider],
|
|
216
221
|
set: {
|
|
217
|
-
accessToken: data.accessToken,
|
|
218
|
-
refreshToken: data.refreshToken ?? sql `credentials.refresh_token`,
|
|
219
|
-
tokenExpiresAt: data.tokenExpiresAt,
|
|
220
222
|
scopes: data.scopes,
|
|
221
223
|
providerAccountId: data.providerAccountId,
|
|
222
224
|
providerAccountEmail: data.providerAccountEmail,
|
|
@@ -226,23 +228,6 @@ export const credentialQueries = {
|
|
|
226
228
|
.returning();
|
|
227
229
|
return result[0];
|
|
228
230
|
},
|
|
229
|
-
async updateTokens(userId, provider, accessToken, refreshToken, expiresAt) {
|
|
230
|
-
const db = getDb();
|
|
231
|
-
const updates = {
|
|
232
|
-
accessToken,
|
|
233
|
-
updatedAt: new Date(),
|
|
234
|
-
};
|
|
235
|
-
if (refreshToken !== undefined) {
|
|
236
|
-
updates.refreshToken = refreshToken;
|
|
237
|
-
}
|
|
238
|
-
if (expiresAt !== undefined) {
|
|
239
|
-
updates.tokenExpiresAt = expiresAt;
|
|
240
|
-
}
|
|
241
|
-
await db
|
|
242
|
-
.update(schema.credentials)
|
|
243
|
-
.set(updates)
|
|
244
|
-
.where(and(eq(schema.credentials.userId, userId), eq(schema.credentials.provider, provider)));
|
|
245
|
-
},
|
|
246
231
|
async delete(userId, provider) {
|
|
247
232
|
const db = getDb();
|
|
248
233
|
await db
|
|
@@ -272,11 +257,25 @@ export const workspaceQueries = {
|
|
|
272
257
|
.where(eq(schema.workspaces.customDomain, domain));
|
|
273
258
|
return result[0] ?? null;
|
|
274
259
|
},
|
|
260
|
+
async findAll() {
|
|
261
|
+
const db = getDb();
|
|
262
|
+
return db
|
|
263
|
+
.select()
|
|
264
|
+
.from(schema.workspaces)
|
|
265
|
+
.orderBy(desc(schema.workspaces.createdAt));
|
|
266
|
+
},
|
|
275
267
|
async create(data) {
|
|
276
268
|
const db = getDb();
|
|
277
269
|
const result = await db.insert(schema.workspaces).values(data).returning();
|
|
278
270
|
return result[0];
|
|
279
271
|
},
|
|
272
|
+
async update(id, data) {
|
|
273
|
+
const db = getDb();
|
|
274
|
+
await db
|
|
275
|
+
.update(schema.workspaces)
|
|
276
|
+
.set({ ...data, updatedAt: new Date() })
|
|
277
|
+
.where(eq(schema.workspaces.id, id));
|
|
278
|
+
},
|
|
280
279
|
async updateStatus(id, status, options) {
|
|
281
280
|
const db = getDb();
|
|
282
281
|
await db
|
|
@@ -652,6 +651,14 @@ export const repositoryQueries = {
|
|
|
652
651
|
.where(eq(schema.repositories.githubFullName, fullName));
|
|
653
652
|
return result[0] ?? null;
|
|
654
653
|
},
|
|
654
|
+
async findByGithubFullName(fullName) {
|
|
655
|
+
const db = getDb();
|
|
656
|
+
// Use case-insensitive match since GitHub repo names are case-insensitive
|
|
657
|
+
return db
|
|
658
|
+
.select()
|
|
659
|
+
.from(schema.repositories)
|
|
660
|
+
.where(sql `LOWER(${schema.repositories.githubFullName}) = LOWER(${fullName})`);
|
|
661
|
+
},
|
|
655
662
|
async findByUserId(userId) {
|
|
656
663
|
const db = getDb();
|
|
657
664
|
return db
|
|
@@ -121,6 +121,25 @@ export declare const users: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
121
121
|
}, {}, {
|
|
122
122
|
length: 50;
|
|
123
123
|
}>;
|
|
124
|
+
stripeCustomerId: import("drizzle-orm/pg-core").PgColumn<{
|
|
125
|
+
name: "stripe_customer_id";
|
|
126
|
+
tableName: "users";
|
|
127
|
+
dataType: "string";
|
|
128
|
+
columnType: "PgVarchar";
|
|
129
|
+
data: string;
|
|
130
|
+
driverParam: string;
|
|
131
|
+
notNull: false;
|
|
132
|
+
hasDefault: false;
|
|
133
|
+
isPrimaryKey: false;
|
|
134
|
+
isAutoincrement: false;
|
|
135
|
+
hasRuntimeDefault: false;
|
|
136
|
+
enumValues: [string, ...string[]];
|
|
137
|
+
baseColumn: never;
|
|
138
|
+
identity: undefined;
|
|
139
|
+
generated: undefined;
|
|
140
|
+
}, {}, {
|
|
141
|
+
length: 255;
|
|
142
|
+
}>;
|
|
124
143
|
nangoConnectionId: import("drizzle-orm/pg-core").PgColumn<{
|
|
125
144
|
name: "nango_connection_id";
|
|
126
145
|
tableName: "users";
|
|
@@ -565,57 +584,6 @@ export declare const credentials: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
565
584
|
}, {}, {
|
|
566
585
|
length: 50;
|
|
567
586
|
}>;
|
|
568
|
-
accessToken: import("drizzle-orm/pg-core").PgColumn<{
|
|
569
|
-
name: "access_token";
|
|
570
|
-
tableName: "credentials";
|
|
571
|
-
dataType: "string";
|
|
572
|
-
columnType: "PgText";
|
|
573
|
-
data: string;
|
|
574
|
-
driverParam: string;
|
|
575
|
-
notNull: true;
|
|
576
|
-
hasDefault: false;
|
|
577
|
-
isPrimaryKey: false;
|
|
578
|
-
isAutoincrement: false;
|
|
579
|
-
hasRuntimeDefault: false;
|
|
580
|
-
enumValues: [string, ...string[]];
|
|
581
|
-
baseColumn: never;
|
|
582
|
-
identity: undefined;
|
|
583
|
-
generated: undefined;
|
|
584
|
-
}, {}, {}>;
|
|
585
|
-
refreshToken: import("drizzle-orm/pg-core").PgColumn<{
|
|
586
|
-
name: "refresh_token";
|
|
587
|
-
tableName: "credentials";
|
|
588
|
-
dataType: "string";
|
|
589
|
-
columnType: "PgText";
|
|
590
|
-
data: string;
|
|
591
|
-
driverParam: string;
|
|
592
|
-
notNull: false;
|
|
593
|
-
hasDefault: false;
|
|
594
|
-
isPrimaryKey: false;
|
|
595
|
-
isAutoincrement: false;
|
|
596
|
-
hasRuntimeDefault: false;
|
|
597
|
-
enumValues: [string, ...string[]];
|
|
598
|
-
baseColumn: never;
|
|
599
|
-
identity: undefined;
|
|
600
|
-
generated: undefined;
|
|
601
|
-
}, {}, {}>;
|
|
602
|
-
tokenExpiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
603
|
-
name: "token_expires_at";
|
|
604
|
-
tableName: "credentials";
|
|
605
|
-
dataType: "date";
|
|
606
|
-
columnType: "PgTimestamp";
|
|
607
|
-
data: Date;
|
|
608
|
-
driverParam: string;
|
|
609
|
-
notNull: false;
|
|
610
|
-
hasDefault: false;
|
|
611
|
-
isPrimaryKey: false;
|
|
612
|
-
isAutoincrement: false;
|
|
613
|
-
hasRuntimeDefault: false;
|
|
614
|
-
enumValues: undefined;
|
|
615
|
-
baseColumn: never;
|
|
616
|
-
identity: undefined;
|
|
617
|
-
generated: undefined;
|
|
618
|
-
}, {}, {}>;
|
|
619
587
|
scopes: import("drizzle-orm/pg-core").PgColumn<{
|
|
620
588
|
name: "scopes";
|
|
621
589
|
tableName: "credentials";
|
package/dist/cloud/db/schema.js
CHANGED
|
@@ -17,6 +17,8 @@ export const users = pgTable('users', {
|
|
|
17
17
|
email: varchar('email', { length: 255 }),
|
|
18
18
|
avatarUrl: varchar('avatar_url', { length: 512 }),
|
|
19
19
|
plan: varchar('plan', { length: 50 }).notNull().default('free'),
|
|
20
|
+
// Stripe billing
|
|
21
|
+
stripeCustomerId: varchar('stripe_customer_id', { length: 255 }),
|
|
20
22
|
// Nango OAuth connections
|
|
21
23
|
nangoConnectionId: varchar('nango_connection_id', { length: 255 }), // Permanent login connection
|
|
22
24
|
incomingConnectionId: varchar('incoming_connection_id', { length: 255 }), // Temp polling connection
|
|
@@ -68,15 +70,14 @@ export const githubInstallationsRelations = relations(githubInstallations, ({ on
|
|
|
68
70
|
repositories: many(repositories),
|
|
69
71
|
}));
|
|
70
72
|
// ============================================================================
|
|
71
|
-
// Credentials (provider
|
|
73
|
+
// Credentials (connected provider registry - no token storage)
|
|
74
|
+
// Note: Tokens are not stored centrally. CLI tools authenticate directly
|
|
75
|
+
// on workspace instances. This table tracks which providers a user has connected.
|
|
72
76
|
// ============================================================================
|
|
73
77
|
export const credentials = pgTable('credentials', {
|
|
74
78
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
75
79
|
userId: uuid('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
|
|
76
80
|
provider: varchar('provider', { length: 50 }).notNull(),
|
|
77
|
-
accessToken: text('access_token').notNull(),
|
|
78
|
-
refreshToken: text('refresh_token'),
|
|
79
|
-
tokenExpiresAt: timestamp('token_expires_at'),
|
|
80
81
|
scopes: text('scopes').array(),
|
|
81
82
|
providerAccountId: varchar('provider_account_id', { length: 255 }),
|
|
82
83
|
providerAccountEmail: varchar('provider_account_email', { length: 255 }),
|
package/dist/cloud/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { createServer } from './server.js';
|
|
7
7
|
export { getConfig, loadConfig, CloudConfig } from './config.js';
|
|
8
|
-
export { CredentialVault } from './vault/index.js';
|
|
9
8
|
export { WorkspaceProvisioner, ProvisionConfig, Workspace, WorkspaceStatus } from './provisioner/index.js';
|
|
10
9
|
export { ScalingPolicyService, ScalingThresholds, ScalingPolicy, ScalingDecision, WorkspaceMetrics, getScalingPolicyService, AutoScaler, ScalingOperation, getAutoScaler, createAutoScaler, CapacityManager, WorkspaceCapacity, PlacementRecommendation, CapacityForecast, getCapacityManager, createCapacityManager, ScalingOrchestrator, ScalingEvent, getScalingOrchestrator, createScalingOrchestrator, } from './services/index.js';
|
|
11
10
|
export * from './billing/index.js';
|
package/dist/cloud/index.js
CHANGED
|
@@ -7,7 +7,6 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
export { createServer } from './server.js';
|
|
8
8
|
export { getConfig, loadConfig } from './config.js';
|
|
9
9
|
// Services
|
|
10
|
-
export { CredentialVault } from './vault/index.js';
|
|
11
10
|
export { WorkspaceProvisioner } from './provisioner/index.js';
|
|
12
11
|
// Scaling infrastructure
|
|
13
12
|
export { ScalingPolicyService, getScalingPolicyService, AutoScaler, getAutoScaler, createAutoScaler, CapacityManager, getCapacityManager, createCapacityManager, ScalingOrchestrator, getScalingOrchestrator, createScalingOrchestrator, } from './services/index.js';
|
|
@@ -76,8 +76,9 @@ export declare class WorkspaceProvisioner {
|
|
|
76
76
|
stop(workspaceId: string): Promise<void>;
|
|
77
77
|
/**
|
|
78
78
|
* Resize a workspace (vertical scaling)
|
|
79
|
+
* @param skipRestart - If true, config is saved but machine won't restart (changes apply on next start)
|
|
79
80
|
*/
|
|
80
|
-
resize(workspaceId: string, tier: ResourceTier): Promise<void>;
|
|
81
|
+
resize(workspaceId: string, tier: ResourceTier, skipRestart?: boolean): Promise<void>;
|
|
81
82
|
/**
|
|
82
83
|
* Update the max agent limit for a workspace
|
|
83
84
|
*/
|
|
@@ -102,6 +103,97 @@ export declare class WorkspaceProvisioner {
|
|
|
102
103
|
currentTier?: string;
|
|
103
104
|
targetTier?: string;
|
|
104
105
|
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Create an on-demand snapshot of a workspace's volume
|
|
108
|
+
* Use before risky operations (e.g., major refactors, untrusted code execution)
|
|
109
|
+
*/
|
|
110
|
+
createSnapshot(workspaceId: string): Promise<{
|
|
111
|
+
snapshotId: string;
|
|
112
|
+
} | null>;
|
|
113
|
+
/**
|
|
114
|
+
* List available snapshots for a workspace
|
|
115
|
+
* Includes both automatic daily snapshots and on-demand snapshots
|
|
116
|
+
*/
|
|
117
|
+
listSnapshots(workspaceId: string): Promise<Array<{
|
|
118
|
+
id: string;
|
|
119
|
+
createdAt: string;
|
|
120
|
+
sizeBytes: number;
|
|
121
|
+
}>>;
|
|
122
|
+
/**
|
|
123
|
+
* Get the volume ID for a workspace (needed for restore operations)
|
|
124
|
+
*/
|
|
125
|
+
getVolumeId(workspaceId: string): Promise<string | null>;
|
|
126
|
+
/**
|
|
127
|
+
* Result of a graceful update attempt
|
|
128
|
+
*/
|
|
129
|
+
static readonly UpdateResult: {
|
|
130
|
+
readonly UPDATED: "updated";
|
|
131
|
+
readonly UPDATED_PENDING_RESTART: "updated_pending_restart";
|
|
132
|
+
readonly SKIPPED_ACTIVE_AGENTS: "skipped_active_agents";
|
|
133
|
+
readonly SKIPPED_NOT_RUNNING: "skipped_not_running";
|
|
134
|
+
readonly NOT_SUPPORTED: "not_supported";
|
|
135
|
+
readonly ERROR: "error";
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Gracefully update a single workspace's image
|
|
139
|
+
*
|
|
140
|
+
* Behavior:
|
|
141
|
+
* - If workspace is stopped: Update config, will use new image on next wake
|
|
142
|
+
* - If workspace is running with no agents: Update config and restart
|
|
143
|
+
* - If workspace is running with active agents: Skip (or force if specified)
|
|
144
|
+
*
|
|
145
|
+
* @param workspaceId - Workspace to update
|
|
146
|
+
* @param newImage - New Docker image to use
|
|
147
|
+
* @param options - Update options
|
|
148
|
+
* @returns Update result with details
|
|
149
|
+
*/
|
|
150
|
+
gracefulUpdateImage(workspaceId: string, newImage: string, options?: {
|
|
151
|
+
force?: boolean;
|
|
152
|
+
skipRestart?: boolean;
|
|
153
|
+
}): Promise<{
|
|
154
|
+
result: string;
|
|
155
|
+
workspaceId: string;
|
|
156
|
+
machineState?: string;
|
|
157
|
+
agentCount?: number;
|
|
158
|
+
agents?: Array<{
|
|
159
|
+
name: string;
|
|
160
|
+
status: string;
|
|
161
|
+
}>;
|
|
162
|
+
error?: string;
|
|
163
|
+
}>;
|
|
164
|
+
/**
|
|
165
|
+
* Gracefully update all workspaces to a new image
|
|
166
|
+
*
|
|
167
|
+
* Processes workspaces in batches, respecting active agents unless forced.
|
|
168
|
+
* Returns detailed results for each workspace.
|
|
169
|
+
*
|
|
170
|
+
* @param newImage - New Docker image to use
|
|
171
|
+
* @param options - Update options
|
|
172
|
+
* @returns Summary and per-workspace results
|
|
173
|
+
*/
|
|
174
|
+
gracefulUpdateAllImages(newImage: string, options?: {
|
|
175
|
+
force?: boolean;
|
|
176
|
+
skipRestart?: boolean;
|
|
177
|
+
batchSize?: number;
|
|
178
|
+
userIds?: string[];
|
|
179
|
+
workspaceIds?: string[];
|
|
180
|
+
}): Promise<{
|
|
181
|
+
summary: {
|
|
182
|
+
total: number;
|
|
183
|
+
updated: number;
|
|
184
|
+
pendingRestart: number;
|
|
185
|
+
skippedActiveAgents: number;
|
|
186
|
+
skippedNotRunning: number;
|
|
187
|
+
errors: number;
|
|
188
|
+
};
|
|
189
|
+
results: Array<{
|
|
190
|
+
result: string;
|
|
191
|
+
workspaceId: string;
|
|
192
|
+
machineState?: string;
|
|
193
|
+
agentCount?: number;
|
|
194
|
+
error?: string;
|
|
195
|
+
}>;
|
|
196
|
+
}>;
|
|
105
197
|
}
|
|
106
198
|
export declare function getProvisioner(): WorkspaceProvisioner;
|
|
107
199
|
//# sourceMappingURL=index.d.ts.map
|