diff --git a/.changes/next-release/feature-6de3f384-aa3b-47fe-b895-d41ef23ed6da.json b/.changes/next-release/feature-6de3f384-aa3b-47fe-b895-d41ef23ed6da.json new file mode 100644 index 00000000000..b6509a913ff --- /dev/null +++ b/.changes/next-release/feature-6de3f384-aa3b-47fe-b895-d41ef23ed6da.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "Support for Amazon Q Builder ID paid tier" +} \ No newline at end of file diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/resources/META-INF/plugin-codewhisperer.xml b/plugins/amazonq/codewhisperer/jetbrains-community/resources/META-INF/plugin-codewhisperer.xml index 6a2088d39c0..7fdcf371ad4 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/resources/META-INF/plugin-codewhisperer.xml +++ b/plugins/amazonq/codewhisperer/jetbrains-community/resources/META-INF/plugin-codewhisperer.xml @@ -139,5 +139,7 @@ class="software.aws.toolkits.jetbrains.services.cwc.commands.codescan.actions.CodeScanCompleteAction" /> + diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/explorer/QStatusBarLoggedInActionGroup.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/explorer/QStatusBarLoggedInActionGroup.kt index 3dd88d45d22..53f6fe82b2d 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/explorer/QStatusBarLoggedInActionGroup.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/explorer/QStatusBarLoggedInActionGroup.kt @@ -12,15 +12,12 @@ import com.intellij.openapi.project.Project import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.actions.SsoLogoutAction -import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.core.credentials.sono.isSono -import software.aws.toolkits.jetbrains.services.amazonq.actions.QSwitchProfilesAction import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileManager import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererConnectOnGithubAction import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererLearnMoreAction import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererProvideFeedbackAction -import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererShowSettingsAction import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.actions.CodeWhispererCodeScanRunAction import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.actions.ActionProvider import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.actions.Customize @@ -54,6 +51,7 @@ class QStatusBarLoggedInActionGroup : DefaultActionGroup() { override fun getChildren(e: AnActionEvent?) = e?.project?.let { val isPendingActiveProfile = QRegionProfileManager.getInstance().hasValidConnectionButNoActiveProfile(it) + val actionManager = ActionManager.getInstance() buildList { if (!isPendingActiveProfile) { addAll(buildActionListForActiveProfileSelected(it, actionProvider)) @@ -64,15 +62,18 @@ class QStatusBarLoggedInActionGroup : DefaultActionGroup() { addAll(buildActionListForConnectHelp(actionProvider)) add(Separator.create()) - add(CodeWhispererShowSettingsAction()) - ( - ToolkitConnectionManager.getInstance(it).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection - )?.takeIf { !it.isSono() } - ?.let { add(QSwitchProfilesAction()) } - ToolkitConnectionManager.getInstance(it).activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let { c -> - (c as? AwsBearerTokenConnection)?.let { connection -> - add(SsoLogoutAction(connection)) + add(actionManager.getAction("codewhisperer.settings")) + + val connection = ToolkitConnectionManager.getInstance(it).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection + + if (connection != null) { + if (!connection.isSono()) { + add(actionManager.getAction("codewhisperer.switchProfiles")) + } else { + add(actionManager.getAction("q.manage.subscription")) } + + add(SsoLogoutAction(connection)) } }.toTypedArray() }.orEmpty() diff --git a/plugins/amazonq/shared/jetbrains-community/resources/software/aws/toolkits/resources/AmazonQBundle.properties b/plugins/amazonq/shared/jetbrains-community/resources/software/aws/toolkits/resources/AmazonQBundle.properties index ab7face28d9..2a1fb1068ed 100644 --- a/plugins/amazonq/shared/jetbrains-community/resources/software/aws/toolkits/resources/AmazonQBundle.properties +++ b/plugins/amazonq/shared/jetbrains-community/resources/software/aws/toolkits/resources/AmazonQBundle.properties @@ -9,6 +9,7 @@ amazonqInlineChat.popup.title=Enter Instructions for Q amazonq.refresh.panel=Refresh Chat Session amazonq.title=Amazon Q amazonq.workspace.settings.open.prompt=Workspace index is now enabled. You can disable it from Amazon Q settings. +action.q.manage.subscription.text=Manage Subscription action.q.profile.usage.text=You changed your profile action.q.profile.usage=You''re using the ''{0}'' profile for Amazon Q. action.q.switchProfiles.text=Change Profile diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/actions/ManageSubscription.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/actions/ManageSubscription.kt new file mode 100644 index 00000000000..10568619c64 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/actions/ManageSubscription.kt @@ -0,0 +1,58 @@ +// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.codewhisperer.actions + +import com.intellij.openapi.actionSystem.ActionUpdateThread +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.progress.currentThreadCoroutineScope +import com.intellij.openapi.project.DumbAware +import kotlinx.coroutines.future.await +import kotlinx.coroutines.launch +import org.eclipse.lsp4j.ExecuteCommandParams +import software.aws.toolkits.core.utils.error +import software.aws.toolkits.core.utils.getLogger +import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection +import software.aws.toolkits.jetbrains.core.credentials.sono.isSono +import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService + +class ManageSubscription : AnAction(), DumbAware { + override fun getActionUpdateThread() = ActionUpdateThread.BGT + + override fun update(e: AnActionEvent) { + val project = e.project + // disable if user is IdC + if (project == null) { + e.presentation.isEnabledAndVisible = false + } else { + val connection = ToolkitConnectionManager.getInstance(project) + .activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection + + e.presentation.isEnabledAndVisible = connection.isSono() + } + } + + override fun actionPerformed(e: AnActionEvent) { + val project = e.project ?: return + currentThreadCoroutineScope().launch { + AmazonQLspService.getInstance(project).execute { lsp -> + lsp.workspaceService.executeCommand( + ExecuteCommandParams().apply { + this.command = "aws/chat/manageSubscription" + } + ) + }.handleAsync { _, ex -> + if (ex != null) { + LOG.error(ex) { "Failed aws/chat/manageSubscription" } + } + }.await() + } + } + + companion object { + private val LOG = getLogger() + } +} diff --git a/plugins/core/webview/src/q-ui/components/qOptions.vue b/plugins/core/webview/src/q-ui/components/qOptions.vue index 0903d22b17d..3fe29b5efd7 100644 --- a/plugins/core/webview/src/q-ui/components/qOptions.vue +++ b/plugins/core/webview/src/q-ui/components/qOptions.vue @@ -26,8 +26,8 @@ :isSelected="selectedLoginOption === LoginOption.BUILDER_ID" :itemId="LoginOption.BUILDER_ID" :login-type="LoginOption.BUILDER_ID" - :itemTitle="'Use for free'" - :itemText="'No AWS account required'" + :itemTitle="'Personal account'" + :itemText="'Best for personal use. Free to start with a Builder ID'" class="font-amazon bottom-small-gap" > @@ -37,7 +37,8 @@ :isSelected="selectedLoginOption === LoginOption.ENTERPRISE_SSO" :itemId="LoginOption.ENTERPRISE_SSO" :login-type="LoginOption.ENTERPRISE_SSO" - :itemTitle="'Use with Pro license'" + :itemTitle="'Company account'" + :itemText="'Best for individual teams or organizations'" class="font-amazon bottom-small-gap" >