dev3000 0.0.114 → 0.0.116

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 (146) hide show
  1. package/dist/cdp-monitor.d.ts.map +1 -1
  2. package/dist/cdp-monitor.js +20 -28
  3. package/dist/cdp-monitor.js.map +1 -1
  4. package/dist/cli.js +74 -22
  5. package/dist/cli.js.map +1 -1
  6. package/dist/dev-environment.d.ts.map +1 -1
  7. package/dist/dev-environment.js +43 -11
  8. package/dist/dev-environment.js.map +1 -1
  9. package/dist/src/tui-interface-impl.tsx +175 -127
  10. package/dist/tui-interface-impl.d.ts.map +1 -1
  11. package/dist/tui-interface-impl.js +113 -74
  12. package/dist/tui-interface-impl.js.map +1 -1
  13. package/mcp-server/.next/BUILD_ID +1 -1
  14. package/mcp-server/.next/build-manifest.json +2 -2
  15. package/mcp-server/.next/fallback-build-manifest.json +2 -2
  16. package/mcp-server/.next/prerender-manifest.json +3 -3
  17. package/mcp-server/.next/server/app/_global-error.html +2 -2
  18. package/mcp-server/.next/server/app/_global-error.rsc +1 -1
  19. package/mcp-server/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  20. package/mcp-server/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  21. package/mcp-server/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/mcp-server/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/mcp-server/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/mcp-server/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  25. package/mcp-server/.next/server/app/_not-found.html +1 -1
  26. package/mcp-server/.next/server/app/_not-found.rsc +2 -2
  27. package/mcp-server/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  28. package/mcp-server/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  29. package/mcp-server/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  30. package/mcp-server/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  31. package/mcp-server/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  32. package/mcp-server/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  33. package/mcp-server/.next/server/app/api/cloud/start-fix/route.js +2 -2
  34. package/mcp-server/.next/server/app/api/cloud/start-fix/route.js.nft.json +1 -1
  35. package/mcp-server/.next/server/app/auth/error/page_client-reference-manifest.js +1 -1
  36. package/mcp-server/.next/server/app/auth/error.html +1 -1
  37. package/mcp-server/.next/server/app/auth/error.rsc +2 -2
  38. package/mcp-server/.next/server/app/auth/error.segments/_full.segment.rsc +2 -2
  39. package/mcp-server/.next/server/app/auth/error.segments/_head.segment.rsc +1 -1
  40. package/mcp-server/.next/server/app/auth/error.segments/_index.segment.rsc +2 -2
  41. package/mcp-server/.next/server/app/auth/error.segments/_tree.segment.rsc +2 -2
  42. package/mcp-server/.next/server/app/auth/error.segments/auth/error/__PAGE__.segment.rsc +1 -1
  43. package/mcp-server/.next/server/app/auth/error.segments/auth/error.segment.rsc +1 -1
  44. package/mcp-server/.next/server/app/auth/error.segments/auth.segment.rsc +1 -1
  45. package/mcp-server/.next/server/app/index.html +1 -1
  46. package/mcp-server/.next/server/app/index.rsc +3 -3
  47. package/mcp-server/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  48. package/mcp-server/.next/server/app/index.segments/_full.segment.rsc +3 -3
  49. package/mcp-server/.next/server/app/index.segments/_head.segment.rsc +1 -1
  50. package/mcp-server/.next/server/app/index.segments/_index.segment.rsc +2 -2
  51. package/mcp-server/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  52. package/mcp-server/.next/server/app/logs/page.js.nft.json +1 -1
  53. package/mcp-server/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  54. package/mcp-server/.next/server/app/mcp/route.js +2 -2
  55. package/mcp-server/.next/server/app/page.js.nft.json +1 -1
  56. package/mcp-server/.next/server/app/page_client-reference-manifest.js +1 -1
  57. package/mcp-server/.next/server/app/signin/page_client-reference-manifest.js +1 -1
  58. package/mcp-server/.next/server/app/video/[session]/page_client-reference-manifest.js +1 -1
  59. package/mcp-server/.next/server/app/workflows/[id]/report/page_client-reference-manifest.js +1 -1
  60. package/mcp-server/.next/server/app/workflows/new/page.js.nft.json +1 -1
  61. package/mcp-server/.next/server/app/workflows/new/page_client-reference-manifest.js +1 -1
  62. package/mcp-server/.next/server/app/workflows/page.js.nft.json +1 -1
  63. package/mcp-server/.next/server/app/workflows/page_client-reference-manifest.js +1 -1
  64. package/mcp-server/.next/server/chunks/[root-of-the-server]__157de66b._.js +284 -37
  65. package/mcp-server/.next/server/chunks/[root-of-the-server]__157de66b._.js.map +1 -1
  66. package/mcp-server/.next/server/chunks/[root-of-the-server]__730a8fd0._.js +1 -1
  67. package/mcp-server/.next/server/chunks/[root-of-the-server]__730a8fd0._.js.map +1 -1
  68. package/mcp-server/.next/server/chunks/[root-of-the-server]__748f411f._.js +1 -1
  69. package/mcp-server/.next/server/chunks/[root-of-the-server]__748f411f._.js.map +1 -1
  70. package/mcp-server/.next/server/chunks/[root-of-the-server]__8a84f9f4._.js +20 -20
  71. package/mcp-server/.next/server/chunks/[root-of-the-server]__8a84f9f4._.js.map +1 -1
  72. package/mcp-server/.next/server/chunks/[root-of-the-server]__c1681338._.js +3 -0
  73. package/mcp-server/.next/server/chunks/[root-of-the-server]__c1681338._.js.map +1 -0
  74. package/mcp-server/.next/server/chunks/[root-of-the-server]__ec6a1335._.js.map +1 -1
  75. package/mcp-server/.next/server/chunks/bee4f_next_dist_esm_build_templates_app-route_1ece9366.js +5 -5
  76. package/mcp-server/.next/server/chunks/bee4f_next_dist_esm_build_templates_app-route_1ece9366.js.map +1 -1
  77. package/mcp-server/.next/server/chunks/mcp-server_app_api_cloud_fix-workflow_steps_ts_b65f3271._.js +121 -27
  78. package/mcp-server/.next/server/chunks/mcp-server_app_api_cloud_fix-workflow_steps_ts_b65f3271._.js.map +1 -1
  79. package/mcp-server/.next/server/chunks/node_modules__pnpm_85ddbe9c._.js +1 -1
  80. package/mcp-server/.next/server/chunks/node_modules__pnpm_85ddbe9c._.js.map +1 -1
  81. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__2e44f0db._.js +3 -0
  82. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__2e44f0db._.js.map +1 -0
  83. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__3585c949._.js +3 -0
  84. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__3585c949._.js.map +1 -0
  85. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__477c3bbb._.js +3 -0
  86. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__477c3bbb._.js.map +1 -0
  87. package/mcp-server/.next/server/chunks/ssr/{[root-of-the-server]__570677dc._.js → [root-of-the-server]__880839a0._.js} +2 -2
  88. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__880839a0._.js.map +1 -0
  89. package/mcp-server/.next/server/chunks/ssr/_41b8f993._.js +3 -0
  90. package/mcp-server/.next/server/chunks/ssr/_41b8f993._.js.map +1 -0
  91. package/mcp-server/.next/server/chunks/ssr/_9ba0ef29._.js +3 -0
  92. package/mcp-server/.next/server/chunks/ssr/_9ba0ef29._.js.map +1 -0
  93. package/mcp-server/.next/server/chunks/ssr/_cd4dc25e._.js.map +1 -1
  94. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_workflows_new_new-workflow-client_tsx_1312c046._.js +2 -2
  95. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_workflows_new_new-workflow-client_tsx_1312c046._.js.map +1 -1
  96. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_workflows_workflows-client_tsx_268cfd4a._.js +7 -0
  97. package/mcp-server/.next/server/chunks/ssr/mcp-server_app_workflows_workflows-client_tsx_268cfd4a._.js.map +1 -0
  98. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_961f21c4._.js +3 -0
  99. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_961f21c4._.js.map +1 -0
  100. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_a82244bf._.js +3 -0
  101. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_a82244bf._.js.map +1 -0
  102. package/mcp-server/.next/server/chunks/ssr/{node_modules__pnpm_07527699._.js → node_modules__pnpm_eb98e511._.js} +2 -2
  103. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_eb98e511._.js.map +1 -0
  104. package/mcp-server/.next/server/server-reference-manifest.js +1 -1
  105. package/mcp-server/.next/server/server-reference-manifest.json +1 -1
  106. package/mcp-server/.next/static/chunks/000849a6a897f531.css +1 -0
  107. package/mcp-server/.next/static/chunks/048cee2510ddb1a0.js +1 -0
  108. package/mcp-server/.next/static/chunks/0622bd0e093adee7.js +3 -0
  109. package/mcp-server/.next/static/chunks/{46f60efee5f19794.js → 16359f64918a93f3.js} +1 -1
  110. package/mcp-server/.next/static/chunks/1851a3e70d7efc10.js +1 -0
  111. package/mcp-server/.next/static/chunks/{cc6addc4bb10fa11.js → 2ad16eeb719786f1.js} +1 -1
  112. package/mcp-server/.next/static/chunks/57feca7a4e06545e.js +7 -0
  113. package/mcp-server/.next/static/chunks/93db5737a327ab0c.js +6 -0
  114. package/mcp-server/.next/static/chunks/9fd3c715ecfb4d05.js +1 -0
  115. package/mcp-server/.next/static/chunks/b4b1ec6435790587.js +1 -0
  116. package/mcp-server/.next/static/chunks/cfe150cb2048b7e8.js +1 -0
  117. package/mcp-server/app/api/cloud/fix-workflow/steps.ts +359 -28
  118. package/mcp-server/app/api/cloud/fix-workflow/workflow.ts +16 -8
  119. package/mcp-server/app/api/cloud/start-fix/route.ts +2 -2
  120. package/mcp-server/app/api/tools/route.ts +11 -12
  121. package/mcp-server/app/api/workflows/route.ts +45 -1
  122. package/mcp-server/app/mcp/tools.ts +58 -98
  123. package/mcp-server/app/workflows/workflows-client.tsx +259 -100
  124. package/package.json +1 -1
  125. package/src/tui-interface-impl.tsx +175 -127
  126. package/mcp-server/.next/server/chunks/[root-of-the-server]__75d68567._.js +0 -3
  127. package/mcp-server/.next/server/chunks/[root-of-the-server]__75d68567._.js.map +0 -1
  128. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__0ff05d72._.js +0 -3
  129. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__0ff05d72._.js.map +0 -1
  130. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__27cc5956._.js +0 -3
  131. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__27cc5956._.js.map +0 -1
  132. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__570677dc._.js.map +0 -1
  133. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__ef510343._.js +0 -3
  134. package/mcp-server/.next/server/chunks/ssr/[root-of-the-server]__ef510343._.js.map +0 -1
  135. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_07527699._.js.map +0 -1
  136. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_7cc36047._.js +0 -3
  137. package/mcp-server/.next/server/chunks/ssr/node_modules__pnpm_7cc36047._.js.map +0 -1
  138. package/mcp-server/.next/static/chunks/07848f6bd2a7e5f6.js +0 -3
  139. package/mcp-server/.next/static/chunks/637a66565f27572f.js +0 -6
  140. package/mcp-server/.next/static/chunks/aed4fb5252a4bc95.js +0 -3
  141. package/mcp-server/.next/static/chunks/e8d521464b0c96ca.css +0 -1
  142. package/mcp-server/.next/static/chunks/ff53279afa939907.js +0 -1
  143. package/mcp-server/.next/static/chunks/ffa2ecb6845be49c.js +0 -1
  144. /package/mcp-server/.next/static/{ZvLsxTWoDyQzaSsr_VeX6 → G5taiQ-Jp0B_MdvkQuoIT}/_buildManifest.js +0 -0
  145. /package/mcp-server/.next/static/{ZvLsxTWoDyQzaSsr_VeX6 → G5taiQ-Jp0B_MdvkQuoIT}/_clientMiddlewareManifest.json +0 -0
  146. /package/mcp-server/.next/static/{ZvLsxTWoDyQzaSsr_VeX6 → G5taiQ-Jp0B_MdvkQuoIT}/_ssgManifest.js +0 -0
