diff --git a/plugins/agent-workbench/claude/common/resources/intellij.agent.workbench.claude.common.xml b/plugins/agent-workbench/claude/common/resources/intellij.agent.workbench.claude.common.xml
index e9f4a7dec93a..36f681611254 100644
--- a/plugins/agent-workbench/claude/common/resources/intellij.agent.workbench.claude.common.xml
+++ b/plugins/agent-workbench/claude/common/resources/intellij.agent.workbench.claude.common.xml
@@ -1 +1,7 @@
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/agent-workbench/codex/sessions/resources/intellij.agent.workbench.codex.sessions.xml b/plugins/agent-workbench/codex/sessions/resources/intellij.agent.workbench.codex.sessions.xml
index 19b56a701603..6bd8b4c35969 100644
--- a/plugins/agent-workbench/codex/sessions/resources/intellij.agent.workbench.codex.sessions.xml
+++ b/plugins/agent-workbench/codex/sessions/resources/intellij.agent.workbench.codex.sessions.xml
@@ -2,6 +2,7 @@
+
diff --git a/plugins/agent-workbench/json/BUILD.bazel b/plugins/agent-workbench/json/BUILD.bazel
index f8accde5a1ec..abee59dd1dc4 100644
--- a/plugins/agent-workbench/json/BUILD.bazel
+++ b/plugins/agent-workbench/json/BUILD.bazel
@@ -1,11 +1,18 @@
### auto-generated section `build intellij.agent.workbench.json` start
-load("@rules_jvm//:jvm.bzl", "jvm_library")
+load("@rules_jvm//:jvm.bzl", "jvm_library", "resourcegroup")
+
+resourcegroup(
+ name = "json_resources",
+ srcs = glob(["resources/**/*"]),
+ strip_prefix = "resources"
+)
jvm_library(
name = "json",
module_name = "intellij.agent.workbench.json",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True),
+ resources = [":json_resources"],
deps = [
"@lib//:kotlin-stdlib",
"//libraries/jackson/jackson",
diff --git a/plugins/agent-workbench/json/intellij.agent.workbench.json.iml b/plugins/agent-workbench/json/intellij.agent.workbench.json.iml
index 31be22a62084..03d91ce79088 100644
--- a/plugins/agent-workbench/json/intellij.agent.workbench.json.iml
+++ b/plugins/agent-workbench/json/intellij.agent.workbench.json.iml
@@ -3,6 +3,7 @@
+
diff --git a/plugins/agent-workbench/json/resources/intellij.agent.workbench.json.xml b/plugins/agent-workbench/json/resources/intellij.agent.workbench.json.xml
new file mode 100644
index 000000000000..6fb76a66265d
--- /dev/null
+++ b/plugins/agent-workbench/json/resources/intellij.agent.workbench.json.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/plugins/agent-workbench/plugin/plugin-content.yaml b/plugins/agent-workbench/plugin/plugin-content.yaml
index 0d0687416c1f..79e720c1c158 100644
--- a/plugins/agent-workbench/plugin/plugin-content.yaml
+++ b/plugins/agent-workbench/plugin/plugin-content.yaml
@@ -16,6 +16,9 @@
- name: lib/modules/intellij.agent.workbench.codex.sessions.jar
contentModules:
- name: intellij.agent.workbench.codex.sessions
+- name: lib/modules/intellij.agent.workbench.json.jar
+ contentModules:
+ - name: intellij.agent.workbench.json
- name: lib/modules/intellij.agent.workbench.sessions.jar
contentModules:
- - name: intellij.agent.workbench.sessions
+ - name: intellij.agent.workbench.sessions
\ No newline at end of file
diff --git a/plugins/agent-workbench/plugin/resources/META-INF/plugin.xml b/plugins/agent-workbench/plugin/resources/META-INF/plugin.xml
index 3326c1aacb72..0b4a06509422 100644
--- a/plugins/agent-workbench/plugin/resources/META-INF/plugin.xml
+++ b/plugins/agent-workbench/plugin/resources/META-INF/plugin.xml
@@ -5,6 +5,7 @@
Agent Workbench - AI-based developement for IntelliJ
JetBrains
+
diff --git a/plugins/agent-workbench/sessions/resources/intellij.agent.workbench.sessions.xml b/plugins/agent-workbench/sessions/resources/intellij.agent.workbench.sessions.xml
index 65c2c98c28a5..7dd14fd8a30f 100644
--- a/plugins/agent-workbench/sessions/resources/intellij.agent.workbench.sessions.xml
+++ b/plugins/agent-workbench/sessions/resources/intellij.agent.workbench.sessions.xml
@@ -39,6 +39,7 @@
+
-
+
\ No newline at end of file
diff --git a/plugins/agent-workbench/sessions/resources/messages/AgentSessionsBundle.properties b/plugins/agent-workbench/sessions/resources/messages/AgentSessionsBundle.properties
index cc0f571ee98a..d8e42722c9c8 100644
--- a/plugins/agent-workbench/sessions/resources/messages/AgentSessionsBundle.properties
+++ b/plugins/agent-workbench/sessions/resources/messages/AgentSessionsBundle.properties
@@ -23,6 +23,7 @@ toolwindow.provider.codex=Codex
toolwindow.provider.claude=Claude
action.AgentWorkbenchSessions.Refresh.text=Refresh
action.AgentWorkbenchSessions.ToggleDedicatedFrame.text=Open Chat in Dedicated Frame
+action.AgentWorkbenchSessions.ToggleClaudeQuotaWidget.text=Show Claude Usage in Status Bar
action.AgentWorkbenchSessions.ActivateWithProjectShortcut.text=Agent Threads
advanced.settings.agent.workbench=Agent Workbench
advanced.setting.agent.workbench.chat.open.in.dedicated.frame=Open Agent chat in dedicated frame
@@ -46,3 +47,7 @@ status.bar.claude.quota.display.name=Claude Usage
status.bar.claude.quota.text={0}% of {1}
status.bar.claude.quota.tooltip.session=Session (5h): {0}% \u2014 resets {1}
status.bar.claude.quota.tooltip.weekly=Weekly (7d): {0}% \u2014 resets {1}
+toolwindow.claude.quota.hint.title=See Claude usage in your status bar
+toolwindow.claude.quota.hint.body=Track 5h and 7d quota at a glance while you work.
+toolwindow.claude.quota.hint.enable=Enable
+toolwindow.claude.quota.hint.dismiss=Dismiss
diff --git a/plugins/agent-workbench/sessions/src/AgentSessionsService.kt b/plugins/agent-workbench/sessions/src/AgentSessionsService.kt
index 16674733dbb0..a88e3df1c5ca 100644
--- a/plugins/agent-workbench/sessions/src/AgentSessionsService.kt
+++ b/plugins/agent-workbench/sessions/src/AgentSessionsService.kt
@@ -541,6 +541,7 @@ internal class AgentSessionsService private constructor(
fun openChatThread(path: String, thread: AgentSessionThread, currentProject: Project? = null) {
val normalized = normalizePath(path)
val key = buildOpenThreadActionKey(path = normalized, thread = thread)
+ markClaudeQuotaHintEligible(thread.provider)
actionGate.launch(
scope = serviceScope,
key = key,
@@ -565,6 +566,7 @@ internal class AgentSessionsService private constructor(
fun openChatSubAgent(path: String, thread: AgentSessionThread, subAgent: AgentSubAgent, currentProject: Project? = null) {
val normalized = normalizePath(path)
val key = buildOpenSubAgentActionKey(path = normalized, thread = thread, subAgent = subAgent)
+ markClaudeQuotaHintEligible(thread.provider)
actionGate.launch(
scope = serviceScope,
key = key,
@@ -586,6 +588,7 @@ internal class AgentSessionsService private constructor(
) {
val normalized = normalizePath(path)
val key = buildCreateSessionActionKey(normalized, provider, mode)
+ markClaudeQuotaHintEligible(provider)
actionGate.launch(
scope = serviceScope,
key = key,
@@ -899,6 +902,13 @@ internal class AgentSessionsService private constructor(
return "$OPEN_PROJECT_ACTION_KEY_PREFIX:$path"
}
+ private fun markClaudeQuotaHintEligible(provider: AgentSessionProvider) {
+ if (provider != AgentSessionProvider.CLAUDE) {
+ return
+ }
+ service().markClaudeQuotaHintEligible()
+ }
+
private fun buildCreateSessionActionKey(path: String, provider: AgentSessionProvider, mode: AgentSessionLaunchMode): String {
return "$CREATE_SESSION_ACTION_KEY_PREFIX:$path:$provider:mode=$mode"
}
diff --git a/plugins/agent-workbench/sessions/src/AgentSessionsToggleClaudeQuotaWidgetAction.kt b/plugins/agent-workbench/sessions/src/AgentSessionsToggleClaudeQuotaWidgetAction.kt
new file mode 100644
index 000000000000..3bd2a0753b53
--- /dev/null
+++ b/plugins/agent-workbench/sessions/src/AgentSessionsToggleClaudeQuotaWidgetAction.kt
@@ -0,0 +1,17 @@
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.agent.workbench.sessions
+
+import com.intellij.agent.workbench.sessions.claude.ClaudeQuotaStatusBarWidgetSettings
+import com.intellij.openapi.actionSystem.ActionUpdateThread
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.project.DumbAwareToggleAction
+
+internal class AgentSessionsToggleClaudeQuotaWidgetAction : DumbAwareToggleAction() {
+ override fun isSelected(e: AnActionEvent): Boolean = ClaudeQuotaStatusBarWidgetSettings.isEnabled()
+
+ override fun setSelected(e: AnActionEvent, state: Boolean) {
+ ClaudeQuotaStatusBarWidgetSettings.setEnabled(state)
+ }
+
+ override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
+}
diff --git a/plugins/agent-workbench/sessions/src/AgentSessionsToolWindow.kt b/plugins/agent-workbench/sessions/src/AgentSessionsToolWindow.kt
index 896428c5abd0..9fbe2800d9a9 100644
--- a/plugins/agent-workbench/sessions/src/AgentSessionsToolWindow.kt
+++ b/plugins/agent-workbench/sessions/src/AgentSessionsToolWindow.kt
@@ -3,11 +3,14 @@ package com.intellij.agent.workbench.sessions
// @spec community/plugins/agent-workbench/spec/agent-sessions.spec.md
// @spec community/plugins/agent-workbench/spec/agent-sessions-thread-visibility.spec.md
+import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
@@ -15,12 +18,17 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.unit.dp
import com.intellij.agent.workbench.chat.AgentChatTabSelectionService
+import com.intellij.agent.workbench.sessions.claude.ClaudeQuotaStatusBarWidgetSettings
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
+import kotlinx.coroutines.delay
import org.jetbrains.jewel.foundation.theme.JewelTheme
+import org.jetbrains.jewel.ui.component.OutlinedButton
import org.jetbrains.jewel.ui.component.Text
+import kotlin.time.Duration.Companion.seconds
@Composable
internal fun agentSessionsToolWindow(currentProject: Project) {
@@ -30,11 +38,27 @@ internal fun agentSessionsToolWindow(currentProject: Project) {
val state by service.state.collectAsState()
val selectedChatTab by chatSelectionService.selectedChatTab.collectAsState()
val lastUsedProvider by uiStateService.lastUsedProviderFlow.collectAsState()
+ val claudeQuotaHintEligible by uiStateService.claudeQuotaHintEligibleFlow.collectAsState()
+ val claudeQuotaHintAcknowledged by uiStateService.claudeQuotaHintAcknowledgedFlow.collectAsState()
+ val isClaudeQuotaWidgetEnabled by ClaudeQuotaStatusBarWidgetSettings.enabledFlow.collectAsState()
LaunchedEffect(Unit) {
service.refresh()
}
+ LaunchedEffect(Unit) {
+ while (true) {
+ ClaudeQuotaStatusBarWidgetSettings.syncEnabledState()
+ delay(1.seconds)
+ }
+ }
+
+ LaunchedEffect(claudeQuotaHintEligible, claudeQuotaHintAcknowledged, isClaudeQuotaWidgetEnabled) {
+ if (claudeQuotaHintEligible && !claudeQuotaHintAcknowledged && isClaudeQuotaWidgetEnabled) {
+ uiStateService.acknowledgeClaudeQuotaHint()
+ }
+ }
+
LaunchedEffect(selectedChatTab, state.projects) {
val currentSelection = selectedChatTab ?: return@LaunchedEffect
val identity = parseAgentSessionIdentity(currentSelection.threadIdentity) ?: return@LaunchedEffect
@@ -66,6 +90,14 @@ internal fun agentSessionsToolWindow(currentProject: Project) {
visibleThreadCounts = state.visibleThreadCounts,
onShowMoreThreads = { path -> service.showMoreThreads(path) },
selectedTreeId = selectedTreeId,
+ showClaudeQuotaHint = claudeQuotaHintEligible && !claudeQuotaHintAcknowledged && !isClaudeQuotaWidgetEnabled,
+ onEnableClaudeQuotaWidget = {
+ ClaudeQuotaStatusBarWidgetSettings.setEnabled(true)
+ uiStateService.acknowledgeClaudeQuotaHint()
+ },
+ onDismissClaudeQuotaHint = {
+ uiStateService.acknowledgeClaudeQuotaHint()
+ },
)
}
@@ -86,6 +118,9 @@ internal fun agentSessionsToolWindowContent(
visibleThreadCounts: Map = emptyMap(),
onShowMoreThreads: (String) -> Unit = {},
selectedTreeId: SessionTreeId? = null,
+ showClaudeQuotaHint: Boolean = false,
+ onEnableClaudeQuotaWidget: () -> Unit = {},
+ onDismissClaudeQuotaHint: () -> Unit = {},
) {
Column(
modifier = Modifier
@@ -93,6 +128,13 @@ internal fun agentSessionsToolWindowContent(
.padding(horizontal = 10.dp, vertical = 12.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
) {
+ if (showClaudeQuotaHint) {
+ claudeQuotaHintBanner(
+ onEnableClaudeQuotaWidget = onEnableClaudeQuotaWidget,
+ onDismiss = onDismissClaudeQuotaHint,
+ )
+ }
+
when {
state.projects.isEmpty() -> emptyState(isLoading = state.lastUpdatedAt == null)
else -> sessionTree(
@@ -116,6 +158,44 @@ internal fun agentSessionsToolWindowContent(
}
}
+@Composable
+private fun claudeQuotaHintBanner(
+ onEnableClaudeQuotaWidget: () -> Unit,
+ onDismiss: () -> Unit,
+) {
+ val shape = RoundedCornerShape(8.dp)
+ val borderColor = JewelTheme.globalColors.borders.normal
+ .takeOrElse { JewelTheme.globalColors.text.disabled }
+ .copy(alpha = 0.35f)
+ val bodyColor = JewelTheme.globalColors.text.normal.copy(alpha = 0.84f)
+
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .border(width = 1.dp, color = borderColor, shape = shape)
+ .padding(10.dp),
+ verticalArrangement = Arrangement.spacedBy(6.dp),
+ ) {
+ Text(
+ text = AgentSessionsBundle.message("toolwindow.claude.quota.hint.title"),
+ style = AgentSessionsTextStyles.projectTitle(),
+ )
+ Text(
+ text = AgentSessionsBundle.message("toolwindow.claude.quota.hint.body"),
+ style = AgentSessionsTextStyles.threadTitle(),
+ color = bodyColor,
+ )
+ Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
+ OutlinedButton(onClick = onEnableClaudeQuotaWidget) {
+ Text(AgentSessionsBundle.message("toolwindow.claude.quota.hint.enable"))
+ }
+ OutlinedButton(onClick = onDismiss) {
+ Text(AgentSessionsBundle.message("toolwindow.claude.quota.hint.dismiss"))
+ }
+ }
+ }
+}
+
@Composable
private fun emptyState(isLoading: Boolean) {
val messageKey = if (isLoading) "toolwindow.loading" else "toolwindow.empty.global"
diff --git a/plugins/agent-workbench/sessions/src/AgentSessionsTreeUiStateService.kt b/plugins/agent-workbench/sessions/src/AgentSessionsTreeUiStateService.kt
index af8c076a1bc2..4b663ce029b7 100644
--- a/plugins/agent-workbench/sessions/src/AgentSessionsTreeUiStateService.kt
+++ b/plugins/agent-workbench/sessions/src/AgentSessionsTreeUiStateService.kt
@@ -114,6 +114,10 @@ internal class AgentSessionsTreeUiStateService
private val _lastUsedProviderFlow = MutableStateFlow(getLastUsedProvider())
val lastUsedProviderFlow: StateFlow = _lastUsedProviderFlow.asStateFlow()
+ private val _claudeQuotaHintEligibleFlow = MutableStateFlow(state.claudeQuotaHintEligible)
+ val claudeQuotaHintEligibleFlow: StateFlow = _claudeQuotaHintEligibleFlow.asStateFlow()
+ private val _claudeQuotaHintAcknowledgedFlow = MutableStateFlow(state.claudeQuotaHintAcknowledged)
+ val claudeQuotaHintAcknowledgedFlow: StateFlow = _claudeQuotaHintAcknowledgedFlow.asStateFlow()
override fun isProjectCollapsed(path: String): Boolean {
return normalizeSessionsProjectPath(path) in state.collapsedProjectPaths
@@ -240,9 +244,23 @@ internal class AgentSessionsTreeUiStateService
_lastUsedProviderFlow.value = provider
}
+ fun markClaudeQuotaHintEligible() {
+ if (state.claudeQuotaHintEligible) return
+ updateState { it.copy(claudeQuotaHintEligible = true) }
+ _claudeQuotaHintEligibleFlow.value = true
+ }
+
+ fun acknowledgeClaudeQuotaHint() {
+ if (state.claudeQuotaHintAcknowledged) return
+ updateState { it.copy(claudeQuotaHintAcknowledged = true) }
+ _claudeQuotaHintAcknowledgedFlow.value = true
+ }
+
override fun loadState(state: SessionsTreeUiStateState) {
super.loadState(state)
_lastUsedProviderFlow.value = state.lastUsedProvider?.let(AgentSessionProvider::fromOrNull)
+ _claudeQuotaHintEligibleFlow.value = state.claudeQuotaHintEligible
+ _claudeQuotaHintAcknowledgedFlow.value = state.claudeQuotaHintAcknowledged
}
@Serializable
@@ -251,6 +269,8 @@ internal class AgentSessionsTreeUiStateService
@JvmField val visibleThreadCountByProject: Map = emptyMap(),
@JvmField val openProjectThreadPreviewsByProject: Map> = emptyMap(),
@JvmField val lastUsedProvider: String? = null,
+ @JvmField val claudeQuotaHintEligible: Boolean = false,
+ @JvmField val claudeQuotaHintAcknowledged: Boolean = false,
)
@Serializable
diff --git a/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidget.kt b/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidget.kt
index 483e342dddea..76f6ed28a122 100644
--- a/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidget.kt
+++ b/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidget.kt
@@ -26,17 +26,17 @@ import javax.swing.JPanel
import javax.swing.JProgressBar
import javax.swing.Timer
-private const val WIDGET_ID = "claude.quota"
+internal const val CLAUDE_QUOTA_WIDGET_ID = "claude.quota"
private const val UI_REFRESH_INTERVAL_MS = 5_000
private const val UI_REFRESH_INITIAL_DELAY_MS = 1_000
private const val WARNING_QUOTA_PERCENT = 80
internal class ClaudeQuotaStatusBarWidgetFactory : StatusBarWidgetFactory {
- override fun getId(): String = WIDGET_ID
+ override fun getId(): String = CLAUDE_QUOTA_WIDGET_ID
override fun getDisplayName(): String = AgentSessionsBundle.message("status.bar.claude.quota.display.name")
- override fun isEnabledByDefault(): Boolean = true
+ override fun isEnabledByDefault(): Boolean = false
override fun createWidget(project: Project): StatusBarWidget = ClaudeQuotaStatusBarWidget()
}
@@ -62,7 +62,7 @@ internal class ClaudeQuotaStatusBarWidget : CustomStatusBarWidget, Activatable {
override fun getPresentation(): StatusBarWidget.WidgetPresentation? = null
- override fun ID(): String = WIDGET_ID
+ override fun ID(): String = CLAUDE_QUOTA_WIDGET_ID
override fun getComponent(): JComponent = myComponent.get()
diff --git a/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidgetSettings.kt b/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidgetSettings.kt
new file mode 100644
index 000000000000..cae868390e4e
--- /dev/null
+++ b/plugins/agent-workbench/sessions/src/claude/ClaudeQuotaStatusBarWidgetSettings.kt
@@ -0,0 +1,48 @@
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.agent.workbench.sessions.claude
+
+import com.intellij.openapi.components.service
+import com.intellij.openapi.project.ProjectManager
+import com.intellij.openapi.wm.StatusBarWidgetFactory
+import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetSettings
+import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+internal object ClaudeQuotaStatusBarWidgetSettings {
+ private val _enabledFlow = MutableStateFlow(readEnabledFromSettings())
+ val enabledFlow: StateFlow = _enabledFlow.asStateFlow()
+
+ fun isEnabled(): Boolean {
+ syncEnabledState()
+ return _enabledFlow.value
+ }
+
+ fun syncEnabledState() {
+ _enabledFlow.value = readEnabledFromSettings()
+ }
+
+ fun setEnabled(enabled: Boolean) {
+ val factory = findFactory() ?: return
+ val settings = StatusBarWidgetSettings.getInstance()
+ if (settings.isEnabled(factory) == enabled) {
+ return
+ }
+
+ settings.setEnabled(factory, enabled)
+ for (project in ProjectManager.getInstance().openProjects) {
+ project.service().updateWidget(factory)
+ }
+ _enabledFlow.value = enabled
+ }
+
+ private fun readEnabledFromSettings(): Boolean {
+ val factory = findFactory() ?: return false
+ return StatusBarWidgetSettings.getInstance().isEnabled(factory)
+ }
+
+ private fun findFactory(): StatusBarWidgetFactory? {
+ return StatusBarWidgetFactory.EP_NAME.extensionList.firstOrNull { it.id == CLAUDE_QUOTA_WIDGET_ID }
+ }
+}
diff --git a/plugins/agent-workbench/sessions/testSrc/AgentSessionsClaudeQuotaWidgetActionRegistrationTest.kt b/plugins/agent-workbench/sessions/testSrc/AgentSessionsClaudeQuotaWidgetActionRegistrationTest.kt
new file mode 100644
index 000000000000..5a9e0b4e0f62
--- /dev/null
+++ b/plugins/agent-workbench/sessions/testSrc/AgentSessionsClaudeQuotaWidgetActionRegistrationTest.kt
@@ -0,0 +1,18 @@
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.agent.workbench.sessions
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+
+class AgentSessionsClaudeQuotaWidgetActionRegistrationTest {
+ @Test
+ fun gearActionsContainClaudeQuotaWidgetToggle() {
+ val descriptor = checkNotNull(javaClass.classLoader.getResource("intellij.agent.workbench.sessions.xml")) {
+ "Module descriptor intellij.agent.workbench.sessions.xml is missing"
+ }.readText()
+
+ assertThat(descriptor)
+ .contains("")
+ .contains("