@@ -143,6 +143,13 @@ type ResolvedExecEnvPreparedState = {
143143 pluginEnv ?: Record < string , string > ;
144144} ;
145145const resolvedExecEnvPreparedStates = new WeakMap < ExecToolArgs , ResolvedExecEnvPreparedState > ( ) ;
146+ type DeferredResolveExecEnvPreparedState = {
147+ hookContext ?: HookContext ;
148+ } ;
149+ const deferredResolveExecEnvPreparedStates = new WeakMap <
150+ ExecToolArgs ,
151+ DeferredResolveExecEnvPreparedState
152+ > ( ) ;
146153type ResolvedExecWorkdirPreparedState = {
147154 host : ExecHost ;
148155 inputWorkdir ?: string ;
@@ -162,6 +169,10 @@ const XML_ARG_VALUE_EXEC_PARAM_KEYS = [
162169 "node" ,
163170] as const ;
164171
172+ function isExecToolArgsObject ( value : unknown ) : value is ExecToolArgs {
173+ return typeof value === "object" && value !== null && ! Array . isArray ( value ) ;
174+ }
175+
165176function filterPluginExecEnv ( rawEnv : Record < string , string > ) : Record < string , string > | undefined {
166177 const env : Record < string , string > = { } ;
167178 for ( const [ rawKey , value ] of Object . entries ( rawEnv ) ) {
@@ -201,6 +212,20 @@ function isResolveExecEnvPrepared(params: ExecToolArgs): boolean {
201212 return Boolean ( getResolvedExecEnvPreparedState ( params ) ) ;
202213}
203214
215+ function markDeferredResolveExecEnvPrepared < T extends ExecToolArgs > (
216+ params : T ,
217+ state : DeferredResolveExecEnvPreparedState ,
218+ ) : T {
219+ deferredResolveExecEnvPreparedStates . set ( params , state ) ;
220+ return params ;
221+ }
222+
223+ function getDeferredResolveExecEnvPreparedState (
224+ params : ExecToolArgs ,
225+ ) : DeferredResolveExecEnvPreparedState | undefined {
226+ return deferredResolveExecEnvPreparedStates . get ( params ) ;
227+ }
228+
204229function markResolvedExecWorkdirPrepared < T extends ExecToolArgs > (
205230 params : T ,
206231 state : ResolvedExecWorkdirPreparedState ,
@@ -1475,20 +1500,31 @@ export function createExecTool(
14751500 if ( workdirState ?. resolution . kind === "unavailable" ) {
14761501 return params ;
14771502 }
1478- if ( shouldDeferResolveExecEnvUntilWorkdirValidated ( params ) ) {
1503+ if ( ! isExecToolArgsObject ( params ) ) {
14791504 return params ;
14801505 }
1506+ if ( shouldDeferResolveExecEnvUntilWorkdirValidated ( params ) ) {
1507+ return markDeferredResolveExecEnvPrepared ( params , {
1508+ hookContext : context . hookContext as HookContext | undefined ,
1509+ } ) ;
1510+ }
14811511 return prepareParamsWithResolvedExecEnv ( params , {
14821512 hookContext : context . hookContext as HookContext | undefined ,
14831513 } ) ;
14841514 } ,
14851515 finalizeBeforeToolCallParams : ( params , preparedParams ) => {
1486- const execParams = params as ExecToolArgs ;
14871516 const envState = getResolvedExecEnvPreparedState ( preparedParams as ExecToolArgs ) ;
1517+ const deferredEnvState = getDeferredResolveExecEnvPreparedState (
1518+ preparedParams as ExecToolArgs ,
1519+ ) ;
14881520 const workdirState = getResolvedExecWorkdirPreparedState ( preparedParams as ExecToolArgs ) ;
1489- if ( ! envState && ! workdirState ) {
1521+ if ( ! envState && ! deferredEnvState && ! workdirState ) {
1522+ return params ;
1523+ }
1524+ if ( ! isExecToolArgsObject ( params ) ) {
14901525 return params ;
14911526 }
1527+ const execParams = params ;
14921528 let host : ExecHost | undefined ;
14931529 const resolveFinalHost = ( ) => {
14941530 host ??= resolveHostForParams ( execParams ) ;
@@ -1511,6 +1547,9 @@ export function createExecTool(
15111547 if ( envState ) {
15121548 markResolveExecEnvPrepared ( execParams , envState ) ;
15131549 }
1550+ if ( deferredEnvState ) {
1551+ markDeferredResolveExecEnvPrepared ( execParams , deferredEnvState ) ;
1552+ }
15141553 if ( workdirState ) {
15151554 markResolvedExecWorkdirPrepared ( execParams , workdirState ) ;
15161555 }
@@ -1522,6 +1561,7 @@ export function createExecTool(
15221561 XML_ARG_VALUE_EXEC_PARAM_KEYS ,
15231562 ) ;
15241563 const resolveExecEnvPrepared = isResolveExecEnvPrepared ( args as ExecToolArgs ) ;
1564+ const deferredResolveExecEnvState = getDeferredResolveExecEnvPreparedState ( params ) ;
15251565 const preparedWorkdirState = getResolvedExecWorkdirPreparedState ( params ) ;
15261566
15271567 const maxOutput = DEFAULT_MAX_OUTPUT ;
@@ -1724,7 +1764,9 @@ export function createExecTool(
17241764 logInfo ( `exec: elevated command ${ truncateMiddle ( params . command , 120 ) } ` ) ;
17251765 }
17261766 if ( ! resolveExecEnvPrepared ) {
1727- params = await prepareParamsWithResolvedExecEnv ( params ) ;
1767+ params = await prepareParamsWithResolvedExecEnv ( params , {
1768+ hookContext : deferredResolveExecEnvState ?. hookContext ,
1769+ } ) ;
17281770 }
17291771
17301772 const inheritedBaseEnv = coerceEnv ( process . env ) ;
0 commit comments