Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@
"@aws-sdk/s3-request-presigner": "<3.731.0",
"@aws-sdk/smithy-client": "<3.731.0",
"@aws-sdk/util-arn-parser": "<3.731.0",
"@aws/mynah-ui": "^4.31.0-beta.2",
"@aws/mynah-ui": "^4.31.0-beta.3",
"@gerhobbelt/gitignore-parser": "^0.2.0-9",
"@iarna/toml": "^2.2.5",
"@smithy/fetch-http-handler": "^5.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export class Connector extends BaseConnector {
}

if (messageData.type === 'asyncEventProgressMessage') {
const isPromptInputDisabled = true
const isPromptInputDisabled = false
this.onAsyncEventProgress(
messageData.tabID,
messageData.inProgress,
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/amazonq/webview/ui/followUps/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export class FollowUpInteractionHandler {
if (followUp.prompt !== undefined) {
this.mynahUI.updateStore(tabID, {
loadingChat: true,
cancelButtonWhenLoading: false,
promptInputDisabledState: true,
})
this.mynahUI.addChatItem(tabID, {
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/amazonq/webview/ui/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,6 @@ export const createMynahUI = (
) {
mynahUI.updateStore(tabID, {
loadingChat: true,
cancelButtonWhenLoading: false,
promptInputDisabledState: true,
})

Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/amazonq/webview/ui/messages/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ export class MessageController {

this.mynahUI.updateStore(selectedTab.id, {
loadingChat: true,
cancelButtonWhenLoading: false,
promptInputDisabledState: true,
})
this.mynahUI.addChatItem(selectedTab.id, message)
Expand Down Expand Up @@ -120,7 +119,6 @@ export class MessageController {

this.mynahUI.updateStore(newTabID, {
loadingChat: true,
cancelButtonWhenLoading: false,
promptInputDisabledState: true,
})

Expand Down
1 change: 0 additions & 1 deletion packages/core/src/amazonq/webview/ui/messages/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export class TextMessageHandler {

this.mynahUI.updateStore(tabID, {
loadingChat: true,
cancelButtonWhenLoading: false,
promptInputDisabledState: true,
})

Expand Down
223 changes: 98 additions & 125 deletions packages/core/src/amazonq/webview/ui/quickActions/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,107 +103,122 @@ export class QuickActionHandler {
}
}

private handleScanCommand(tabID: string, eventId: string | undefined) {
if (!this.isScanEnabled) {
/**
* Common helper method to handle specialized tab commands (scan, test, transform)
* @param options Configuration options for the specialized tab
*/
private handleSpecializedTabCommand(options: {
tabID: string // Current tab ID
eventId?: string // Event ID for tracking
isEnabled: boolean // Feature flag
tabType: TabType // Type of tab to create/switch to
existingTabType: TabType // Type to look for in existing tabs
taskName?: string // Optional task name
promptText?: string // Optional prompt text
onExistingTab: (tabId: string) => void // Callback for existing tab
onNewTab: (tabId: string) => void // Callback for new tab
}): void {
if (!options.isEnabled) {
return
}
let scanTabId: string | undefined = undefined

// Check if a tab of this type already exists
let existingTabId: string | undefined = undefined
for (const tab of this.tabsStorage.getTabs()) {
if (tab.type === 'review') {
scanTabId = tab.id
if (tab.type === options.existingTabType) {
existingTabId = tab.id
break
}
}

if (scanTabId !== undefined) {
this.mynahUI.selectTab(scanTabId, eventId || '')
this.connector.onTabChange(scanTabId)
this.connector.scans(scanTabId)
// If tab exists, select it and run the callback
if (existingTabId !== undefined) {
this.mynahUI.selectTab(existingTabId, options.eventId || '')
this.connector.onTabChange(existingTabId)
options.onExistingTab(existingTabId)
return
}

let affectedTabId: string | undefined = tabID
// if there is no scan tab, open a new one
// Otherwise, create a new tab
let affectedTabId: string | undefined = options.tabID

// If current tab is not unknown or welcome, create a new tab
const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type
if (currentTabType !== 'unknown' && currentTabType !== 'welcome') {
affectedTabId = this.mynahUI.updateStore('', {
loadingChat: true,
})
}

// Handle case where we can't create a new tab
if (affectedTabId === undefined) {
this.mynahUI.notify({
content: uiComponentsTexts.noMoreTabsTooltip,
type: NotificationType.WARNING,
})
return
} else {
this.tabsStorage.updateTabTypeFromUnknown(affectedTabId, 'review')
this.connector.onKnownTabOpen(affectedTabId)
this.connector.onUpdateTabType(affectedTabId)

// reset chat history
this.mynahUI.updateStore(affectedTabId, {
chatItems: [],
})

this.mynahUI.updateStore(affectedTabId, this.tabDataGenerator.getTabData('review', true, undefined)) // creating a new tab and printing some title

// disable chat prompt
this.mynahUI.updateStore(affectedTabId, {
loadingChat: true,
})
this.connector.scans(affectedTabId)
}
}

private handleTestCommand(chatPrompt: ChatPrompt, tabID: string, eventId: string | undefined) {
if (!this.isTestEnabled) {
return
}
const testTabId = this.tabsStorage.getTabs().find((tab) => tab.type === 'testgen')?.id
const realPromptText = chatPrompt.escapedPrompt?.trim() ?? ''
// Set up the new tab
this.tabsStorage.updateTabTypeFromUnknown(affectedTabId, options.tabType)
this.connector.onKnownTabOpen(affectedTabId)
this.connector.onUpdateTabType(affectedTabId)

if (testTabId !== undefined) {
this.mynahUI.selectTab(testTabId, eventId || '')
this.connector.onTabChange(testTabId)
this.connector.startTestGen(testTabId, realPromptText)
return
}
// Reset chat history
this.mynahUI.updateStore(affectedTabId, {
chatItems: [],
})

let affectedTabId: string | undefined = tabID
// if there is no test tab, open a new one
const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type
if (currentTabType !== 'unknown' && currentTabType !== 'welcome') {
affectedTabId = this.mynahUI.updateStore('', {
loadingChat: true,
})
}
// Set tab data
const isEmpty = options.promptText === undefined || options.promptText === ''
this.mynahUI.updateStore(
affectedTabId,
this.tabDataGenerator.getTabData(options.tabType, isEmpty, options.taskName)
)

if (affectedTabId === undefined) {
this.mynahUI.notify({
content: uiComponentsTexts.noMoreTabsTooltip,
type: NotificationType.WARNING,
})
return
} else {
this.tabsStorage.updateTabTypeFromUnknown(affectedTabId, 'testgen')
this.connector.onKnownTabOpen(affectedTabId)
this.connector.onUpdateTabType(affectedTabId)
// Disable chat prompt while loading
this.mynahUI.updateStore(affectedTabId, {
loadingChat: true,
})

// reset chat history
this.mynahUI.updateStore(affectedTabId, {
chatItems: [],
})
// Run the callback for the new tab
options.onNewTab(affectedTabId)
}

// creating a new tab and printing some title
this.mynahUI.updateStore(
affectedTabId,
this.tabDataGenerator.getTabData('testgen', realPromptText === '', 'Q - Test')
)
private handleScanCommand(tabID: string, eventId: string | undefined) {
this.handleSpecializedTabCommand({
tabID,
eventId,
isEnabled: this.isScanEnabled,
tabType: 'review',
existingTabType: 'review',
onExistingTab: (tabId) => {
this.connector.scans(tabId)
},
onNewTab: (tabId) => {
this.connector.scans(tabId)
},
})
}

this.connector.startTestGen(affectedTabId, realPromptText)
}
private handleTestCommand(chatPrompt: ChatPrompt, tabID: string, eventId: string | undefined) {
const realPromptText = chatPrompt.escapedPrompt?.trim() ?? ''

this.handleSpecializedTabCommand({
tabID,
eventId,
isEnabled: this.isTestEnabled,
tabType: 'testgen',
existingTabType: 'testgen',
taskName: 'Q - Test',
promptText: realPromptText,
onExistingTab: (tabId) => {
this.connector.startTestGen(tabId, realPromptText)
},
onNewTab: (tabId) => {
this.connector.startTestGen(tabId, realPromptText)
},
})
}

private handleCommand(props: HandleCommandProps) {
Expand Down Expand Up @@ -272,7 +287,6 @@ export class QuickActionHandler {

this.mynahUI.updateStore(affectedTabId, {
loadingChat: true,
cancelButtonWhenLoading: false,
promptInputDisabledState: true,
})

Expand All @@ -286,60 +300,19 @@ export class QuickActionHandler {
}

private handleGumbyCommand(tabID: string, eventId: string | undefined) {
if (!this.isGumbyEnabled) {
return
}

let gumbyTabId: string | undefined = undefined

for (const tab of this.tabsStorage.getTabs()) {
if (tab.type === 'gumby') {
gumbyTabId = tab.id
}
}

if (gumbyTabId !== undefined) {
this.mynahUI.selectTab(gumbyTabId, eventId || '')
this.connector.onTabChange(gumbyTabId)
return
}

let affectedTabId: string | undefined = tabID
// if there is no gumby tab, open a new one
const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type
if (currentTabType !== 'unknown' && currentTabType !== 'welcome') {
affectedTabId = this.mynahUI.updateStore('', {
loadingChat: true,
cancelButtonWhenLoading: false,
})
}

if (affectedTabId === undefined) {
this.mynahUI.notify({
content: uiComponentsTexts.noMoreTabsTooltip,
type: NotificationType.WARNING,
})
return
} else {
this.tabsStorage.updateTabTypeFromUnknown(affectedTabId, 'gumby')
this.connector.onKnownTabOpen(affectedTabId)
this.connector.onUpdateTabType(affectedTabId)

// reset chat history
this.mynahUI.updateStore(affectedTabId, {
chatItems: [],
})

this.mynahUI.updateStore(affectedTabId, this.tabDataGenerator.getTabData('gumby', true, undefined))

// disable chat prompt
this.mynahUI.updateStore(affectedTabId, {
loadingChat: true,
cancelButtonWhenLoading: false,
})

this.connector.transform(affectedTabId)
}
this.handleSpecializedTabCommand({
tabID,
eventId,
isEnabled: this.isGumbyEnabled,
tabType: 'gumby',
existingTabType: 'gumby',
onExistingTab: () => {
// Nothing special to do for existing transform tab
},
onNewTab: (tabId) => {
this.connector.transform(tabId)
},
})
}

private handleClearCommand(tabID: string) {
Expand Down