@@ -4,11 +4,184 @@
4
4
  */
5
5
 
6
6
  import { put } from "@vercel/blob"
7
+ import type { Sandbox } from "@vercel/sandbox"
7
8
  import { createGateway, generateText } from "ai"
8
9
  import { createD3kSandbox as createD3kSandboxUtil } from "@/lib/cloud/d3k-sandbox"
9
10
 
11
+ /**
12
+ * Helper function to properly consume sandbox command output
13
+ * The Vercel Sandbox SDK returns a result object with an async logs() iterator
14
+ */
15
+ async function runSandboxCommand(
16
+ sandbox: Sandbox,
17
+ cmd: string,
18
+ args: string[]
19
+ ): Promise<{ exitCode: number; stdout: string; stderr: string }> {
20
+ const result = await sandbox.runCommand({ cmd, args })
21
+ let stdout = ""
22
+ let stderr = ""
23
+ for await (const log of result.logs()) {
24
+ if (log.stream === "stdout") {
25
+ stdout += log.data
26
+ } else {
27
+ stderr += log.data
28
+ }
29
+ }
30
+ await result.wait()
31
+ return { exitCode: result.exitCode, stdout, stderr }
32
+ }
33
+
34
+ /**
35
+ * Capture a screenshot using puppeteer-core inside the sandbox
36
+ * Returns the base64 encoded PNG image data and logs the page title
37
+ */
38
+ async function captureScreenshotInSandbox(
39
+ sandbox: Sandbox,
40
+ appUrl: string,
41
+ chromiumPath: string,
42
+ label: string,
43
+ sandboxCwd = "/vercel/sandbox"
44
+ ): Promise<string | null> {
45
+ console.log(`[Screenshot] Capturing ${label} screenshot of ${appUrl}...`)
46
+
47
+ // Create a Node.js script to capture screenshot with puppeteer-core
48
+ // The script is placed in the sandbox cwd so it can find puppeteer-core from node_modules
49
+ // Output format: JSON with { title, screenshot } on first line, then base64 data
50
+ const screenshotScript = `
51
+ const puppeteer = require('puppeteer-core');
52
+
53
+ (async () => {
54
+ let browser;
55
+ try {
56
+ browser = await puppeteer.launch({
57
+ executablePath: '${chromiumPath}',
58
+ headless: true,
59
+ args: [
60
+ '--no-sandbox',
61
+ '--disable-setuid-sandbox',
62
+ '--disable-dev-shm-usage',
63
+ '--disable-gpu',
64
+ '--single-process'
65
+ ]
66
+ });
67
+
68
+ const page = await browser.newPage();
69
+ await page.setViewport({ width: 1280, height: 720 });
70
+
71
+ // Navigate with a reasonable timeout
72
+ await page.goto('${appUrl}', {
73
+ waitUntil: 'networkidle2',
74
+ timeout: 30000
75
+ });
76
+
77
+ // Get the page title for verification
78
+ const title = await page.title();
79
+ console.error('PAGE_TITLE:' + title);
80
+
81
+ // Wait a bit for any animations/layout shifts
82
+ await new Promise(r => setTimeout(r, 2000));
83
+
84
+ // Take screenshot as base64
85
+ const screenshot = await page.screenshot({
86
+ encoding: 'base64',
87
+ fullPage: false
88
+ });
89
+
90
+ console.log(screenshot);
91
+
92
+ await browser.close();
93
+ } catch (error) {
94
+ console.error('Screenshot error:', error.message);
95
+ if (browser) await browser.close();
96
+ process.exit(1);
97
+ }
98
+ })();
99
+ `
100
+
101
+ try {
102
+ // Write the script to the sandbox cwd so it can find puppeteer-core from node_modules
103
+ const scriptPath = `${sandboxCwd}/_screenshot.js`
104
+ const writeResult = await runSandboxCommand(sandbox, "sh", [
105
+ "-c",
106
+ `cat > ${scriptPath} << 'SCRIPT_EOF'
107
+ ${screenshotScript}
108
+ SCRIPT_EOF`
109
+ ])
110
+
111
+ if (writeResult.exitCode !== 0) {
112
+ console.log(`[Screenshot] Failed to write script: ${writeResult.stderr}`)
113
+ return null
114
+ }
115
+
116
+ // Run the script from the sandbox directory so node can find puppeteer-core in node_modules
117
+ const screenshotResult = await sandbox.runCommand({
118
+ cmd: "node",
119
+ args: [scriptPath],
120
+ cwd: sandboxCwd
121
+ })
122
+
123
+ let stdout = ""
124
+ let stderr = ""
125
+ for await (const log of screenshotResult.logs()) {
126
+ if (log.stream === "stdout") {
127
+ stdout += log.data
128
+ } else {
129
+ stderr += log.data
130
+ }
131
+ }
132
+ await screenshotResult.wait()
133
+
134
+ // Extract page title from stderr (format: PAGE_TITLE:xxx)
135
+ const titleMatch = stderr.match(/PAGE_TITLE:(.*)/)
136
+ if (titleMatch) {
137
+ console.log(`[Screenshot] Page title: "${titleMatch[1]}"`)
138
+ }
139
+
140
+ if (screenshotResult.exitCode !== 0) {
141
+ console.log(`[Screenshot] Failed to capture: ${stderr}`)
142
+ return null
143
+ }
144
+
145
+ // The stdout should be the base64 image
146
+ const base64Data = stdout.trim()
147
+ if (base64Data && base64Data.length > 100) {
148
+ console.log(`[Screenshot] Captured ${label} screenshot (${base64Data.length} bytes base64)`)
149
+ return base64Data
150
+ }
151
+
152
+ console.log(`[Screenshot] No valid screenshot data returned`)
153
+ return null
154
+ } catch (error) {
155
+ console.log(`[Screenshot] Error: ${error instanceof Error ? error.message : String(error)}`)
156
+ return null
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Upload a base64 screenshot to Vercel Blob
162
+ */
163
+ async function uploadScreenshot(base64Data: string, label: string, projectName: string): Promise<string | null> {
164
+ try {
165
+ const imageBuffer = Buffer.from(base64Data, "base64")
166
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-")
167
+ const filename = `screenshot-${label}-${projectName}-${timestamp}.png`
168
+
169
+ const blob = await put(filename, imageBuffer, {
170
+ access: "public",
171
+ contentType: "image/png"
172
+ })
173
+
174
+ console.log(`[Screenshot] Uploaded ${label} screenshot: ${blob.url}`)
175
+ return blob.url
176
+ } catch (error) {
177
+ console.log(`[Screenshot] Upload failed: ${error instanceof Error ? error.message : String(error)}`)
178
+ return null
179
+ }
180
+ }
181
+
10
182
  /**
11
183
  * Step 0: Create d3k sandbox with MCP tools pre-configured
184
+ * Also captures a "before" screenshot of the app
12
185
  */
13
186
  export async function createD3kSandbox(
14
187
  repoUrl: string,
@@ -48,34 +221,137 @@ export async function createD3kSandbox(
48
221
  console.log(`[Step 0] Dev URL: ${sandboxResult.devUrl}`)
49
222
  console.log(`[Step 0] MCP URL: ${sandboxResult.mcpUrl}`)
50
223
 
224
+ // Get the chromium path for screenshots
225
+ console.log(`[Step 0] Getting Chromium path for screenshots...`)
226
+ let chromiumPath = "/tmp/chromium"
227
+ try {
228
+ const chromiumResult = await runSandboxCommand(sandboxResult.sandbox, "node", [
229
+ "-e",
230
+ "require('@sparticuz/chromium').executablePath().then(p => console.log(p))"
231
+ ])
232
+ if (chromiumResult.exitCode === 0 && chromiumResult.stdout.trim()) {
233
+ chromiumPath = chromiumResult.stdout.trim()
234
+ console.log(`[Step 0] Chromium path: ${chromiumPath}`)
235
+ }
236
+ } catch {
237
+ console.log(`[Step 0] Could not get chromium path, using default: ${chromiumPath}`)
238
+ }
239
+
240
+ // CRITICAL DIAGNOSTIC: Test Chrome with EXACT d3k command
241
+ // d3k uses: --user-data-dir, no --remote-debugging-address, loading page, etc.
242
+ console.log(`[Step 0] ===== CHROMIUM CDP TEST (d3k exact command) =====`)
243
+ try {
244
+ const chromeTestScript = `
245
+ exec 2>&1
246
+ echo "=== Chromium CDP Test (d3k exact command) ==="
247
+ echo "Chromium path: ${chromiumPath}"
248
+ echo ""
249
+
250
+ # Create user-data-dir like d3k does
251
+ USER_DATA_DIR="/tmp/d3k-test-profile"
252
+ mkdir -p "$USER_DATA_DIR"
253
+ echo "1. Created user-data-dir: $USER_DATA_DIR"
254
+
255
+ # Create loading page like d3k does
256
+ LOADING_DIR="/tmp/dev3000-loading"
257
+ mkdir -p "$LOADING_DIR"
258
+ cat > "$LOADING_DIR/loading.html" << 'LOADINGHTML'
259
+ <!DOCTYPE html>
260
+ <html>
261
+ <head><title>Loading...</title></head>
262
+ <body><h1>Loading dev3000...</h1></body>
263
+ </html>
264
+ LOADINGHTML
265
+ echo "2. Created loading page: $LOADING_DIR/loading.html"
266
+ echo ""
267
+
268
+ # Use EXACT d3k command (from cdp-monitor.ts)
269
+ # Note: d3k does NOT use --remote-debugging-address
270
+ echo "3. Starting Chrome with d3k's exact args..."
271
+ echo " Command: ${chromiumPath} --remote-debugging-port=9222 --user-data-dir=$USER_DATA_DIR --no-first-run --no-default-browser-check --disable-component-extensions-with-background-pages --disable-background-networking --disable-sync --metrics-recording-only --disable-default-apps --disable-session-crashed-bubble --disable-restore-session-state --headless=new --no-sandbox --disable-setuid-sandbox --disable-gpu --disable-dev-shm-usage file://$LOADING_DIR/loading.html"
272
+
273
+ timeout 15 "${chromiumPath}" \\
274
+ --remote-debugging-port=9222 \\
275
+ --user-data-dir="$USER_DATA_DIR" \\
276
+ --no-first-run \\
277
+ --no-default-browser-check \\
278
+ --disable-component-extensions-with-background-pages \\
279
+ --disable-background-networking \\
280
+ --disable-sync \\
281
+ --metrics-recording-only \\
282
+ --disable-default-apps \\
283
+ --disable-session-crashed-bubble \\
284
+ --disable-restore-session-state \\
285
+ --headless=new \\
286
+ --no-sandbox \\
287
+ --disable-setuid-sandbox \\
288
+ --disable-gpu \\
289
+ --disable-dev-shm-usage \\
290
+ "file://$LOADING_DIR/loading.html" &
291
+ PID=$!
292
+ echo " Chrome PID: $PID"
293
+ sleep 3
294
+ echo ""
295
+
296
+ echo "4. Checking if Chrome is still running..."
297
+ if ps -p $PID > /dev/null 2>&1; then
298
+ echo " Chrome is RUNNING after 3s"
299
+ echo ""
300
+ echo "5. Trying CDP (note: d3k doesn't use --remote-debugging-address)..."
301
+ echo " Trying 127.0.0.1..."
302
+ curl -s --max-time 5 http://127.0.0.1:9222/json/version 2>&1 || echo " 127.0.0.1 failed"
303
+ echo ""
304
+ echo " Trying localhost..."
305
+ curl -s --max-time 5 http://localhost:9222/json/version 2>&1 || echo " localhost failed"
306
+ echo ""
307
+ echo "6. Checking what's listening on 9222..."
308
+ ss -tlnp 2>/dev/null | grep 9222 || netstat -tlnp 2>/dev/null | grep 9222 || echo " Could not check listening ports"
309
+ echo ""
310
+ echo "7. Killing test Chrome..."
311
+ kill $PID 2>/dev/null
312
+ else
313
+ echo " Chrome DIED within 3s"
314
+ wait $PID 2>/dev/null
315
+ EXIT_CODE=$?
316
+ echo " Exit code: $EXIT_CODE"
317
+ echo ""
318
+ echo " Checking for crash logs..."
319
+ ls -la "$USER_DATA_DIR" 2>&1 | head -10 || echo " No user-data-dir"
320
+ fi
321
+ echo ""
322
+ echo "=== End d3k exact command test ==="
323
+ `
324
+ const chromeTest = await runSandboxCommand(sandboxResult.sandbox, "bash", ["-c", chromeTestScript])
325
+ console.log(`[Step 0] d3k Chrome test (exit ${chromeTest.exitCode}):\n${chromeTest.stdout || "(no output)"}`)
326
+ if (chromeTest.stderr) console.log(`[Step 0] d3k Chrome test stderr: ${chromeTest.stderr}`)
327
+ } catch (error) {
328
+ console.log(`[Step 0] d3k Chrome test error: ${error instanceof Error ? error.message : String(error)}`)
329
+ }
330
+ console.log(`[Step 0] ===== END d3k EXACT COMMAND TEST =====`)
331
+
332
+ // Capture "BEFORE" screenshot - this shows the app before any fixes
333
+ console.log(`[Step 0] Capturing BEFORE screenshot...`)
334
+ let beforeScreenshotUrl: string | null = null
335
+ try {
336
+ const beforeBase64 = await captureScreenshotInSandbox(
337
+ sandboxResult.sandbox,
338
+ "http://localhost:3000",
339
+ chromiumPath,
340
+ "before"
341
+ )
342
+ if (beforeBase64) {
343
+ beforeScreenshotUrl = await uploadScreenshot(beforeBase64, "before", projectName)
344
+ }
345
+ } catch (error) {
346
+ console.log(`[Step 0] Before screenshot failed: ${error instanceof Error ? error.message : String(error)}`)
347
+ }
348
+
51
349
  // Now capture CLS and errors using MCP from INSIDE the sandbox
52
- // We must do this in Step 0 while we have the sandbox object
53
350
  console.log(`[Step 0] Capturing CLS metrics from inside sandbox...`)
54
351
 
55
352
  let clsData: unknown = null
56
353
  let mcpError: string | null = null
57
354
 
58
- // Helper function to properly consume sandbox command output
59
- // The Vercel Sandbox SDK returns a result object with an async logs() iterator
60
- async function runSandboxCommand(
61
- sandbox: typeof sandboxResult.sandbox,
62
- cmd: string,
63
- args: string[]
64
- ): Promise<{ exitCode: number; stdout: string; stderr: string }> {
65
- const result = await sandbox.runCommand({ cmd, args })
66
- let stdout = ""
67
- let stderr = ""
68
- for await (const log of result.logs()) {
69
- if (log.stream === "stdout") {
70
- stdout += log.data
71
- } else {
72
- stderr += log.data
73
- }
74
- }
75
- await result.wait()
76
- return { exitCode: result.exitCode, stdout, stderr }
77
- }
78
-
79
355
  try {
80
356
  // Call fix_my_app MCP tool via curl from inside the sandbox
81
357
  // This avoids network isolation issues - we're calling localhost:3684 from within the sandbox
@@ -156,6 +432,27 @@ export async function createD3kSandbox(
156
432
  }
157
433
  console.log(`[Step 0] === End sandbox log dump ===`)
158
434
 
435
+ // Capture git diff from sandbox - this shows any changes made by d3k
436
+ console.log(`[Step 0] Capturing git diff from sandbox...`)
437
+ let gitDiff: string | null = null
438
+ try {
439
+ const diffResult = await runSandboxCommand(sandboxResult.sandbox, "sh", [
440
+ "-c",
441
+ "cd /vercel/sandbox && git diff --no-color 2>/dev/null || echo 'No git diff available'"
442
+ ])
443
+ if (diffResult.exitCode === 0 && diffResult.stdout.trim() && diffResult.stdout.trim() !== "No git diff available") {
444
+ gitDiff = diffResult.stdout.trim()
445
+ console.log(`[Step 0] Git diff captured (${gitDiff.length} chars)`)
446
+ console.log(`[Step 0] Git diff preview:\n${gitDiff.substring(0, 500)}...`)
447
+ } else {
448
+ console.log(`[Step 0] No git changes detected in sandbox`)
449
+ }
450
+ } catch (diffError) {
451
+ console.log(
452
+ `[Step 0] Failed to capture git diff: ${diffError instanceof Error ? diffError.message : String(diffError)}`
453
+ )
454
+ }
455
+
159
456
  // Note: We cannot return the cleanup function or sandbox object as they're not serializable
160
457
  // Sandbox cleanup will happen automatically when the sandbox times out
161
458
  return {
@@ -163,7 +460,10 @@ export async function createD3kSandbox(
163
460
  devUrl: sandboxResult.devUrl,
164
461
  bypassToken: sandboxResult.bypassToken,
165
462
  clsData,
166
- mcpError
463
+ mcpError,
464
+ beforeScreenshotUrl,
465
+ chromiumPath,
466
+ gitDiff
167
467
  }
168
468
  }
169
469
 
@@ -176,14 +476,18 @@ export async function fetchRealLogs(
176
476
  bypassToken?: string,
177
477
  sandboxDevUrl?: string,
178
478
  clsData?: unknown,
179
- mcpError?: string | null
479
+ mcpError?: string | null,
480
+ beforeScreenshotUrlFromStep0?: string | null
180
481
  ) {
181
482
  "use step"
182
483
 
183
- // If we already have CLS data from Step 0, use it
484
+ // If we already have CLS data from Step 0, use it along with the screenshot
184
485
  if (clsData) {
185
486
  console.log("[Step 1] Using CLS data captured in Step 0")
186
- return { logAnalysis: JSON.stringify(clsData, null, 2), beforeScreenshotUrl: null }
487
+ if (beforeScreenshotUrlFromStep0) {
488
+ console.log(`[Step 1] Before screenshot from Step 0: ${beforeScreenshotUrlFromStep0}`)
489
+ }
490
+ return { logAnalysis: JSON.stringify(clsData, null, 2), beforeScreenshotUrl: beforeScreenshotUrlFromStep0 || null }
187
491
  }
188
492
 
189
493
  // If there was an MCP error in Step 0, log it
@@ -573,7 +877,13 @@ Format your response as a clear, structured report that helps identify what's br
573
877
  const response = await fetch(urlWithBypass, { method: "GET", headers })
574
878
  const body = await response.text()
575
879
 
880
+ // Extract and log page title from HTML
881
+ const titleMatch = body.match(/<title[^>]*>([^<]*)<\/title>/i)
882
+ const pageTitle = titleMatch ? titleMatch[1].trim() : "(no title found)"
883
+ console.log(`[Step 1] HTTP fallback - Page title: "${pageTitle}"`)
884
+
576
885
  let logAnalysis = `Dev Server URL: ${devUrl}\n`
886
+ logAnalysis += `Page Title: ${pageTitle}\n`
577
887
  logAnalysis += `HTTP Status: ${response.status} ${response.statusText}\n\n`
578
888
  logAnalysis += `Note: Browser automation failed, using fallback HTTP fetch.\n\n`
579
889
 
@@ -685,7 +995,8 @@ export async function uploadToBlob(
685
995
  projectName: string,
686
996
  logAnalysis: string,
687
997
  devUrl: string,
688
- beforeScreenshotUrl?: string | null
998
+ beforeScreenshotUrl?: string | null,
999
+ gitDiff?: string | null
689
1000
  ) {
690
1001
  "use step"
691
1002
 
@@ -693,6 +1004,9 @@ export async function uploadToBlob(
693
1004
  if (beforeScreenshotUrl) {
694
1005
  console.log(`[Step 3] Including before screenshot: ${beforeScreenshotUrl}`)
695
1006
  }
1007
+ if (gitDiff) {
1008
+ console.log(`[Step 3] Including git diff (${gitDiff.length} chars)`)
1009
+ }
696
1010
 
697
1011
  // Create screenshot section if we have a screenshot
698
1012
  const screenshotSection = beforeScreenshotUrl
@@ -704,6 +1018,21 @@ This screenshot was captured when the sandbox dev server first loaded, proving t
704
1018
 
705
1019
  ---
706
1020
 
1021
+ `
1022
+ : ""
1023
+
1024
+ // Create git diff section if we have a diff from the sandbox
1025
+ const gitDiffSection = gitDiff
1026
+ ? `## Actual Git Diff from Sandbox
1027
+
1028
+ The following diff shows the actual changes made by d3k in the sandbox environment:
1029
+
1030
+ \`\`\`diff
1031
+ ${gitDiff}
1032
+ \`\`\`
1033
+
1034
+ ---
1035
+
707
1036
  `
708
1037
  : ""
709
1038
 
@@ -712,12 +1041,14 @@ This screenshot was captured when the sandbox dev server first loaded, proving t
712
1041
  const enhancedMarkdown = `# Fix Proposal for ${projectName}
713
1042
 
714
1043
  **Generated**: ${timestamp}
1044
+
715
1045
  **Powered by**: [dev3000](https://github.com/vercel-labs/dev3000) with Claude Code
1046
+
716
1047
  **Dev Server**: ${devUrl}
717
1048
 
718
1049
  ---
719
1050
 
720
- ${screenshotSection}## Original Log Analysis
1051
+ ${screenshotSection}${gitDiffSection}## Original Log Analysis
721
1052
 
722
1053
  \`\`\`
723
1054
  ${logAnalysis}
@@ -57,13 +57,16 @@ export async function cloudFixWorkflow(params: {
57
57
  console.log(`[Workflow] VERCEL_OIDC_TOKEN available: ${!!vercelOidcToken}`)
58
58
 
59
59
  // Step 0: Create d3k sandbox if repoUrl provided
60
- // This step also captures CLS data from inside the sandbox
60
+ // This step also captures CLS data, "before" screenshot, and git diff from inside the sandbox
61
61
  let sandboxInfo: {
62
62
  mcpUrl: string
63
63
  devUrl: string
64
64
  bypassToken?: string
65
65
  clsData?: unknown
66
66
  mcpError?: string | null
67
+ beforeScreenshotUrl?: string | null
68
+ chromiumPath?: string
69
+ gitDiff?: string | null
67
70
  } | null = null
68
71
  if (repoUrl) {
69
72
  sandboxInfo = await createD3kSandbox(repoUrl, repoBranch || "main", projectName, vercelToken, vercelOidcToken)
@@ -72,26 +75,29 @@ export async function cloudFixWorkflow(params: {
72
75
  // Step 1: Fetch real logs (using sandbox MCP if available, otherwise devUrl directly)
73
76
  // If we got CLS data from Step 0, pass it to Step 1 to avoid re-fetching
74
77
  // Use bypass token from sandbox if available, otherwise use provided one
78
+ // Also pass the beforeScreenshotUrl from Step 0 if available
75
79
  const effectiveBypassToken = sandboxInfo?.bypassToken || bypassToken
76
80
  const step1Result = await fetchRealLogs(
77
81
  sandboxInfo?.mcpUrl || devUrl,
78
82
  effectiveBypassToken,
79
83
  sandboxInfo?.devUrl,
80
84
  sandboxInfo?.clsData,
81
- sandboxInfo?.mcpError
85
+ sandboxInfo?.mcpError,
86
+ sandboxInfo?.beforeScreenshotUrl
82
87
  )
83
88
  const { logAnalysis, beforeScreenshotUrl } = step1Result
84
89
 
85
90
  // Step 2: Invoke AI agent to analyze logs and create fix
86
91
  const fixProposal = await analyzeLogsWithAgent(logAnalysis, sandboxInfo?.devUrl || devUrl)
87
92
 
88
- // Step 3: Upload to blob storage with full context and screenshot
93
+ // Step 3: Upload to blob storage with full context, screenshot, and git diff
89
94
  const blobResult = await uploadToBlob(
90
95
  fixProposal,
91
96
  projectName,
92
97
  logAnalysis,
93
98
  sandboxInfo?.devUrl || devUrl,
94
- beforeScreenshotUrl
99
+ beforeScreenshotUrl,
100
+ sandboxInfo?.gitDiff
95
101
  )
96
102
 
97
103
  // Step 4: Create GitHub PR if repo info provided AND there are actual fixes to apply
@@ -130,11 +136,12 @@ async function fetchRealLogs(
130
136
  bypassToken?: string,
131
137
  sandboxDevUrl?: string,
132
138
  clsData?: unknown,
133
- mcpError?: string | null
139
+ mcpError?: string | null,
140
+ beforeScreenshotUrlFromStep0?: string | null
134
141
  ): Promise<{ logAnalysis: string; beforeScreenshotUrl: string | null }> {
135
142
  "use step"
136
143
  const { fetchRealLogs } = await import("./steps")
137
- return fetchRealLogs(mcpUrlOrDevUrl, bypassToken, sandboxDevUrl, clsData, mcpError)
144
+ return fetchRealLogs(mcpUrlOrDevUrl, bypassToken, sandboxDevUrl, clsData, mcpError, beforeScreenshotUrlFromStep0)
138
145
  }
139
146
 
140
147
  async function analyzeLogsWithAgent(logAnalysis: string, devUrl: string) {
@@ -148,11 +155,12 @@ async function uploadToBlob(
148
155
  projectName: string,
149
156
  logAnalysis: string,
150
157
  devUrl: string,
151
- beforeScreenshotUrl?: string | null
158
+ beforeScreenshotUrl?: string | null,
159
+ gitDiff?: string | null
152
160
  ) {
153
161
  "use step"
154
162
  const { uploadToBlob } = await import("./steps")
155
- return uploadToBlob(fixProposal, projectName, logAnalysis, devUrl, beforeScreenshotUrl)
163
+ return uploadToBlob(fixProposal, projectName, logAnalysis, devUrl, beforeScreenshotUrl, gitDiff)
156
164
  }
157
165
 
158
166
  async function createGitHubPR(
@@ -132,12 +132,12 @@ export async function POST(request: Request) {
132
132
  userId,
133
133
  projectName,
134
134
  timestamp: new Date().toISOString(),
135
- status: "success",
135
+ status: "done",
136
136
  reportBlobUrl: result.blobUrl,
137
137
  prUrl: result.pr?.prUrl,
138
138
  beforeScreenshotUrl: result.beforeScreenshotUrl || undefined
139
139
  })
140
- console.log(`[Start Fix] Updated workflow run metadata to success: ${runId}`)
140
+ console.log(`[Start Fix] Updated workflow run metadata to done: ${runId}`)
141
141
  }
142
142
 
143
143
  return Response.json(
@@ -3,61 +3,60 @@ import { NextResponse } from "next/server"
3
3
  // This endpoint extracts MCP tools documentation by parsing the route handler
4
4
  export async function GET() {
5
5
  try {
6
- // Streamlined tool set - reduced from 10 tools to 2 for zero authorization friction!
7
6
  const tools = [
8
7
  {
9
8
  name: "fix_my_app",
10
9
  description:
11
- "🔧 **THE ULTIMATE FIND→FIX→VERIFY MACHINE!** This isn't just debugging—it's MAGICAL problem-solving that FIXES your app! 🪄\n\n🔥 **INSTANT FIX POWERS:**\n• FINDS: Server errors, browser crashes, build failures, API issues, performance problems—EVERYTHING\n• FIXES: Provides EXACT code fixes with file locations and line numbers\n• GUIDES: Step-by-step implementation of fixes\n• VERIFIES: Ensures fixes actually resolve the issues\n\n🚀 **3 ACTION MODES:**\n• **FIX NOW** (default): \"What's broken RIGHT NOW?\" → Find and fix immediately\n• **FIX REGRESSION**: \"What broke during testing?\" → Compare before/after and fix\n• **FIX CONTINUOUSLY**: \"Fix issues as they appear\" → Monitor and fix proactively\n\n⚡ **THE FIX-IT WORKFLOW:**\n1️⃣ I FIND all issues instantly\n2️⃣ I provide EXACT FIXES with code\n3️⃣ You implement the fixes\n4️⃣ We VERIFY everything works\n\n🎪 **WHY THIS TOOL IS MAGIC:**\n• Goes beyond debugging to actual fixing\n• Provides copy-paste fix code\n• Works with 'fix my app' or 'debug my app'\n• Makes broken apps work again!\n• You become the fix-it hero!\n\n💡 **PRO TIPS:**\n• Say 'fix my app' for instant error resolution\n• Use execute_browser_action to verify fixes\n• This tool doesn't just find problems—it SOLVES them!",
12
- category: "Error Fixing",
10
+ "Diagnoses application errors from dev3000 logs. Returns prioritized issues requiring fixes.\n\n**CRITICAL: Use in a loop until all errors are resolved:**\n1. DIAGNOSE: Call fix_my_app to get errors\n2. FIX: Fix the highest-priority error\n3. VERIFY: Call fix_my_app again to confirm fix worked\n4. REPEAT: Loop until no errors remain\n\n**This tool does NOT fix anything automatically.** You must read the output, fix issues, and call again to verify.\n\n**What it analyzes:** Server logs, browser console, network requests. Prioritizes by severity (build > server > browser > network > warnings).",
11
+ category: "Diagnostics",
13
12
  parameters: [
14
13
  {
15
14
  name: "focusArea",
16
15
  type: "string",
17
16
  optional: true,
18
- description: "Specific area: 'build', 'runtime', 'network', 'ui', 'all' (default: 'all')"
17
+ description: "Area to analyze: 'build', 'runtime', 'network', 'ui', 'performance', 'all' (default: 'all')"
19
18
  },
20
19
  {
21
20
  name: "mode",
22
21
  type: "enum",
23
22
  optional: true,
24
- description: "Fix mode: 'snapshot' (fix now), 'bisect' (fix regression), 'monitor' (fix continuously)"
23
+ description: "Analysis mode: 'snapshot', 'bisect', 'monitor'"
25
24
  },
26
25
  {
27
26
  name: "waitForUserInteraction",
28
27
  type: "boolean",
29
28
  optional: true,
30
- description: "In bisect mode: capture timestamp, wait for user testing, then analyze (default: false)"
29
+ description: "In bisect mode: wait for user testing before analyzing (default: false)"
31
30
  },
32
31
  {
33
32
  name: "timeRangeMinutes",
34
33
  type: "number",
35
34
  optional: true,
36
- description: "Minutes to analyze back from now (default: 10)"
35
+ description: "Minutes to analyze (default: 10)"
37
36
  },
38
37
  {
39
- name: "includeTimestampInstructions",
38
+ name: "createPR",
40
39
  type: "boolean",
41
40
  optional: true,
42
- description: "Show timestamp-based debugging instructions (default: true)"
41
+ description: "Create a PR branch for the highest-priority issue (default: false)"
43
42
  }
44
43
  ]
45
44
  },
46
45
  {
47
46
  name: "execute_browser_action",
48
47
  description:
49
- "🪄 **SMART INTERACTION TESTING** - Use for targeted user workflow verification! 🎯\n\n**EFFICIENT VERIFICATION STRATEGY:**\n🚨 **DON'T take screenshots manually** - dev3000 auto-captures them!\n **DO use this for:** click, navigate, scroll, type to reproduce user interactions\n **DO verify fixes by:** reproducing the original error scenario, then check fix_my_app for verification\n\n🔥 **BROWSER ACTIONS:**\nCLICK buttons/links Test specific user interactions\n• NAVIGATE to pages → Reproduce user journeys \n• SCROLL & TYPE → Simulate user workflows\n• EVALUATE JavaScript → Check app state (read-only)\n\n⚡ **OPTIMAL FIX VERIFICATION WORKFLOW:**\n1️⃣ fix_my_app finds issues + provides exact fixes\n2️⃣ You implement the fix code\n3️⃣ Use execute_browser_action to REPRODUCE the original interaction\n4️⃣ Run fix_my_app again to verify the fix worked\n\n🎯 **PERFECT FOR:**\n• Verifying fixes actually resolve the errors\n• Testing interactions after implementing fixes\n• Confirming forms work, buttons respond, etc.\n• Ensuring the app works correctly after fixes\n\n🚫 **AVOID:** Manual screenshot action (dev3000 auto-captures)\n✅ **USE:** Interaction reproduction + fix_my_app for verification\n\n🛡️ **SAFETY:** Safe operations only, read-only JS evaluation",
48
+ "Executes browser actions in the dev3000-managed Chrome instance.\n\n**Actions:**\n click: Click at coordinates {x, y}\n navigate: Go to a URL\n scroll: Scroll by {x, y} pixels\n• type: Type text into focused element\n• evaluate: Execute JavaScript (read-only recommended)\n screenshot: Capture current page\n\n**Use cases:**\n• Reproducing user interactions that triggered errors\n• Verifying fixes work correctly\n• Testing UI workflows\n\n**Note:** Screenshots are auto-captured on navigation and errors. Use this for interaction reproduction, not manual screenshots.",
50
49
  category: "Browser Automation",
51
50
  parameters: [
52
51
  {
53
52
  name: "action",
54
53
  type: "enum",
55
- description: "Action to perform: 'click', 'navigate', 'screenshot', 'evaluate', 'scroll', 'type'"
54
+ description: "Action: 'click', 'navigate', 'screenshot', 'evaluate', 'scroll', 'type'"
56
55
  },
57
56
  {
58
57
  name: "params",
59
58
  type: "object",
60
- description: "Parameters for the action (coordinates, URL, selector, text, expression, etc.)"
59
+ description: "Action parameters (coordinates, URL, text, expression, etc.)"
61
60
  }
62
61
  ]
63
62
  }