dev3000 0.0.121 → 0.0.124
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/cli.js +19 -0
- package/dist/cli.js.map +1 -1
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +11 -0
- package/dist/dev-environment.js.map +1 -1
- package/dist/utils/log-filename.d.ts.map +1 -1
- package/dist/utils/log-filename.js +8 -3
- package/dist/utils/log-filename.js.map +1 -1
- package/mcp-server/app/mcp/route.ts +81 -7
- package/mcp-server/app/mcp/tools.ts +33 -3
- package/mcp-server/next-env.d.ts +1 -1
- package/mcp-server/package.json +0 -12
- package/package.json +6 -7
- package/mcp-server/.next/build/chunks/[root-of-the-server]__25374c4f._.js +0 -500
- package/mcp-server/.next/build/chunks/[root-of-the-server]__25374c4f._.js.map +0 -11
- package/mcp-server/.next/build/chunks/[root-of-the-server]__6e020478._.js +0 -441
- package/mcp-server/.next/build/chunks/[root-of-the-server]__6e020478._.js.map +0 -7
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c438ef56._.js +0 -205
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c438ef56._.js.map +0 -8
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c7ae8543._.js +0 -500
- package/mcp-server/.next/build/chunks/[root-of-the-server]__c7ae8543._.js.map +0 -11
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_80bff36f._.js +0 -13
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_postcss_ts_80bff36f._.js.map +0 -5
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_webpack-loaders_ts_c84aa21a._.js +0 -12
- package/mcp-server/.next/build/chunks/[turbopack-node]_transforms_webpack-loaders_ts_c84aa21a._.js.map +0 -5
- package/mcp-server/.next/build/chunks/[turbopack]_runtime.js +0 -770
- package/mcp-server/.next/build/chunks/[turbopack]_runtime.js.map +0 -10
- package/mcp-server/.next/build/chunks/node_modules__pnpm_806d01c0._.js +0 -6758
- package/mcp-server/.next/build/chunks/node_modules__pnpm_806d01c0._.js.map +0 -47
- package/mcp-server/.next/build/package.json +0 -1
- package/mcp-server/.next/build/postcss.js +0 -6
- package/mcp-server/.next/build/postcss.js.map +0 -5
- package/mcp-server/.next/build/webpack-loaders.js +0 -6
- package/mcp-server/.next/build/webpack-loaders.js.map +0 -5
- package/mcp-server/.next/package.json +0 -1
- package/mcp-server/app/api/auth/authorize/route.ts +0 -52
- package/mcp-server/app/api/auth/callback/route.ts +0 -128
- package/mcp-server/app/api/auth/signout/route.ts +0 -34
- package/mcp-server/app/api/auth/token/route.ts +0 -16
- package/mcp-server/app/api/cloud/check-pr/route.ts +0 -53
- package/mcp-server/app/api/cloud/check-pr/steps.ts +0 -458
- package/mcp-server/app/api/cloud/check-pr/workflow.ts +0 -109
- package/mcp-server/app/api/cloud/fix-workflow/health/route.ts +0 -10
- package/mcp-server/app/api/cloud/fix-workflow/route.ts +0 -50
- package/mcp-server/app/api/cloud/fix-workflow/steps.ts +0 -2091
- package/mcp-server/app/api/cloud/fix-workflow/workflow.ts +0 -296
- package/mcp-server/app/api/cloud/start-fix/route.ts +0 -192
- package/mcp-server/app/api/integration/webhook/route.ts +0 -290
- package/mcp-server/app/api/projects/[projectId]/bypass-token/route.ts +0 -48
- package/mcp-server/app/api/projects/branches/route.ts +0 -115
- package/mcp-server/app/api/projects/check-protection/route.ts +0 -33
- package/mcp-server/app/api/projects/route.ts +0 -97
- package/mcp-server/app/api/workflows/route.ts +0 -105
- package/mcp-server/app/auth/error/page.tsx +0 -47
- package/mcp-server/app/signin/page.tsx +0 -37
- package/mcp-server/app/workflows/[id]/report/agent-analysis.tsx +0 -7
- package/mcp-server/app/workflows/[id]/report/page.tsx +0 -199
- package/mcp-server/app/workflows/new/new-workflow-client.tsx +0 -32
- package/mcp-server/app/workflows/new/page.tsx +0 -13
- package/mcp-server/app/workflows/new-workflow-modal.tsx +0 -973
- package/mcp-server/app/workflows/page.tsx +0 -16
- package/mcp-server/app/workflows/workflows-client.tsx +0 -290
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloud Fix Workflow Function - Core workflow logic
|
|
3
|
-
*
|
|
4
|
-
* This file contains ONLY the workflow function and step wrappers.
|
|
5
|
-
* It does NOT import workflow/api to avoid bundler issues.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Main workflow function that orchestrates the fix process
|
|
10
|
-
*/
|
|
11
|
-
export async function cloudFixWorkflow(params: {
|
|
12
|
-
devUrl: string
|
|
13
|
-
projectName: string
|
|
14
|
-
vercelToken?: string
|
|
15
|
-
vercelOidcToken?: string
|
|
16
|
-
repoOwner?: string
|
|
17
|
-
repoName?: string
|
|
18
|
-
baseBranch?: string
|
|
19
|
-
bypassToken?: string
|
|
20
|
-
repoUrl?: string
|
|
21
|
-
repoBranch?: string
|
|
22
|
-
runId?: string // For progress tracking
|
|
23
|
-
userId?: string // For progress tracking
|
|
24
|
-
}) {
|
|
25
|
-
"use workflow"
|
|
26
|
-
|
|
27
|
-
const {
|
|
28
|
-
devUrl,
|
|
29
|
-
projectName,
|
|
30
|
-
vercelToken,
|
|
31
|
-
vercelOidcToken: vercelOidcTokenParam,
|
|
32
|
-
repoOwner,
|
|
33
|
-
repoName,
|
|
34
|
-
baseBranch = "main",
|
|
35
|
-
bypassToken,
|
|
36
|
-
repoUrl,
|
|
37
|
-
repoBranch,
|
|
38
|
-
runId,
|
|
39
|
-
userId
|
|
40
|
-
} = params
|
|
41
|
-
const timestamp = new Date().toISOString()
|
|
42
|
-
|
|
43
|
-
console.log("[Workflow] Starting cloud fix workflow...")
|
|
44
|
-
console.log(`[Workflow] Dev URL: ${devUrl}`)
|
|
45
|
-
console.log(`[Workflow] Project: ${projectName}`)
|
|
46
|
-
console.log(`[Workflow] Timestamp: ${new Date().toISOString()}`)
|
|
47
|
-
console.log(`[Workflow] Bypass Token: ${bypassToken ? "provided" : "not provided"}`)
|
|
48
|
-
if (repoOwner && repoName) {
|
|
49
|
-
console.log(`[Workflow] GitHub Repo: ${repoOwner}/${repoName}`)
|
|
50
|
-
console.log(`[Workflow] Base Branch: ${baseBranch}`)
|
|
51
|
-
}
|
|
52
|
-
if (repoUrl) {
|
|
53
|
-
console.log(`[Workflow] Will create sandbox from: ${repoUrl}`)
|
|
54
|
-
console.log(`[Workflow] Branch: ${repoBranch || "main"}`)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Use VERCEL_OIDC_TOKEN from params (passed from request header) or fall back to env
|
|
58
|
-
// At runtime, OIDC token is in x-vercel-oidc-token header, not process.env
|
|
59
|
-
const vercelOidcToken = vercelOidcTokenParam || process.env.VERCEL_OIDC_TOKEN
|
|
60
|
-
console.log(`[Workflow] VERCEL_OIDC_TOKEN from param: ${!!vercelOidcTokenParam}`)
|
|
61
|
-
console.log(`[Workflow] VERCEL_OIDC_TOKEN from env: ${!!process.env.VERCEL_OIDC_TOKEN}`)
|
|
62
|
-
console.log(`[Workflow] VERCEL_OIDC_TOKEN available: ${!!vercelOidcToken}`)
|
|
63
|
-
|
|
64
|
-
// Helper to update progress if tracking is enabled
|
|
65
|
-
const updateProgress = async (stepNumber: number, currentStep: string, sandboxUrl?: string) => {
|
|
66
|
-
if (runId && userId) {
|
|
67
|
-
await updateWorkflowProgressStep(userId, runId, projectName, timestamp, stepNumber, currentStep, sandboxUrl)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Step 0: Create d3k sandbox if repoUrl provided
|
|
72
|
-
// This step also captures CLS data, "before" screenshot, git diff, and d3k artifacts from inside the sandbox
|
|
73
|
-
// It also saves an initial report to blob storage so we have data even if later steps fail
|
|
74
|
-
let sandboxInfo: {
|
|
75
|
-
mcpUrl: string
|
|
76
|
-
devUrl: string
|
|
77
|
-
bypassToken?: string
|
|
78
|
-
clsData?: unknown
|
|
79
|
-
mcpError?: string | null
|
|
80
|
-
beforeScreenshotUrl?: string | null
|
|
81
|
-
chromiumPath?: string
|
|
82
|
-
gitDiff?: string | null
|
|
83
|
-
d3kArtifacts?: {
|
|
84
|
-
clsScreenshots: Array<{ label: string; blobUrl: string; timestamp: number }>
|
|
85
|
-
screencastSessionId: string | null
|
|
86
|
-
fullLogs: string | null
|
|
87
|
-
metadata: Record<string, unknown> | null
|
|
88
|
-
}
|
|
89
|
-
reportId?: string
|
|
90
|
-
reportBlobUrl?: string
|
|
91
|
-
agentAnalysis?: string | null
|
|
92
|
-
} | null = null
|
|
93
|
-
if (repoUrl) {
|
|
94
|
-
await updateProgress(0, "Creating development sandbox...")
|
|
95
|
-
sandboxInfo = await createD3kSandbox(
|
|
96
|
-
repoUrl,
|
|
97
|
-
repoBranch || "main",
|
|
98
|
-
projectName,
|
|
99
|
-
vercelToken,
|
|
100
|
-
vercelOidcToken,
|
|
101
|
-
runId // Pass runId so Step 0 can save the initial report with consistent ID
|
|
102
|
-
)
|
|
103
|
-
if (sandboxInfo?.devUrl) {
|
|
104
|
-
await updateProgress(0, "Sandbox ready, capturing CLS metrics...", sandboxInfo.devUrl)
|
|
105
|
-
}
|
|
106
|
-
if (sandboxInfo?.reportBlobUrl) {
|
|
107
|
-
console.log(`[Workflow] Report saved: ${sandboxInfo.reportBlobUrl}`)
|
|
108
|
-
}
|
|
109
|
-
if (sandboxInfo?.agentAnalysis) {
|
|
110
|
-
console.log(`[Workflow] Agent analysis completed in Step 0`)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Step 1: Fetch real logs (only if we don't have sandbox data)
|
|
115
|
-
// Skip if we already got CLS data and agent analysis from Step 0
|
|
116
|
-
let logAnalysis = ""
|
|
117
|
-
let beforeScreenshotUrl: string | null = sandboxInfo?.beforeScreenshotUrl || null
|
|
118
|
-
|
|
119
|
-
if (!sandboxInfo?.clsData) {
|
|
120
|
-
await updateProgress(1, "Capturing performance metrics (CLS, LCP, errors)...")
|
|
121
|
-
const effectiveBypassToken = sandboxInfo?.bypassToken || bypassToken
|
|
122
|
-
const step1Result = await fetchRealLogs(
|
|
123
|
-
sandboxInfo?.mcpUrl || devUrl,
|
|
124
|
-
effectiveBypassToken,
|
|
125
|
-
sandboxInfo?.devUrl,
|
|
126
|
-
sandboxInfo?.clsData,
|
|
127
|
-
sandboxInfo?.mcpError,
|
|
128
|
-
sandboxInfo?.beforeScreenshotUrl
|
|
129
|
-
)
|
|
130
|
-
logAnalysis = step1Result.logAnalysis
|
|
131
|
-
beforeScreenshotUrl = step1Result.beforeScreenshotUrl
|
|
132
|
-
await updateProgress(1, `Captured ${logAnalysis.length > 5000 ? "detailed" : "initial"} diagnostics`)
|
|
133
|
-
} else {
|
|
134
|
-
logAnalysis = JSON.stringify(sandboxInfo.clsData, null, 2)
|
|
135
|
-
await updateProgress(1, "Using CLS data from sandbox")
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Step 2: AI agent analysis
|
|
139
|
-
// If we already ran the agent in Step 0 (with sandbox tools), use that result
|
|
140
|
-
// Otherwise, run the basic agent without sandbox access
|
|
141
|
-
let fixProposal: string
|
|
142
|
-
|
|
143
|
-
if (sandboxInfo?.agentAnalysis) {
|
|
144
|
-
// Agent already ran with sandbox tools in Step 0
|
|
145
|
-
fixProposal = sandboxInfo.agentAnalysis
|
|
146
|
-
await updateProgress(2, "AI agent completed analysis with code access")
|
|
147
|
-
} else {
|
|
148
|
-
// Fallback: run agent without sandbox (limited mode)
|
|
149
|
-
await updateProgress(2, "AI agent analyzing logs (limited mode)...")
|
|
150
|
-
fixProposal = await analyzeLogsWithAgent(logAnalysis, sandboxInfo?.devUrl || devUrl)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Provide feedback on what was found
|
|
154
|
-
const hasError = fixProposal.toLowerCase().includes("error") || fixProposal.toLowerCase().includes("issue")
|
|
155
|
-
const hasFix = fixProposal.includes("```diff")
|
|
156
|
-
if (hasFix) {
|
|
157
|
-
await updateProgress(2, "AI generated a fix proposal with code changes")
|
|
158
|
-
} else if (hasError) {
|
|
159
|
-
await updateProgress(2, "AI identified issues but no code fix needed")
|
|
160
|
-
} else {
|
|
161
|
-
await updateProgress(2, "AI analysis complete - system appears healthy")
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Step 3: Upload to blob storage as JSON with full context
|
|
165
|
-
await updateProgress(3, "Compiling full report with screenshots...")
|
|
166
|
-
const agentAnalysisModel = "anthropic/claude-sonnet-4-20250514" // Model used in analyzeLogsWithAgent
|
|
167
|
-
const blobResult = await uploadToBlob(
|
|
168
|
-
fixProposal,
|
|
169
|
-
projectName,
|
|
170
|
-
logAnalysis,
|
|
171
|
-
sandboxInfo?.devUrl || devUrl,
|
|
172
|
-
beforeScreenshotUrl,
|
|
173
|
-
sandboxInfo?.gitDiff,
|
|
174
|
-
sandboxInfo?.d3kArtifacts,
|
|
175
|
-
runId,
|
|
176
|
-
sandboxInfo?.mcpUrl,
|
|
177
|
-
agentAnalysisModel
|
|
178
|
-
)
|
|
179
|
-
await updateProgress(3, "Report uploaded to Vercel Blob")
|
|
180
|
-
|
|
181
|
-
// Step 4: Create GitHub PR if repo info provided AND there are actual fixes to apply
|
|
182
|
-
let prResult = null
|
|
183
|
-
const hasGitPatch = fixProposal.includes("```diff")
|
|
184
|
-
if (repoOwner && repoName && hasGitPatch) {
|
|
185
|
-
await updateProgress(4, `Creating PR on ${repoOwner}/${repoName}...`)
|
|
186
|
-
prResult = await createGitHubPR(fixProposal, blobResult.blobUrl, repoOwner, repoName, baseBranch, projectName)
|
|
187
|
-
if (prResult?.success) {
|
|
188
|
-
await updateProgress(4, `PR #${prResult.prNumber} created successfully`)
|
|
189
|
-
}
|
|
190
|
-
} else if (repoOwner && repoName && !hasGitPatch) {
|
|
191
|
-
await updateProgress(4, "No code changes needed - skipping PR")
|
|
192
|
-
console.log("[Workflow] No git patch found - skipping PR creation (system is healthy)")
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Note: Sandbox cleanup is handled automatically by the sandbox timeout
|
|
196
|
-
// We cannot store cleanup functions as they're not serializable
|
|
197
|
-
|
|
198
|
-
return Response.json({
|
|
199
|
-
...blobResult,
|
|
200
|
-
pr: prResult
|
|
201
|
-
})
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Step function wrappers that dynamically import the actual implementations
|
|
205
|
-
async function createD3kSandbox(
|
|
206
|
-
repoUrl: string,
|
|
207
|
-
branch: string,
|
|
208
|
-
projectName: string,
|
|
209
|
-
vercelToken?: string,
|
|
210
|
-
vercelOidcToken?: string,
|
|
211
|
-
runId?: string
|
|
212
|
-
) {
|
|
213
|
-
"use step"
|
|
214
|
-
const { createD3kSandbox } = await import("./steps")
|
|
215
|
-
return createD3kSandbox(repoUrl, branch, projectName, vercelToken, vercelOidcToken, runId)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
async function fetchRealLogs(
|
|
219
|
-
mcpUrlOrDevUrl: string,
|
|
220
|
-
bypassToken?: string,
|
|
221
|
-
sandboxDevUrl?: string,
|
|
222
|
-
clsData?: unknown,
|
|
223
|
-
mcpError?: string | null,
|
|
224
|
-
beforeScreenshotUrlFromStep0?: string | null
|
|
225
|
-
): Promise<{ logAnalysis: string; beforeScreenshotUrl: string | null }> {
|
|
226
|
-
"use step"
|
|
227
|
-
const { fetchRealLogs } = await import("./steps")
|
|
228
|
-
return fetchRealLogs(mcpUrlOrDevUrl, bypassToken, sandboxDevUrl, clsData, mcpError, beforeScreenshotUrlFromStep0)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
async function analyzeLogsWithAgent(logAnalysis: string, devUrl: string) {
|
|
232
|
-
"use step"
|
|
233
|
-
const { analyzeLogsWithAgent } = await import("./steps")
|
|
234
|
-
return analyzeLogsWithAgent(logAnalysis, devUrl)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async function uploadToBlob(
|
|
238
|
-
fixProposal: string,
|
|
239
|
-
projectName: string,
|
|
240
|
-
logAnalysis: string,
|
|
241
|
-
devUrl: string,
|
|
242
|
-
beforeScreenshotUrl?: string | null,
|
|
243
|
-
gitDiff?: string | null,
|
|
244
|
-
d3kArtifacts?: {
|
|
245
|
-
clsScreenshots: Array<{ label: string; blobUrl: string; timestamp: number }>
|
|
246
|
-
screencastSessionId: string | null
|
|
247
|
-
fullLogs: string | null
|
|
248
|
-
metadata: Record<string, unknown> | null
|
|
249
|
-
},
|
|
250
|
-
runId?: string,
|
|
251
|
-
sandboxMcpUrl?: string,
|
|
252
|
-
agentAnalysisModel?: string
|
|
253
|
-
) {
|
|
254
|
-
"use step"
|
|
255
|
-
const { uploadToBlob } = await import("./steps")
|
|
256
|
-
return uploadToBlob(
|
|
257
|
-
fixProposal,
|
|
258
|
-
projectName,
|
|
259
|
-
logAnalysis,
|
|
260
|
-
devUrl,
|
|
261
|
-
beforeScreenshotUrl,
|
|
262
|
-
gitDiff,
|
|
263
|
-
d3kArtifacts,
|
|
264
|
-
runId,
|
|
265
|
-
sandboxMcpUrl,
|
|
266
|
-
agentAnalysisModel
|
|
267
|
-
)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
async function createGitHubPR(
|
|
271
|
-
fixProposal: string,
|
|
272
|
-
blobUrl: string,
|
|
273
|
-
repoOwner: string,
|
|
274
|
-
repoName: string,
|
|
275
|
-
baseBranch: string,
|
|
276
|
-
projectName: string
|
|
277
|
-
) {
|
|
278
|
-
"use step"
|
|
279
|
-
const { createGitHubPR } = await import("./steps")
|
|
280
|
-
return createGitHubPR(fixProposal, blobUrl, repoOwner, repoName, baseBranch, projectName)
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Step wrapper for updating workflow progress (uses dynamic import like other steps)
|
|
284
|
-
async function updateWorkflowProgressStep(
|
|
285
|
-
userId: string,
|
|
286
|
-
runId: string,
|
|
287
|
-
projectName: string,
|
|
288
|
-
timestamp: string,
|
|
289
|
-
stepNumber: number,
|
|
290
|
-
currentStep: string,
|
|
291
|
-
sandboxUrl?: string
|
|
292
|
-
) {
|
|
293
|
-
"use step"
|
|
294
|
-
const { updateWorkflowProgress } = await import("@/lib/workflow-storage")
|
|
295
|
-
return updateWorkflowProgress(userId, runId, projectName, timestamp, stepNumber, currentStep, sandboxUrl)
|
|
296
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "crypto"
|
|
2
|
-
import { start } from "workflow/api"
|
|
3
|
-
import { saveWorkflowRun } from "@/lib/workflow-storage"
|
|
4
|
-
import { cloudFixWorkflow } from "../fix-workflow/workflow"
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* API Route to Start Cloud Fix Workflow
|
|
8
|
-
*
|
|
9
|
-
* This endpoint uses the Workflow SDK's start() API to invoke the workflow
|
|
10
|
-
* and waits for the result using run.returnValue, which includes the blob URL
|
|
11
|
-
* where the fix proposal was uploaded.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// Configure longer timeout for workflow execution (10 minutes)
|
|
15
|
-
export const maxDuration = 600
|
|
16
|
-
|
|
17
|
-
// CORS headers - allowing credentials from localhost
|
|
18
|
-
const corsHeaders = {
|
|
19
|
-
"Access-Control-Allow-Origin": "http://localhost:3000",
|
|
20
|
-
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
|
21
|
-
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
22
|
-
"Access-Control-Allow-Credentials": "true"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Handle OPTIONS preflight request
|
|
26
|
-
export async function OPTIONS() {
|
|
27
|
-
return new Response(null, {
|
|
28
|
-
status: 204,
|
|
29
|
-
headers: corsHeaders
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function POST(request: Request) {
|
|
34
|
-
let userId: string | undefined
|
|
35
|
-
let projectName: string | undefined
|
|
36
|
-
let runId: string | undefined
|
|
37
|
-
let runTimestamp: string | undefined
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// Get user's access token from cookies or Authorization header
|
|
41
|
-
const { cookies: getCookies } = await import("next/headers")
|
|
42
|
-
const cookieStore = await getCookies()
|
|
43
|
-
let accessToken = cookieStore.get("access_token")?.value
|
|
44
|
-
|
|
45
|
-
// Fallback to Authorization header for cross-origin requests
|
|
46
|
-
if (!accessToken) {
|
|
47
|
-
const authHeader = request.headers.get("Authorization")
|
|
48
|
-
if (authHeader?.startsWith("Bearer ")) {
|
|
49
|
-
accessToken = authHeader.substring(7)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (!accessToken) {
|
|
54
|
-
return Response.json(
|
|
55
|
-
{ success: false, error: "Not authenticated. Please sign in to use workflows." },
|
|
56
|
-
{ status: 401, headers: corsHeaders }
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Get VERCEL_OIDC_TOKEN from request header (runtime token)
|
|
61
|
-
const vercelOidcToken = request.headers.get("x-vercel-oidc-token") || process.env.VERCEL_OIDC_TOKEN
|
|
62
|
-
console.log(`[Start Fix] VERCEL_OIDC_TOKEN available: ${!!vercelOidcToken}`)
|
|
63
|
-
|
|
64
|
-
const body = await request.json()
|
|
65
|
-
const { devUrl, repoOwner, repoName, baseBranch, bypassToken, repoUrl, repoBranch } = body
|
|
66
|
-
userId = body.userId
|
|
67
|
-
projectName = body.projectName
|
|
68
|
-
|
|
69
|
-
console.log("[Start Fix] Starting cloud fix workflow...")
|
|
70
|
-
console.log(`[Start Fix] Dev URL: ${devUrl}`)
|
|
71
|
-
console.log(`[Start Fix] Project: ${projectName}`)
|
|
72
|
-
console.log(`[Start Fix] User ID: ${userId}`)
|
|
73
|
-
console.log(`[Start Fix] Bypass Token: ${bypassToken ? "provided" : "not provided"}`)
|
|
74
|
-
if (repoUrl) {
|
|
75
|
-
console.log(`[Start Fix] Will create sandbox from: ${repoUrl}`)
|
|
76
|
-
console.log(`[Start Fix] Branch: ${repoBranch || "main"}`)
|
|
77
|
-
}
|
|
78
|
-
if (repoOwner && repoName) {
|
|
79
|
-
console.log(`[Start Fix] GitHub: ${repoOwner}/${repoName} (base: ${baseBranch || "main"})`)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Start the workflow and get a Run object
|
|
83
|
-
// Pass serializable data instead of Request object
|
|
84
|
-
// The workflow will fetch real logs from the devUrl and optionally create a PR
|
|
85
|
-
const workflowParams: Parameters<typeof cloudFixWorkflow>[0] = {
|
|
86
|
-
devUrl,
|
|
87
|
-
projectName,
|
|
88
|
-
vercelToken: accessToken, // Pass user's access token for sandbox creation
|
|
89
|
-
vercelOidcToken, // Pass OIDC token from request header for sandbox creation
|
|
90
|
-
...(repoOwner && { repoOwner }),
|
|
91
|
-
...(repoName && { repoName }),
|
|
92
|
-
...(baseBranch && { baseBranch }),
|
|
93
|
-
...(bypassToken && { bypassToken }),
|
|
94
|
-
...(repoUrl && { repoUrl }),
|
|
95
|
-
...(repoBranch && { repoBranch })
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Save workflow run metadata at start if userId and projectName provided
|
|
99
|
-
if (userId && projectName) {
|
|
100
|
-
runId = randomUUID()
|
|
101
|
-
runTimestamp = new Date().toISOString()
|
|
102
|
-
await saveWorkflowRun({
|
|
103
|
-
id: runId,
|
|
104
|
-
userId,
|
|
105
|
-
projectName,
|
|
106
|
-
timestamp: runTimestamp,
|
|
107
|
-
status: "running",
|
|
108
|
-
currentStep: "Starting workflow...",
|
|
109
|
-
stepNumber: 0
|
|
110
|
-
})
|
|
111
|
-
console.log(`[Start Fix] Saved workflow run metadata (running): ${runId}`)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Pass runId and userId to workflow for progress tracking
|
|
115
|
-
const workflowParamsWithTracking = {
|
|
116
|
-
...workflowParams,
|
|
117
|
-
runId,
|
|
118
|
-
userId
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const run = await start(cloudFixWorkflow, [workflowParamsWithTracking])
|
|
122
|
-
|
|
123
|
-
console.log(`[Start Fix] Workflow started, waiting for completion...`)
|
|
124
|
-
|
|
125
|
-
// Wait for workflow to complete and get the Response
|
|
126
|
-
const workflowResponse = await run.returnValue
|
|
127
|
-
|
|
128
|
-
// Parse the JSON result from the Response
|
|
129
|
-
const result = await workflowResponse.json()
|
|
130
|
-
|
|
131
|
-
console.log(`[Start Fix] Workflow completed successfully`)
|
|
132
|
-
if (result.blobUrl) {
|
|
133
|
-
console.log(`[Start Fix] Fix proposal uploaded to: ${result.blobUrl}`)
|
|
134
|
-
}
|
|
135
|
-
if (result.pr?.prUrl) {
|
|
136
|
-
console.log(`[Start Fix] GitHub PR created: ${result.pr.prUrl}`)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Update workflow run metadata with success status (use same timestamp to overwrite)
|
|
140
|
-
if (userId && projectName && runId && runTimestamp) {
|
|
141
|
-
await saveWorkflowRun({
|
|
142
|
-
id: runId,
|
|
143
|
-
userId,
|
|
144
|
-
projectName,
|
|
145
|
-
timestamp: runTimestamp,
|
|
146
|
-
status: "done",
|
|
147
|
-
reportBlobUrl: result.blobUrl,
|
|
148
|
-
prUrl: result.pr?.prUrl,
|
|
149
|
-
beforeScreenshotUrl: result.beforeScreenshotUrl || undefined
|
|
150
|
-
})
|
|
151
|
-
console.log(`[Start Fix] Updated workflow run metadata to done: ${runId}`)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return Response.json(
|
|
155
|
-
{
|
|
156
|
-
success: true,
|
|
157
|
-
message: "Cloud fix workflow completed successfully",
|
|
158
|
-
projectName,
|
|
159
|
-
runId,
|
|
160
|
-
blobUrl: result.blobUrl,
|
|
161
|
-
fixProposal: result.fixProposal,
|
|
162
|
-
pr: result.pr
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
headers: corsHeaders
|
|
166
|
-
}
|
|
167
|
-
)
|
|
168
|
-
} catch (error) {
|
|
169
|
-
console.error("[Start Fix] Error running workflow:", error)
|
|
170
|
-
|
|
171
|
-
// Update workflow run metadata with failure status (use same timestamp to overwrite)
|
|
172
|
-
if (userId && projectName && runId && runTimestamp) {
|
|
173
|
-
await saveWorkflowRun({
|
|
174
|
-
id: runId,
|
|
175
|
-
userId,
|
|
176
|
-
projectName,
|
|
177
|
-
timestamp: runTimestamp,
|
|
178
|
-
status: "failure",
|
|
179
|
-
error: error instanceof Error ? error.message : String(error)
|
|
180
|
-
}).catch((err) => console.error("[Start Fix] Failed to save error metadata:", err))
|
|
181
|
-
console.log(`[Start Fix] Updated workflow run metadata to failure: ${runId}`)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return Response.json(
|
|
185
|
-
{
|
|
186
|
-
success: false,
|
|
187
|
-
error: error instanceof Error ? error.message : String(error)
|
|
188
|
-
},
|
|
189
|
-
{ status: 500, headers: corsHeaders }
|
|
190
|
-
)
|
|
191
|
-
}
|
|
192
|
-
}
|