@@ -8,6 +8,7 @@ import type {
88} from '../../../schema' ;
99import { getAgentRuntimeStatus } from '../../aws' ;
1010import { getErrorMessage } from '../../errors' ;
11+ import { ExecLogger } from '../../logging' ;
1112import type { ResourceDeploymentState } from './constants' ;
1213
1314export type { ResourceDeploymentState } ;
@@ -28,6 +29,7 @@ export interface ProjectStatusResult {
2829 targetRegion ?: string ;
2930 resources : ResourceStatusEntry [ ] ;
3031 error ?: string ;
32+ logPath ?: string ;
3133}
3234
3335export interface StatusContext {
@@ -43,6 +45,7 @@ export interface RuntimeLookupResult {
4345 runtimeId ?: string ;
4446 runtimeStatus ?: string ;
4547 error ?: string ;
48+ logPath ?: string ;
4649}
4750
4851/**
@@ -156,100 +159,164 @@ export async function handleProjectStatus(
156159 context : StatusContext ,
157160 options : { targetName ?: string } = { }
158161) : Promise < ProjectStatusResult > {
162+ const logger = new ExecLogger ( { command : 'status' } ) ;
159163 const { project, deployedState, awsTargets, mcpSpec } = context ;
160164
165+ logger . startStep ( 'Resolve target' ) ;
161166 const deployedTargetNames = Object . keys ( deployedState . targets ) ;
162167 const targetNames = deployedTargetNames . length > 0 ? deployedTargetNames : awsTargets . map ( t => t . name ) ;
163-
164168 const selectedTargetName = options . targetName ?? targetNames [ 0 ] ;
165169
170+ logger . log ( `Project: ${ project . name } ` ) ;
171+ logger . log ( `Available targets: ${ targetNames . length > 0 ? targetNames . join ( ', ' ) : '(none)' } ` ) ;
172+ logger . log ( `Selected target: ${ selectedTargetName ?? '(none)' } ` ) ;
173+
166174 if ( options . targetName && ! targetNames . includes ( options . targetName ) ) {
175+ const error =
176+ targetNames . length > 0
177+ ? `Target '${ options . targetName } ' not found. Available: ${ targetNames . join ( ', ' ) } `
178+ : `Target '${ options . targetName } ' not found. No targets configured.` ;
179+ logger . endStep ( 'error' , error ) ;
180+ logger . finalize ( false ) ;
167181 return {
168182 success : false ,
169183 projectName : project . name ,
170184 targetName : options . targetName ,
171185 resources : [ ] ,
172- error :
173- targetNames . length > 0
174- ? `Target '${ options . targetName } ' not found. Available: ${ targetNames . join ( ', ' ) } `
175- : `Target '${ options . targetName } ' not found. No targets configured.` ,
186+ error,
187+ logPath : logger . getRelativeLogPath ( ) ,
176188 } ;
177189 }
190+ logger . endStep ( 'success' ) ;
178191
192+ logger . startStep ( 'Compute resource statuses' ) ;
179193 const targetConfig = selectedTargetName ? awsTargets . find ( t => t . name === selectedTargetName ) : undefined ;
180194 const targetResources = selectedTargetName ? deployedState . targets [ selectedTargetName ] ?. resources : undefined ;
181195
182196 const resources = computeResourceStatuses ( project , targetResources , mcpSpec ) ;
183197
198+ const deployed = resources . filter ( r => r . deploymentState === 'deployed' ) . length ;
199+ const localOnly = resources . filter ( r => r . deploymentState === 'local-only' ) . length ;
200+ const pendingRemoval = resources . filter ( r => r . deploymentState === 'pending-removal' ) . length ;
201+ logger . log (
202+ `Resources: ${ resources . length } total (${ deployed } deployed, ${ localOnly } local-only, ${ pendingRemoval } pending-removal)`
203+ ) ;
204+ for ( const entry of resources ) {
205+ logger . log (
206+ ` ${ entry . resourceType } /${ entry . name } : ${ entry . deploymentState } ${ entry . identifier ? ` [${ entry . identifier } ]` : '' } `
207+ ) ;
208+ }
209+ logger . endStep ( 'success' ) ;
210+
184211 // Enrich deployed agents with live runtime status (parallel, entries replaced by index)
185212 if ( targetConfig ) {
186213 const agentStates = targetResources ?. agents ?? { } ;
187-
188- await Promise . all (
189- resources . map ( async ( entry , i ) => {
190- if ( entry . resourceType !== 'agent' || entry . deploymentState !== 'deployed' ) return ;
191-
192- const agentState = agentStates [ entry . name ] ;
193- if ( ! agentState ) return ;
194-
195- try {
196- const runtimeStatus = await getAgentRuntimeStatus ( {
197- region : targetConfig . region ,
198- runtimeId : agentState . runtimeId ,
199- } ) ;
200- resources [ i ] = { ...entry , detail : runtimeStatus . status } ;
201- } catch ( error ) {
202- resources [ i ] = { ...entry , error : getErrorMessage ( error ) } ;
203- }
204- } )
214+ const deployedAgents = resources . filter (
215+ ( e , _i ) => e . resourceType === 'agent' && e . deploymentState === 'deployed' && agentStates [ e . name ]
205216 ) ;
217+
218+ if ( deployedAgents . length > 0 ) {
219+ logger . startStep (
220+ `Fetch runtime status (${ deployedAgents . length } agent${ deployedAgents . length !== 1 ? 's' : '' } )`
221+ ) ;
222+
223+ await Promise . all (
224+ resources . map ( async ( entry , i ) => {
225+ if ( entry . resourceType !== 'agent' || entry . deploymentState !== 'deployed' ) return ;
226+
227+ const agentState = agentStates [ entry . name ] ;
228+ if ( ! agentState ) return ;
229+
230+ try {
231+ const runtimeStatus = await getAgentRuntimeStatus ( {
232+ region : targetConfig . region ,
233+ runtimeId : agentState . runtimeId ,
234+ } ) ;
235+ resources [ i ] = { ...entry , detail : runtimeStatus . status } ;
236+ logger . log ( ` ${ entry . name } : ${ runtimeStatus . status } (${ agentState . runtimeId } )` ) ;
237+ } catch ( error ) {
238+ const errorMsg = getErrorMessage ( error ) ;
239+ resources [ i ] = { ...entry , error : errorMsg } ;
240+ logger . log ( ` ${ entry . name } : ERROR - ${ errorMsg } ` , 'error' ) ;
241+ }
242+ } )
243+ ) ;
244+
245+ const hasErrors = resources . some ( r => r . error ) ;
246+ logger . endStep ( hasErrors ? 'error' : 'success' ) ;
247+ }
206248 }
207249
250+ logger . finalize ( true ) ;
208251 return {
209252 success : true ,
210253 projectName : project . name ,
211254 targetName : selectedTargetName ?? '' ,
212255 targetRegion : targetConfig ?. region ,
213256 resources,
257+ logPath : logger . getRelativeLogPath ( ) ,
214258 } ;
215259}
216260
217261export async function handleRuntimeLookup (
218262 context : StatusContext ,
219263 options : { agentRuntimeId : string ; targetName ?: string }
220264) : Promise < RuntimeLookupResult > {
265+ const logger = new ExecLogger ( { command : 'status' } ) ;
221266 const { awsTargets } = context ;
222267
268+ logger . startStep ( 'Resolve target' ) ;
223269 const targetNames = awsTargets . map ( target => target . name ) ;
224270 if ( targetNames . length === 0 ) {
225- return { success : false , error : 'No deployment targets found. Run `agentcore create` first.' } ;
271+ const error = 'No deployment targets found. Run `agentcore create` first.' ;
272+ logger . endStep ( 'error' , error ) ;
273+ logger . finalize ( false ) ;
274+ return { success : false , error, logPath : logger . getRelativeLogPath ( ) } ;
226275 }
227276
228277 const selectedTargetName = options . targetName ?? targetNames [ 0 ] ! ;
229278
230279 if ( options . targetName && ! targetNames . includes ( options . targetName ) ) {
231- return { success : false , error : `Target '${ options . targetName } ' not found. Available: ${ targetNames . join ( ', ' ) } ` } ;
280+ const error = `Target '${ options . targetName } ' not found. Available: ${ targetNames . join ( ', ' ) } ` ;
281+ logger . endStep ( 'error' , error ) ;
282+ logger . finalize ( false ) ;
283+ return { success : false , error, logPath : logger . getRelativeLogPath ( ) } ;
232284 }
233285
234286 const targetConfig = awsTargets . find ( target => target . name === selectedTargetName ) ;
235287
236288 if ( ! targetConfig ) {
237- return { success : false , error : `Target config '${ selectedTargetName } ' not found in aws-targets` } ;
289+ const error = `Target config '${ selectedTargetName } ' not found in aws-targets` ;
290+ logger . endStep ( 'error' , error ) ;
291+ logger . finalize ( false ) ;
292+ return { success : false , error, logPath : logger . getRelativeLogPath ( ) } ;
238293 }
239294
295+ logger . log ( `Target: ${ selectedTargetName } (${ targetConfig . region } )` ) ;
296+ logger . endStep ( 'success' ) ;
297+
298+ logger . startStep ( `Lookup runtime ${ options . agentRuntimeId } ` ) ;
240299 try {
241300 const runtimeStatus = await getAgentRuntimeStatus ( {
242301 region : targetConfig . region ,
243302 runtimeId : options . agentRuntimeId ,
244303 } ) ;
245304
305+ logger . log ( `Runtime: ${ runtimeStatus . runtimeId } — ${ runtimeStatus . status } ` ) ;
306+ logger . endStep ( 'success' ) ;
307+ logger . finalize ( true ) ;
308+
246309 return {
247310 success : true ,
248311 targetName : selectedTargetName ,
249312 runtimeId : runtimeStatus . runtimeId ,
250313 runtimeStatus : runtimeStatus . status ,
314+ logPath : logger . getRelativeLogPath ( ) ,
251315 } ;
252316 } catch ( error ) {
253- return { success : false , error : getErrorMessage ( error ) } ;
317+ const errorMsg = getErrorMessage ( error ) ;
318+ logger . endStep ( 'error' , errorMsg ) ;
319+ logger . finalize ( false ) ;
320+ return { success : false , error : errorMsg , logPath : logger . getRelativeLogPath ( ) } ;
254321 }
255322}
0 commit comments