@@ -150,25 +150,41 @@ func (b *e2bBackend) Run(ctx context.Context, req RunRequest) (RunResult, error)
150150 removeLeaseClaim (leaseID )
151151 }()
152152 }
153+ result := RunResult {
154+ SyncDelegated : true ,
155+ Session : & RunSessionHandle {
156+ Provider : e2bProvider ,
157+ LeaseID : leaseID ,
158+ Slug : slug ,
159+ Reused : ! acquired ,
160+ Kept : ! shouldStop ,
161+ CleanupCommand : e2bCleanupCommand (leaseID ),
162+ },
163+ }
164+ finishResult := func () RunResult {
165+ result .Total = b .now ().Sub (started )
166+ result .Session .Kept = ! shouldStop
167+ return result
168+ }
153169
154170 session , err := client .ConnectSandbox (ctx , sandboxID , e2bTimeoutSeconds (b .cfg .TTL ))
155171 if err != nil {
156- return RunResult {} , e2bError ("connect sandbox" , err )
172+ return finishResult () , e2bError ("connect sandbox" , err )
157173 }
158174 workspace := e2bWorkspacePath (b .cfg )
159175 syncDuration := time .Duration (0 )
160176 syncPhases := []timingPhase {{Name : "sync" , Skipped : true , Reason : "--no-sync" }}
161177 if ! req .NoSync {
162178 syncPhases , syncDuration , err = b .syncWorkspace (ctx , client , session , req , workspace )
163179 if err != nil {
164- return RunResult { Total : b . now (). Sub ( started ), SyncDelegated : true } , err
180+ return finishResult () , err
165181 }
166182 fmt .Fprintf (b .rt .Stderr , "sync complete in %s\n " , syncDuration .Round (time .Millisecond ))
167183 } else if err := b .prepareWorkspace (ctx , client , session , workspace ); err != nil {
168- return RunResult {} , err
184+ return finishResult () , err
169185 }
170186 if req .SyncOnly {
171- result := RunResult { Total : b . now (). Sub ( started ), SyncDelegated : true }
187+ result := finishResult ()
172188 fmt .Fprintf (b .rt .Stdout , "synced %s\n " , workspace )
173189 if req .TimingJSON {
174190 err := writeTimingJSON (b .rt .Stderr , timingReport {
@@ -189,7 +205,7 @@ func (b *e2bBackend) Run(ctx context.Context, req RunRequest) (RunResult, error)
189205 }
190206 command := e2bCommandString (req .Command , req .ShellMode )
191207 if command == "" {
192- return RunResult {} , exit (2 , "missing command" )
208+ return finishResult () , exit (2 , "missing command" )
193209 }
194210 commandStarted := b .now ()
195211 fmt .Fprintf (b .rt .Stderr , "running on e2b %s\n " , strings .Join (req .Command , " " ))
@@ -203,12 +219,10 @@ func (b *e2bBackend) Run(ctx context.Context, req RunRequest) (RunResult, error)
203219 Stderr : b .rt .Stderr ,
204220 })
205221 commandDuration := b .now ().Sub (commandStarted )
206- result := RunResult {
207- ExitCode : exitCode ,
208- Command : commandDuration ,
209- Total : b .now ().Sub (started ),
210- SyncDelegated : true ,
211- }
222+ result .ExitCode = exitCode
223+ result .Command = commandDuration
224+ result .Total = b .now ().Sub (started )
225+ result .Session .Kept = ! shouldStop
212226 if req .NoSync {
213227 fmt .Fprintf (b .rt .Stderr , "e2b run summary sync_skipped=true command=%s total=%s exit=%d\n " , result .Command .Round (time .Millisecond ), result .Total .Round (time .Millisecond ), result .ExitCode )
214228 } else {
@@ -233,13 +247,13 @@ func (b *e2bBackend) Run(ctx context.Context, req RunRequest) (RunResult, error)
233247 }
234248 if commandErr != nil {
235249 handleDelegatedRunFailure (b .rt .Stderr , req , e2bProvider , leaseID , slug , b .cfg .IdleTimeout , b .cfg .TTL , acquired , & shouldStop )
236- return result , ExitError {Code : 1 , Message : fmt .Sprintf ("e2b run failed: %v" , commandErr )}
250+ return finishResult () , ExitError {Code : 1 , Message : fmt .Sprintf ("e2b run failed: %v" , commandErr )}
237251 }
238252 if result .ExitCode != 0 {
239253 handleDelegatedRunFailure (b .rt .Stderr , req , e2bProvider , leaseID , slug , b .cfg .IdleTimeout , b .cfg .TTL , acquired , & shouldStop )
240- return result , ExitError {Code : result .ExitCode , Message : fmt .Sprintf ("e2b run exited %d" , result .ExitCode )}
254+ return finishResult () , ExitError {Code : result .ExitCode , Message : fmt .Sprintf ("e2b run exited %d" , result .ExitCode )}
241255 }
242- return result , nil
256+ return finishResult () , nil
243257}
244258
245259func (b * e2bBackend ) List (ctx context.Context , req ListRequest ) ([]LeaseView , error ) {
@@ -369,6 +383,10 @@ func (b *e2bBackend) deleteSandboxForCleanup(client e2bAPI, sandboxID string) er
369383 return client .DeleteSandbox (ctx , sandboxID )
370384}
371385
386+ func e2bCleanupCommand (leaseID string ) string {
387+ return fmt .Sprintf ("crabbox stop --provider %s --id %s" , e2bProvider , shellQuote (leaseID ))
388+ }
389+
372390func (b * e2bBackend ) resolveSandboxID (ctx context.Context , client e2bAPI , id , repoRoot string , reclaim bool ) (string , string , string , error ) {
373391 if id == "" {
374392 return "" , "" , "" , exit (2 , "provider=e2b requires a Crabbox lease id, slug, or E2B sandbox id" )
0 commit comments