@@ -166,7 +166,7 @@ import { CancellationError, workspaceUtils } from '@aws/lsp-core'
166166import { FsRead , FsReadParams } from './tools/fsRead'
167167import { ListDirectory , ListDirectoryParams } from './tools/listDirectory'
168168import { FsWrite , FsWriteParams } from './tools/fsWrite'
169- import { ExecuteBash , ExecuteBashParams } from './tools/executeBash'
169+ import { commandCategories , ExecuteBash , ExecuteBashParams } from './tools/executeBash'
170170import { ExplanatoryParams , InvokeOutput , ToolApprovalException } from './tools/toolShared'
171171import { validatePathBasic , validatePathExists , validatePaths as validatePathsSync } from './utils/pathValidation'
172172import { GrepSearch , SanitizedRipgrepOutput } from './tools/grepSearch'
@@ -233,7 +233,7 @@ import { getLatestAvailableModel } from './utils/agenticChatControllerHelper'
233233import { ActiveUserTracker } from '../../shared/activeUserTracker'
234234import { UserContext } from '../../client/token/codewhispererbearertokenclient'
235235import { CodeWhispererServiceToken } from '../../shared/codeWhispererService'
236- import { McpPermissionType } from './tools/mcp/mcpTypes'
236+ import { McpPermissionType , MCPServerPermission } from './tools/mcp/mcpTypes'
237237import { DisplayFindings } from './tools/qCodeAnalysis/displayFindings'
238238import { IdleWorkspaceManager } from '../workspaceContext/IdleWorkspaceManager'
239239
@@ -407,24 +407,23 @@ export class AgenticChatController implements ChatHandlers {
407407 if ( params . buttonId === BUTTON_TRUST_COMMAND ) {
408408 // get result from metadata
409409 const toolName = params . metadata ! [ 'toolName' ]
410- const newPermission = params . metadata ! [ 'permission' ]
410+ const new_permission = params . metadata ! [ 'permission' ]
411411 const serverName = params . metadata ! [ 'serverName' ]
412412
413- const currentPermission = McpManager . instance . getToolPerm ( serverName , toolName )
413+ const current_permission = McpManager . instance . getToolPerm ( serverName , toolName )
414414 // only trigger update if curren != previous
415- if ( currentPermission !== newPermission ) {
415+ if ( current_permission !== new_permission ) {
416416 // generate perm object
417417 const perm = await this . #mcpEventHandler. generateEmptyBuiltInToolPermission ( )
418418
419419 // load updated permission
420- perm . toolPerms [ toolName ] = newPermission as McpPermissionType
420+ perm . toolPerms [ toolName ] = new_permission as McpPermissionType
421421
422422 // update permission
423423 try {
424424 await McpManager . instance . updateServerPermission ( serverName , perm )
425425 // if the new permission is asks --> only update permission, dont continue
426- // this only happen on a completed card
427- if ( newPermission === 'ask' ) {
426+ if ( new_permission === 'ask' ) {
428427 return {
429428 success : true ,
430429 }
@@ -449,7 +448,6 @@ export class AgenticChatController implements ChatHandlers {
449448 params . messageId . endsWith ( SUFFIX_PERMISSION )
450449 ? params . messageId . replace ( SUFFIX_PERMISSION , '' )
451450 : params . messageId
452-
453451 const handler = session . data . getDeferredToolExecution ( messageId )
454452 if ( ! handler ?. reject || ! handler . resolve ) {
455453 if ( params . buttonId === BUTTON_TRUST_COMMAND ) {
@@ -1460,6 +1458,18 @@ export class AgenticChatController implements ChatHandlers {
14601458 metric . setDimension ( 'requestIds' , metric . metric . requestIds )
14611459 const toolNames = this . #toolUseLatencies. map ( item => item . toolName )
14621460 const toolUseIds = this . #toolUseLatencies. map ( item => item . toolUseId )
1461+
1462+ const builtInToolNames = new Set ( this . #features. agent . getBuiltInToolNames ( ) )
1463+ const permission : string [ ] = [ ]
1464+
1465+ for ( const toolName of toolNames ) {
1466+ if ( builtInToolNames . has ( toolName ) ) {
1467+ permission . push ( McpManager . instance . getToolPerm ( 'Built-in' , toolName ) )
1468+ } else {
1469+ // TODO: determine mcp-server of the current tool to get permission
1470+ }
1471+ }
1472+
14631473 this . #telemetryController. emitAgencticLoop_InvokeLLM (
14641474 response . $metadata . requestId ! ,
14651475 conversationId ,
@@ -1475,7 +1485,8 @@ export class AgenticChatController implements ChatHandlers {
14751485 this . #timeBetweenChunks,
14761486 session . pairProgrammingMode ,
14771487 this . #abTestingAllocation?. experimentName ,
1478- this . #abTestingAllocation?. userVariation
1488+ this . #abTestingAllocation?. userVariation ,
1489+ permission
14791490 )
14801491 } else {
14811492 // Send an error card to UI?
@@ -1708,6 +1719,7 @@ export class AgenticChatController implements ChatHandlers {
17081719 promptBlockId : number ,
17091720 session : ChatSessionService ,
17101721 toolName : string ,
1722+ commandCategory ?: CommandCategory ,
17111723 tabId ?: string
17121724 ) {
17131725 const deferred = this . #createDeferred( )
@@ -1716,7 +1728,7 @@ export class AgenticChatController implements ChatHandlers {
17161728 await deferred . promise
17171729 // Note: we want to overwrite the button block because it already exists in the stream.
17181730 await resultStream . overwriteResultBlock (
1719- this . #getUpdateToolConfirmResult( toolUse , true , toolName , tabId ) ,
1731+ this . #getUpdateToolConfirmResult( toolUse , true , toolName , undefined , commandCategory , tabId ) ,
17201732 promptBlockId
17211733 )
17221734 }
@@ -1772,6 +1784,10 @@ export class AgenticChatController implements ChatHandlers {
17721784 } )
17731785 }
17741786 }
1787+
1788+ // for later use
1789+ let finalCommandCategory : CommandCategory | undefined
1790+
17751791 switch ( toolUse . name ) {
17761792 case FS_READ :
17771793 case LIST_DIRECTORY :
@@ -1807,6 +1823,8 @@ export class AgenticChatController implements ChatHandlers {
18071823 approvedPaths
18081824 )
18091825
1826+ finalCommandCategory = commandCategory
1827+
18101828 const isExecuteBash = toolUse . name === EXECUTE_BASH
18111829
18121830 // check if tool execution's path is out of workspace
@@ -1837,7 +1855,7 @@ export class AgenticChatController implements ChatHandlers {
18371855 warning ,
18381856 commandCategory ,
18391857 toolUse . name ,
1840- undefined ,
1858+ builtInPermission ,
18411859 tabId
18421860 )
18431861 cachedButtonBlockId = await chatResultStream . writeResultBlock ( confirmationResult )
@@ -1859,6 +1877,7 @@ export class AgenticChatController implements ChatHandlers {
18591877 cachedButtonBlockId ,
18601878 session ,
18611879 toolUse . name ,
1880+ commandCategory ,
18621881 tabId
18631882 )
18641883 }
@@ -1913,7 +1932,7 @@ export class AgenticChatController implements ChatHandlers {
19131932 requiresAcceptance ,
19141933 warning ,
19151934 undefined ,
1916- toolName , // Pass the original tool name here
1935+ toolName , // Pass the original tool name here,
19171936 undefined ,
19181937 tabId
19191938 )
@@ -1924,6 +1943,7 @@ export class AgenticChatController implements ChatHandlers {
19241943 cachedButtonBlockId ,
19251944 session ,
19261945 toolName ,
1946+ undefined ,
19271947 tabId
19281948 )
19291949 }
@@ -1976,7 +1996,7 @@ export class AgenticChatController implements ChatHandlers {
19761996 session . addApprovedPath ( inputPath )
19771997 }
19781998
1979- const ws = this . #getWritableStream( chatResultStream , toolUse )
1999+ const ws = this . #getWritableStream( chatResultStream , toolUse , finalCommandCategory )
19802000 const result = await this . #features. agent . runTool ( toolUse . name , toolUse . input , token , ws )
19812001
19822002 let toolResultContent : ToolResultContentBlock
@@ -2394,7 +2414,11 @@ export class AgenticChatController implements ChatHandlers {
23942414 } )
23952415 }
23962416
2397- #getWritableStream( chatResultStream : AgenticChatResultStream , toolUse : ToolUse ) : WritableStream | undefined {
2417+ #getWritableStream(
2418+ chatResultStream : AgenticChatResultStream ,
2419+ toolUse : ToolUse ,
2420+ commandCategory ?: CommandCategory
2421+ ) : WritableStream | undefined {
23982422 if ( toolUse . name === CodeReview . toolName ) {
23992423 return this . #getToolOverWritableStream( chatResultStream , toolUse )
24002424 }
@@ -2413,7 +2437,14 @@ export class AgenticChatController implements ChatHandlers {
24132437
24142438 const completedHeader : ChatMessage [ 'header' ] = {
24152439 body : 'shell' ,
2416- status : { status : 'success' , icon : 'ok' , text : 'Completed' } ,
2440+ status : {
2441+ status : 'success' ,
2442+ icon : 'ok' ,
2443+ text : 'Completed' ,
2444+ ...( toolUse . name === EXECUTE_BASH
2445+ ? { description : this . #getCommandCategoryDescription( commandCategory ?? CommandCategory . ReadOnly ) }
2446+ : { } ) ,
2447+ } ,
24172448 buttons : [ ] ,
24182449 }
24192450
@@ -2465,10 +2496,11 @@ export class AgenticChatController implements ChatHandlers {
24652496 isAccept : boolean ,
24662497 originalToolName : string ,
24672498 toolType ?: string ,
2499+ commandCategory ?: CommandCategory ,
24682500 tabId ?: string
24692501 ) : ChatResult {
24702502 const toolName = originalToolName ?? ( toolType || toolUse . name )
2471-
2503+ const quickSettings = this . #buildQuickSettings ( toolUse , toolName ! , toolType , tabId )
24722504 // Handle bash commands with special formatting
24732505 if ( toolName === EXECUTE_BASH ) {
24742506 return {
@@ -2488,6 +2520,7 @@ export class AgenticChatController implements ChatHandlers {
24882520 } ) ,
24892521 buttons : isAccept ? [ this . #renderStopShellCommandButton( ) ] : [ ] ,
24902522 } ,
2523+ quickSettings,
24912524 }
24922525 }
24932526
@@ -2775,13 +2808,8 @@ export class AgenticChatController implements ChatHandlers {
27752808 const quickSettings = this . #buildQuickSettings( toolUse , toolName ! , toolType , tabId )
27762809 // Configure tool-specific UI elements
27772810 switch ( toolName ) {
2778- case EXECUTE_BASH : {
2811+ case 'executeBash' : {
27792812 const commandString = ( toolUse . input as unknown as ExecuteBashParams ) . command
2780- // get feature flag
2781- const shortcut =
2782- this . #features. lsp . getClientInitializeParams ( ) ?. initializationOptions ?. aws ?. awsClientCapabilities ?. q
2783- ?. shortcut
2784-
27852813 const runKey = this . #getKeyBinding( 'aws.amazonq.runCmdExecution' )
27862814 const rejectKey = this . #getKeyBinding( 'aws.amazonq.rejectCmdExecution' )
27872815
@@ -2817,16 +2845,12 @@ export class AgenticChatController implements ChatHandlers {
28172845 : undefined
28182846
28192847 header = {
2820- status : requiresAcceptance
2821- ? {
2822- icon : statusIcon ,
2823- status : statusType ,
2824- position : 'left' ,
2825- description : this . #getCommandCategoryDescription(
2826- commandCategory ?? CommandCategory . ReadOnly
2827- ) ,
2828- }
2829- : { } ,
2848+ status : {
2849+ icon : statusIcon ,
2850+ status : statusType ,
2851+ position : 'left' ,
2852+ description : this . #getCommandCategoryDescription( commandCategory ?? CommandCategory . ReadOnly ) ,
2853+ } ,
28302854 body : 'shell' ,
28312855 buttons,
28322856 }
@@ -2944,6 +2968,7 @@ export class AgenticChatController implements ChatHandlers {
29442968 messageId : this . #getMessageIdForToolUse( toolType , toolUse ) ,
29452969 header,
29462970 body : warning ? ( toolName === EXECUTE_BASH ? '' : '\n\n' ) + body : body ,
2971+ quickSettings,
29472972 }
29482973 } else {
29492974 return {
0 commit comments