@@ -28,8 +28,8 @@ import {
2828import type { OwnedProcessRecordStore } from '../../utils/owned-process-record.ts' ;
2929
3030const AGENT_BROWSER = 'agent-browser' ;
31- // Exported so WEB_BROWSER_SESSION_TEARDOWN_BUDGET_MS ( daemon/server/daemon-runtime.ts) can be
32- // pinned to it instead of drifting out of sync with a copied number .
31+ // Exported so daemon shutdown can pin its web-close budget to the ceiling enforced for one
32+ // `agent-browser` CLI call instead of copying a number that can drift .
3333export const AGENT_BROWSER_TIMEOUT_MS = 30_000 ;
3434const AGENT_BROWSER_DOCTOR_HINT =
3535 'Run `agent-device web setup` to install the managed web backend.' ;
@@ -238,24 +238,28 @@ async function runAgentBrowserJson(
238238) : Promise < unknown > {
239239 const { session, options, signal } = params ;
240240 const cliArgs = [ ...args , '--json' , ...( session ? [ '--session' , session ] : [ ] ) ] ;
241- const result = await runAgentBrowserCommand ( cliArgs , options , signal ) ;
242- const parsed = parseAgentBrowserJson ( result . stdout , result . stderr , cliArgs , result . exitCode ) ;
243- return unwrapAgentBrowserJson ( parsed , result , cliArgs ) ;
241+ return await runAgentBrowserCommand (
242+ cliArgs ,
243+ options ,
244+ ( result ) => {
245+ const parsed = parseAgentBrowserJson ( result . stdout , result . stderr , cliArgs , result . exitCode ) ;
246+ return unwrapAgentBrowserJson ( parsed , result , cliArgs ) ;
247+ } ,
248+ signal ,
249+ ) ;
244250}
245251
246252async function runAgentBrowserCommand (
247253 cliArgs : string [ ] ,
248254 options : AgentBrowserProviderOptions ,
255+ interpret : ( result : { stdout : string ; stderr : string ; exitCode : number } ) => unknown ,
249256 signal ?: AbortSignal ,
250- ) : Promise < {
251- stdout : string ;
252- stderr : string ;
253- exitCode : number ;
254- } > {
257+ ) : Promise < unknown > {
255258 let stdout = '' ;
256259 let stderr = '' ;
257260 let exitCode = 0 ;
258261 let commandCompleted = false ;
262+ let semanticSuccess = false ;
259263 const status = getManagedAgentBrowserStatus ( { stateDir : options . stateDir } ) ;
260264 try {
261265 await cleanupProviderStartupOrphans ( options ) ;
@@ -271,24 +275,39 @@ async function runAgentBrowserCommand(
271275 exitCode = result . exitCode ;
272276 commandCompleted = true ;
273277 } catch ( error ) {
278+ await finalizeAgentBrowserProcessRecord ( {
279+ cliArgs,
280+ commandCompleted,
281+ exitCode,
282+ semanticSuccess,
283+ options,
284+ status,
285+ } ) ;
274286 throw mapAgentBrowserRunError ( error , cliArgs ) ;
287+ }
288+
289+ try {
290+ const result = { stdout, stderr, exitCode } ;
291+ const output = interpret ( result ) ;
292+ semanticSuccess = true ;
293+ return output ;
275294 } finally {
276295 await finalizeAgentBrowserProcessRecord ( {
277296 cliArgs,
278297 commandCompleted,
279298 exitCode,
299+ semanticSuccess,
280300 options,
281301 status,
282302 } ) ;
283303 }
284-
285- return { stdout, stderr, exitCode } ;
286304}
287305
288306async function finalizeAgentBrowserProcessRecord ( params : {
289307 cliArgs : string [ ] ;
290308 commandCompleted : boolean ;
291309 exitCode : number ;
310+ semanticSuccess : boolean ;
292311 options : AgentBrowserProviderOptions ;
293312 status : ReturnType < typeof getManagedAgentBrowserStatus > ;
294313} ) : Promise < void > {
@@ -315,12 +334,13 @@ async function finalizeAgentBrowserProcessRecord(params: {
315334function canClearAgentBrowserRecord (
316335 params : Pick <
317336 Parameters < typeof finalizeAgentBrowserProcessRecord > [ 0 ] ,
318- 'cliArgs' | 'commandCompleted' | 'exitCode'
337+ 'cliArgs' | 'commandCompleted' | 'exitCode' | 'semanticSuccess'
319338 > ,
320339 otherOpenSessionCount : number ,
321340) : boolean {
322341 return (
323342 params . commandCompleted &&
343+ params . semanticSuccess &&
324344 params . cliArgs [ 0 ] === 'close' &&
325345 params . exitCode === 0 &&
326346 otherOpenSessionCount === 0
0 commit comments