11import type { BuildExtension } from "@trigger.dev/build" ;
22import { spawn } from "child_process" ;
3- import { chmodSync , copyFileSync , existsSync , readdirSync } from "fs" ;
3+ import { existsSync , readdirSync } from "fs" ;
44import type { CursorEvent } from "@/lib/cursor-events" ;
55import { logger } from "@trigger.dev/sdk" ;
66
@@ -49,20 +49,15 @@ type SpawnCursorAgentOptions = {
4949/**
5050 * Spawn cursor-agent at runtime inside the Trigger.dev container.
5151 *
52- * Returns a NDJSON ReadableStream of CursorEvents and a waitUntilExit()
53- * that resolves with the exit code and stderr.
54- *
55- * Handles the /tmp copy + chmod workaround needed because the runtime
56- * strips execute permissions, and cursor-agent's native .node modules
57- * require its bundled node (ABI mismatch with container node).
52+ * Uses cursor-agent's bundled node (not process.execPath) because its
53+ * native .node modules require ABI compatibility.
5854 */
5955export function spawnCursorAgent (
6056 args : string [ ] ,
6157 options : SpawnCursorAgentOptions ,
6258) : CursorAgent {
6359 const entryPoint = `${ CURSOR_AGENT_DIR } /index.js` ;
6460 const bundledNode = `${ CURSOR_AGENT_DIR } /node` ;
65- const tmpNode = "/tmp/cursor-node" ;
6661
6762 if ( ! existsSync ( entryPoint ) ) {
6863 const dirExists = existsSync ( CURSOR_AGENT_DIR ) ;
@@ -71,17 +66,7 @@ export function spawnCursorAgent(
7166 ) ;
7267 }
7368
74- try {
75- copyFileSync ( bundledNode , tmpNode ) ;
76- chmodSync ( tmpNode , 0o755 ) ;
77- } catch ( err : unknown ) {
78- // ETXTBSY = file is being executed by another run on this machine — safe to skip
79- if ( ! ( err instanceof Error && "code" in err && err . code === "ETXTBSY" ) ) {
80- throw err ;
81- }
82- }
83-
84- const child = spawn ( tmpNode , [ entryPoint , ...args ] , {
69+ const child = spawn ( bundledNode , [ entryPoint , ...args ] , {
8570 stdio : [ "ignore" , "pipe" , "pipe" ] ,
8671 env : {
8772 ...process . env ,
0 commit comments