agent-relay 2.0.23 → 2.0.24
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/dist/src/cli/index.js +66 -13
- package/package.json +18 -52
- package/packages/api-types/package.json +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/cli-tester/package.json +1 -1
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +1 -1
- package/packages/daemon/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/package.json +2 -2
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/package.json +2 -2
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +1 -1
- package/packages/wrapper/package.json +6 -6
- package/deploy/init-db.sql +0 -5
- package/deploy/scripts/setup-fly-workspaces.sh +0 -69
- package/deploy/scripts/setup-railway.sh +0 -75
- package/dist/src/cloud/index.d.ts +0 -8
- package/dist/src/cloud/index.js +0 -8
- package/packages/cloud/dist/api/admin.d.ts +0 -8
- package/packages/cloud/dist/api/admin.js +0 -225
- package/packages/cloud/dist/api/auth.d.ts +0 -20
- package/packages/cloud/dist/api/auth.js +0 -138
- package/packages/cloud/dist/api/billing.d.ts +0 -7
- package/packages/cloud/dist/api/billing.js +0 -564
- package/packages/cloud/dist/api/cli-pty-runner.d.ts +0 -53
- package/packages/cloud/dist/api/cli-pty-runner.js +0 -175
- package/packages/cloud/dist/api/codex-auth-helper.d.ts +0 -21
- package/packages/cloud/dist/api/codex-auth-helper.js +0 -327
- package/packages/cloud/dist/api/consensus.d.ts +0 -13
- package/packages/cloud/dist/api/consensus.js +0 -261
- package/packages/cloud/dist/api/coordinators.d.ts +0 -8
- package/packages/cloud/dist/api/coordinators.js +0 -750
- package/packages/cloud/dist/api/daemons.d.ts +0 -12
- package/packages/cloud/dist/api/daemons.js +0 -535
- package/packages/cloud/dist/api/email-auth.d.ts +0 -11
- package/packages/cloud/dist/api/email-auth.js +0 -347
- package/packages/cloud/dist/api/generic-webhooks.d.ts +0 -8
- package/packages/cloud/dist/api/generic-webhooks.js +0 -129
- package/packages/cloud/dist/api/git.d.ts +0 -8
- package/packages/cloud/dist/api/git.js +0 -269
- package/packages/cloud/dist/api/github-app.d.ts +0 -11
- package/packages/cloud/dist/api/github-app.js +0 -223
- package/packages/cloud/dist/api/middleware/planLimits.d.ts +0 -43
- package/packages/cloud/dist/api/middleware/planLimits.js +0 -202
- package/packages/cloud/dist/api/monitoring.d.ts +0 -11
- package/packages/cloud/dist/api/monitoring.js +0 -578
- package/packages/cloud/dist/api/nango-auth.d.ts +0 -9
- package/packages/cloud/dist/api/nango-auth.js +0 -741
- package/packages/cloud/dist/api/onboarding.d.ts +0 -15
- package/packages/cloud/dist/api/onboarding.js +0 -679
- package/packages/cloud/dist/api/policy.d.ts +0 -8
- package/packages/cloud/dist/api/policy.js +0 -229
- package/packages/cloud/dist/api/provider-env.d.ts +0 -26
- package/packages/cloud/dist/api/provider-env.js +0 -141
- package/packages/cloud/dist/api/providers.d.ts +0 -7
- package/packages/cloud/dist/api/providers.js +0 -574
- package/packages/cloud/dist/api/repos.d.ts +0 -8
- package/packages/cloud/dist/api/repos.js +0 -577
- package/packages/cloud/dist/api/sessions.d.ts +0 -11
- package/packages/cloud/dist/api/sessions.js +0 -302
- package/packages/cloud/dist/api/teams.d.ts +0 -7
- package/packages/cloud/dist/api/teams.js +0 -281
- package/packages/cloud/dist/api/test-helpers.d.ts +0 -10
- package/packages/cloud/dist/api/test-helpers.js +0 -745
- package/packages/cloud/dist/api/usage.d.ts +0 -7
- package/packages/cloud/dist/api/usage.js +0 -111
- package/packages/cloud/dist/api/webhooks.d.ts +0 -8
- package/packages/cloud/dist/api/webhooks.js +0 -645
- package/packages/cloud/dist/api/workspaces.d.ts +0 -25
- package/packages/cloud/dist/api/workspaces.js +0 -1799
- package/packages/cloud/dist/billing/index.d.ts +0 -9
- package/packages/cloud/dist/billing/index.js +0 -9
- package/packages/cloud/dist/billing/plans.d.ts +0 -39
- package/packages/cloud/dist/billing/plans.js +0 -245
- package/packages/cloud/dist/billing/service.d.ts +0 -80
- package/packages/cloud/dist/billing/service.js +0 -388
- package/packages/cloud/dist/billing/types.d.ts +0 -141
- package/packages/cloud/dist/billing/types.js +0 -7
- package/packages/cloud/dist/config.d.ts +0 -5
- package/packages/cloud/dist/config.js +0 -5
- package/packages/cloud/dist/db/bulk-ingest.d.ts +0 -89
- package/packages/cloud/dist/db/bulk-ingest.js +0 -268
- package/packages/cloud/dist/db/drizzle.d.ts +0 -290
- package/packages/cloud/dist/db/drizzle.js +0 -1422
- package/packages/cloud/dist/db/index.d.ts +0 -56
- package/packages/cloud/dist/db/index.js +0 -70
- package/packages/cloud/dist/db/schema.d.ts +0 -5117
- package/packages/cloud/dist/db/schema.js +0 -656
- package/packages/cloud/dist/index.d.ts +0 -11
- package/packages/cloud/dist/index.js +0 -38
- package/packages/cloud/dist/provisioner/index.d.ts +0 -207
- package/packages/cloud/dist/provisioner/index.js +0 -2118
- package/packages/cloud/dist/server.d.ts +0 -17
- package/packages/cloud/dist/server.js +0 -2055
- package/packages/cloud/dist/services/auto-scaler.d.ts +0 -152
- package/packages/cloud/dist/services/auto-scaler.js +0 -439
- package/packages/cloud/dist/services/capacity-manager.d.ts +0 -148
- package/packages/cloud/dist/services/capacity-manager.js +0 -449
- package/packages/cloud/dist/services/ci-agent-spawner.d.ts +0 -49
- package/packages/cloud/dist/services/ci-agent-spawner.js +0 -373
- package/packages/cloud/dist/services/cloud-message-bus.d.ts +0 -28
- package/packages/cloud/dist/services/cloud-message-bus.js +0 -19
- package/packages/cloud/dist/services/compute-enforcement.d.ts +0 -57
- package/packages/cloud/dist/services/compute-enforcement.js +0 -175
- package/packages/cloud/dist/services/coordinator.d.ts +0 -62
- package/packages/cloud/dist/services/coordinator.js +0 -389
- package/packages/cloud/dist/services/index.d.ts +0 -17
- package/packages/cloud/dist/services/index.js +0 -25
- package/packages/cloud/dist/services/intro-expiration.d.ts +0 -60
- package/packages/cloud/dist/services/intro-expiration.js +0 -252
- package/packages/cloud/dist/services/mention-handler.d.ts +0 -65
- package/packages/cloud/dist/services/mention-handler.js +0 -405
- package/packages/cloud/dist/services/nango.d.ts +0 -219
- package/packages/cloud/dist/services/nango.js +0 -424
- package/packages/cloud/dist/services/persistence.d.ts +0 -131
- package/packages/cloud/dist/services/persistence.js +0 -200
- package/packages/cloud/dist/services/planLimits.d.ts +0 -147
- package/packages/cloud/dist/services/planLimits.js +0 -335
- package/packages/cloud/dist/services/presence-registry.d.ts +0 -56
- package/packages/cloud/dist/services/presence-registry.js +0 -91
- package/packages/cloud/dist/services/scaling-orchestrator.d.ts +0 -159
- package/packages/cloud/dist/services/scaling-orchestrator.js +0 -502
- package/packages/cloud/dist/services/scaling-policy.d.ts +0 -121
- package/packages/cloud/dist/services/scaling-policy.js +0 -415
- package/packages/cloud/dist/services/ssh-security.d.ts +0 -31
- package/packages/cloud/dist/services/ssh-security.js +0 -63
- package/packages/cloud/dist/services/workspace-keepalive.d.ts +0 -76
- package/packages/cloud/dist/services/workspace-keepalive.js +0 -234
- package/packages/cloud/dist/shims/consensus.d.ts +0 -23
- package/packages/cloud/dist/shims/consensus.js +0 -5
- package/packages/cloud/dist/webhooks/index.d.ts +0 -24
- package/packages/cloud/dist/webhooks/index.js +0 -29
- package/packages/cloud/dist/webhooks/parsers/github.d.ts +0 -8
- package/packages/cloud/dist/webhooks/parsers/github.js +0 -234
- package/packages/cloud/dist/webhooks/parsers/index.d.ts +0 -23
- package/packages/cloud/dist/webhooks/parsers/index.js +0 -30
- package/packages/cloud/dist/webhooks/parsers/linear.d.ts +0 -9
- package/packages/cloud/dist/webhooks/parsers/linear.js +0 -258
- package/packages/cloud/dist/webhooks/parsers/slack.d.ts +0 -9
- package/packages/cloud/dist/webhooks/parsers/slack.js +0 -214
- package/packages/cloud/dist/webhooks/responders/github.d.ts +0 -8
- package/packages/cloud/dist/webhooks/responders/github.js +0 -73
- package/packages/cloud/dist/webhooks/responders/index.d.ts +0 -23
- package/packages/cloud/dist/webhooks/responders/index.js +0 -30
- package/packages/cloud/dist/webhooks/responders/linear.d.ts +0 -9
- package/packages/cloud/dist/webhooks/responders/linear.js +0 -149
- package/packages/cloud/dist/webhooks/responders/slack.d.ts +0 -20
- package/packages/cloud/dist/webhooks/responders/slack.js +0 -178
- package/packages/cloud/dist/webhooks/router.d.ts +0 -25
- package/packages/cloud/dist/webhooks/router.js +0 -504
- package/packages/cloud/dist/webhooks/rules-engine.d.ts +0 -24
- package/packages/cloud/dist/webhooks/rules-engine.js +0 -287
- package/packages/cloud/dist/webhooks/types.d.ts +0 -186
- package/packages/cloud/dist/webhooks/types.js +0 -8
- package/packages/cloud/package.json +0 -60
- package/scripts/run-migrations.js +0 -43
- package/scripts/setup-stripe-products.ts +0 -312
- package/scripts/verify-schema.js +0 -134
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Setup Fly.io for Agent Relay Workspaces
|
|
3
|
-
# Run this from the project root
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
echo "=== Agent Relay Cloud - Fly.io Workspace Setup ==="
|
|
8
|
-
echo ""
|
|
9
|
-
|
|
10
|
-
# Check for fly CLI
|
|
11
|
-
if ! command -v fly &> /dev/null; then
|
|
12
|
-
echo "Error: Fly CLI not found. Install it with:"
|
|
13
|
-
echo " curl -L https://fly.io/install.sh | sh"
|
|
14
|
-
exit 1
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
# Check if logged in
|
|
18
|
-
if ! fly auth whoami &> /dev/null; then
|
|
19
|
-
echo "Please log in to Fly.io first:"
|
|
20
|
-
fly auth login
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
# Get org
|
|
24
|
-
FLY_ORG=${FLY_ORG:-personal}
|
|
25
|
-
echo "Using Fly.io org: $FLY_ORG"
|
|
26
|
-
|
|
27
|
-
echo ""
|
|
28
|
-
echo "=== Building Workspace Image ==="
|
|
29
|
-
echo ""
|
|
30
|
-
|
|
31
|
-
# Build and push the workspace image
|
|
32
|
-
cd deploy/workspace
|
|
33
|
-
|
|
34
|
-
echo "Building workspace Docker image..."
|
|
35
|
-
docker build -t ghcr.io/khaliqgant/agent-relay-workspace:latest .
|
|
36
|
-
|
|
37
|
-
echo ""
|
|
38
|
-
echo "Pushing to GitHub Container Registry..."
|
|
39
|
-
echo "(Make sure you're logged in: docker login ghcr.io)"
|
|
40
|
-
docker push ghcr.io/khaliqgant/agent-relay-workspace:latest
|
|
41
|
-
|
|
42
|
-
cd ../..
|
|
43
|
-
|
|
44
|
-
echo ""
|
|
45
|
-
echo "=== Get Your API Token ==="
|
|
46
|
-
echo ""
|
|
47
|
-
echo "Run this to get your Fly.io API token:"
|
|
48
|
-
echo " fly auth token"
|
|
49
|
-
echo ""
|
|
50
|
-
echo "Add it to your Railway environment:"
|
|
51
|
-
echo " FLY_API_TOKEN=<token>"
|
|
52
|
-
echo " FLY_ORG=$FLY_ORG"
|
|
53
|
-
echo " COMPUTE_PROVIDER=fly"
|
|
54
|
-
echo ""
|
|
55
|
-
|
|
56
|
-
echo "=== Custom Domain Setup ==="
|
|
57
|
-
echo ""
|
|
58
|
-
echo "To use custom workspace domains (e.g., abc123.ws.agent-relay.com):"
|
|
59
|
-
echo ""
|
|
60
|
-
echo "1. Add a wildcard CNAME record in your DNS:"
|
|
61
|
-
echo " *.ws.agent-relay.com CNAME fly.dev"
|
|
62
|
-
echo ""
|
|
63
|
-
echo "2. Set the domain in Railway:"
|
|
64
|
-
echo " FLY_WORKSPACE_DOMAIN=ws.agent-relay.com"
|
|
65
|
-
echo ""
|
|
66
|
-
echo "3. Each workspace will be accessible at:"
|
|
67
|
-
echo " https://{workspace-id}.ws.agent-relay.com"
|
|
68
|
-
echo ""
|
|
69
|
-
echo "Setup complete!"
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Setup Agent Relay Cloud on Railway
|
|
3
|
-
# Run this from the project root
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
echo "=== Agent Relay Cloud - Railway Setup ==="
|
|
8
|
-
echo ""
|
|
9
|
-
|
|
10
|
-
# Check for railway CLI
|
|
11
|
-
if ! command -v railway &> /dev/null; then
|
|
12
|
-
echo "Error: Railway CLI not found. Install it with:"
|
|
13
|
-
echo " npm install -g @railway/cli"
|
|
14
|
-
exit 1
|
|
15
|
-
fi
|
|
16
|
-
|
|
17
|
-
# Check if logged in
|
|
18
|
-
if ! railway whoami &> /dev/null; then
|
|
19
|
-
echo "Please log in to Railway first:"
|
|
20
|
-
railway login
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
echo "Creating Railway project..."
|
|
24
|
-
railway init --name agent-relay-cloud
|
|
25
|
-
|
|
26
|
-
echo ""
|
|
27
|
-
echo "Adding PostgreSQL database..."
|
|
28
|
-
railway add --plugin postgresql
|
|
29
|
-
|
|
30
|
-
echo ""
|
|
31
|
-
echo "Adding Redis..."
|
|
32
|
-
railway add --plugin redis
|
|
33
|
-
|
|
34
|
-
echo ""
|
|
35
|
-
echo "=== Required Environment Variables ==="
|
|
36
|
-
echo "Please set these in Railway dashboard or via CLI:"
|
|
37
|
-
echo ""
|
|
38
|
-
echo "Required:"
|
|
39
|
-
echo " SESSION_SECRET - openssl rand -hex 32"
|
|
40
|
-
echo " GITHUB_CLIENT_ID - From GitHub OAuth App"
|
|
41
|
-
echo " GITHUB_CLIENT_SECRET - From GitHub OAuth App"
|
|
42
|
-
echo " VAULT_ENCRYPTION_KEY - openssl rand -hex 32"
|
|
43
|
-
echo ""
|
|
44
|
-
echo "For Fly.io workspaces:"
|
|
45
|
-
echo " COMPUTE_PROVIDER=fly"
|
|
46
|
-
echo " FLY_API_TOKEN - fly auth token"
|
|
47
|
-
echo " FLY_ORG=personal"
|
|
48
|
-
echo " FLY_WORKSPACE_DOMAIN - e.g., ws.agent-relay.com"
|
|
49
|
-
echo ""
|
|
50
|
-
echo "For Stripe billing:"
|
|
51
|
-
echo " STRIPE_SECRET_KEY"
|
|
52
|
-
echo " STRIPE_PUBLISHABLE_KEY"
|
|
53
|
-
echo " STRIPE_WEBHOOK_SECRET"
|
|
54
|
-
echo ""
|
|
55
|
-
|
|
56
|
-
echo "Set variables with:"
|
|
57
|
-
echo " railway variables set KEY=value"
|
|
58
|
-
echo ""
|
|
59
|
-
|
|
60
|
-
echo "When ready, deploy with:"
|
|
61
|
-
echo " railway up"
|
|
62
|
-
echo ""
|
|
63
|
-
|
|
64
|
-
echo "=== DNS Configuration ==="
|
|
65
|
-
echo "After deployment, configure your DNS:"
|
|
66
|
-
echo ""
|
|
67
|
-
echo "1. Get your Railway domain:"
|
|
68
|
-
echo " railway domain"
|
|
69
|
-
echo ""
|
|
70
|
-
echo "2. Configure DNS records:"
|
|
71
|
-
echo " api.agent-relay.com CNAME <railway-domain>"
|
|
72
|
-
echo " app.agent-relay.com CNAME <your-dashboard-host>"
|
|
73
|
-
echo " agent-relay.com A <your-landing-host>"
|
|
74
|
-
echo " *.ws.agent-relay.com CNAME fly.dev (for workspaces)"
|
|
75
|
-
echo ""
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated Import from '@agent-relay/cloud' instead.
|
|
3
|
-
*
|
|
4
|
-
* This file re-exports from the @relay/cloud package for backward compatibility.
|
|
5
|
-
* All cloud functionality has been moved to packages/cloud/.
|
|
6
|
-
*/
|
|
7
|
-
export * from '@agent-relay/cloud';
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/cloud/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated Import from '@agent-relay/cloud' instead.
|
|
3
|
-
*
|
|
4
|
-
* This file re-exports from the @relay/cloud package for backward compatibility.
|
|
5
|
-
* All cloud functionality has been moved to packages/cloud/.
|
|
6
|
-
*/
|
|
7
|
-
export * from '@agent-relay/cloud';
|
|
8
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Admin API Routes
|
|
3
|
-
*
|
|
4
|
-
* Administrative endpoints for managing workspaces at scale.
|
|
5
|
-
* Protected by admin secret (ADMIN_API_SECRET environment variable).
|
|
6
|
-
*/
|
|
7
|
-
export declare const adminRouter: import("express-serve-static-core").Router;
|
|
8
|
-
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Admin API Routes
|
|
3
|
-
*
|
|
4
|
-
* Administrative endpoints for managing workspaces at scale.
|
|
5
|
-
* Protected by admin secret (ADMIN_API_SECRET environment variable).
|
|
6
|
-
*/
|
|
7
|
-
import { Router } from 'express';
|
|
8
|
-
import { getConfig } from '../config.js';
|
|
9
|
-
import { getProvisioner, WorkspaceProvisioner } from '../provisioner/index.js';
|
|
10
|
-
export const adminRouter = Router();
|
|
11
|
-
/**
|
|
12
|
-
* Middleware to authenticate admin requests
|
|
13
|
-
* Requires ADMIN_API_SECRET header to match environment variable
|
|
14
|
-
*/
|
|
15
|
-
async function requireAdminAuth(req, res, next) {
|
|
16
|
-
const authHeader = req.headers['x-admin-secret'] || req.headers.authorization;
|
|
17
|
-
const adminSecret = process.env.ADMIN_API_SECRET;
|
|
18
|
-
if (!adminSecret) {
|
|
19
|
-
res.status(503).json({ error: 'Admin API not configured' });
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
// Support both x-admin-secret header and Bearer token
|
|
23
|
-
const providedSecret = authHeader?.toString().replace('Bearer ', '');
|
|
24
|
-
if (!providedSecret || providedSecret !== adminSecret) {
|
|
25
|
-
res.status(401).json({ error: 'Invalid admin credentials' });
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
next();
|
|
29
|
-
}
|
|
30
|
-
// Apply admin auth to all routes
|
|
31
|
-
adminRouter.use(requireAdminAuth);
|
|
32
|
-
/**
|
|
33
|
-
* POST /api/admin/workspaces/update-image
|
|
34
|
-
*
|
|
35
|
-
* Gracefully update workspace images across all or specific workspaces.
|
|
36
|
-
*
|
|
37
|
-
* Request body:
|
|
38
|
-
* - image: New Docker image to deploy (required)
|
|
39
|
-
* - workspaceIds?: Array of specific workspace IDs to update
|
|
40
|
-
* - userIds?: Array of user IDs whose workspaces to update
|
|
41
|
-
* - force?: Force update even if agents are active (default: false)
|
|
42
|
-
* - skipRestart?: Update config without restarting (default: false)
|
|
43
|
-
* - batchSize?: Number of concurrent updates (default: 5)
|
|
44
|
-
*
|
|
45
|
-
* Response:
|
|
46
|
-
* - summary: { total, updated, pendingRestart, skippedActiveAgents, skippedVerificationFailed, skippedNotRunning, errors }
|
|
47
|
-
* - results: Array of per-workspace results
|
|
48
|
-
*/
|
|
49
|
-
adminRouter.post('/workspaces/update-image', async (req, res) => {
|
|
50
|
-
const { image, workspaceIds, userIds, force = false, skipRestart = false, batchSize = 5, } = req.body;
|
|
51
|
-
if (!image) {
|
|
52
|
-
res.status(400).json({ error: 'image is required' });
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
console.log(`[admin] Starting workspace image update to ${image}`, {
|
|
56
|
-
workspaceIds: workspaceIds?.length ?? 'all',
|
|
57
|
-
userIds: userIds?.length ?? 'all',
|
|
58
|
-
force,
|
|
59
|
-
skipRestart,
|
|
60
|
-
batchSize,
|
|
61
|
-
});
|
|
62
|
-
try {
|
|
63
|
-
const provisioner = getProvisioner();
|
|
64
|
-
const result = await provisioner.gracefulUpdateAllImages(image, {
|
|
65
|
-
workspaceIds,
|
|
66
|
-
userIds,
|
|
67
|
-
force,
|
|
68
|
-
skipRestart,
|
|
69
|
-
batchSize,
|
|
70
|
-
});
|
|
71
|
-
res.json(result);
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
console.error('[admin] Error updating workspace images:', error);
|
|
75
|
-
res.status(500).json({
|
|
76
|
-
error: 'Failed to update workspace images',
|
|
77
|
-
details: error.message,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
/**
|
|
82
|
-
* POST /api/admin/workspaces/:id/update-image
|
|
83
|
-
*
|
|
84
|
-
* Gracefully update a single workspace's image.
|
|
85
|
-
*
|
|
86
|
-
* Request body:
|
|
87
|
-
* - image: New Docker image to deploy (required)
|
|
88
|
-
* - force?: Force update even if agents are active (default: false)
|
|
89
|
-
* - skipRestart?: Update config without restarting (default: false)
|
|
90
|
-
*
|
|
91
|
-
* Response:
|
|
92
|
-
* - result: Update result code
|
|
93
|
-
* - workspaceId: Workspace ID
|
|
94
|
-
* - machineState?: Current machine state
|
|
95
|
-
* - agentCount?: Number of active agents (if applicable)
|
|
96
|
-
* - error?: Error message (if applicable)
|
|
97
|
-
*/
|
|
98
|
-
adminRouter.post('/workspaces/:id/update-image', async (req, res) => {
|
|
99
|
-
const id = req.params.id;
|
|
100
|
-
const { image, force = false, skipRestart = false, } = req.body;
|
|
101
|
-
if (!image) {
|
|
102
|
-
res.status(400).json({ error: 'image is required' });
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
console.log(`[admin] Updating workspace ${id} image to ${image}`, { force, skipRestart });
|
|
106
|
-
try {
|
|
107
|
-
const provisioner = getProvisioner();
|
|
108
|
-
const result = await provisioner.gracefulUpdateImage(id, image, {
|
|
109
|
-
force,
|
|
110
|
-
skipRestart,
|
|
111
|
-
});
|
|
112
|
-
// Return appropriate status code based on result
|
|
113
|
-
if (result.result === WorkspaceProvisioner.UpdateResult.ERROR) {
|
|
114
|
-
res.status(500).json(result);
|
|
115
|
-
}
|
|
116
|
-
else if (result.result === WorkspaceProvisioner.UpdateResult.NOT_SUPPORTED) {
|
|
117
|
-
res.status(400).json(result);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
res.json(result);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
console.error(`[admin] Error updating workspace ${id}:`, error);
|
|
125
|
-
res.status(500).json({
|
|
126
|
-
error: 'Failed to update workspace image',
|
|
127
|
-
details: error.message,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
/**
|
|
132
|
-
* GET /api/admin/workspaces/:id/agents
|
|
133
|
-
*
|
|
134
|
-
* Check active agents in a workspace.
|
|
135
|
-
* Useful for pre-flight checks before updates.
|
|
136
|
-
*
|
|
137
|
-
* Response:
|
|
138
|
-
* - hasActiveAgents: boolean
|
|
139
|
-
* - agentCount: number
|
|
140
|
-
* - agents: Array of { name, status }
|
|
141
|
-
*/
|
|
142
|
-
adminRouter.get('/workspaces/:id/agents', async (req, res) => {
|
|
143
|
-
const id = req.params.id;
|
|
144
|
-
try {
|
|
145
|
-
// Query workspace directly from DB and check agents via daemon API
|
|
146
|
-
const workspace = await (await import('../db/index.js')).db.workspaces.findById(id);
|
|
147
|
-
if (!workspace) {
|
|
148
|
-
res.status(404).json({ error: 'Workspace not found' });
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (workspace.computeProvider !== 'fly') {
|
|
152
|
-
res.status(400).json({ error: 'Only Fly.io workspaces support agent checking' });
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
// Query the workspace daemon directly
|
|
156
|
-
const baseUrl = workspace.publicUrl;
|
|
157
|
-
if (!baseUrl) {
|
|
158
|
-
res.json({ hasActiveAgents: false, agentCount: 0, agents: [] });
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
// Use /api/data endpoint which returns { agents: [...], ... }
|
|
163
|
-
// Note: /api/agents doesn't exist on the workspace dashboard-server
|
|
164
|
-
const response = await fetch(`${baseUrl}/api/data`, {
|
|
165
|
-
method: 'GET',
|
|
166
|
-
headers: { 'Accept': 'application/json' },
|
|
167
|
-
signal: AbortSignal.timeout(10_000),
|
|
168
|
-
});
|
|
169
|
-
if (!response.ok) {
|
|
170
|
-
res.json({ hasActiveAgents: false, agentCount: 0, agents: [], error: `Daemon returned ${response.status}` });
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
const data = await response.json();
|
|
174
|
-
const agents = data.agents || [];
|
|
175
|
-
const activeAgents = agents.filter(a => {
|
|
176
|
-
const status = (a.status ?? '').toLowerCase();
|
|
177
|
-
const activityState = (a.activityState ?? '').toLowerCase();
|
|
178
|
-
const isProcessing = a.isProcessing === true;
|
|
179
|
-
if (activityState === 'active' || activityState === 'idle')
|
|
180
|
-
return true;
|
|
181
|
-
if (status && status !== 'disconnected' && status !== 'offline')
|
|
182
|
-
return true;
|
|
183
|
-
if (isProcessing)
|
|
184
|
-
return true;
|
|
185
|
-
return false;
|
|
186
|
-
});
|
|
187
|
-
res.json({
|
|
188
|
-
hasActiveAgents: activeAgents.length > 0,
|
|
189
|
-
agentCount: activeAgents.length,
|
|
190
|
-
agents: agents.map(a => ({ name: a.name, status: a.status || a.activityState || 'unknown' })),
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
// Workspace might be stopped
|
|
195
|
-
res.json({
|
|
196
|
-
hasActiveAgents: false,
|
|
197
|
-
agentCount: 0,
|
|
198
|
-
agents: [],
|
|
199
|
-
error: `Could not reach workspace: ${error.message}`,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
204
|
-
console.error(`[admin] Error checking agents for workspace ${id}:`, error);
|
|
205
|
-
res.status(500).json({
|
|
206
|
-
error: 'Failed to check workspace agents',
|
|
207
|
-
details: error.message,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
/**
|
|
212
|
-
* GET /api/admin/health
|
|
213
|
-
*
|
|
214
|
-
* Health check for admin API.
|
|
215
|
-
*/
|
|
216
|
-
adminRouter.get('/health', (_req, res) => {
|
|
217
|
-
res.json({
|
|
218
|
-
status: 'ok',
|
|
219
|
-
timestamp: new Date().toISOString(),
|
|
220
|
-
config: {
|
|
221
|
-
computeProvider: getConfig().compute.provider,
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
//# sourceMappingURL=admin.js.map
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auth API Routes
|
|
3
|
-
*
|
|
4
|
-
* Session management routes.
|
|
5
|
-
* User login is handled via Nango (see nango-auth.ts).
|
|
6
|
-
* GitHub repo operations are in github-app.ts.
|
|
7
|
-
*/
|
|
8
|
-
import { Request, Response } from 'express';
|
|
9
|
-
export declare const authRouter: import("express-serve-static-core").Router;
|
|
10
|
-
declare module 'express-session' {
|
|
11
|
-
interface SessionData {
|
|
12
|
-
userId?: string;
|
|
13
|
-
githubToken?: string;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Middleware to require authentication
|
|
18
|
-
*/
|
|
19
|
-
export declare function requireAuth(req: Request, res: Response, next: () => void): Response<any, Record<string, any>> | undefined;
|
|
20
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auth API Routes
|
|
3
|
-
*
|
|
4
|
-
* Session management routes.
|
|
5
|
-
* User login is handled via Nango (see nango-auth.ts).
|
|
6
|
-
* GitHub repo operations are in github-app.ts.
|
|
7
|
-
*/
|
|
8
|
-
import { Router } from 'express';
|
|
9
|
-
import { db } from '../db/index.js';
|
|
10
|
-
export const authRouter = Router();
|
|
11
|
-
/**
|
|
12
|
-
* GET /api/auth/github
|
|
13
|
-
* Redirect to Nango login flow
|
|
14
|
-
* @deprecated Use /api/auth/nango/login-session instead
|
|
15
|
-
*/
|
|
16
|
-
authRouter.get('/github', (_req, res) => {
|
|
17
|
-
res.redirect('/api/auth/nango/login-session');
|
|
18
|
-
});
|
|
19
|
-
/**
|
|
20
|
-
* POST /api/auth/logout
|
|
21
|
-
* Logout user
|
|
22
|
-
*/
|
|
23
|
-
authRouter.post('/logout', (req, res) => {
|
|
24
|
-
req.session.destroy((err) => {
|
|
25
|
-
if (err) {
|
|
26
|
-
return res.status(500).json({ error: 'Failed to logout' });
|
|
27
|
-
}
|
|
28
|
-
res.json({ success: true });
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
/**
|
|
32
|
-
* GET /api/auth/me
|
|
33
|
-
* Get current user
|
|
34
|
-
*/
|
|
35
|
-
authRouter.get('/me', async (req, res) => {
|
|
36
|
-
if (!req.session.userId) {
|
|
37
|
-
return res.status(401).json({ error: 'Not authenticated' });
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
const user = await db.users.findById(req.session.userId);
|
|
41
|
-
if (!user) {
|
|
42
|
-
return res.status(401).json({ error: 'User not found' });
|
|
43
|
-
}
|
|
44
|
-
// Get connected providers
|
|
45
|
-
const credentials = await db.credentials.findByUserId(user.id);
|
|
46
|
-
const connectedProviders = credentials.map((c) => ({
|
|
47
|
-
provider: c.provider,
|
|
48
|
-
email: c.providerAccountEmail,
|
|
49
|
-
connectedAt: c.createdAt,
|
|
50
|
-
}));
|
|
51
|
-
// Get pending invites
|
|
52
|
-
const pendingInvites = await db.workspaceMembers.getPendingInvites(user.id);
|
|
53
|
-
// Check for pending GitHub installation request
|
|
54
|
-
const pendingGitHubApproval = !!user.pendingInstallationRequest;
|
|
55
|
-
res.json({
|
|
56
|
-
id: user.id,
|
|
57
|
-
githubUsername: user.githubUsername,
|
|
58
|
-
displayName: user.displayName || user.githubUsername || user.email?.split('@')[0] || null,
|
|
59
|
-
email: user.email,
|
|
60
|
-
avatarUrl: user.avatarUrl,
|
|
61
|
-
plan: user.plan,
|
|
62
|
-
connectedProviders,
|
|
63
|
-
pendingInvites: pendingInvites.length,
|
|
64
|
-
pendingGitHubApproval,
|
|
65
|
-
onboardingCompleted: !!user.onboardingCompletedAt,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
console.error('Error getting user:', error);
|
|
70
|
-
res.status(500).json({ error: 'Failed to get user' });
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
/**
|
|
74
|
-
* Middleware to require authentication
|
|
75
|
-
*/
|
|
76
|
-
export function requireAuth(req, res, next) {
|
|
77
|
-
if (!req.session.userId) {
|
|
78
|
-
return res.status(401).json({
|
|
79
|
-
error: 'Authentication required',
|
|
80
|
-
code: 'SESSION_EXPIRED',
|
|
81
|
-
message: 'Your session has expired. Please log in again.',
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
next();
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* GET /api/auth/session
|
|
88
|
-
* Check if current session is valid
|
|
89
|
-
*/
|
|
90
|
-
authRouter.get('/session', async (req, res) => {
|
|
91
|
-
if (!req.session.userId) {
|
|
92
|
-
return res.json({
|
|
93
|
-
authenticated: false,
|
|
94
|
-
code: 'SESSION_EXPIRED',
|
|
95
|
-
message: 'Your session has expired. Please log in again.',
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
// Verify user still exists
|
|
100
|
-
const user = await db.users.findById(req.session.userId);
|
|
101
|
-
if (!user) {
|
|
102
|
-
req.session.destroy(() => { });
|
|
103
|
-
return res.json({
|
|
104
|
-
authenticated: false,
|
|
105
|
-
code: 'USER_NOT_FOUND',
|
|
106
|
-
message: 'User account not found. Please log in again.',
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
// Get connected providers
|
|
110
|
-
const credentials = await db.credentials.findByUserId(user.id);
|
|
111
|
-
const connectedProviders = credentials.map((c) => ({
|
|
112
|
-
provider: c.provider,
|
|
113
|
-
email: c.providerAccountEmail,
|
|
114
|
-
connectedAt: c.createdAt,
|
|
115
|
-
}));
|
|
116
|
-
res.json({
|
|
117
|
-
authenticated: true,
|
|
118
|
-
user: {
|
|
119
|
-
id: user.id,
|
|
120
|
-
githubUsername: user.githubUsername,
|
|
121
|
-
displayName: user.displayName || user.githubUsername || user.email?.split('@')[0] || null,
|
|
122
|
-
email: user.email,
|
|
123
|
-
avatarUrl: user.avatarUrl,
|
|
124
|
-
plan: user.plan,
|
|
125
|
-
},
|
|
126
|
-
connectedProviders,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
console.error('Session check error:', error);
|
|
131
|
-
res.status(500).json({
|
|
132
|
-
authenticated: false,
|
|
133
|
-
code: 'SESSION_ERROR',
|
|
134
|
-
message: 'An error occurred while checking your session.',
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
//# sourceMappingURL=auth.js.map
|