diff --git a/.idea/modules.xml b/.idea/modules.xml
index 0b9e4fa1a489..a73dfb43345a 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -47,8 +47,6 @@
-
-
@@ -1234,17 +1232,6 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/BUILD.bazel b/BUILD.bazel
index f78b851b4e41..3d8f82839a16 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -876,18 +876,6 @@ jvm_library(
"//plugins/lombok:lombok-tests_test_lib",
"//platform/util/concurrency:concurrency-tests",
"//platform/util/concurrency:concurrency-tests_test_lib",
- "//plugins/agent-workbench/lib-agent/cli:ai-agent-cli-tests",
- "//plugins/agent-workbench/lib-agent/cli:ai-agent-cli-tests_test_lib",
- "//plugins/agent-workbench/lib-agent/common:ai-agent-common-tests",
- "//plugins/agent-workbench/lib-agent/common:ai-agent-common-tests_test_lib",
- "//plugins/agent-workbench/lib-agent/core:ai-agent-core-tests",
- "//plugins/agent-workbench/lib-agent/core:ai-agent-core-tests_test_lib",
- "//plugins/agent-workbench/lib-agent/filewatch:ai-agent-filewatch-tests",
- "//plugins/agent-workbench/lib-agent/filewatch:ai-agent-filewatch-tests_test_lib",
- "//plugins/agent-workbench/lib-agent/json:ai-agent-json-tests",
- "//plugins/agent-workbench/lib-agent/json:ai-agent-json-tests_test_lib",
- "//plugins/agent-workbench/prompt/core:agent-workbench-prompt-core-tests",
- "//plugins/agent-workbench/prompt/core:agent-workbench-prompt-core-tests_test_lib",
"//plugins/ant:ant-tests",
"//plugins/ant:ant-tests_test_lib",
"//plugins/commander:commander-tests",
diff --git a/build/bazel-generated-file-list.txt b/build/bazel-generated-file-list.txt
index 8db5548f4850..3f69d602d0c4 100644
--- a/build/bazel-generated-file-list.txt
+++ b/build/bazel-generated-file-list.txt
@@ -979,13 +979,6 @@ plugins/ByteCodeViewer
plugins/IntelliLang
plugins/IntelliLang/backend
plugins/IntelliLang/tests
-plugins/agent-workbench/lib-agent/cli
-plugins/agent-workbench/lib-agent/common
-plugins/agent-workbench/lib-agent/core
-plugins/agent-workbench/lib-agent/filewatch
-plugins/agent-workbench/lib-agent/json
-plugins/agent-workbench/lib-agent/sessions-core
-plugins/agent-workbench/prompt/core
plugins/ant
plugins/ant/jps-plugin
plugins/built-in-help
diff --git a/intellij.idea.community.main.tests.iml b/intellij.idea.community.main.tests.iml
index 65beec42f43a..3702ea85f94f 100644
--- a/intellij.idea.community.main.tests.iml
+++ b/intellij.idea.community.main.tests.iml
@@ -138,12 +138,6 @@
-
-
-
-
-
-
diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt
index 1089e25a522a..74df2a4ec490 100644
--- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt
+++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt
@@ -1489,12 +1489,6 @@ private suspend fun publishTestDiscovery(messages: BuildMessages, file: String?)
private val COMMUNITY_AGGREGATOR_BAZEL_MIGRATED_MODULES = listOf(
"intellij.maven.server.eventListener.tests",
"intellij.agent.workbench.chat.tests",
- "intellij.platform.ai.agent.cli.tests",
- "intellij.platform.ai.agent.common.tests",
- "intellij.platform.ai.agent.core.tests",
- "intellij.platform.ai.agent.filewatch.tests",
- "intellij.platform.ai.agent.json.tests",
- "intellij.agent.workbench.prompt.core.tests",
"intellij.ant.tests",
"intellij.commander.tests",
"intellij.completionMlRanking.tests",
diff --git a/plugins/agent-workbench/lib-agent/cli/BUILD.bazel b/plugins/agent-workbench/lib-agent/cli/BUILD.bazel
deleted file mode 100644
index d1e2f9cb691b..000000000000
--- a/plugins/agent-workbench/lib-agent/cli/BUILD.bazel
+++ /dev/null
@@ -1,133 +0,0 @@
-load("@community//build:tests-options.bzl", "jps_test")
-load("@rules_jvm//:jvm.bzl", "jvm_library")
-
-### auto-generated section `build intellij.platform.ai.agent.cli` start
-
-jvm_library(
- name = "cli",
- srcs = glob(
- [
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/*.form",
- ],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.cli",
- resource_strip_prefix = "resources",
- resources = glob(
- ["resources/**/*"],
- ),
- visibility = ["//visibility:public"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//platform/core-api:core",
- "//platform/util",
- "//platform/platform-util-io:ide-util-io",
- "//platform/eel",
- "//platform/eel-provider",
- "//plugins/terminal",
- ],
-)
-
-jvm_library(
- name = "cli_test_lib",
- testonly = True,
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.cli",
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":cli",
- "//platform/core-api:core_test_lib",
- "//platform/util:util_test_lib",
- "//platform/platform-util-io:ide-util-io_test_lib",
- "//platform/eel:eel_test_lib",
- "//platform/eel-provider:eel-provider_test_lib",
- "//plugins/terminal:terminal_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.cli` end
-
-### auto-generated section `iml intellij.platform.ai.agent.cli` start
-exports_files(
- [
- "intellij.platform.ai.agent.cli.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.cli` end
-
-### auto-generated section `build intellij.platform.ai.agent.cli.tests` start
-
-jvm_library(
- name = "ai-agent-cli-tests",
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.cli.tests",
- visibility = ["//visibility:public"],
-)
-
-jvm_library(
- name = "ai-agent-cli-tests_test_lib",
- testonly = True,
- srcs = glob(
- [
- "testSrc/**/*.kt",
- "testSrc/**/*.java",
- "testSrc/**/*.form",
- ],
- allow_empty = True,
- ),
- associates = [
- "//plugins/agent-workbench/lib-agent/cli",
- "//plugins/agent-workbench/lib-agent/cli:cli_test_lib",
- ],
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":ai-agent-cli-tests",
- "//platform/platform-util-io:ide-util-io_test_lib",
- ],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//libraries/kotlinx/coroutines/core",
- "//libraries/kotlinx/coroutines/core:core_test_lib",
- "//platform/core-api:core",
- "//platform/core-api:core_test_lib",
- "//platform/util",
- "//platform/util:util_test_lib",
- "//platform/platform-util-io:ide-util-io",
- "//plugins/terminal",
- "//plugins/terminal:terminal_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.cli.tests` end
-
-### auto-generated section `iml intellij.platform.ai.agent.cli.tests` start
-exports_files(
- [
- "intellij.platform.ai.agent.cli.tests.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.cli.tests` end
-
-### auto-generated section `test intellij.platform.ai.agent.cli.tests` start
-
-jps_test(
- name = "ai-agent-cli-tests_test",
- runtime_deps = [":ai-agent-cli-tests_test_lib"],
-)
-### auto-generated section `test intellij.platform.ai.agent.cli.tests` end
diff --git a/plugins/agent-workbench/lib-agent/cli/api-dump.txt b/plugins/agent-workbench/lib-agent/cli/api-dump.txt
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/plugins/agent-workbench/lib-agent/cli/intellij.platform.ai.agent.cli.iml b/plugins/agent-workbench/lib-agent/cli/intellij.platform.ai.agent.cli.iml
deleted file mode 100644
index 9ca02a22f06f..000000000000
--- a/plugins/agent-workbench/lib-agent/cli/intellij.platform.ai.agent.cli.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/cli/intellij.platform.ai.agent.cli.tests.iml b/plugins/agent-workbench/lib-agent/cli/intellij.platform.ai.agent.cli.tests.iml
deleted file mode 100644
index e82df67b6861..000000000000
--- a/plugins/agent-workbench/lib-agent/cli/intellij.platform.ai.agent.cli.tests.iml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/cli/resources/intellij.platform.ai.agent.cli.xml b/plugins/agent-workbench/lib-agent/cli/resources/intellij.platform.ai.agent.cli.xml
deleted file mode 100644
index 54fcb179df89..000000000000
--- a/plugins/agent-workbench/lib-agent/cli/resources/intellij.platform.ai.agent.cli.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/plugins/agent-workbench/lib-agent/cli/src/AgentCliExecutableResolver.kt b/plugins/agent-workbench/lib-agent/cli/src/AgentCliExecutableResolver.kt
deleted file mode 100644
index b5c6fb69977c..000000000000
--- a/plugins/agent-workbench/lib-agent/cli/src/AgentCliExecutableResolver.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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.platform.ai.agent.cli
-
-import com.intellij.execution.configurations.PathEnvironmentVariableUtil
-import com.intellij.openapi.diagnostic.logger
-import com.intellij.openapi.progress.ProcessCanceledException
-import com.intellij.platform.eel.provider.LocalEelDescriptor
-import com.intellij.platform.eel.provider.toEelApi
-import kotlinx.coroutines.CancellationException
-import org.jetbrains.annotations.ApiStatus
-import org.jetbrains.plugins.terminal.agent.TerminalAgent
-import org.jetbrains.plugins.terminal.agent.TerminalAgentResolver
-import java.nio.file.Files
-import java.nio.file.Path
-
-private val LOG = logger()
-
-private class AgentCliExecutableResolverLogCategory
-
-@ApiStatus.Internal
-suspend fun resolveExecutableViaTerminalResolver(
- terminalAgent: TerminalAgent,
- binaryPathResolver: suspend (TerminalAgent) -> String? = ::resolveTerminalAgentBinaryPath,
-): String? {
- return try {
- binaryPathResolver(terminalAgent)
- }
- catch (e: CancellationException) {
- throw e
- }
- catch (e: ProcessCanceledException) {
- throw e
- }
- catch (e: Throwable) {
- LOG.debug("Failed to resolve binary for terminal agent '${terminalAgent.agentKey.key}'", e)
- null
- }
-}
-
-@ApiStatus.Internal
-suspend fun resolveExecutableViaTerminalResolver(
- terminalAgentKey: String,
- fallbackResolver: (() -> String?)? = null,
- missingAgentMessage: String? = null,
- terminalAgentLookup: (TerminalAgent.AgentKey) -> TerminalAgent? = TerminalAgent::findByKey,
- binaryPathResolver: suspend (TerminalAgent) -> String? = ::resolveTerminalAgentBinaryPath,
-): String? {
- val terminalAgent = lookupTerminalAgent(terminalAgentKey, terminalAgentLookup)
- if (terminalAgent == null) {
- if (missingAgentMessage != null) {
- LOG.warn(missingAgentMessage)
- }
- return fallbackResolver?.invoke()
- }
- return resolveExecutableViaTerminalResolver(terminalAgent, binaryPathResolver) ?: fallbackResolver?.invoke()
-}
-
-@ApiStatus.Internal
-suspend fun resolveExecutableOrDefaultViaTerminalResolver(
- defaultCommand: String,
- terminalAgent: TerminalAgent,
- binaryPathResolver: suspend (TerminalAgent) -> String? = ::resolveTerminalAgentBinaryPath,
-): String {
- return resolveExecutableViaTerminalResolver(terminalAgent, binaryPathResolver) ?: defaultCommand
-}
-
-@ApiStatus.Internal
-suspend fun resolveExecutableOrDefaultViaTerminalResolver(
- defaultCommand: String,
- terminalAgentKey: String,
- fallbackResolver: (() -> String?)? = null,
- missingAgentMessage: String? = null,
- terminalAgentLookup: (TerminalAgent.AgentKey) -> TerminalAgent? = TerminalAgent::findByKey,
- binaryPathResolver: suspend (TerminalAgent) -> String? = ::resolveTerminalAgentBinaryPath,
-): String {
- return resolveExecutableViaTerminalResolver(
- terminalAgentKey = terminalAgentKey,
- fallbackResolver = fallbackResolver,
- missingAgentMessage = missingAgentMessage,
- terminalAgentLookup = terminalAgentLookup,
- binaryPathResolver = binaryPathResolver,
- ) ?: defaultCommand
-}
-
-@ApiStatus.Internal
-fun resolveExecutableFromPath(command: String): String? {
- return PathEnvironmentVariableUtil.findExecutableInPathOnAnyOS(command)?.toPath()?.toAbsolutePath()?.toString()
-}
-
-@ApiStatus.Internal
-fun resolveExecutableFromPathOrLocalBin(
- command: String,
- localExecutableNames: List = listOf(command),
- userHomePath: Path? = System.getProperty("user.home")?.let(Path::of),
-): String? {
- resolveExecutableFromPath(command)?.let { return it }
- val homePath = userHomePath ?: return null
- for (executableName in localExecutableNames) {
- val localBin = homePath.resolve(".local").resolve("bin").resolve(executableName)
- if (Files.isRegularFile(localBin)) return localBin.toAbsolutePath().toString()
- }
- return null
-}
-
-@ApiStatus.Internal
-fun terminalAgentBinaryNameOrDefault(
- terminalAgentKey: String,
- defaultCommand: String,
- terminalAgentLookup: (TerminalAgent.AgentKey) -> TerminalAgent? = TerminalAgent::findByKey,
-): String {
- return lookupTerminalAgent(terminalAgentKey, terminalAgentLookup)?.binaryName ?: defaultCommand
-}
-
-private fun lookupTerminalAgent(
- terminalAgentKey: String,
- terminalAgentLookup: (TerminalAgent.AgentKey) -> TerminalAgent?,
-): TerminalAgent? {
- return runCatching {
- terminalAgentLookup(TerminalAgent.AgentKey(terminalAgentKey))
- }.onFailure { error ->
- LOG.debug("Failed to resolve terminal agent for key '$terminalAgentKey'", error)
- }.getOrNull()
-}
-
-private suspend fun resolveTerminalAgentBinaryPath(terminalAgent: TerminalAgent): String? {
- val eelApi = LocalEelDescriptor.toEelApi()
- return TerminalAgentResolver.findBinaryPath(terminalAgent, eelApi)
-}
diff --git a/plugins/agent-workbench/lib-agent/cli/testSrc/AgentCliExecutableResolverTest.kt b/plugins/agent-workbench/lib-agent/cli/testSrc/AgentCliExecutableResolverTest.kt
deleted file mode 100644
index 24524b9ada69..000000000000
--- a/plugins/agent-workbench/lib-agent/cli/testSrc/AgentCliExecutableResolverTest.kt
+++ /dev/null
@@ -1,210 +0,0 @@
-// 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.platform.ai.agent.cli
-
-import com.intellij.openapi.progress.ProcessCanceledException
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.runBlocking
-import org.assertj.core.api.Assertions.assertThat
-import org.assertj.core.api.Assertions.assertThatThrownBy
-import org.jetbrains.plugins.terminal.agent.TerminalAgent
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.io.TempDir
-import java.nio.file.Files
-import java.nio.file.Path
-import javax.swing.Icon
-
-class AgentCliExecutableResolverTest {
- @Test
- fun directAgentResolutionUsesInjectedBinaryResolver(): Unit = runBlocking(Dispatchers.Default) {
- val agent = testTerminalAgent(key = "codex", binaryName = "codex")
-
- val executable = resolveExecutableViaTerminalResolver(agent) { terminalAgent ->
- "/opt/bin/${terminalAgent.binaryName}"
- }
-
- assertThat(executable).isEqualTo("/opt/bin/codex")
- }
-
- @Test
- fun keyBasedResolutionUsesRegisteredAgent(): Unit = runBlocking(Dispatchers.Default) {
- val agent = testTerminalAgent(key = "claude_code", binaryName = "claude")
-
- val executable = resolveExecutableViaTerminalResolver(
- terminalAgentKey = "claude_code",
- terminalAgentLookup = { key -> if (key.key == "claude_code") agent else null },
- binaryPathResolver = { terminalAgent -> "/usr/local/bin/${terminalAgent.binaryName}" },
- )
-
- assertThat(executable).isEqualTo("/usr/local/bin/claude")
- }
-
- @Test
- fun registeredAgentUsesFallbackWhenBinaryLookupFindsNoExecutable(): Unit = runBlocking(Dispatchers.Default) {
- val agent = testTerminalAgent(key = "codex", binaryName = "codex")
-
- val executable = resolveExecutableViaTerminalResolver(
- terminalAgentKey = "codex",
- fallbackResolver = { "/fallback/codex" },
- terminalAgentLookup = { key -> if (key.key == "codex") agent else null },
- binaryPathResolver = { null },
- )
-
- assertThat(executable).isEqualTo("/fallback/codex")
- }
-
- @Test
- fun registeredAgentUsesFallbackWhenBinaryLookupFails(): Unit = runBlocking(Dispatchers.Default) {
- val agent = testTerminalAgent(key = "codex", binaryName = "codex")
-
- val executable = resolveExecutableViaTerminalResolver(
- terminalAgentKey = "codex",
- fallbackResolver = { "/fallback/codex" },
- terminalAgentLookup = { key -> if (key.key == "codex") agent else null },
- binaryPathResolver = { error("broken binary lookup") },
- )
-
- assertThat(executable).isEqualTo("/fallback/codex")
- }
-
- @Test
- fun binaryLookupCancellationPropagates() {
- val agent = testTerminalAgent(key = "codex", binaryName = "codex")
-
- assertThatThrownBy {
- runBlocking(Dispatchers.Default) {
- resolveExecutableViaTerminalResolver(agent) {
- throw CancellationException("cancelled")
- }
- }
- }.isInstanceOf(CancellationException::class.java)
- }
-
- @Test
- fun binaryLookupProcessCancellationPropagates() {
- val agent = testTerminalAgent(key = "codex", binaryName = "codex")
-
- assertThatThrownBy {
- runBlocking(Dispatchers.Default) {
- resolveExecutableViaTerminalResolver(agent) {
- throw ProcessCanceledException()
- }
- }
- }.isInstanceOf(ProcessCanceledException::class.java)
- }
-
- @Test
- fun missingAgentUsesFallbackWithoutBinaryLookup(): Unit = runBlocking(Dispatchers.Default) {
- var binaryLookupCalled = false
-
- val executable = resolveExecutableViaTerminalResolver(
- terminalAgentKey = "missing",
- fallbackResolver = { "/fallback/agent" },
- terminalAgentLookup = { null },
- binaryPathResolver = {
- binaryLookupCalled = true
- "/unexpected"
- },
- )
-
- assertThat(executable).isEqualTo("/fallback/agent")
- assertThat(binaryLookupCalled).isFalse()
- }
-
- @Test
- fun lookupFailureUsesFallbackWithoutBinaryLookup(): Unit = runBlocking(Dispatchers.Default) {
- var binaryLookupCalled = false
-
- val executable = resolveExecutableViaTerminalResolver(
- terminalAgentKey = "broken",
- fallbackResolver = { "/fallback/agent" },
- terminalAgentLookup = { error("broken terminal agent extension") },
- binaryPathResolver = {
- binaryLookupCalled = true
- "/unexpected"
- },
- )
-
- assertThat(executable).isEqualTo("/fallback/agent")
- assertThat(binaryLookupCalled).isFalse()
- }
-
- @Test
- fun defaultCommandIsReturnedWhenResolverFindsNoExecutable(): Unit = runBlocking(Dispatchers.Default) {
- val executable = resolveExecutableOrDefaultViaTerminalResolver(
- defaultCommand = "pi",
- terminalAgent = testTerminalAgent(key = "pi", binaryName = "pi"),
- binaryPathResolver = { null },
- )
-
- assertThat(executable).isEqualTo("pi")
- }
-
- @Test
- fun terminalAgentBinaryNameFallsBackToDefault() {
- val registered = testTerminalAgent(key = "codex", binaryName = "codex-nightly")
-
- assertThat(
- terminalAgentBinaryNameOrDefault(
- terminalAgentKey = "codex",
- defaultCommand = "codex",
- terminalAgentLookup = { key -> if (key.key == "codex") registered else null },
- )
- ).isEqualTo("codex-nightly")
- assertThat(
- terminalAgentBinaryNameOrDefault(
- terminalAgentKey = "missing",
- defaultCommand = "codex",
- terminalAgentLookup = { null },
- )
- ).isEqualTo("codex")
- assertThat(
- terminalAgentBinaryNameOrDefault(
- terminalAgentKey = "broken",
- defaultCommand = "codex",
- terminalAgentLookup = { error("broken terminal agent extension") },
- )
- ).isEqualTo("codex")
- }
-
- @Test
- fun localBinFallbackResolvesHomeRelativeExecutable(@TempDir homePath: Path) {
- val executable = homePath.resolve(".local").resolve("bin").resolve("agent-test-cli")
- Files.createDirectories(executable.parent)
- Files.writeString(executable, "")
-
- assertThat(
- resolveExecutableFromPathOrLocalBin(
- command = "agent-test-cli-command-that-should-not-exist",
- localExecutableNames = listOf("agent-test-cli"),
- userHomePath = homePath,
- )
- ).isEqualTo(executable.toAbsolutePath().toString())
- }
-
- @Test
- fun localBinFallbackIgnoresNonFileCandidates(@TempDir homePath: Path) {
- val executableDirectory = homePath.resolve(".local").resolve("bin").resolve("agent-test-cli")
- Files.createDirectories(executableDirectory)
-
- assertThat(
- resolveExecutableFromPathOrLocalBin(
- command = "agent-test-cli-command-that-should-not-exist",
- localExecutableNames = listOf("agent-test-cli"),
- userHomePath = homePath,
- )
- ).isNull()
- }
-}
-
-private fun testTerminalAgent(
- key: String,
- binaryName: String,
-): TerminalAgent {
- return object : TerminalAgent {
- override val agentKey: TerminalAgent.AgentKey = TerminalAgent.AgentKey(key)
- override val displayName: String = "Test Agent"
- override val binaryName: String = binaryName
- override val icon: Icon? = null
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/common/BUILD.bazel b/plugins/agent-workbench/lib-agent/common/BUILD.bazel
deleted file mode 100644
index 8bf2f1b40663..000000000000
--- a/plugins/agent-workbench/lib-agent/common/BUILD.bazel
+++ /dev/null
@@ -1,128 +0,0 @@
-load("@community//build:tests-options.bzl", "jps_test")
-load("@rules_jvm//:jvm.bzl", "jvm_library")
-
-### auto-generated section `build intellij.platform.ai.agent.common` start
-
-jvm_library(
- name = "common",
- srcs = glob(
- [
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/*.form",
- ],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.common",
- resource_strip_prefix = "resources",
- resources = glob(
- ["resources/**/*"],
- ),
- visibility = ["//visibility:public"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//platform/util/concurrency",
- "//platform/core-api:core",
- "//platform/util",
- "//plugins/agent-workbench/lib-agent/core",
- "//platform/util:util-ui",
- ],
-)
-
-jvm_library(
- name = "common_test_lib",
- testonly = True,
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.common",
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":common",
- "//platform/util/concurrency:concurrency_test_lib",
- "//platform/core-api:core_test_lib",
- "//platform/util:util_test_lib",
- "//plugins/agent-workbench/lib-agent/core:core_test_lib",
- "//platform/util:util-ui_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.common` end
-
-### auto-generated section `iml intellij.platform.ai.agent.common` start
-exports_files(
- [
- "intellij.platform.ai.agent.common.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.common` end
-
-### auto-generated section `build intellij.platform.ai.agent.common.tests` start
-
-jvm_library(
- name = "ai-agent-common-tests",
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.common.tests",
- visibility = ["//visibility:public"],
-)
-
-jvm_library(
- name = "ai-agent-common-tests_test_lib",
- testonly = True,
- srcs = glob(
- [
- "testSrc/**/*.kt",
- "testSrc/**/*.java",
- "testSrc/**/*.form",
- ],
- allow_empty = True,
- ),
- associates = [
- "//plugins/agent-workbench/lib-agent/common",
- "//plugins/agent-workbench/lib-agent/common:common_test_lib",
- ],
- visibility = ["//visibility:public"],
- runtime_deps = [":ai-agent-common-tests"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//platform/util",
- "//platform/util:util_test_lib",
- "//platform/util:util-ui",
- "//platform/util:util-ui_test_lib",
- "//plugins/agent-workbench/lib-agent/core",
- "//plugins/agent-workbench/lib-agent/core:core_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.common.tests` end
-
-### auto-generated section `iml intellij.platform.ai.agent.common.tests` start
-exports_files(
- [
- "intellij.platform.ai.agent.common.tests.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.common.tests` end
-
-### auto-generated section `test intellij.platform.ai.agent.common.tests` start
-
-jps_test(
- name = "ai-agent-common-tests_test",
- runtime_deps = [":ai-agent-common-tests_test_lib"],
-)
-### auto-generated section `test intellij.platform.ai.agent.common.tests` end
diff --git a/plugins/agent-workbench/lib-agent/common/api-dump.txt b/plugins/agent-workbench/lib-agent/common/api-dump.txt
deleted file mode 100644
index d47430a969ac..000000000000
--- a/plugins/agent-workbench/lib-agent/common/api-dump.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-f:com.intellij.platform.ai.agent.common.AgentThreadActivityIconsKt
-- sf:withAgentThreadActivityBadge(javax.swing.Icon,com.intellij.platform.ai.agent.core.AgentThreadActivity):javax.swing.Icon
-f:com.intellij.platform.ai.agent.common.AgentThreadActivityPresentation
-- f:darkFallbackRgb:java.lang.Integer
-- f:lightFallbackRgb:java.lang.Integer
-- f:namedColorKey:java.lang.String
-- f:showBadge:Z
-- f:statusMessageKey:java.lang.String
-- (java.lang.String,java.lang.Integer,java.lang.Integer,java.lang.String,Z):V
-- b:(java.lang.String,java.lang.Integer,java.lang.Integer,java.lang.String,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.Integer
-- f:component3():java.lang.Integer
-- f:component4():java.lang.String
-- f:component5():Z
-- f:copy(java.lang.String,java.lang.Integer,java.lang.Integer,java.lang.String,Z):com.intellij.platform.ai.agent.common.AgentThreadActivityPresentation
-- bs:copy$default(com.intellij.platform.ai.agent.common.AgentThreadActivityPresentation,java.lang.String,java.lang.Integer,java.lang.Integer,java.lang.String,Z,I,java.lang.Object):com.intellij.platform.ai.agent.common.AgentThreadActivityPresentation
-- equals(java.lang.Object):Z
-- f:getNamedColor():com.intellij.ui.JBColor
-- hashCode():I
-f:com.intellij.platform.ai.agent.common.AgentThreadActivityPresentationKt
-- sf:presentation(com.intellij.platform.ai.agent.core.AgentThreadActivity):com.intellij.platform.ai.agent.common.AgentThreadActivityPresentation
-- sf:statusBadgeColor(com.intellij.platform.ai.agent.core.AgentThreadActivity):java.awt.Color
-- sf:statusColor(com.intellij.platform.ai.agent.core.AgentThreadActivity):java.awt.Color
-- sf:statusMessageKey(com.intellij.platform.ai.agent.core.AgentThreadActivity):java.lang.String
-f:com.intellij.platform.ai.agent.common.icons.AgentWorkbenchCommonIcons
-- sf:Claude:javax.swing.Icon
-- sf:ClaudeGray:javax.swing.Icon
-- sf:Codex:javax.swing.Icon
-- sf:CodexGray:javax.swing.Icon
-- sf:Junie:javax.swing.Icon
-- sf:JunieGray:javax.swing.Icon
-- sf:Opencode:javax.swing.Icon
-- sf:OpencodeGray:javax.swing.Icon
-- sf:PI:javax.swing.Icon
-- ():V
diff --git a/plugins/agent-workbench/lib-agent/common/exposed-third-party-api.txt b/plugins/agent-workbench/lib-agent/common/exposed-third-party-api.txt
deleted file mode 100644
index 1ff3abdfef32..000000000000
--- a/plugins/agent-workbench/lib-agent/common/exposed-third-party-api.txt
+++ /dev/null
@@ -1 +0,0 @@
-kotlin/jvm/internal/DefaultConstructorMarker
diff --git a/plugins/agent-workbench/lib-agent/common/intellij.platform.ai.agent.common.iml b/plugins/agent-workbench/lib-agent/common/intellij.platform.ai.agent.common.iml
deleted file mode 100644
index 53abddcc8905..000000000000
--- a/plugins/agent-workbench/lib-agent/common/intellij.platform.ai.agent.common.iml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/common/intellij.platform.ai.agent.common.tests.iml b/plugins/agent-workbench/lib-agent/common/intellij.platform.ai.agent.common.tests.iml
deleted file mode 100644
index e45e71009bf3..000000000000
--- a/plugins/agent-workbench/lib-agent/common/intellij.platform.ai.agent.common.tests.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/claude.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/claude.svg
deleted file mode 100644
index 608e410c88dc..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/claude.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/claudeGray.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/claudeGray.svg
deleted file mode 100644
index 8c29b71a2d4f..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/claudeGray.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/claudeGray_dark.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/claudeGray_dark.svg
deleted file mode 100644
index 7760a3972166..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/claudeGray_dark.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/codex.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/codex.svg
deleted file mode 100644
index 260bd482b98f..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/codex.svg
+++ /dev/null
@@ -1,40 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/codexGray.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/codexGray.svg
deleted file mode 100644
index 01f9c93170b1..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/codexGray.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/codexGray_dark.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/codexGray_dark.svg
deleted file mode 100644
index b7649320c888..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/codexGray_dark.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/junie.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/junie.svg
deleted file mode 100644
index 50ff09c43518..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/junie.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/junieGray.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/junieGray.svg
deleted file mode 100644
index 96df5d3d3e08..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/junieGray.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/junieGray_dark.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/junieGray_dark.svg
deleted file mode 100644
index 94174d8d84ee..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/junieGray_dark.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/opencode.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/opencode.svg
deleted file mode 100644
index b36d603ac649..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/opencode.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/opencodeGray.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/opencodeGray.svg
deleted file mode 100644
index 2f2fc6527c08..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/opencodeGray.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/opencodeGray_dark.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/opencodeGray_dark.svg
deleted file mode 100644
index d1c887a28504..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/opencodeGray_dark.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/pi.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/pi.svg
deleted file mode 100644
index 5b44c8dae766..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/pi.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/icons/pi_dark.svg b/plugins/agent-workbench/lib-agent/common/resources/icons/pi_dark.svg
deleted file mode 100644
index 9dea38a1d1bf..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/icons/pi_dark.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
diff --git a/plugins/agent-workbench/lib-agent/common/resources/intellij.platform.ai.agent.common.xml b/plugins/agent-workbench/lib-agent/common/resources/intellij.platform.ai.agent.common.xml
deleted file mode 100644
index 5c833a56b5f1..000000000000
--- a/plugins/agent-workbench/lib-agent/common/resources/intellij.platform.ai.agent.common.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/plugins/agent-workbench/lib-agent/common/src/AgentThreadActivityIcons.kt b/plugins/agent-workbench/lib-agent/common/src/AgentThreadActivityIcons.kt
deleted file mode 100644
index a06ae84001c2..000000000000
--- a/plugins/agent-workbench/lib-agent/common/src/AgentThreadActivityIcons.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.platform.ai.agent.common
-
-import com.intellij.platform.ai.agent.core.AgentThreadActivity
-import com.intellij.ui.IconManager
-import javax.swing.Icon
-
-fun withAgentThreadActivityBadge(baseIcon: Icon, activity: AgentThreadActivity): Icon {
- val badgeColor = activity.statusBadgeColor() ?: return baseIcon
- return IconManager.getInstance().withIconBadge(baseIcon, badgeColor)
-}
diff --git a/plugins/agent-workbench/lib-agent/common/src/AgentThreadActivityPresentation.kt b/plugins/agent-workbench/lib-agent/common/src/AgentThreadActivityPresentation.kt
deleted file mode 100644
index eb4c13ad18e5..000000000000
--- a/plugins/agent-workbench/lib-agent/common/src/AgentThreadActivityPresentation.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-@file:Suppress("UseJBColor")
-
-package com.intellij.platform.ai.agent.common
-
-import com.intellij.platform.ai.agent.core.AgentThreadActivity
-import com.intellij.ui.JBColor
-import java.awt.Color
-
-data class AgentThreadActivityPresentation(
- @JvmField val namedColorKey: String?,
- @JvmField val lightFallbackRgb: Int?,
- @JvmField val darkFallbackRgb: Int?,
- @JvmField val statusMessageKey: String,
- @JvmField val showBadge: Boolean = true,
-) {
- val namedColor: JBColor? = namedColorKey?.let { key ->
- JBColor.namedColor(key, JBColor(requireNotNull(lightFallbackRgb), requireNotNull(darkFallbackRgb)))
- }
-
- override fun toString(): String {
- return "AgentThreadActivityPresentation(" +
- "$namedColorKey, " +
- "${lightFallbackRgb?.let { Color(it) }}, " +
- "${darkFallbackRgb?.let { Color(it) }}, " +
- "$statusMessageKey, " +
- "$showBadge" +
- ")"
- }
-}
-
-private fun threadActivityPresentation(
- namedColorKey: String,
- lightFallbackColor: Int,
- darkFallbackColor: Int,
- statusMessageKey: String,
- showBadge: Boolean = true,
-): AgentThreadActivityPresentation {
- return AgentThreadActivityPresentation(
- namedColorKey = namedColorKey,
- lightFallbackRgb = lightFallbackColor,
- darkFallbackRgb = darkFallbackColor,
- statusMessageKey = statusMessageKey,
- showBadge = showBadge,
- )
-}
-
-// Idle/no-signal state: intentionally unaccented and unbadged.
-private val READY_PRESENTATION = AgentThreadActivityPresentation(
- namedColorKey = null,
- lightFallbackRgb = null,
- darkFallbackRgb = null,
- statusMessageKey = "toolwindow.thread.status.ready",
- showBadge = false,
-)
-
-// Active work in progress.
-private val PROCESSING_PRESENTATION = threadActivityPresentation(
- namedColorKey = "IconBadge.successBackground",
- lightFallbackColor = Color(0x55A76A).rgb,
- darkFallbackColor = Color(0x5FAD65).rgb,
- statusMessageKey = "toolwindow.thread.status.in.progress",
-)
-
-// Review-mode output waiting for user attention.
-private val REVIEWING_PRESENTATION = threadActivityPresentation(
- namedColorKey = "IconBadge.warningBackground",
- lightFallbackColor = Color(0xFFAF0F).rgb,
- darkFallbackColor = Color(0xF2C55C).rgb,
- statusMessageKey = "toolwindow.thread.status.needs.review",
-)
-
-// Completed assistant output waiting to be seen.
-private val UNREAD_PRESENTATION = threadActivityPresentation(
- namedColorKey = "IconBadge.infoBackground",
- lightFallbackColor = Color(0x588CF3).rgb,
- darkFallbackColor = Color(0x548AF7).rgb,
- statusMessageKey = "toolwindow.thread.status.done",
-)
-
-// Explicit user action required.
-private val NEEDS_INPUT_PRESENTATION = threadActivityPresentation(
- namedColorKey = "IconBadge.warningBackground",
- lightFallbackColor = Color(0xFFAF0F).rgb,
- darkFallbackColor = Color(0xF2C55C).rgb,
- statusMessageKey = "toolwindow.thread.status.needs.input",
-)
-
-fun AgentThreadActivity.presentation(): AgentThreadActivityPresentation {
- return when (this) {
- AgentThreadActivity.READY -> READY_PRESENTATION
- AgentThreadActivity.PROCESSING -> PROCESSING_PRESENTATION
- AgentThreadActivity.REVIEWING -> REVIEWING_PRESENTATION
- AgentThreadActivity.NEEDS_INPUT -> NEEDS_INPUT_PRESENTATION
- AgentThreadActivity.UNREAD -> UNREAD_PRESENTATION
- }
-}
-
-fun AgentThreadActivity.statusColor(): Color? = presentation().namedColor
-
-fun AgentThreadActivity.statusBadgeColor(): Color? {
- val presentation = presentation()
- return presentation.namedColor?.takeIf { presentation.showBadge }
-}
-
-fun AgentThreadActivity.statusMessageKey(): String = presentation().statusMessageKey
diff --git a/plugins/agent-workbench/lib-agent/common/src/icons/AgentWorkbenchCommonIcons.java b/plugins/agent-workbench/lib-agent/common/src/icons/AgentWorkbenchCommonIcons.java
deleted file mode 100644
index 13bdf9f5917f..000000000000
--- a/plugins/agent-workbench/lib-agent/common/src/icons/AgentWorkbenchCommonIcons.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.platform.ai.agent.common.icons;
-
-import com.intellij.ui.IconManager;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-/**
- * NOTE THIS FILE IS AUTO-GENERATED
- * DO NOT EDIT IT BY HAND, run "Generate icon classes" configuration instead
- */
-public final class AgentWorkbenchCommonIcons {
- private static @NotNull Icon load(@NotNull String path, int cacheKey, int flags) {
- return IconManager.getInstance().loadRasterizedIcon(path, AgentWorkbenchCommonIcons.class.getClassLoader(), cacheKey, flags);
- }
- /** 16x16 */ public static final @NotNull Icon Claude = load("icons/claude.svg", -294097785, 0);
- /** 16x16 */ public static final @NotNull Icon ClaudeGray = load("icons/claudeGray.svg", 1540268029, 2);
- /** 16x16 */ public static final @NotNull Icon Codex = load("icons/codex.svg", -72483386, 0);
- /** 16x16 */ public static final @NotNull Icon CodexGray = load("icons/codexGray.svg", 1835398902, 2);
- /** 16x16 */ public static final @NotNull Icon Junie = load("icons/junie.svg", -76396756, 0);
- /** 16x16 */ public static final @NotNull Icon JunieGray = load("icons/junieGray.svg", 465929641, 2);
- /** 16x16 */ public static final @NotNull Icon Opencode = load("icons/opencode.svg", -1522185687, 0);
- /** 16x16 */ public static final @NotNull Icon OpencodeGray = load("icons/opencodeGray.svg", 1279569419, 2);
- /** 16x16 */ public static final @NotNull Icon PI = load("icons/pi.svg", 1349425160, 2);
-}
diff --git a/plugins/agent-workbench/lib-agent/common/testSrc/AgentThreadActivityPresentationTest.kt b/plugins/agent-workbench/lib-agent/common/testSrc/AgentThreadActivityPresentationTest.kt
deleted file mode 100644
index 10003b1e580c..000000000000
--- a/plugins/agent-workbench/lib-agent/common/testSrc/AgentThreadActivityPresentationTest.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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.platform.ai.agent.common
-
-import com.intellij.platform.ai.agent.core.AgentThreadActivity
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import java.awt.Color
-import java.util.concurrent.TimeUnit
-import javax.swing.UIManager
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class AgentThreadActivityPresentationTest {
- @Test
- fun usesThreadPresentationsAndMessageKeys() {
- val expected = linkedMapOf(
- AgentThreadActivity.READY to AgentThreadActivityPresentation(
- namedColorKey = null,
- lightFallbackRgb = null,
- darkFallbackRgb = null,
- statusMessageKey = "toolwindow.thread.status.ready",
- showBadge = false,
- ),
- AgentThreadActivity.PROCESSING to AgentThreadActivityPresentation(
- namedColorKey = "IconBadge.successBackground",
- lightFallbackRgb = Color(0x55A76A).rgb,
- darkFallbackRgb = Color(0x5FAD65).rgb,
- statusMessageKey = "toolwindow.thread.status.in.progress",
- ),
- AgentThreadActivity.REVIEWING to AgentThreadActivityPresentation(
- namedColorKey = "IconBadge.warningBackground",
- lightFallbackRgb = Color(0xFFAF0F).rgb,
- darkFallbackRgb = Color(0xF2C55C).rgb,
- statusMessageKey = "toolwindow.thread.status.needs.review",
- ),
- AgentThreadActivity.UNREAD to AgentThreadActivityPresentation(
- namedColorKey = "IconBadge.infoBackground",
- lightFallbackRgb = Color(0x588CF3).rgb,
- darkFallbackRgb = Color(0x548AF7).rgb,
- statusMessageKey = "toolwindow.thread.status.done",
- ),
- AgentThreadActivity.NEEDS_INPUT to AgentThreadActivityPresentation(
- namedColorKey = "IconBadge.warningBackground",
- lightFallbackRgb = Color(0xFFAF0F).rgb,
- darkFallbackRgb = Color(0xF2C55C).rgb,
- statusMessageKey = "toolwindow.thread.status.needs.input",
- ),
- )
-
- expected.forEach { (activity, presentation) ->
- assertThat(activity.presentation()).isEqualTo(presentation)
- val statusColor = activity.statusColor()
- if (presentation.namedColorKey == null) {
- assertThat(statusColor).isNull()
- }
- else {
- assertThat(statusColor?.rgb).isIn(
- Color(requireNotNull(presentation.lightFallbackRgb)).rgb,
- Color(requireNotNull(presentation.darkFallbackRgb)).rgb,
- )
- }
- assertThat(activity.statusBadgeColor()?.rgb).isEqualTo(if (presentation.showBadge) statusColor?.rgb else null)
- assertThat(activity.statusMessageKey()).isEqualTo(presentation.statusMessageKey)
- }
- }
-
- @Test
- fun prefersUiManagerOverrideForNamedColor() {
- val overrideColor = Color(0x112233)
-
- withTemporaryNeedsInputUiColor(overrideColor) {
- assertThat(AgentThreadActivity.NEEDS_INPUT.statusColor()?.rgb).isEqualTo(overrideColor.rgb)
- assertThat(AgentThreadActivity.NEEDS_INPUT.statusBadgeColor()?.rgb).isEqualTo(overrideColor.rgb)
- }
- }
-
- private fun withTemporaryNeedsInputUiColor(color: Color, action: () -> Unit) {
- val key = "IconBadge.warningBackground"
- val defaults = UIManager.getDefaults()
- val previous = defaults[key]
- UIManager.put(key, color)
- try {
- action()
- }
- finally {
- if (previous == null) {
- defaults.remove(key)
- }
- else {
- UIManager.put(key, previous)
- }
- }
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/core/BUILD.bazel b/plugins/agent-workbench/lib-agent/core/BUILD.bazel
deleted file mode 100644
index 137a2a05c6ed..000000000000
--- a/plugins/agent-workbench/lib-agent/core/BUILD.bazel
+++ /dev/null
@@ -1,120 +0,0 @@
-load("@community//build:tests-options.bzl", "jps_test")
-load("@rules_jvm//:jvm.bzl", "jvm_library")
-
-### auto-generated section `build intellij.platform.ai.agent.core` start
-
-jvm_library(
- name = "core",
- srcs = glob(
- [
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/*.form",
- ],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.core",
- resource_strip_prefix = "resources",
- resources = glob(
- ["resources/**/*"],
- ),
- visibility = ["//visibility:public"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//platform/util/concurrency",
- "//platform/core-api:core",
- "//platform/util",
- ],
-)
-
-jvm_library(
- name = "core_test_lib",
- testonly = True,
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.core",
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":core",
- "//platform/util/concurrency:concurrency_test_lib",
- "//platform/core-api:core_test_lib",
- "//platform/util:util_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.core` end
-
-### auto-generated section `iml intellij.platform.ai.agent.core` start
-exports_files(
- [
- "intellij.platform.ai.agent.core.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.core` end
-
-### auto-generated section `build intellij.platform.ai.agent.core.tests` start
-
-jvm_library(
- name = "ai-agent-core-tests",
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.core.tests",
- visibility = ["//visibility:public"],
-)
-
-jvm_library(
- name = "ai-agent-core-tests_test_lib",
- testonly = True,
- srcs = glob(
- [
- "testSrc/**/*.kt",
- "testSrc/**/*.java",
- "testSrc/**/*.form",
- ],
- allow_empty = True,
- ),
- associates = [
- "//plugins/agent-workbench/lib-agent/core",
- "//plugins/agent-workbench/lib-agent/core:core_test_lib",
- ],
- visibility = ["//visibility:public"],
- runtime_deps = [":ai-agent-core-tests"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//platform/util/concurrency",
- "//platform/util/concurrency:concurrency_test_lib",
- "//platform/core-api:core",
- "//platform/core-api:core_test_lib",
- "//platform/util",
- "//platform/util:util_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.core.tests` end
-
-### auto-generated section `iml intellij.platform.ai.agent.core.tests` start
-exports_files(
- [
- "intellij.platform.ai.agent.core.tests.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.core.tests` end
-
-### auto-generated section `test intellij.platform.ai.agent.core.tests` start
-
-jps_test(
- name = "ai-agent-core-tests_test",
- runtime_deps = [":ai-agent-core-tests_test_lib"],
-)
-### auto-generated section `test intellij.platform.ai.agent.core.tests` end
diff --git a/plugins/agent-workbench/lib-agent/core/api-dump.txt b/plugins/agent-workbench/lib-agent/core/api-dump.txt
deleted file mode 100644
index 06c27eb3a5c9..000000000000
--- a/plugins/agent-workbench/lib-agent/core/api-dump.txt
+++ /dev/null
@@ -1,256 +0,0 @@
-e:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- java.lang.Enum
-- sf:NEEDS_INPUT:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- sf:PROCESSING:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- sf:READY:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- sf:REVIEWING:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- sf:UNREAD:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.core.AgentThreadActivity
-- s:values():com.intellij.platform.ai.agent.core.AgentThreadActivity[]
-e:com.intellij.platform.ai.agent.core.AgentThreadActivityBucket
-- java.lang.Enum
-- sf:ATTENTION:com.intellij.platform.ai.agent.core.AgentThreadActivityBucket
-- sf:DONE:com.intellij.platform.ai.agent.core.AgentThreadActivityBucket
-- sf:RUNNING:com.intellij.platform.ai.agent.core.AgentThreadActivityBucket
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.core.AgentThreadActivityBucket
-- s:values():com.intellij.platform.ai.agent.core.AgentThreadActivityBucket[]
-f:com.intellij.platform.ai.agent.core.AgentThreadActivityKt
-- sf:chromeBucket(com.intellij.platform.ai.agent.core.AgentThreadActivityReport):com.intellij.platform.ai.agent.core.AgentThreadActivityBucket
-- sf:isWorking(com.intellij.platform.ai.agent.core.AgentThreadActivity):Z
-f:com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- sf:Companion:com.intellij.platform.ai.agent.core.AgentThreadActivityReport$Companion
-- sf:READY:com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:chromeActivity:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- f:rowActivity:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- (com.intellij.platform.ai.agent.core.AgentThreadActivity,com.intellij.platform.ai.agent.core.AgentThreadActivity):V
-- b:(com.intellij.platform.ai.agent.core.AgentThreadActivity,com.intellij.platform.ai.agent.core.AgentThreadActivity,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():com.intellij.platform.ai.agent.core.AgentThreadActivity
-- f:component2():com.intellij.platform.ai.agent.core.AgentThreadActivity
-- f:copy(com.intellij.platform.ai.agent.core.AgentThreadActivity,com.intellij.platform.ai.agent.core.AgentThreadActivity):com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- bs:copy$default(com.intellij.platform.ai.agent.core.AgentThreadActivityReport,com.intellij.platform.ai.agent.core.AgentThreadActivity,com.intellij.platform.ai.agent.core.AgentThreadActivity,I,java.lang.Object):com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.AgentThreadActivityReport$Companion
-f:com.intellij.platform.ai.agent.core.AgentThreadIdentity
-- f:providerId:java.lang.String
-- f:threadId:java.lang.String
-- (java.lang.String,java.lang.String):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:copy(java.lang.String,java.lang.String):com.intellij.platform.ai.agent.core.AgentThreadIdentity
-- bs:copy$default(com.intellij.platform.ai.agent.core.AgentThreadIdentity,java.lang.String,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.core.AgentThreadIdentity
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.AgentThreadIdentityKt
-- sf:buildAgentThreadIdentity(java.lang.String,java.lang.String):java.lang.String
-- sf:parseAgentThreadIdentity(java.lang.String):com.intellij.platform.ai.agent.core.AgentThreadIdentity
-f:com.intellij.platform.ai.agent.core.AgentWorkbenchPathUtilKt
-- sf:normalizeAgentSessionProjectPath(java.lang.String):java.lang.String
-- sf:normalizeAgentSessionTitle(java.lang.String):java.lang.String
-- sf:normalizeAgentWorkbenchPath(java.lang.String):java.lang.String
-- sf:normalizeAgentWorkbenchPathOrNull(java.lang.String):java.lang.String
-- sf:parseAgentWorkbenchPathOrNull(java.lang.String):java.nio.file.Path
-f:com.intellij.platform.ai.agent.core.extensions.OverridableValue
-- (kotlin.jvm.functions.Function0):V
-- f:value():java.lang.Object
-- f:withOverride(java.lang.Object,kotlin.jvm.functions.Function0):java.lang.Object
-f:com.intellij.platform.ai.agent.core.extensions.SingleExtensionPointResolver
-- (com.intellij.openapi.diagnostic.Logger,com.intellij.openapi.extensions.ExtensionPointName,java.lang.String,kotlin.jvm.functions.Function1):V
-- f:findFirstOrNull():java.lang.Object
-f:com.intellij.platform.ai.agent.core.extensions.SnapshotExtensionPointCache
-- (com.intellij.openapi.diagnostic.Logger,com.intellij.openapi.extensions.ExtensionPointName,java.lang.Class,java.lang.Object,java.lang.String,kotlin.jvm.functions.Function1):V
-- f:getSnapshotOrEmpty():java.lang.Object
-f:com.intellij.platform.ai.agent.core.extensions.SuspendingOverridableValue
-- (kotlin.jvm.functions.Function0):V
-- f:value():java.lang.Object
-- f:withOverride(java.lang.Object,kotlin.jvm.functions.Function1,kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.core.session.AgentSessionArchiveTitlesKt
-- sf:AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX:java.lang.String
-- sf:buildAgentSessionArchivedThreadTitle(java.lang.String,java.lang.String):java.lang.String
-- sf:isAgentSessionArchivedThreadTitle(java.lang.String):Z
-- sf:normalizeAgentSessionStoredThreadTitle(java.lang.String):java.lang.String
-- sf:resolveAgentSessionArchivedTitleState(java.lang.String,java.lang.String):com.intellij.platform.ai.agent.core.session.AgentSessionArchivedTitleState
-- sf:stripAgentSessionArchivedThreadTitlePrefix(java.lang.String):java.lang.String
-f:com.intellij.platform.ai.agent.core.session.AgentSessionArchivedTitleState
-- f:archived:Z
-- f:title:java.lang.String
-- (java.lang.String,Z):V
-- f:component1():java.lang.String
-- f:component2():Z
-- f:copy(java.lang.String,Z):com.intellij.platform.ai.agent.core.session.AgentSessionArchivedTitleState
-- bs:copy$default(com.intellij.platform.ai.agent.core.session.AgentSessionArchivedTitleState,java.lang.String,Z,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSessionArchivedTitleState
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.session.AgentSessionCost
-- f:amountUsd:java.math.BigDecimal
-- f:kind:com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- f:matchedModelId:java.lang.String
-- (java.math.BigDecimal,com.intellij.platform.ai.agent.core.session.AgentSessionCostKind,java.lang.String):V
-- b:(java.math.BigDecimal,com.intellij.platform.ai.agent.core.session.AgentSessionCostKind,java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.math.BigDecimal
-- f:component2():com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- f:component3():java.lang.String
-- f:copy(java.math.BigDecimal,com.intellij.platform.ai.agent.core.session.AgentSessionCostKind,java.lang.String):com.intellij.platform.ai.agent.core.session.AgentSessionCost
-- bs:copy$default(com.intellij.platform.ai.agent.core.session.AgentSessionCost,java.math.BigDecimal,com.intellij.platform.ai.agent.core.session.AgentSessionCostKind,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSessionCost
-- equals(java.lang.Object):Z
-- hashCode():I
-e:com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- java.lang.Enum
-- sf:ESTIMATED:com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- sf:EXACT:com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- sf:UNAVAILABLE:com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.core.session.AgentSessionCostKind
-- s:values():com.intellij.platform.ai.agent.core.session.AgentSessionCostKind[]
-e:com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- java.lang.Enum
-- sf:STANDARD:com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- sf:YOLO:com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- s:values():com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode[]
-f:com.intellij.platform.ai.agent.core.session.AgentSessionModelsKt
-- sf:agentSessionOutlinePhaseTitle(java.lang.String,I):java.lang.String
-- bs:agentSessionOutlinePhaseTitle$default(java.lang.String,I,I,java.lang.Object):java.lang.String
-- sf:buildAgentSessionOutlineTree(java.util.List):java.util.List
-- sf:compactAgentSessionOutlineText(java.lang.String,I):java.lang.String
-- sf:dedupeAgentSessionOutlineText(java.lang.String):java.lang.String
-- sf:normalizeAgentSessionOutlinePreview(java.lang.String,I):java.lang.String
-- bs:normalizeAgentSessionOutlinePreview$default(java.lang.String,I,I,java.lang.Object):java.lang.String
-- sf:summarizeAgentSessionOutlineChildren(java.util.List):java.lang.String
-f:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItem
-- f:children:java.util.List
-- f:id:java.lang.String
-- f:kind:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- f:preview:java.lang.String
-- f:timestampMs:java.lang.Long
-- f:title:java.lang.String
-- (java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,java.util.List):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,java.util.List,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- f:component3():java.lang.String
-- f:component4():java.lang.String
-- f:component5():java.lang.Long
-- f:component6():java.util.List
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,java.util.List):com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItem
-- bs:copy$default(com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItem,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,java.util.List,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItem
-- equals(java.lang.Object):Z
-- f:getTimestampMillis():java.lang.Long
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemBuilder
-- f:children:java.util.List
-- f:id:java.lang.String
-- kind:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- preview:java.lang.String
-- f:summarizesChildren:Z
-- f:timestampMs:java.lang.Long
-- title:java.lang.String
-- (java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,Z,java.util.List):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,Z,java.util.List,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:build():com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItem
-e:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- java.lang.Enum
-- sf:AGENT_WORK:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:APPROVAL_REQUEST:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:ASSISTANT_RESPONSE:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:INPUT_REQUEST:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:METADATA:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:PLAN:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:SUMMARY:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:TOOL_CALL:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:TOOL_RESULT:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- sf:USER_PROMPT:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- s:values():com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind[]
-f:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineTreeRecord
-- f:id:java.lang.String
-- f:kind:com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- f:parentId:java.lang.String
-- f:preview:java.lang.String
-- f:timestampMs:java.lang.Long
-- f:title:java.lang.String
-- f:visible:Z
-- (java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,Z):V
-- b:(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3():com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-- f:component4():java.lang.String
-- f:component5():java.lang.String
-- f:component6():java.lang.Long
-- f:component7():Z
-- f:copy(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,Z):com.intellij.platform.ai.agent.core.session.AgentSessionOutlineTreeRecord
-- bs:copy$default(com.intellij.platform.ai.agent.core.session.AgentSessionOutlineTreeRecord,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind,java.lang.String,java.lang.String,java.lang.Long,Z,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSessionOutlineTreeRecord
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.session.AgentSessionProvider
-- sf:Companion:com.intellij.platform.ai.agent.core.session.AgentSessionProvider$Companion
-- bsf:box-impl(java.lang.String):com.intellij.platform.ai.agent.core.session.AgentSessionProvider
-- equals(java.lang.Object):Z
-- s:equals-impl(java.lang.String,java.lang.Object):Z
-- sf:equals-impl0(java.lang.String,java.lang.String):Z
-- f:getValue():java.lang.String
-- hashCode():I
-- s:hashCode-impl(java.lang.String):I
-- s:toString-impl(java.lang.String):java.lang.String
-- bf:unbox-impl():java.lang.String
-f:com.intellij.platform.ai.agent.core.session.AgentSessionProvider$Companion
-- f:from-V7M2pUA(java.lang.String):java.lang.String
-- f:fromOrNull-6Etz2MU(java.lang.String):java.lang.String
-f:com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- f:activityReport:com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:archived:Z
-- f:cost:com.intellij.platform.ai.agent.core.session.AgentSessionCost
-- f:id:java.lang.String
-- f:originBranch:java.lang.String
-- f:subAgents:java.util.List
-- f:title:java.lang.String
-- f:updatedAt:J
-- b:(java.lang.String,java.lang.String,J,Z,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.String,java.util.List,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionCost,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3():J
-- f:component4():Z
-- f:component5():com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:component6-dBzBBrw():java.lang.String
-- f:component7():java.util.List
-- f:component8():java.lang.String
-- f:component9():com.intellij.platform.ai.agent.core.session.AgentSessionCost
-- f:copy-JxZNnm8(java.lang.String,java.lang.String,J,Z,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.String,java.util.List,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionCost):com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- bs:copy-JxZNnm8$default(com.intellij.platform.ai.agent.core.session.AgentSessionThread,java.lang.String,java.lang.String,J,Z,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.String,java.util.List,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionCost,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- equals(java.lang.Object):Z
-- f:getProvider-dBzBBrw():java.lang.String
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.session.AgentSessionThreadOutline
-- f:items:java.util.List
-- f:threadId:java.lang.String
-- f:title:java.lang.String
-- f:updatedAt:J
-- f:component1-dBzBBrw():java.lang.String
-- f:component2():java.lang.String
-- f:component3():java.lang.String
-- f:component4():J
-- f:component5():java.util.List
-- f:copy-fQRq96w(java.lang.String,java.lang.String,java.lang.String,J,java.util.List):com.intellij.platform.ai.agent.core.session.AgentSessionThreadOutline
-- bs:copy-fQRq96w$default(com.intellij.platform.ai.agent.core.session.AgentSessionThreadOutline,java.lang.String,java.lang.String,java.lang.String,J,java.util.List,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSessionThreadOutline
-- equals(java.lang.Object):Z
-- f:getProvider-dBzBBrw():java.lang.String
-- f:getSessionId():java.lang.String
-- hashCode():I
-f:com.intellij.platform.ai.agent.core.session.AgentSubAgent
-- f:activity:com.intellij.platform.ai.agent.core.AgentThreadActivity
-- f:id:java.lang.String
-- f:name:java.lang.String
-- (java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivity):V
-- b:(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivity,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3():com.intellij.platform.ai.agent.core.AgentThreadActivity
-- f:copy(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivity):com.intellij.platform.ai.agent.core.session.AgentSubAgent
-- bs:copy$default(com.intellij.platform.ai.agent.core.session.AgentSubAgent,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivity,I,java.lang.Object):com.intellij.platform.ai.agent.core.session.AgentSubAgent
-- equals(java.lang.Object):Z
-- hashCode():I
diff --git a/plugins/agent-workbench/lib-agent/core/exposed-third-party-api.txt b/plugins/agent-workbench/lib-agent/core/exposed-third-party-api.txt
deleted file mode 100644
index ee686436f8d7..000000000000
--- a/plugins/agent-workbench/lib-agent/core/exposed-third-party-api.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-java/math/BigDecimal
-kotlin/jvm/internal/DefaultConstructorMarker
diff --git a/plugins/agent-workbench/lib-agent/core/intellij.platform.ai.agent.core.iml b/plugins/agent-workbench/lib-agent/core/intellij.platform.ai.agent.core.iml
deleted file mode 100644
index 268f5e4ebc8f..000000000000
--- a/plugins/agent-workbench/lib-agent/core/intellij.platform.ai.agent.core.iml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/core/intellij.platform.ai.agent.core.tests.iml b/plugins/agent-workbench/lib-agent/core/intellij.platform.ai.agent.core.tests.iml
deleted file mode 100644
index 6f1d307f4497..000000000000
--- a/plugins/agent-workbench/lib-agent/core/intellij.platform.ai.agent.core.tests.iml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/core/resources/intellij.platform.ai.agent.core.xml b/plugins/agent-workbench/lib-agent/core/resources/intellij.platform.ai.agent.core.xml
deleted file mode 100644
index 6fb76a66265d..000000000000
--- a/plugins/agent-workbench/lib-agent/core/resources/intellij.platform.ai.agent.core.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/core/src/AgentThreadActivity.kt b/plugins/agent-workbench/lib-agent/core/src/AgentThreadActivity.kt
deleted file mode 100644
index ab889b3178dd..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/AgentThreadActivity.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.platform.ai.agent.core
-
-import org.jetbrains.annotations.ApiStatus
-
-enum class AgentThreadActivity {
- READY,
- PROCESSING,
- REVIEWING,
- NEEDS_INPUT,
- UNREAD,
-}
-
-data class AgentThreadActivityReport(
- @JvmField val rowActivity: AgentThreadActivity,
- @JvmField val chromeActivity: AgentThreadActivity? = rowActivity,
-) {
- companion object {
- @JvmField
- val READY: AgentThreadActivityReport = AgentThreadActivityReport(AgentThreadActivity.READY)
- }
-}
-
-enum class AgentThreadActivityBucket {
- ATTENTION,
- RUNNING,
- DONE,
-}
-
-val AgentThreadActivity.isWorking: Boolean
- get() = this == AgentThreadActivity.PROCESSING || this == AgentThreadActivity.REVIEWING
-
-fun AgentThreadActivityReport.chromeBucket(): AgentThreadActivityBucket? {
- return when (chromeActivity) {
- AgentThreadActivity.NEEDS_INPUT,
- AgentThreadActivity.REVIEWING,
- -> AgentThreadActivityBucket.ATTENTION
-
- AgentThreadActivity.PROCESSING -> AgentThreadActivityBucket.RUNNING
- AgentThreadActivity.UNREAD -> AgentThreadActivityBucket.DONE
- AgentThreadActivity.READY,
- null,
- -> null
- }
-}
-
-@ApiStatus.Internal
-fun AgentThreadActivityReport.chromePresentationActivity(): AgentThreadActivity {
- // Chrome consumers need a concrete badge state; null chrome activity means no badge.
- return chromeActivity ?: AgentThreadActivity.READY
-}
diff --git a/plugins/agent-workbench/lib-agent/core/src/AgentThreadIdentity.kt b/plugins/agent-workbench/lib-agent/core/src/AgentThreadIdentity.kt
deleted file mode 100644
index 393af5e25490..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/AgentThreadIdentity.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.platform.ai.agent.core
-
-private val PROVIDER_ID_REGEX = Regex("[a-z][a-z0-9._-]*")
-
-data class AgentThreadIdentity(
- @JvmField val providerId: String,
- @JvmField val threadId: String,
-)
-
-fun buildAgentThreadIdentity(providerId: String, threadId: String): String {
- require(PROVIDER_ID_REGEX.matches(providerId)) {
- "Invalid provider id '$providerId'. Expected: ${PROVIDER_ID_REGEX.pattern}"
- }
- require(threadId.isNotBlank()) {
- "Thread id must not be blank"
- }
- return "$providerId:$threadId"
-}
-
-fun parseAgentThreadIdentity(identity: String): AgentThreadIdentity? {
- val separator = identity.indexOf(':')
- if (separator <= 0 || separator == identity.lastIndex) {
- return null
- }
-
- val providerId = identity.substring(0, separator)
- if (!PROVIDER_ID_REGEX.matches(providerId)) {
- return null
- }
-
- val threadId = identity.substring(separator + 1)
- if (threadId.isBlank()) {
- return null
- }
-
- return AgentThreadIdentity(providerId = providerId, threadId = threadId)
-}
diff --git a/plugins/agent-workbench/lib-agent/core/src/AgentWorkbenchPathUtil.kt b/plugins/agent-workbench/lib-agent/core/src/AgentWorkbenchPathUtil.kt
deleted file mode 100644
index 1ee4346e606e..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/AgentWorkbenchPathUtil.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.platform.ai.agent.core
-
-import java.nio.file.InvalidPathException
-import java.nio.file.Path
-import kotlin.io.path.invariantSeparatorsPathString
-
-fun parseAgentWorkbenchPathOrNull(path: String): Path? {
- return try {
- Path.of(path)
- }
- catch (_: InvalidPathException) {
- null
- }
-}
-
-fun normalizeAgentWorkbenchPath(path: String): String {
- return parseAgentWorkbenchPathOrNull(path)?.invariantSeparatorsPathString ?: path
-}
-
-fun normalizeAgentWorkbenchPathOrNull(path: String): String? {
- return parseAgentWorkbenchPathOrNull(path)?.invariantSeparatorsPathString
-}
-
-fun normalizeAgentSessionProjectPath(path: String): String? {
- val trimmedPath = path.trim().takeIf { it.isNotEmpty() } ?: return null
- val normalizedPath = normalizeAgentWorkbenchPathOrNull(trimmedPath) ?: return null
- return normalizedPath.trimEnd('/').ifEmpty { "/" }
-}
-
-fun normalizeAgentSessionTitle(title: String?): String? {
- return title
- ?.replace('\n', ' ')
- ?.replace('\r', ' ')
- ?.replace(AGENT_SESSION_TITLE_WHITESPACE, " ")
- ?.trim()
- ?.takeIf { it.isNotEmpty() }
-}
-
-private val AGENT_SESSION_TITLE_WHITESPACE = Regex("\\s+")
diff --git a/plugins/agent-workbench/lib-agent/core/src/extensions/AgentWorkbenchExtensionPointSupport.kt b/plugins/agent-workbench/lib-agent/core/src/extensions/AgentWorkbenchExtensionPointSupport.kt
deleted file mode 100644
index 158e8644bc3c..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/extensions/AgentWorkbenchExtensionPointSupport.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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.platform.ai.agent.core.extensions
-
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.extensions.ExtensionPointName
-import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.sync.withLock
-
-private sealed interface OverrideState {
- data object Unset : OverrideState
-
- data class Value(val value: T) : OverrideState
-}
-
-class OverridableValue(
- private val fallback: () -> T,
-) {
- private val lock = Any()
-
- @Volatile
- private var overrideState: OverrideState = OverrideState.Unset
-
- fun value(): T {
- return when (val current = overrideState) {
- OverrideState.Unset -> fallback()
- is OverrideState.Value -> current.value
- }
- }
-
- fun withOverride(value: T, action: () -> R): R {
- return synchronized(lock) {
- val previous = overrideState
- overrideState = OverrideState.Value(value)
- try {
- action()
- }
- finally {
- overrideState = previous
- }
- }
- }
-}
-
-class SuspendingOverridableValue(
- private val fallback: () -> T,
-) {
- private val mutex = Mutex()
-
- @Volatile
- private var overrideState: OverrideState = OverrideState.Unset
-
- fun value(): T {
- return when (val current = overrideState) {
- OverrideState.Unset -> fallback()
- is OverrideState.Value -> current.value
- }
- }
-
- suspend fun withOverride(value: T, action: suspend () -> R): R {
- return mutex.withLock {
- val previous = overrideState
- overrideState = OverrideState.Value(value)
- try {
- action()
- }
- finally {
- overrideState = previous
- }
- }
- }
-}
-
-class SnapshotExtensionPointCache(
- private val log: Logger,
- private val extensionPoint: ExtensionPointName,
- private val cacheId: Class,
- private val emptySnapshot: S,
- private val unavailableMessage: String,
- private val buildSnapshot: (Iterable) -> S,
-) {
- fun getSnapshotOrEmpty(): S {
- return try {
- extensionPoint.computeIfAbsent(cacheId) {
- buildSnapshot(extensionPoint.extensionList)
- }
- }
- catch (t: IllegalStateException) {
- log.debug(unavailableMessage, t)
- emptySnapshot
- }
- catch (t: IllegalArgumentException) {
- log.debug(unavailableMessage, t)
- emptySnapshot
- }
- }
-}
-
-class SingleExtensionPointResolver(
- private val log: Logger,
- private val extensionPoint: ExtensionPointName,
- private val unavailableMessage: String,
- private val multipleExtensionsMessage: (List) -> String,
-) {
- fun findFirstOrNull(): T? {
- val extensions = try {
- extensionPoint.extensionList
- }
- catch (t: IllegalStateException) {
- log.debug(unavailableMessage, t)
- return null
- }
- catch (t: IllegalArgumentException) {
- log.debug(unavailableMessage, t)
- return null
- }
-
- if (extensions.size > 1) {
- log.warn(multipleExtensionsMessage(extensions))
- }
- return extensions.firstOrNull()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionArchiveTitles.kt b/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionArchiveTitles.kt
deleted file mode 100644
index 53e47e7900bf..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionArchiveTitles.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.platform.ai.agent.core.session
-
-const val AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX: String = "[archived] "
-
-data class AgentSessionArchivedTitleState(
- @JvmField val title: String,
- @JvmField val archived: Boolean,
-)
-
-fun resolveAgentSessionArchivedTitleState(rawTitle: String, defaultTitle: String): AgentSessionArchivedTitleState {
- val archived = isAgentSessionArchivedThreadTitle(rawTitle)
- val visibleTitle = normalizeAgentSessionStoredThreadTitle(stripAgentSessionArchivedThreadTitlePrefix(rawTitle))
- ?: defaultTitle
- return AgentSessionArchivedTitleState(title = visibleTitle, archived = archived)
-}
-
-fun buildAgentSessionArchivedThreadTitle(title: String, defaultTitle: String): String {
- return AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX + resolveAgentSessionArchivedTitleState(title, defaultTitle).title
-}
-
-fun isAgentSessionArchivedThreadTitle(title: String): Boolean {
- return title.startsWith(AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX)
-}
-
-fun stripAgentSessionArchivedThreadTitlePrefix(title: String): String {
- return if (isAgentSessionArchivedThreadTitle(title)) title.removePrefix(AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX) else title
-}
-
-fun normalizeAgentSessionStoredThreadTitle(value: String?): String? {
- val normalized = value
- ?.replace('\n', ' ')
- ?.replace('\r', ' ')
- ?.replace(Regex("\\s+"), " ")
- ?.trim()
- ?: return null
- return normalized.takeIf(String::isNotEmpty)
-}
diff --git a/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionCost.kt b/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionCost.kt
deleted file mode 100644
index f95fd39a032f..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionCost.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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.platform.ai.agent.core.session
-
-import java.math.BigDecimal
-
-enum class AgentSessionCostKind {
- EXACT,
- ESTIMATED,
- UNAVAILABLE,
-}
-
-data class AgentSessionCost(
- @JvmField val amountUsd: BigDecimal?,
- @JvmField val kind: AgentSessionCostKind,
- @JvmField val matchedModelId: String? = null,
-)
diff --git a/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionModels.kt b/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionModels.kt
deleted file mode 100644
index 8199469ad2f3..000000000000
--- a/plugins/agent-workbench/lib-agent/core/src/session/AgentSessionModels.kt
+++ /dev/null
@@ -1,288 +0,0 @@
-// 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.platform.ai.agent.core.session
-
-// @spec plugins/air/spec/sessions/agent-terminal-sessions.spec.md
-
-import com.intellij.platform.ai.agent.core.AgentThreadActivity
-import com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-import com.intellij.openapi.util.NlsSafe
-import java.util.IdentityHashMap
-
-private val AGENT_SESSION_PROVIDER_ID_REGEX = Regex("[a-z][a-z0-9._-]*")
-private val AGENT_SESSION_OUTLINE_WHITESPACE = Regex("\\s+")
-
-@JvmInline
-value class AgentSessionProvider private constructor(val value: String) {
- companion object {
- fun from(value: String): AgentSessionProvider {
- require(AGENT_SESSION_PROVIDER_ID_REGEX.matches(value)) {
- "Invalid provider id '$value'. Expected: ${AGENT_SESSION_PROVIDER_ID_REGEX.pattern}"
- }
- return AgentSessionProvider(value)
- }
-
- fun fromOrNull(value: String): AgentSessionProvider? {
- return if (AGENT_SESSION_PROVIDER_ID_REGEX.matches(value)) AgentSessionProvider(value) else null
- }
- }
-
- override fun toString(): String = value
-}
-
-enum class AgentSessionLaunchMode {
- STANDARD,
- YOLO,
-}
-
-data class AgentSubAgent(
- @JvmField val id: @NlsSafe String,
- @JvmField val name: @NlsSafe String,
- @JvmField val activity: AgentThreadActivity = AgentThreadActivity.READY,
-)
-
-data class AgentSessionThread(
- @JvmField val id: String,
- @JvmField val title: String,
- @JvmField val updatedAt: Long,
- @JvmField val archived: Boolean,
- @JvmField val activityReport: AgentThreadActivityReport = AgentThreadActivityReport.READY,
- val provider: AgentSessionProvider,
- @JvmField val subAgents: List = emptyList(),
- @JvmField val originBranch: String? = null,
- @JvmField val cost: AgentSessionCost? = null,
-)
-
-/**
- * Provider-neutral outline for a persisted agent thread.
- *
- * This is a role-aware conversation outline, not a dump of provider-specific log records. [items] are the visible roots in provider
- * history order. Providers should hide bookkeeping containers and expose user prompts, assistant responses, tool activity, plans,
- * approvals, and summaries with the closest [AgentSessionOutlineItemKind]. A `null` outline from a source means the provider cannot
- * load an outline for the thread; an empty [items] list means the outline is supported but has no visible entries.
- */
-data class AgentSessionThreadOutline(
- val provider: AgentSessionProvider,
- @JvmField val threadId: String,
- @JvmField val title: String,
- @JvmField val updatedAt: Long,
- @JvmField val items: List,
-) {
- val sessionId: String
- get() = threadId
-}
-
-/**
- * Visible item in an [AgentSessionThreadOutline].
- *
- * [id] must be unique within the outline and stable across reloads for the same provider record. If navigation or fork actions are
- * enabled for this item, [id] must be a provider/backend anchor rather than a UI ordinal. [kind] is semantic role data and should be
- * mapped from native provider roles, not chosen for presentation only. [title] is the primary row label; [preview] is supporting text
- * and may contain the message body when the title is intentionally blank. [children] describe ownership or causality, for example tool
- * calls and results under the assistant/work item that produced them.
- */
-data class AgentSessionOutlineItem(
- @JvmField val id: String,
- @JvmField val kind: AgentSessionOutlineItemKind,
- @JvmField val title: String,
- @JvmField val preview: String? = null,
- @JvmField val timestampMs: Long? = null,
- @JvmField val children: List = emptyList(),
-) {
- val timestampMillis: Long?
- get() = timestampMs
-}
-
-/**
- * Semantic role of an [AgentSessionOutlineItem].
- *
- * Providers should map native transcript roles to these values consistently so shared UI and actions can reason about the outline:
- * user-authored prompts use [USER_PROMPT], assistant text uses [ASSISTANT_RESPONSE], provider processing phases use [AGENT_WORK],
- * invocations use [TOOL_CALL], their outputs use [TOOL_RESULT], and internal or unknown records should be skipped or mapped to
- * [METADATA] instead of leaking raw provider event names.
- */
-enum class AgentSessionOutlineItemKind {
- USER_PROMPT,
- ASSISTANT_RESPONSE,
- AGENT_WORK,
- TOOL_CALL,
- TOOL_RESULT,
- PLAN,
- APPROVAL_REQUEST,
- INPUT_REQUEST,
- SUMMARY,
- METADATA,
-}
-
-/** Mutable helper for constructing nested [AgentSessionOutlineItem] trees. */
-class AgentSessionOutlineItemBuilder(
- @JvmField val id: String,
- @JvmField var kind: AgentSessionOutlineItemKind,
- @JvmField var title: String,
- @JvmField var preview: String?,
- @JvmField val timestampMs: Long?,
- @JvmField val summarizesChildren: Boolean = false,
- @JvmField val children: MutableList = ArrayList(),
-) {
- fun build(): AgentSessionOutlineItem {
- val builtChildren = children.map(AgentSessionOutlineItemBuilder::build)
- return AgentSessionOutlineItem(
- id = id,
- kind = kind,
- title = title,
- preview = if (summarizesChildren && builtChildren.isNotEmpty()) summarizeAgentSessionOutlineChildren(builtChildren) else preview,
- timestampMs = timestampMs,
- children = builtChildren,
- )
- }
-}
-
-/**
- * Flat source record used by [buildAgentSessionOutlineTree].
- *
- * [parentId] links provider records before they are converted to visible outline items. Set [visible] to `false` for bookkeeping
- * containers such as raw turns or sessions; their visible descendants are promoted to the nearest visible ancestor or to the root.
- * Records with missing, blank, or self-referential parents become roots. Duplicate ids keep the first record.
- */
-data class AgentSessionOutlineTreeRecord(
- @JvmField val id: String,
- @JvmField val parentId: String?,
- @JvmField val kind: AgentSessionOutlineItemKind,
- @JvmField val title: String,
- @JvmField val preview: String? = null,
- @JvmField val timestampMs: Long? = null,
- @JvmField val visible: Boolean = true,
-)
-
-/**
- * Builds a visible outline tree from flat provider records.
- *
- * Returned roots and siblings are ordered by [AgentSessionOutlineTreeRecord.timestampMs] when present, then by input order. Invisible
- * records are not returned, but their visible descendants are preserved and promoted. This lets providers keep raw parent/child
- * relationships for future navigation while presenting a flat, role-aware conversation timeline.
- */
-fun buildAgentSessionOutlineTree(records: List): List {
- if (records.isEmpty()) {
- return emptyList()
- }
-
- val nodesById = LinkedHashMap(records.size)
- records.forEachIndexed { index, record ->
- val id = record.id.trim().takeIf { it.isNotEmpty() } ?: return@forEachIndexed
- nodesById.putIfAbsent(id, AgentSessionOutlineTreeNode(record = record, order = index))
- }
-
- val roots = ArrayList()
- for (node in nodesById.values) {
- val parentId = node.record.parentId?.trim()?.takeIf { it.isNotEmpty() && it != node.record.id }
- val parent = parentId?.let(nodesById::get)
- if (parent == null) {
- roots += node
- }
- else {
- parent.children += node
- }
- }
- return buildVisibleOutlineItems(roots)
-}
-
-fun normalizeAgentSessionOutlinePreview(value: String?, maxLength: Int = 160): String? {
- val normalized = value
- ?.replace('\n', ' ')
- ?.replace('\r', ' ')
- ?.replace(AGENT_SESSION_OUTLINE_WHITESPACE, " ")
- ?.trim()
- ?.takeIf { it.isNotEmpty() }
- ?: return null
- return if (normalized.length <= maxLength) normalized else normalized.take(maxLength - 3).trimEnd() + "..."
-}
-
-fun compactAgentSessionOutlineText(value: String?, maxLength: Int): String? {
- return normalizeAgentSessionOutlinePreview(value, maxLength = maxLength)
-}
-
-fun agentSessionOutlinePhaseTitle(preview: String?, maxLength: Int = 90): String? {
- val normalizedPreview = normalizeAgentSessionOutlinePreview(preview) ?: return null
- val sentenceEnd = normalizedPreview.indexOfAny(charArrayOf('.', '!', '?'))
- val firstSentence = if (sentenceEnd > 0) normalizedPreview.take(sentenceEnd + 1) else normalizedPreview
- return firstSentence.take(maxLength).trimEnd().takeIf { it.isNotEmpty() }
-}
-
-fun dedupeAgentSessionOutlineText(value: String): String {
- return value.replace(AGENT_SESSION_OUTLINE_WHITESPACE, " ").trim().lowercase()
-}
-
-fun summarizeAgentSessionOutlineChildren(children: List): String? {
- val parts = ArrayList(6)
- addAgentSessionOutlineCount(parts, children.count { it.kind == AgentSessionOutlineItemKind.TOOL_CALL }, "tool")
- addAgentSessionOutlineCount(parts, children.count { it.kind == AgentSessionOutlineItemKind.TOOL_RESULT }, "result")
- addAgentSessionOutlineCount(parts, children.count { it.kind == AgentSessionOutlineItemKind.PLAN }, "plan")
- addAgentSessionOutlineCount(parts, children.count { it.kind == AgentSessionOutlineItemKind.APPROVAL_REQUEST }, "approval")
- addAgentSessionOutlineCount(parts, children.count { it.kind == AgentSessionOutlineItemKind.INPUT_REQUEST }, "input request")
- addAgentSessionOutlineCount(parts, children.count { it.kind == AgentSessionOutlineItemKind.AGENT_WORK }, "work item")
- return parts.joinToString(", ").takeIf { it.isNotEmpty() }
-}
-
-private fun buildVisibleOutlineItems(roots: List): List {
- val builtByNode = IdentityHashMap>()
- val stack = ArrayDeque()
- roots.sortedWith(AGENT_SESSION_OUTLINE_TREE_NODE_COMPARATOR).asReversed().forEach { root ->
- stack.addLast(AgentSessionOutlineTreeStackFrame(root, childrenVisited = false))
- }
-
- while (stack.isNotEmpty()) {
- val frame = stack.removeLast()
- val node = frame.node
- if (!frame.childrenVisited) {
- stack.addLast(AgentSessionOutlineTreeStackFrame(node, childrenVisited = true))
- node.children.sortedWith(AGENT_SESSION_OUTLINE_TREE_NODE_COMPARATOR).asReversed().forEach { child ->
- stack.addLast(AgentSessionOutlineTreeStackFrame(child, childrenVisited = false))
- }
- continue
- }
-
- val builtChildren = node.children.sortedWith(AGENT_SESSION_OUTLINE_TREE_NODE_COMPARATOR)
- .flatMap { child -> builtByNode.remove(child).orEmpty() }
- val record = node.record
- builtByNode[node] = if (record.visible) {
- listOf(
- AgentSessionOutlineItem(
- id = record.id,
- kind = record.kind,
- title = record.title,
- preview = normalizeAgentSessionOutlinePreview(record.preview),
- timestampMs = record.timestampMs,
- children = builtChildren,
- )
- )
- }
- else {
- builtChildren
- }
- }
-
- return roots.sortedWith(AGENT_SESSION_OUTLINE_TREE_NODE_COMPARATOR)
- .flatMap { root -> builtByNode[root].orEmpty() }
-}
-
-private fun addAgentSessionOutlineCount(parts: MutableList, count: Int, label: String) {
- if (count <= 0) {
- return
- }
- parts += "$count ${if (count == 1) label else label + "s"}"
-}
-
-private data class AgentSessionOutlineTreeNode(
- @JvmField val record: AgentSessionOutlineTreeRecord,
- @JvmField val order: Int,
- @JvmField val children: MutableList = ArrayList(),
-)
-
-private data class AgentSessionOutlineTreeStackFrame(
- @JvmField val node: AgentSessionOutlineTreeNode,
- @JvmField val childrenVisited: Boolean,
-)
-
-private val AGENT_SESSION_OUTLINE_TREE_NODE_COMPARATOR = compareBy(
- { node -> node.record.timestampMs ?: Long.MAX_VALUE },
- { node -> node.order },
-)
diff --git a/plugins/agent-workbench/lib-agent/core/testSrc/AgentSessionArchiveTitlesTest.kt b/plugins/agent-workbench/lib-agent/core/testSrc/AgentSessionArchiveTitlesTest.kt
deleted file mode 100644
index d072849231c1..000000000000
--- a/plugins/agent-workbench/lib-agent/core/testSrc/AgentSessionArchiveTitlesTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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.platform.ai.agent.core
-
-import com.intellij.platform.ai.agent.core.session.AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX
-import com.intellij.platform.ai.agent.core.session.buildAgentSessionArchivedThreadTitle
-import com.intellij.platform.ai.agent.core.session.resolveAgentSessionArchivedTitleState
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-
-class AgentSessionArchiveTitlesTest {
- @Test
- fun `archived title prefix is stripped from visible title`() {
- val state = resolveAgentSessionArchivedTitleState("${AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX}Fix tests", defaultTitle = "Fallback")
-
- assertThat(state.archived).isTrue()
- assertThat(state.title).isEqualTo("Fix tests")
- }
-
- @Test
- fun `missing visible title falls back to default`() {
- val state = resolveAgentSessionArchivedTitleState(AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX, defaultTitle = "Fallback")
-
- assertThat(state.archived).isTrue()
- assertThat(state.title).isEqualTo("Fallback")
- }
-
- @Test
- fun `building archived title does not duplicate prefix`() {
- val archivedTitle =
- buildAgentSessionArchivedThreadTitle("${AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX}Fix tests", defaultTitle = "Fallback")
-
- assertThat(archivedTitle).isEqualTo("${AGENT_SESSION_ARCHIVED_THREAD_TITLE_PREFIX}Fix tests")
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/core/testSrc/AgentSessionOutlineTreeTest.kt b/plugins/agent-workbench/lib-agent/core/testSrc/AgentSessionOutlineTreeTest.kt
deleted file mode 100644
index 36788fda04c1..000000000000
--- a/plugins/agent-workbench/lib-agent/core/testSrc/AgentSessionOutlineTreeTest.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.platform.ai.agent.core
-
-import com.intellij.platform.ai.agent.core.session.AgentSessionOutlineItemKind
-import com.intellij.platform.ai.agent.core.session.AgentSessionOutlineTreeRecord
-import com.intellij.platform.ai.agent.core.session.buildAgentSessionOutlineTree
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-
-class AgentSessionOutlineTreeTest {
- @Test
- fun `hidden bookkeeping records promote visible children`() {
- val items = buildAgentSessionOutlineTree(
- listOf(
- record(id = "user", parentId = null, kind = AgentSessionOutlineItemKind.USER_PROMPT, title = "User", timestampMs = 1_000L),
- record(id = "label", parentId = "user", visible = false, timestampMs = 2_000L),
- record(id = "assistant",
- parentId = "label",
- kind = AgentSessionOutlineItemKind.ASSISTANT_RESPONSE,
- title = "Done",
- timestampMs = 3_000L),
- )
- )
-
- assertThat(items).hasSize(1)
- assertThat(items.single().id).isEqualTo("user")
- assertThat(items.single().children.map { it.id }).containsExactly("assistant")
- }
-
- @Test
- fun `missing and self parents become timestamp ordered roots`() {
- val items = buildAgentSessionOutlineTree(
- listOf(
- record(id = "late", parentId = "missing", title = "Late", timestampMs = 3_000L),
- record(id = "early", parentId = "early", title = "Early", timestampMs = 1_000L),
- )
- )
-
- assertThat(items.map { it.id }).containsExactly("early", "late")
- }
-
- private fun record(
- id: String,
- parentId: String?,
- kind: AgentSessionOutlineItemKind = AgentSessionOutlineItemKind.METADATA,
- title: String = "Metadata",
- timestampMs: Long?,
- visible: Boolean = true,
- ): AgentSessionOutlineTreeRecord {
- return AgentSessionOutlineTreeRecord(
- id = id,
- parentId = parentId,
- kind = kind,
- title = title,
- timestampMs = timestampMs,
- visible = visible,
- )
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/core/testSrc/AgentThreadIdentityTest.kt b/plugins/agent-workbench/lib-agent/core/testSrc/AgentThreadIdentityTest.kt
deleted file mode 100644
index ab3f5fba490a..000000000000
--- a/plugins/agent-workbench/lib-agent/core/testSrc/AgentThreadIdentityTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.platform.ai.agent.core
-
-import org.assertj.core.api.Assertions.assertThat
-import org.assertj.core.api.Assertions.assertThatThrownBy
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import java.util.concurrent.TimeUnit
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class AgentThreadIdentityTest {
- @Test
- fun buildsAndParsesValidIdentity() {
- val identity = buildAgentThreadIdentity(providerId = "codex", threadId = "thread-1")
-
- assertThat(identity).isEqualTo("codex:thread-1")
- assertThat(parseAgentThreadIdentity(identity)).isEqualTo(AgentThreadIdentity(providerId = "codex", threadId = "thread-1"))
- }
-
- @Test
- fun rejectsInvalidProviderIdWhenBuildingIdentity() {
- assertThatThrownBy { buildAgentThreadIdentity(providerId = "Codex", threadId = "thread-1") }
- .isInstanceOf(IllegalArgumentException::class.java)
- .hasMessageContaining("Invalid provider id")
- }
-
- @Test
- fun rejectsBlankThreadIdWhenBuildingIdentity() {
- assertThatThrownBy { buildAgentThreadIdentity(providerId = "codex", threadId = " ") }
- .isInstanceOf(IllegalArgumentException::class.java)
- .hasMessageContaining("Thread id must not be blank")
- }
-
- @Test
- fun rejectsMalformedIdentityWhenParsing() {
- assertThat(parseAgentThreadIdentity("codex")).isNull()
- assertThat(parseAgentThreadIdentity("Codex:thread-1")).isNull()
- assertThat(parseAgentThreadIdentity("codex: ")).isNull()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/core/testSrc/AgentWorkbenchPathUtilTest.kt b/plugins/agent-workbench/lib-agent/core/testSrc/AgentWorkbenchPathUtilTest.kt
deleted file mode 100644
index 3ffe090d1b8b..000000000000
--- a/plugins/agent-workbench/lib-agent/core/testSrc/AgentWorkbenchPathUtilTest.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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.platform.ai.agent.core
-
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import java.nio.file.Path
-import java.util.concurrent.TimeUnit
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class AgentWorkbenchPathUtilTest {
- @Test
- fun parsesAndNormalizesValidPaths() {
- val nativePath = Path.of("workspace", "child").toString()
-
- assertThat(parseAgentWorkbenchPathOrNull(nativePath)).isEqualTo(Path.of("workspace", "child"))
- assertThat(normalizeAgentWorkbenchPath(nativePath)).isEqualTo("workspace/child")
- assertThat(normalizeAgentWorkbenchPathOrNull(nativePath)).isEqualTo("workspace/child")
- }
-
- @Test
- fun preservesInvalidPathsWhenNormalizationFails() {
- val invalidPath = "bad" + '\u0000' + "path"
-
- assertThat(parseAgentWorkbenchPathOrNull(invalidPath)).isNull()
- assertThat(normalizeAgentWorkbenchPath(invalidPath)).isEqualTo(invalidPath)
- assertThat(normalizeAgentWorkbenchPathOrNull(invalidPath)).isNull()
- }
-
- @Test
- fun normalizesAgentSessionProjectPaths() {
- val nativePath = Path.of("workspace", "child").toString()
-
- assertThat(normalizeAgentSessionProjectPath(" $nativePath/ ")).isEqualTo("workspace/child")
- assertThat(normalizeAgentSessionProjectPath("/")).isEqualTo("/")
- assertThat(normalizeAgentSessionProjectPath(" ")).isNull()
- assertThat(normalizeAgentSessionProjectPath("bad" + '\u0000' + "path")).isNull()
- }
-
- @Test
- fun normalizesAgentSessionTitles() {
- assertThat(normalizeAgentSessionTitle(" first\nsecond\tthird\r ")).isEqualTo("first second third")
- assertThat(normalizeAgentSessionTitle(" ")).isNull()
- assertThat(normalizeAgentSessionTitle(null)).isNull()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/BUILD.bazel b/plugins/agent-workbench/lib-agent/filewatch/BUILD.bazel
deleted file mode 100644
index 7c0de5ff40ba..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/BUILD.bazel
+++ /dev/null
@@ -1,115 +0,0 @@
-load("@community//build:tests-options.bzl", "jps_test")
-load("@rules_jvm//:jvm.bzl", "jvm_library")
-
-### auto-generated section `build intellij.platform.ai.agent.filewatch` start
-
-jvm_library(
- name = "filewatch",
- srcs = glob(
- [
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/*.form",
- ],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.filewatch",
- resource_strip_prefix = "resources",
- resources = glob(
- ["resources/**/*"],
- ),
- visibility = ["//visibility:public"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//libraries/kotlinx/coroutines/core",
- "@lib//:jna",
- "//platform/util",
- ],
-)
-
-jvm_library(
- name = "filewatch_test_lib",
- testonly = True,
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.filewatch",
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":filewatch",
- "//libraries/kotlinx/coroutines/core:core_test_lib",
- "//platform/util:util_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.filewatch` end
-
-### auto-generated section `iml intellij.platform.ai.agent.filewatch` start
-exports_files(
- [
- "intellij.platform.ai.agent.filewatch.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.filewatch` end
-
-### auto-generated section `build intellij.platform.ai.agent.filewatch.tests` start
-
-jvm_library(
- name = "ai-agent-filewatch-tests",
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.filewatch.tests",
- visibility = ["//visibility:public"],
-)
-
-jvm_library(
- name = "ai-agent-filewatch-tests_test_lib",
- testonly = True,
- srcs = glob(
- [
- "testSrc/**/*.kt",
- "testSrc/**/*.java",
- "testSrc/**/*.form",
- ],
- allow_empty = True,
- ),
- associates = [
- "//plugins/agent-workbench/lib-agent/filewatch",
- "//plugins/agent-workbench/lib-agent/filewatch:filewatch_test_lib",
- ],
- visibility = ["//visibility:public"],
- runtime_deps = [":ai-agent-filewatch-tests"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//libraries/kotlinx/coroutines/core",
- "//libraries/kotlinx/coroutines/core:core_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.filewatch.tests` end
-
-### auto-generated section `iml intellij.platform.ai.agent.filewatch.tests` start
-exports_files(
- [
- "intellij.platform.ai.agent.filewatch.tests.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.filewatch.tests` end
-
-### auto-generated section `test intellij.platform.ai.agent.filewatch.tests` start
-
-jps_test(
- name = "ai-agent-filewatch-tests_test",
- runtime_deps = [":ai-agent-filewatch-tests_test_lib"],
-)
-### auto-generated section `test intellij.platform.ai.agent.filewatch.tests` end
diff --git a/plugins/agent-workbench/lib-agent/filewatch/api-dump.txt b/plugins/agent-workbench/lib-agent/filewatch/api-dump.txt
deleted file mode 100644
index f213de6dbeed..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/api-dump.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-f:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchDirectoryWatcher
-- java.lang.AutoCloseable
-- (java.util.Collection,kotlinx.coroutines.CoroutineScope,kotlin.jvm.functions.Function2,kotlin.jvm.functions.Function2):V
-- b:(java.util.Collection,kotlinx.coroutines.CoroutineScope,kotlin.jvm.functions.Function2,kotlin.jvm.functions.Function2,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- close():V
-- f:closeAndJoin(kotlin.coroutines.Continuation):java.lang.Object
-- f:isActive():Z
-f:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent
-- f:count:I
-- f:eventType:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- f:isDirectory:Z
-- f:path:java.nio.file.Path
-- f:rootPath:java.nio.file.Path
-- (com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType,java.nio.file.Path,java.nio.file.Path,Z,I):V
-- f:component1():com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- f:component2():java.nio.file.Path
-- f:component3():java.nio.file.Path
-- f:component4():Z
-- f:component5():I
-- f:copy(com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType,java.nio.file.Path,java.nio.file.Path,Z,I):com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent
-- bs:copy$default(com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent,com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType,java.nio.file.Path,java.nio.file.Path,Z,I,I,java.lang.Object):com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent
-- equals(java.lang.Object):Z
-- hashCode():I
-e:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- java.lang.Enum
-- sf:CREATE:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- sf:DELETE:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- sf:MODIFY:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- sf:OVERFLOW:com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-- s:values():com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType[]
-com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchLoop
-- java.lang.AutoCloseable
-- a:watch(kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.filewatch.ImmediateFileChangeFlowKt
-- sf:agentWorkbenchImmediateFileChangeFlow(java.util.Collection):kotlinx.coroutines.flow.Flow
diff --git a/plugins/agent-workbench/lib-agent/filewatch/exposed-third-party-api.txt b/plugins/agent-workbench/lib-agent/filewatch/exposed-third-party-api.txt
deleted file mode 100644
index 1ff3abdfef32..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/exposed-third-party-api.txt
+++ /dev/null
@@ -1 +0,0 @@
-kotlin/jvm/internal/DefaultConstructorMarker
diff --git a/plugins/agent-workbench/lib-agent/filewatch/intellij.platform.ai.agent.filewatch.iml b/plugins/agent-workbench/lib-agent/filewatch/intellij.platform.ai.agent.filewatch.iml
deleted file mode 100644
index 3295f14679d4..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/intellij.platform.ai.agent.filewatch.iml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/filewatch/intellij.platform.ai.agent.filewatch.tests.iml b/plugins/agent-workbench/lib-agent/filewatch/intellij.platform.ai.agent.filewatch.tests.iml
deleted file mode 100644
index 602c993deae3..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/intellij.platform.ai.agent.filewatch.tests.iml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/filewatch/resources/intellij.platform.ai.agent.filewatch.xml b/plugins/agent-workbench/lib-agent/filewatch/resources/intellij.platform.ai.agent.filewatch.xml
deleted file mode 100644
index 6fb76a66265d..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/resources/intellij.platform.ai.agent.filewatch.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/AgentWorkbenchDirectoryWatcher.kt b/plugins/agent-workbench/lib-agent/filewatch/src/AgentWorkbenchDirectoryWatcher.kt
deleted file mode 100644
index 71510d351de9..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/AgentWorkbenchDirectoryWatcher.kt
+++ /dev/null
@@ -1,205 +0,0 @@
-// 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.platform.ai.agent.filewatch
-
-import com.intellij.platform.ai.agent.filewatch.impl.DirectoryChangeEvent
-import com.intellij.platform.ai.agent.filewatch.impl.DirectoryChangeListener
-import com.intellij.platform.ai.agent.filewatch.impl.DirectoryWatcher
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.cancelAndJoin
-import kotlinx.coroutines.launch
-import java.nio.file.Files
-import java.nio.file.Path
-import java.util.concurrent.atomic.AtomicBoolean
-
-enum class AgentWorkbenchWatchEventType {
- CREATE,
- MODIFY,
- DELETE,
- OVERFLOW,
-}
-
-data class AgentWorkbenchWatchEvent(
- @JvmField val eventType: AgentWorkbenchWatchEventType,
- @JvmField val path: Path?,
- @JvmField val rootPath: Path?,
- @JvmField val isDirectory: Boolean,
- @JvmField val count: Int,
-)
-
-class AgentWorkbenchDirectoryWatcher private constructor(
- roots: Collection,
- scope: CoroutineScope,
- private val onWatchEvent: suspend (AgentWorkbenchWatchEvent) -> Unit,
- private val onFailure: suspend (Throwable) -> Unit = {},
- private val watchLoopFactory: (List, DirectoryChangeListener) -> AgentWorkbenchWatchLoop,
- @Suppress("unused") private val constructorMarker: Unit,
-) : AutoCloseable {
- private val roots = roots.toList()
- private val running = AtomicBoolean(true)
- @Volatile
- private var watchLoop: AgentWorkbenchWatchLoop?
- private val watcherJob: Job?
-
- constructor(
- roots: Collection,
- scope: CoroutineScope,
- onWatchEvent: suspend (AgentWorkbenchWatchEvent) -> Unit,
- onFailure: suspend (Throwable) -> Unit = {},
- ) : this(roots, scope, onWatchEvent, onFailure, ::createDefaultWatchLoop, Unit)
-
- internal constructor(
- roots: Collection,
- scope: CoroutineScope,
- onWatchEvent: suspend (AgentWorkbenchWatchEvent) -> Unit,
- onFailure: suspend (Throwable) -> Unit = {},
- watchLoopFactory: (List, DirectoryChangeListener) -> AgentWorkbenchWatchLoop,
- ) : this(roots, scope, onWatchEvent, onFailure, watchLoopFactory, Unit)
-
- init {
- watchLoop = createWatchLoop(roots)
- watcherJob = if (watchLoop != null) {
- scope.launch(Dispatchers.IO) {
- runWatchLoops()
- }
- }
- else {
- null
- }
- }
-
- val isActive: Boolean
- get() = watchLoop != null && watcherJob?.isActive == true
-
- override fun close() {
- if (!running.compareAndSet(true, false)) return
- watcherJob?.cancel()
- watchLoop?.let { watcher ->
- runCatching {
- watcher.close()
- }
- }
- }
-
- @Suppress("unused")
- suspend fun closeAndJoin() {
- if (running.compareAndSet(true, false)) {
- watcherJob?.cancel()
- runCatching {
- watchLoop?.close()
- }.onFailure { t ->
- onFailure(t)
- }
- }
- watcherJob?.cancelAndJoin()
- }
-
- private fun createWatchLoop(roots: Collection): AgentWorkbenchWatchLoop? {
- val watchRoots = LinkedHashSet()
- for (root in roots) {
- val normalizedPath = normalizeWatchPath(root)
- if (Files.isDirectory(normalizedPath)) {
- watchRoots.add(normalizedPath)
- }
- }
- if (watchRoots.isEmpty()) {
- return null
- }
-
- val listener = object : DirectoryChangeListener {
- override suspend fun onEvent(event: DirectoryChangeEvent) {
- if (running.get()) {
- onWatchEvent(event.toAgentWorkbenchWatchEvent())
- }
- }
-
- override suspend fun onException(e: Exception) {
- if (running.get()) {
- onFailure(e)
- }
- }
- }
- return watchLoopFactory(ArrayList(watchRoots), listener)
- }
-
- private suspend fun runWatchLoops() {
- while (running.get()) {
- val watcher = watchLoop ?: return
- val shouldRestart = try {
- watcher.watch()
- false
- }
- catch (e: CancellationException) {
- throw e
- }
- catch (t: Throwable) {
- if (running.get()) {
- onFailure(t)
- true
- }
- else {
- false
- }
- }
- finally {
- if (watchLoop === watcher) {
- watchLoop = null
- }
- runCatching {
- watcher.close()
- }.onFailure { t ->
- if (running.get()) {
- onFailure(t)
- }
- }
- }
-
- if (!shouldRestart || !running.get()) {
- return
- }
- watchLoop = createWatchLoop(roots)
- }
- }
-}
-
-interface AgentWorkbenchWatchLoop : AutoCloseable {
- suspend fun watch()
-}
-
-private fun createDefaultWatchLoop(paths: List, listener: DirectoryChangeListener): AgentWorkbenchWatchLoop {
- val watcher = DirectoryWatcher(paths, listener)
- return object : AgentWorkbenchWatchLoop {
- override suspend fun watch() {
- watcher.watch()
- }
-
- override fun close() {
- watcher.close()
- }
- }
-}
-
-private fun DirectoryChangeEvent.toAgentWorkbenchWatchEvent(): AgentWorkbenchWatchEvent {
- return AgentWorkbenchWatchEvent(
- eventType = when (eventType) {
- DirectoryChangeEvent.EventType.CREATE -> AgentWorkbenchWatchEventType.CREATE
- DirectoryChangeEvent.EventType.MODIFY -> AgentWorkbenchWatchEventType.MODIFY
- DirectoryChangeEvent.EventType.DELETE -> AgentWorkbenchWatchEventType.DELETE
- DirectoryChangeEvent.EventType.OVERFLOW -> AgentWorkbenchWatchEventType.OVERFLOW
- },
- path = path,
- rootPath = rootPath,
- isDirectory = isDirectory,
- count = count,
- )
-}
-
-private fun normalizeWatchPath(path: Path): Path {
- return runCatching {
- path.toAbsolutePath().normalize()
- }.getOrElse {
- path.normalize()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/ImmediateFileChangeFlow.kt b/plugins/agent-workbench/lib-agent/filewatch/src/ImmediateFileChangeFlow.kt
deleted file mode 100644
index ef7787052227..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/ImmediateFileChangeFlow.kt
+++ /dev/null
@@ -1,224 +0,0 @@
-// 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.platform.ai.agent.filewatch
-
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.KEvent
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_EVENT_ADD
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_EVENT_CLEAR
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_EVENT_FILTER_VNODE
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_NOTE_DELETE
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_NOTE_EXTEND
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_NOTE_RENAME
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_NOTE_REVOKE
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_NOTE_WRITE
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_QUEUE_OPEN_EVENT_ONLY
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.macKQueueApi
-import com.intellij.openapi.util.SystemInfoRt.isMac
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.emptyFlow
-import java.nio.file.Files
-import java.nio.file.Path
-
-fun agentWorkbenchImmediateFileChangeFlow(paths: Collection): Flow {
- if (!isMac || paths.isEmpty()) {
- return emptyFlow()
- }
- val normalizedPaths = paths.asSequence()
- .map(::normalizeImmediateWatchPath)
- .distinct()
- .toList()
- if (normalizedPaths.isEmpty()) {
- return emptyFlow()
- }
-
- return callbackFlow {
- val watcher = MacOSXImmediateFileChangeWatcher.create(
- paths = normalizedPaths,
- onModify = { path -> trySend(path).isSuccess },
- onEmpty = { close() },
- )
- if (watcher == null) {
- close()
- return@callbackFlow
- }
- awaitClose {
- watcher.close()
- }
- }
-}
-
-private class MacOSXImmediateFileChangeWatcher private constructor(
- private val kqueueFd: Int,
- private val onModify: (Path) -> Unit,
- private val onEmpty: () -> Unit,
-) : AutoCloseable {
- companion object {
- fun create(paths: Collection, onModify: (Path) -> Unit, onEmpty: () -> Unit): MacOSXImmediateFileChangeWatcher? {
- val kqueueFd = runCatching {
- macKQueueApi.kqueue()
- }.getOrDefault(-1)
- if (kqueueFd < 0) {
- return null
- }
-
- val watcher = MacOSXImmediateFileChangeWatcher(kqueueFd, onModify, onEmpty)
- for (path in paths) {
- watcher.watch(path)
- }
- if (!watcher.hasWatchedFiles()) {
- watcher.close()
- return null
- }
- watcher.start()
- return watcher
- }
- }
-
- private val lock = Any()
- private val watchedFiles = LinkedHashMap()
- private val watchedFds = HashMap()
- @Volatile
- private var closed = false
-
- private fun start() {
- Thread({ runEventLoop() }, "Agent Workbench macOS immediate file watcher").apply {
- isDaemon = true
- start()
- }
- }
-
- private fun hasWatchedFiles(): Boolean {
- return synchronized(lock) {
- watchedFiles.isNotEmpty()
- }
- }
-
- private fun watch(path: Path) {
- if (!Files.isRegularFile(path)) {
- return
- }
- synchronized(lock) {
- if (closed || path in watchedFiles) {
- return
- }
- }
-
- val fd = runCatching {
- macKQueueApi.open(path.toString(), K_QUEUE_OPEN_EVENT_ONLY)
- }.getOrDefault(-1)
- if (fd < 0) {
- return
- }
-
- var registered = false
- try {
- val event = KEvent(
- ident = fd,
- filter = K_EVENT_FILTER_VNODE,
- flags = (K_EVENT_ADD.toInt() or K_EVENT_CLEAR.toInt()).toShort(),
- fflags = K_NOTE_WRITE or K_NOTE_EXTEND or K_NOTE_DELETE or K_NOTE_RENAME or K_NOTE_REVOKE,
- )
- val result = runCatching {
- macKQueueApi.kevent(kqueueFd, event, 1, null, 0, null)
- }.getOrDefault(-1)
- if (result < 0) {
- return
- }
- val watchedFile = WatchedFile(path, fd)
- synchronized(lock) {
- if (!closed && path !in watchedFiles) {
- watchedFiles[path] = watchedFile
- watchedFds[fd] = watchedFile
- registered = true
- }
- }
- }
- finally {
- if (!registered) {
- closeFileDescriptor(fd)
- }
- }
- }
-
- private fun unwatch(path: Path) {
- removeWatch(path)?.let { watchedFile ->
- closeFileDescriptor(watchedFile.fd)
- }
- }
-
- override fun close() {
- val watchedFilesToClose = synchronized(lock) {
- if (closed) {
- return
- }
- closed = true
- val files = ArrayList(watchedFiles.values)
- watchedFiles.clear()
- watchedFds.clear()
- files
- }
- closeFileDescriptor(kqueueFd)
- for ((_, fd) in watchedFilesToClose) {
- closeFileDescriptor(fd)
- }
- }
-
- private fun runEventLoop() {
- while (!closed) {
- val event = KEvent()
- val result = runCatching {
- macKQueueApi.kevent(kqueueFd, null, 0, event, 1, null)
- }.getOrDefault(-1)
- if (result < 0) {
- return
- }
- if (result == 0) {
- continue
- }
- handleEvent(event)
- }
- }
-
- private fun handleEvent(event: KEvent) {
- val fd = event.ident.toInt()
- val watchedFile = synchronized(lock) {
- watchedFds[fd]
- } ?: return
-
- val flags = event.fflags
- if (flags and (K_NOTE_WRITE or K_NOTE_EXTEND) != 0) {
- onModify(watchedFile.path)
- }
- if (flags and (K_NOTE_DELETE or K_NOTE_RENAME or K_NOTE_REVOKE) != 0) {
- unwatch(watchedFile.path)
- if (!hasWatchedFiles()) {
- onEmpty()
- }
- }
- }
-
- private fun removeWatch(path: Path): WatchedFile? {
- return synchronized(lock) {
- val watchedFile = watchedFiles.remove(path) ?: return@synchronized null
- watchedFds.remove(watchedFile.fd)
- watchedFile
- }
- }
-
- private fun closeFileDescriptor(fd: Int) {
- runCatching {
- macKQueueApi.close(fd)
- }
- }
-
- private data class WatchedFile(@JvmField val path: Path, @JvmField val fd: Int)
-}
-
-private fun normalizeImmediateWatchPath(path: Path): Path {
- return runCatching {
- path.toAbsolutePath().normalize()
- }.getOrElse {
- path.normalize()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryChangeEvent.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryChangeEvent.kt
deleted file mode 100644
index b2ff2b8cc5a7..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryChangeEvent.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl
-
-import java.nio.file.Path
-
-internal data class DirectoryChangeEvent(
- val eventType: EventType,
- val isDirectory: Boolean,
- val path: Path?,
- val count: Int,
- val rootPath: Path?,
-) {
- internal enum class EventType {
- CREATE,
- MODIFY,
- DELETE,
- OVERFLOW,
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryChangeListener.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryChangeListener.kt
deleted file mode 100644
index 70223eb8af82..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryChangeListener.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl
-
-internal fun interface DirectoryChangeListener {
- suspend fun onEvent(event: DirectoryChangeEvent)
-
- suspend fun onException(e: Exception) {
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryWatcher.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryWatcher.kt
deleted file mode 100644
index 08982e7aac30..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/DirectoryWatcher.kt
+++ /dev/null
@@ -1,211 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl
-
-import com.intellij.platform.ai.agent.filewatch.impl.DirectoryChangeEvent.EventType
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.MacOSXListeningWatchService
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.WatchablePath
-import com.intellij.openapi.diagnostic.debug
-import com.intellij.openapi.diagnostic.logger
-import com.sun.nio.file.ExtendedWatchEventModifier
-import kotlinx.coroutines.currentCoroutineContext
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.runInterruptible
-import java.nio.file.ClosedWatchServiceException
-import java.nio.file.FileSystems
-import java.nio.file.Files
-import java.nio.file.LinkOption.NOFOLLOW_LINKS
-import java.nio.file.Path
-import java.nio.file.StandardWatchEventKinds.ENTRY_CREATE
-import java.nio.file.StandardWatchEventKinds.ENTRY_DELETE
-import java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY
-import java.nio.file.StandardWatchEventKinds.OVERFLOW
-import java.nio.file.WatchEvent
-import java.nio.file.WatchKey
-import java.nio.file.WatchService
-import java.nio.file.Watchable
-import java.util.concurrent.ConcurrentHashMap
-import java.util.concurrent.atomic.AtomicBoolean
-
-private val LOG = logger()
-
-internal class DirectoryWatcher(
- paths: List,
- private val listener: DirectoryChangeListener,
- private val watchService: WatchService = createDefaultWatchService(),
- private val fileTreeVisitor: FileTreeVisitor = DefaultFileTreeVisitor,
- private val watchablePathFactory: (Path) -> Watchable = if (watchService is MacOSXListeningWatchService) ::WatchablePath else { path -> path },
-) : AutoCloseable {
- private val paths = paths.map { path -> path.toAbsolutePath() }
- private val isMac = watchService is MacOSXListeningWatchService
- private val registeredPathToRootPath = HashMap()
- private val directories = ConcurrentHashMap.newKeySet()
- private val keyRoots = ConcurrentHashMap()
- private val closed = AtomicBoolean()
- private var fileTreeSupported: Boolean? = null
-
- suspend fun watch() {
- check(!closed.get()) { "watcher already closed" }
- use {
- registerPaths()
- runEventLoop()
- }
- }
-
- override fun close() {
- if (closed.compareAndSet(false, true)) {
- watchService.close()
- }
- }
-
- private suspend fun registerPaths() {
- for (path in paths) {
- registerAll(path, path)
- }
- }
-
- private suspend fun runEventLoop() {
- while (!closed.get() && currentCoroutineContext().isActive) {
- val key = try {
- runInterruptible { watchService.take() }
- }
- catch (_: InterruptedException) {
- return
- }
- catch (_: ClosedWatchServiceException) {
- return
- }
- for (event in key.pollEvents()) {
- try {
- handleEvent(key, event)
- }
- catch (e: Exception) {
- LOG.debug("DirectoryWatcher got an exception while watching!", e)
- listener.onException(e)
- }
- }
- if (!key.reset()) {
- LOG.debug { "WatchKey for [${key.watchable()}] no longer valid; removing." }
- val registeredPath = keyRoots.remove(key)
- registeredPathToRootPath.remove(registeredPath)
- if (keyRoots.isEmpty()) {
- LOG.debug("No more directories left to watch; terminating watcher.")
- throw IllegalStateException("No more directories left to watch")
- }
- }
- }
- }
-
- private suspend fun handleEvent(key: WatchKey, event: WatchEvent<*>) {
- val kind = event.kind()
- val count = event.count()
- val eventPath = event.pathContext()
- val registeredPath = keyRoots[key] ?: throw IllegalStateException("WatchService returned key [$key] but it was not found in keyRoots!")
- val rootPath = registeredPathToRootPath[registeredPath]
- val childPath = eventPath?.let { registeredPath.resolve(it) }
- LOG.debug { "$kind [$childPath]" }
- when {
- kind === OVERFLOW -> onEvent(EventType.OVERFLOW, false, childPath, count, rootPath)
- eventPath == null -> throw IllegalStateException("WatchService returned a null path for ${kind.name()}")
- kind === ENTRY_CREATE -> handleCreate(childPath!!, count, rootPath)
- kind === ENTRY_MODIFY -> onEvent(EventType.MODIFY, directories.contains(childPath), childPath, count, rootPath)
- kind === ENTRY_DELETE -> onEvent(EventType.DELETE, directories.remove(childPath), childPath, count, rootPath)
- }
- }
-
- private suspend fun handleCreate(childPath: Path, count: Int, rootPath: Path?) {
- val isDirectory = Files.isDirectory(childPath, NOFOLLOW_LINKS)
- if (isDirectory) {
- if (!isFileTreeSupported()) {
- registerAll(childPath, rootPath)
- }
- if (!isMac) {
- val createdDirectories = ArrayList()
- val createdFiles = ArrayList()
- runInterruptible {
- fileTreeVisitor.recursiveVisitFiles(childPath, createdDirectories::add, createdFiles::add)
- }
- for (dir in createdDirectories) {
- notifyCreateEvent(true, dir, count, rootPath)
- }
- for (file in createdFiles) {
- notifyCreateEvent(false, file, count, rootPath)
- }
- }
- else {
- notifyCreateEvent(true, childPath, count, rootPath)
- }
- }
- else {
- notifyCreateEvent(false, childPath, count, rootPath)
- }
- }
-
- private suspend fun onEvent(eventType: EventType, isDirectory: Boolean, childPath: Path?, count: Int, rootPath: Path?) {
- LOG.debug { "-> $eventType [$childPath] (isDirectory: $isDirectory)" }
- listener.onEvent(DirectoryChangeEvent(eventType, isDirectory, childPath, count, rootPath))
- }
-
- private suspend fun registerAll(start: Path, context: Path?) {
- if (fileTreeSupported != false) {
- try {
- register(start, true, context)
- fileTreeSupported = true
- addKnownDirectories(start)
- }
- catch (e: UnsupportedOperationException) {
- LOG.debug("Assuming ExtendedWatchEventModifier.FILE_TREE is not supported", e)
- fileTreeSupported = false
- registerAll(start, context)
- }
- }
- else {
- val directories = ArrayList()
- runInterruptible {
- fileTreeVisitor.recursiveVisitFiles(start, directories::add) {}
- }
- for (directory in directories) {
- this.directories.add(directory)
- register(directory, false, context)
- }
- }
- }
-
- private suspend fun addKnownDirectories(start: Path) {
- runInterruptible {
- fileTreeVisitor.recursiveVisitFiles(start, directories::add) {}
- }
- }
-
- private suspend fun register(directory: Path, useFileTreeModifier: Boolean, context: Path?) {
- LOG.debug { "Registering [$directory]." }
- val modifiers = if (useFileTreeModifier) arrayOf(ExtendedWatchEventModifier.FILE_TREE) else emptyArray()
- val watchKey = runInterruptible {
- val watchable = watchablePathFactory(directory)
- watchable.register(watchService, arrayOf(ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY), *modifiers)
- }
- keyRoots[watchKey] = directory
- if (context != null) {
- registeredPathToRootPath[directory] = context
- }
- }
-
- private suspend fun notifyCreateEvent(isDirectory: Boolean, path: Path, count: Int, rootPath: Path?) {
- if (isDirectory) {
- directories.add(path)
- }
- onEvent(EventType.CREATE, isDirectory, path, count, rootPath)
- }
-
- private fun isFileTreeSupported(): Boolean = fileTreeSupported ?: error("fileTreeSupported not initialized")
-
-}
-
-private fun createDefaultWatchService(): WatchService {
- return if (System.getProperty("os.name").contains("mac", ignoreCase = true)) {
- MacOSXListeningWatchService(object : MacOSXListeningWatchService.Config {
- })
- }
- else {
- FileSystems.getDefault().newWatchService()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/FileTreeVisitor.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/FileTreeVisitor.kt
deleted file mode 100644
index 81c793e6aa1b..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/FileTreeVisitor.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl
-
-import java.nio.file.FileVisitResult
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.SimpleFileVisitor
-import java.nio.file.attribute.BasicFileAttributes
-
-internal interface FileTreeVisitor {
- fun recursiveVisitFiles(root: Path, directoryConsumer: (Path) -> Unit, fileConsumer: (Path) -> Unit)
-}
-
-internal object DefaultFileTreeVisitor : FileTreeVisitor {
- override fun recursiveVisitFiles(root: Path, directoryConsumer: (Path) -> Unit, fileConsumer: (Path) -> Unit) {
- Files.walkFileTree(root, object : SimpleFileVisitor() {
- override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
- directoryConsumer(dir)
- return FileVisitResult.CONTINUE
- }
-
- override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
- fileConsumer(file)
- return FileVisitResult.CONTINUE
- }
- })
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/PathUtils.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/PathUtils.kt
deleted file mode 100644
index d01e77697dbe..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/PathUtils.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl
-
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.WatchEvent
-
-@Suppress("UNCHECKED_CAST")
-internal fun WatchEvent<*>.pathContext(): Path? = (this as WatchEvent).context()
-
-internal fun recursiveListFiles(fileTreeVisitor: FileTreeVisitor, root: Path): Set {
- val files = HashSet()
- when {
- Files.isDirectory(root) -> fileTreeVisitor.recursiveVisitFiles(root, files::add, files::add)
- Files.exists(root) -> files.add(root)
- }
- return files
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/AbstractWatchService.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/AbstractWatchService.kt
deleted file mode 100644
index 38a4cb882242..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/AbstractWatchService.kt
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl.watchservice
-
-import java.nio.file.ClosedWatchServiceException
-import java.nio.file.Path
-import java.nio.file.ProviderMismatchException
-import java.nio.file.StandardWatchEventKinds.OVERFLOW
-import java.nio.file.WatchEvent
-import java.nio.file.WatchKey
-import java.nio.file.WatchService
-import java.nio.file.Watchable
-import java.util.Collections
-import java.util.concurrent.ArrayBlockingQueue
-import java.util.concurrent.LinkedBlockingQueue
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicBoolean
-import java.util.concurrent.atomic.AtomicInteger
-import java.util.concurrent.atomic.AtomicReference
-
-internal abstract class AbstractWatchService : WatchService {
- private val queue = LinkedBlockingQueue()
- private val poison = AbstractWatchKey(this, null, emptySet(), 1)
- private val open = AtomicBoolean(true)
-
- abstract fun register(watchable: WatchablePath, eventTypes: Iterable>): AbstractWatchKey
-
- val isOpen: Boolean
- get() = open.get()
-
- internal fun enqueue(key: AbstractWatchKey) {
- if (isOpen) {
- queue.add(key)
- }
- }
-
- open fun cancelled(key: AbstractWatchKey) {
- }
-
- override fun poll(): WatchKey? {
- checkOpen()
- return check(queue.poll())
- }
-
- override fun poll(timeout: Long, unit: TimeUnit): WatchKey? {
- checkOpen()
- return check(queue.poll(timeout, unit))
- }
-
- override fun take(): WatchKey {
- checkOpen()
- return check(queue.take()) ?: error("queue.take() returned null")
- }
-
- private fun check(key: WatchKey?): WatchKey? {
- if (key === poison) {
- queue.offer(poison)
- throw ClosedWatchServiceException()
- }
- return key
- }
-
- protected fun checkOpen() {
- if (!open.get()) {
- throw ClosedWatchServiceException()
- }
- }
-
- override fun close() {
- if (open.compareAndSet(true, false)) {
- queue.clear()
- queue.offer(poison)
- }
- }
-
- internal data class Event(
- private val kind: WatchEvent.Kind,
- private val count: Int,
- private val context: T?,
- ) : WatchEvent {
- init {
- require(count >= 0) { "count ($count) must be non-negative" }
- }
-
- override fun kind(): WatchEvent.Kind = kind
-
- override fun count(): Int = count
-
- override fun context(): T? = context
- }
-}
-
-internal open class AbstractWatchKey(
- private val watcher: AbstractWatchService,
- private val watchable: Watchable?,
- @Suppress("unused") subscribedTypes: Iterable>,
- queueSize: Int,
-) : WatchKey {
- private val state = AtomicReference(State.READY)
- private val valid = AtomicBoolean(true)
- private val overflow = AtomicInteger()
- private val events = ArrayBlockingQueue>(queueSize)
-
- fun post(event: WatchEvent<*>) {
- if (!events.offer(event)) {
- overflow.incrementAndGet()
- }
- }
-
- fun signal() {
- if (state.getAndSet(State.SIGNALLED) == State.READY) {
- watcher.enqueue(this)
- }
- }
-
- override fun isValid(): Boolean = watcher.isOpen && valid.get()
-
- override fun pollEvents(): List> {
- val result = ArrayList>(events.size)
- events.drainTo(result)
- val overflowCount = overflow.getAndSet(0)
- if (overflowCount != 0) {
- result.add(AbstractWatchService.Event(OVERFLOW, overflowCount, null))
- }
- return Collections.unmodifiableList(result)
- }
-
- override fun reset(): Boolean {
- if (isValid && state.compareAndSet(State.SIGNALLED, State.READY) && hasPendingEvents()) {
- signal()
- }
- return isValid
- }
-
- private fun hasPendingEvents(): Boolean = !events.isEmpty() || overflow.get() != 0
-
- override fun cancel() {
- valid.set(false)
- watcher.cancelled(this)
- }
-
- override fun watchable(): Watchable? = watchable
-
- fun signalEvent(kind: WatchEvent.Kind, context: Path) {
- post(AbstractWatchService.Event(kind, 1, context))
- signal()
- }
-
- fun signalOverflow(context: Path?) {
- post(AbstractWatchService.Event(OVERFLOW, 1, context))
- signal()
- }
-
- override fun toString(): String = "AbstractWatchKey{watchable=$watchable, valid=${valid.get()}}"
-
- private enum class State {
- READY,
- SIGNALLED,
- }
-}
-
-internal class WatchablePath(val file: Path) : Watchable {
- override fun register(watcher: WatchService, events: Array>, vararg modifiers: WatchEvent.Modifier): WatchKey {
- if (watcher !is AbstractWatchService) {
- throw ProviderMismatchException()
- }
- return watcher.register(this, events.asList())
- }
-
- override fun register(watcher: WatchService, vararg events: WatchEvent.Kind<*>): WatchKey {
- if (!java.nio.file.Files.exists(file)) {
- throw RuntimeException("Directory to watch doesn't exist: $file")
- }
- return register(watcher, events)
- }
-
- override fun toString(): String = "Path{file=$file}"
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/MacOSXListeningWatchService.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/MacOSXListeningWatchService.kt
deleted file mode 100644
index efcac455c524..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/MacOSXListeningWatchService.kt
+++ /dev/null
@@ -1,364 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl.watchservice
-
-import com.intellij.platform.ai.agent.filewatch.impl.DefaultFileTreeVisitor
-import com.intellij.platform.ai.agent.filewatch.impl.FileTreeVisitor
-import com.intellij.platform.ai.agent.filewatch.impl.recursiveListFiles
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.CFArrayRef
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.FSEventStreamRef
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_FSEVENT_STREAM_CREATE_FLAG_FILE_EVENTS
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.K_FSEVENT_STREAM_CREATE_FLAG_NO_DEFER
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.MacFSEventsApi
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.cfIndex
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.libDispatchApi
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.macFSEventsApi
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.jna.toCFString
-import com.sun.jna.NativeLong
-import com.sun.jna.Pointer
-import java.nio.file.Files
-import java.nio.file.NoSuchFileException
-import java.nio.file.Path
-import java.nio.file.StandardWatchEventKinds.ENTRY_CREATE
-import java.nio.file.StandardWatchEventKinds.ENTRY_DELETE
-import java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY
-import java.nio.file.WatchEvent
-
-internal class MacOSXListeningWatchService(config: Config) : AbstractWatchService() {
- interface Config {
- val latency: Double
- get() = DEFAULT_LATENCY
- val queueSize: Int
- get() = DEFAULT_QUEUE_SIZE
- val fileTreeVisitor: FileTreeVisitor
- get() = DefaultFileTreeVisitor
- }
-
- private val callbacks = ArrayList()
- private val streams = ArrayList()
- private val pathsWatching = HashSet()
- private val latency = config.latency
- private val queueSize = config.queueSize
- private val fileTreeVisitor = config.fileTreeVisitor
-
- @Synchronized
- override fun register(watchable: WatchablePath, eventTypes: Iterable>): AbstractWatchKey {
- checkOpen()
- val watchKey = MacOSXWatchKey(this, watchable, eventTypes, queueSize)
- val file = watchable.file.toAbsolutePath()
- val pathToWatch = file.toString().toCFString()
- val values = arrayOf(pathToWatch.pointer)
- val pathsToWatch: CFArrayRef = macFSEventsApi.CFArrayCreate(null, values, cfIndex(1), null)
- val callback = MacOSXListeningCallback(watchKey, fileTreeVisitor, file)
- try {
- val streamRef = macFSEventsApi.FSEventStreamCreate(
- Pointer.NULL,
- callback,
- Pointer.NULL,
- pathsToWatch,
- -1L,
- latency,
- K_FSEVENT_STREAM_CREATE_FLAG_NO_DEFER or K_FSEVENT_STREAM_CREATE_FLAG_FILE_EVENTS,
- )
- val stream = FSEventStream(streamRef, file)
- callback.onClose { close(stream, callback, file) }
- stream.start()
- callbacks.add(callback)
- streams.add(stream)
- pathsWatching.add(file)
- return watchKey
- }
- catch (e: Exception) {
- watchKey.cancel()
- throw e
- }
- finally {
- macFSEventsApi.CFRelease(pathsToWatch)
- macFSEventsApi.CFRelease(pathToWatch)
- }
- }
-
- @Synchronized
- override fun close() {
- super.close()
- streams.forEach(FSEventStream::close)
- streams.clear()
- callbacks.clear()
- pathsWatching.clear()
- }
-
- @Synchronized
- private fun close(stream: FSEventStream, callback: MacOSXListeningCallback, path: Path) {
- streams.remove(stream)
- callbacks.remove(callback)
- pathsWatching.remove(path)
- stream.close()
- }
-
- internal class FSEventStream(
- private val streamRef: FSEventStreamRef,
- private val file: Path,
- ) : AutoCloseable {
- private val dispatchQueue = libDispatchApi.dispatch_queue_create("WatchService for $file", null)
- private var closed = false
-
- fun start() {
- synchronized(streamRef) {
- if (closed) {
- return
- }
- macFSEventsApi.FSEventStreamSetDispatchQueue(streamRef, dispatchQueue)
- if (!macFSEventsApi.FSEventStreamStart(streamRef)) {
- close()
- throw IllegalStateException("Could not start FSEventStream for $file")
- }
- }
- }
-
- override fun close() {
- synchronized(streamRef) {
- if (closed) {
- return
- }
- macFSEventsApi.FSEventStreamStop(streamRef)
- macFSEventsApi.FSEventStreamInvalidate(streamRef)
- macFSEventsApi.FSEventStreamRelease(streamRef)
- libDispatchApi.dispatch_release(dispatchQueue)
- closed = true
- }
- }
- }
-}
-
-private class MacOSXListeningCallback(
- private val watchKey: MacOSXWatchKey,
- private val fileTreeVisitor: FileTreeVisitor,
- private val absPath: Path,
-) : MacFSEventsApi.FSEventStreamCallback {
- private val realPathSize: Int
- private val knownFiles: MutableSet
- private var onCloseCallback: (() -> Unit)? = null
-
- init {
- try {
- val realPath = absPath.toRealPath()
- knownFiles = HashSet(recursiveListFiles(fileTreeVisitor, absPath))
- realPathSize = realPath.toString().length + 1
- }
- catch (e: Exception) {
- throw IllegalStateException("Could not initialize watcher for $absPath", e)
- }
- }
-
- fun onClose(callback: () -> Unit) {
- onCloseCallback = callback
- }
-
- override fun invoke(
- streamRef: FSEventStreamRef,
- clientCallBackInfo: Pointer?,
- numEvents: NativeLong,
- eventPaths: Pointer,
- eventFlags: Pointer?,
- eventIds: Pointer?,
- ) {
- val length = numEvents.toInt()
- val pathNames = eventPaths.getStringArray(0, length)
- for (index in pathNames.indices) {
- if (!watchKey.isValid) {
- return
- }
- val path = toWatchedPath(pathNames[index])
- val flags = FSEventFlags(eventFlags?.getInt((index * Int.SIZE_BYTES).toLong()) ?: 0)
- when {
- flags.requiresRescan -> rescanAfterOverflow(path)
- flags.removed -> handleRemoved(path)
- flags.created -> handleCreated(path, flags)
- flags.renamed -> handleRenamed(path, flags)
- flags.modified -> handleModified(path)
- path in knownFiles && Files.exists(path) -> handleModified(path)
- else -> rescanPath(path)
- }
- }
- }
-
- private fun toWatchedPath(fileName: String): Path {
- return if (fileName.length + 1 != realPathSize) absPath.resolve(fileName.substring(realPathSize)) else absPath
- }
-
- private fun handleCreated(path: Path, flags: FSEventFlags) {
- val wasKnown = !knownFiles.add(path)
- if (wasKnown) {
- handleModified(path)
- }
- else if (watchKey.reportCreateEvents) {
- watchKey.signalEvent(ENTRY_CREATE, path)
- }
- if (flags.directory) {
- rescanPath(path)
- }
- }
-
- private fun handleRemoved(path: Path) {
- val deletedPaths = removeKnownSubtree(path)
- if (deletedPaths.isEmpty()) {
- return
- }
- for (deletedPath in deletedPaths) {
- if (watchKey.reportDeleteEvents) {
- watchKey.signalEvent(ENTRY_DELETE, deletedPath)
- }
- }
- closeIfRootRemoved()
- }
-
- private fun handleRenamed(path: Path, flags: FSEventFlags) {
- if (Files.exists(path)) {
- if (path !in knownFiles) {
- handleCreated(path, flags)
- }
- else {
- handleModified(path)
- }
- }
- else {
- handleRemoved(path)
- }
- }
-
- private fun handleModified(path: Path) {
- if (path in knownFiles && !Files.isDirectory(path) && watchKey.reportModifyEvents) {
- watchKey.signalEvent(ENTRY_MODIFY, path)
- }
- }
-
- private fun rescanAfterOverflow(path: Path) {
- watchKey.signalOverflow(path)
- rescanPath(absPath)
- }
-
- private fun rescanPath(path: Path) {
- val previouslyKnownFiles = HashSet(knownFiles)
- val filesOnDisk = try {
- recursiveListFiles(fileTreeVisitor, path)
- }
- catch (_: NoSuchFileException) {
- handleRemoved(path)
- return
- }
- catch (_: Exception) {
- watchKey.signalOverflow(path)
- return
- }
- for (file in findCreatedFiles(filesOnDisk)) {
- if (watchKey.reportCreateEvents) {
- watchKey.signalEvent(ENTRY_CREATE, file)
- }
- }
- for (file in findModifiedFiles(filesOnDisk, previouslyKnownFiles)) {
- if (watchKey.reportModifyEvents) {
- watchKey.signalEvent(ENTRY_MODIFY, file)
- }
- }
- for (file in findDeletedFiles(path, filesOnDisk)) {
- if (watchKey.reportDeleteEvents) {
- watchKey.signalEvent(ENTRY_DELETE, file)
- }
- }
- closeIfRootRemoved()
- }
-
- private fun removeKnownSubtree(path: Path): List {
- val deletedPaths = ArrayList()
- for (file in ArrayList(knownFiles)) {
- if (file.startsWith(path)) {
- deletedPaths.add(file)
- knownFiles.remove(file)
- }
- }
- return deletedPaths
- }
-
- private fun closeIfRootRemoved() {
- if (knownFiles.isEmpty()) {
- watchKey.cancel()
- onCloseCallback?.invoke()
- }
- }
-
- private fun findCreatedFiles(filesOnDisk: Set): List {
- val createdFiles = ArrayList()
- for (file in filesOnDisk) {
- if (knownFiles.add(file)) {
- createdFiles.add(file)
- }
- }
- return createdFiles
- }
-
- private fun findModifiedFiles(filesOnDisk: Set, previouslyKnownFiles: Set): List {
- val modifiedFiles = ArrayList()
- for (file in filesOnDisk) {
- if (file in previouslyKnownFiles && file in knownFiles && !Files.isDirectory(file)) {
- modifiedFiles.add(file)
- }
- }
- return modifiedFiles
- }
-
- private fun findDeletedFiles(path: Path, filesOnDisk: Set): List {
- val deletedFiles = ArrayList()
- for (file in ArrayList(knownFiles)) {
- if (file.startsWith(path) && file !in filesOnDisk) {
- deletedFiles.add(file)
- knownFiles.remove(file)
- }
- }
- return deletedFiles
- }
-}
-
-private class FSEventFlags(private val value: Int) {
- val created: Boolean = has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_CREATED)
- val removed: Boolean = has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_REMOVED)
- val renamed: Boolean = has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_RENAMED)
- val directory: Boolean = has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_IS_DIR)
- val modified: Boolean = has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_MODIFIED) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_INODE_META_MOD) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_FINDER_INFO_MOD) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_CHANGE_OWNER) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_ITEM_XATTR_MOD)
- val requiresRescan: Boolean = has(K_FSEVENT_STREAM_EVENT_FLAG_MUST_SCAN_SUB_DIRS) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_USER_DROPPED) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_KERNEL_DROPPED) ||
- has(K_FSEVENT_STREAM_EVENT_FLAG_ROOT_CHANGED)
-
- private fun has(flag: Int): Boolean = value and flag != 0
-}
-
-private const val K_FSEVENT_STREAM_EVENT_FLAG_MUST_SCAN_SUB_DIRS: Int = 0x00000001
-private const val K_FSEVENT_STREAM_EVENT_FLAG_USER_DROPPED: Int = 0x00000002
-private const val K_FSEVENT_STREAM_EVENT_FLAG_KERNEL_DROPPED: Int = 0x00000004
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ROOT_CHANGED: Int = 0x00000020
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_CREATED: Int = 0x00000100
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_REMOVED: Int = 0x00000200
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_INODE_META_MOD: Int = 0x00000400
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_RENAMED: Int = 0x00000800
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_MODIFIED: Int = 0x00001000
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_FINDER_INFO_MOD: Int = 0x00002000
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_CHANGE_OWNER: Int = 0x00004000
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_XATTR_MOD: Int = 0x00008000
-private const val K_FSEVENT_STREAM_EVENT_FLAG_ITEM_IS_DIR: Int = 0x00020000
-
-private class MacOSXWatchKey(
- macOSXWatchService: AbstractWatchService,
- watchable: WatchablePath,
- events: Iterable>,
- queueSize: Int,
-) : AbstractWatchKey(macOSXWatchService, watchable, events, queueSize) {
- val reportCreateEvents = events.any { it === ENTRY_CREATE }
- val reportModifyEvents = events.any { it === ENTRY_MODIFY }
- val reportDeleteEvents = events.any { it === ENTRY_DELETE }
-}
-
-private const val DEFAULT_LATENCY = 0.5
-private const val DEFAULT_QUEUE_SIZE = 1024
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/jna/MacFSEventsApi.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/jna/MacFSEventsApi.kt
deleted file mode 100644
index f7d2610ea47a..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/jna/MacFSEventsApi.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl.watchservice.jna
-
-import com.sun.jna.Callback
-import com.sun.jna.Library
-import com.sun.jna.Native
-import com.sun.jna.NativeLong
-import com.sun.jna.Pointer
-import com.sun.jna.ptr.PointerByReference
-
-@Suppress("FunctionName")
-internal interface MacFSEventsApi : Library {
- interface FSEventStreamCallback : Callback {
- fun invoke(
- streamRef: FSEventStreamRef,
- clientCallBackInfo: Pointer?,
- numEvents: NativeLong,
- eventPaths: Pointer,
- eventFlags: Pointer?,
- eventIds: Pointer?,
- )
- }
-
- fun CFArrayCreate(allocator: CFAllocatorRef?, values: Array, numValues: CFIndex, callbacks: Void?): CFArrayRef
-
- fun CFStringCreateWithCharacters(alloc: Void?, chars: CharArray, numChars: CFIndex): CFStringRef
-
- fun FSEventStreamCreate(
- allocator: Pointer?,
- callback: FSEventStreamCallback,
- context: Pointer?,
- pathsToWatch: CFArrayRef,
- sinceWhen: Long,
- latency: Double,
- flags: Int,
- ): FSEventStreamRef
-
- fun FSEventStreamSetDispatchQueue(streamRef: FSEventStreamRef, dispatchQueue: DispatchQueueRef)
-
- fun FSEventStreamStart(streamRef: FSEventStreamRef): Boolean
-
- fun FSEventStreamStop(streamRef: FSEventStreamRef)
-
- fun FSEventStreamInvalidate(streamRef: FSEventStreamRef)
-
- fun FSEventStreamRelease(streamRef: FSEventStreamRef)
-
- fun CFRelease(ref: PointerByReference)
-}
-
-internal val macFSEventsApi: MacFSEventsApi = Native.load("CoreServices", MacFSEventsApi::class.java)
-
-internal const val K_FSEVENT_STREAM_CREATE_FLAG_NO_DEFER: Int = 0x00000002
-internal const val K_FSEVENT_STREAM_CREATE_FLAG_FILE_EVENTS: Int = 0x00000010
-
-@Suppress("FunctionName")
-internal interface LibDispatchApi : Library {
- fun dispatch_queue_create(label: String, attr: Pointer?): DispatchQueueRef
-
- fun dispatch_release(dispatchObject: DispatchQueueRef)
-}
-
-internal val libDispatchApi: LibDispatchApi = Native.load("System", LibDispatchApi::class.java)
-
-internal class CFAllocatorRef : PointerByReference()
-
-internal class CFArrayRef : PointerByReference()
-
-internal class FSEventStreamRef : PointerByReference()
-
-internal class DispatchQueueRef : PointerByReference()
-
-internal class CFIndex() : NativeLong() {
- constructor(value: Long) : this() {
- setValue(value)
- }
-
- override fun toByte(): Byte = toLong().toByte()
-
- override fun toShort(): Short = toLong().toShort()
-}
-
-internal fun cfIndex(value: Int): CFIndex = CFIndex(value.toLong())
-
-internal class CFStringRef : PointerByReference()
-
-internal fun String.toCFString(): CFStringRef {
- val chars = toCharArray()
- return macFSEventsApi.CFStringCreateWithCharacters(null, chars, cfIndex(chars.size))
-}
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/jna/MacKQueueApi.kt b/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/jna/MacKQueueApi.kt
deleted file mode 100644
index 2d43a86a31d6..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/src/impl/watchservice/jna/MacKQueueApi.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl.watchservice.jna
-
-import com.sun.jna.LastErrorException
-import com.sun.jna.Library
-import com.sun.jna.Native
-import com.sun.jna.NativeLong
-import com.sun.jna.Pointer
-import com.sun.jna.Structure
-
-internal interface MacKQueueApi : Library {
- @Throws(LastErrorException::class)
- fun kqueue(): Int
-
- @Throws(LastErrorException::class)
- fun kevent(
- kq: Int,
- changelist: KEvent?,
- nchanges: Int,
- eventlist: KEvent?,
- nevents: Int,
- timeout: Pointer?,
- ): Int
-
- @Throws(LastErrorException::class)
- fun open(path: String, flags: Int): Int
-
- @Throws(LastErrorException::class)
- fun close(fd: Int): Int
-}
-
-@Structure.FieldOrder("ident", "filter", "flags", "fflags", "data", "udata")
-@Suppress("unused")
-internal class KEvent() : Structure() {
- @JvmField var ident: NativeLong = NativeLong(0)
- @JvmField var filter: Short = 0
- @JvmField var flags: Short = 0
- @JvmField var fflags: Int = 0
- @JvmField var data: NativeLong = NativeLong(0)
- @JvmField var udata: Pointer? = null
-
- constructor(ident: Int, filter: Short, flags: Short, fflags: Int) : this() {
- this.ident = NativeLong(ident.toLong())
- this.filter = filter
- this.flags = flags
- this.fflags = fflags
- }
-}
-
-internal val macKQueueApi: MacKQueueApi = Native.load("System", MacKQueueApi::class.java)
-
-internal const val K_QUEUE_OPEN_EVENT_ONLY: Int = 0x8000
-
-internal const val K_EVENT_FILTER_VNODE: Short = -4
-internal const val K_EVENT_ADD: Short = 0x0001
-internal const val K_EVENT_CLEAR: Short = 0x0020
-
-internal const val K_NOTE_DELETE: Int = 0x00000001
-internal const val K_NOTE_WRITE: Int = 0x00000002
-internal const val K_NOTE_EXTEND: Int = 0x00000004
-internal const val K_NOTE_RENAME: Int = 0x00000020
-internal const val K_NOTE_REVOKE: Int = 0x00000040
diff --git a/plugins/agent-workbench/lib-agent/filewatch/testSrc/AgentWorkbenchDirectoryWatcherTest.kt b/plugins/agent-workbench/lib-agent/filewatch/testSrc/AgentWorkbenchDirectoryWatcherTest.kt
deleted file mode 100644
index c6758eb67286..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/testSrc/AgentWorkbenchDirectoryWatcherTest.kt
+++ /dev/null
@@ -1,267 +0,0 @@
-// 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.platform.ai.agent.filewatch
-
-import com.intellij.platform.ai.agent.filewatch.impl.DirectoryChangeEvent
-import com.intellij.platform.ai.agent.filewatch.impl.DirectoryChangeListener
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import java.util.concurrent.TimeUnit
-import org.junit.jupiter.api.io.TempDir
-import java.nio.file.Path
-import java.util.concurrent.LinkedBlockingQueue
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class AgentWorkbenchDirectoryWatcherTest {
- @TempDir
- lateinit var tempDir: Path
-
- @Test
- fun pathlessOverflowIsDelivered() = runBlocking(Dispatchers.Default) {
- val watchLoop = FakeWatchLoop()
- val events = LinkedBlockingQueue()
- val failures = LinkedBlockingQueue()
-
- AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir),
- scope = this,
- onWatchEvent = events::add,
- onFailure = failures::add,
- watchLoopFactory = { _, listener ->
- watchLoop.listener = listener
- watchLoop
- },
- ).use { watcher ->
- watchLoop.offer(DirectoryChangeEvent(DirectoryChangeEvent.EventType.OVERFLOW, false, null, 1, tempDir.toAbsolutePath()))
-
- val event = withTimeout(5.seconds) {
- events.take()
- }
-
- assertThat(event.eventType).isEqualTo(AgentWorkbenchWatchEventType.OVERFLOW)
- assertThat(event.path).isNull()
- assertThat(event.rootPath).isEqualTo(tempDir.toAbsolutePath())
- assertThat(event.count).isEqualTo(1)
- assertThat(failures).isEmpty()
- watcher.close()
- }
- }
-
- @Test
- fun rootPathIsPreservedForDeliveredEvents() {
- runBlocking(Dispatchers.Default) {
- val watchLoop = FakeWatchLoop()
- val events = LinkedBlockingQueue()
- val root = tempDir.toAbsolutePath()
- val changedPath = root.resolve("session.jsonl")
-
- AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir),
- scope = this,
- onWatchEvent = events::add,
- watchLoopFactory = { _, listener ->
- watchLoop.listener = listener
- watchLoop
- },
- ).use {
- watchLoop.offer(DirectoryChangeEvent(DirectoryChangeEvent.EventType.CREATE, false, changedPath, 1, root))
-
- val event = withTimeout(5.seconds) {
- events.take()
- }
-
- assertThat(event.eventType).isEqualTo(AgentWorkbenchWatchEventType.CREATE)
- assertThat(event.path).isEqualTo(changedPath)
- assertThat(event.rootPath).isEqualTo(root)
- }
- }
- }
-
- @Test
- fun closeSuppressesLateEventsAndFailures() = runBlocking(Dispatchers.Default) {
- val watchLoop = FakeWatchLoop()
- val events = LinkedBlockingQueue()
- val failures = LinkedBlockingQueue()
- val root = tempDir.toAbsolutePath()
-
- AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir),
- scope = this,
- onWatchEvent = events::add,
- onFailure = failures::add,
- watchLoopFactory = { _, listener ->
- watchLoop.listener = listener
- watchLoop
- },
- ).use { watcher ->
- watcher.close()
-
- watchLoop.offer(DirectoryChangeEvent(DirectoryChangeEvent.EventType.CREATE, false, root.resolve("late.jsonl"), 1, root))
- watchLoop.fail(IllegalStateException("late failure"))
- delay(200.milliseconds)
-
- assertThat(events).isEmpty()
- assertThat(failures).isEmpty()
- }
- }
-
- @Test
- fun watcherWithNoValidRootsIsInactive() {
- runBlocking(Dispatchers.Default) {
- val watcher = AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir.resolve("missing")),
- scope = this,
- onWatchEvent = {},
- )
-
- assertThat(watcher.isActive).isFalse()
- }
- }
-
- @Test
- fun closeMakesWatcherInactive() {
- runBlocking(Dispatchers.Default) {
- val watchLoop = FakeWatchLoop()
- val watcher = AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir),
- scope = this,
- onWatchEvent = {},
- watchLoopFactory = { _, listener ->
- watchLoop.listener = listener
- watchLoop
- },
- )
-
- assertThat(watcher.isActive).isTrue()
-
- watcher.closeAndJoin()
-
- assertThat(watcher.isActive).isFalse()
- }
- }
-
- @Test
- fun completedWatchLoopMakesWatcherInactive() {
- runBlocking(Dispatchers.Default) {
- val watchLoop = CompletingWatchLoop()
- val watcher = AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir),
- scope = this,
- onWatchEvent = {},
- watchLoopFactory = { _, _ -> watchLoop },
- )
-
- withTimeout(5.seconds) {
- watchLoop.completed.await()
- }
-
- withTimeout(5.seconds) {
- while (watcher.isActive) {
- delay(10.milliseconds)
- }
- }
-
- assertThat(watcher.isActive).isFalse()
- }
- }
-
- @Test
- fun failedWatchLoopRestartsWithSameRoots() {
- runBlocking(Dispatchers.Default) {
- val events = LinkedBlockingQueue()
- val failures = LinkedBlockingQueue()
- val restartedLoop = CompletableDeferred()
- val root = tempDir.toAbsolutePath()
- var createCount = 0
-
- AgentWorkbenchDirectoryWatcher(
- roots = listOf(tempDir),
- scope = this,
- onWatchEvent = events::add,
- onFailure = failures::add,
- watchLoopFactory = { _, listener ->
- createCount += 1
- if (createCount == 1) {
- FailingWatchLoop(IllegalStateException("watch loop failed"))
- }
- else {
- FakeWatchLoop().also { loop ->
- loop.listener = listener
- restartedLoop.complete(loop)
- }
- }
- },
- ).use { watcher ->
- val failure = withTimeout(5.seconds) { failures.take() }
- val loop = withTimeout(5.seconds) { restartedLoop.await() }
-
- loop.offer(DirectoryChangeEvent(DirectoryChangeEvent.EventType.CREATE, false, root.resolve("session.jsonl"), 1, root))
- val event = withTimeout(5.seconds) { events.take() }
-
- assertThat(failure).hasMessage("watch loop failed")
- assertThat(event.path).isEqualTo(root.resolve("session.jsonl"))
- assertThat(watcher.isActive).isTrue()
- }
- }
- }
-}
-
-private class CompletingWatchLoop : AgentWorkbenchWatchLoop {
- val completed = CompletableDeferred()
-
- override suspend fun watch() {
- completed.complete(Unit)
- }
-
- override fun close() {
- }
-}
-
-private class FailingWatchLoop(private val error: Throwable) : AgentWorkbenchWatchLoop {
- override suspend fun watch() {
- throw error
- }
-
- override fun close() {
- }
-}
-
-private class FakeWatchLoop : AgentWorkbenchWatchLoop {
- private val events = LinkedBlockingQueue()
- lateinit var listener: DirectoryChangeListener
-
- @Volatile
- private var closed = false
-
- private object Stop
-
- fun offer(event: DirectoryChangeEvent) {
- events.add(event)
- }
-
- fun fail(e: Exception) {
- events.add(e)
- }
-
- override suspend fun watch() {
- while (!closed) {
- when (val event = events.take()) {
- Stop -> return
- is DirectoryChangeEvent -> listener.onEvent(event)
- is Exception -> listener.onException(event)
- }
- }
- }
-
- override fun close() {
- closed = true
- events.offer(Stop)
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/testSrc/impl/DirectoryWatcherImplTest.kt b/plugins/agent-workbench/lib-agent/filewatch/testSrc/impl/DirectoryWatcherImplTest.kt
deleted file mode 100644
index a5261040e4f4..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/testSrc/impl/DirectoryWatcherImplTest.kt
+++ /dev/null
@@ -1,424 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl
-
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.AbstractWatchKey
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.AbstractWatchService
-import com.intellij.platform.ai.agent.filewatch.impl.watchservice.WatchablePath
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.cancelAndJoin
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
-import org.assertj.core.api.Assertions.assertThat
-import org.assertj.core.api.Assertions.assertThatThrownBy
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import org.junit.jupiter.api.io.TempDir
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.StandardWatchEventKinds.ENTRY_CREATE
-import java.nio.file.StandardWatchEventKinds.ENTRY_DELETE
-import java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY
-import java.nio.file.StandardWatchEventKinds.OVERFLOW
-import java.nio.file.WatchEvent
-import java.nio.file.WatchEvent.Modifier
-import java.nio.file.WatchKey
-import java.nio.file.WatchService
-import java.nio.file.Watchable
-import java.util.concurrent.LinkedBlockingQueue
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicInteger
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class DirectoryWatcherImplTest {
- @TempDir
- lateinit var tempDir: Path
-
- @Test
- fun watchThrowsWhenWatcherIsAlreadyClosed() {
- runBlocking(Dispatchers.IO) {
- val watcher = DirectoryWatcher(listOf(tempDir), EventRecorder())
-
- watcher.close()
-
- assertThatThrownBy { runBlocking { watcher.watch() } }
- .isInstanceOf(IllegalStateException::class.java)
- }
- }
-
- @Test
- fun watchReturnsWhenWatcherIsClosed() = runBlocking(Dispatchers.IO) {
- val watcher = DirectoryWatcher(listOf(tempDir), EventRecorder())
-
- val completed = CompletableDeferred()
- val watchJob = launch {
- watcher.watch()
- completed.complete(Unit)
- }
- try {
- delay(100.milliseconds)
- watcher.close()
-
- withTimeout(5.seconds) {
- completed.await()
- }
- }
- finally {
- watchJob.cancelAndJoin()
- }
- }
-
- @Test
- fun deletingNestedFilesEmitsDeleteEvents() {
- runBlocking(Dispatchers.IO) {
- val parentDir = Files.createDirectory(tempDir.resolve("parent"))
- val childDir = Files.createDirectory(parentDir.resolve("child"))
- val firstFile = Files.createFile(parentDir.resolve("first.jsonl"))
- val secondFile = Files.createFile(childDir.resolve("second.jsonl"))
- val recorder = EventRecorder()
- val watcher = DirectoryWatcher(listOf(tempDir), recorder)
- val watchJob = launch { watcher.watch() }
- try {
- delay(100.milliseconds)
- Files.delete(secondFile)
- Files.delete(firstFile)
-
- recorder.awaitEvent { event -> event.eventType == DirectoryChangeEvent.EventType.DELETE && event.path == secondFile }
- recorder.awaitEvent { event -> event.eventType == DirectoryChangeEvent.EventType.DELETE && event.path == firstFile }
- }
- finally {
- watcher.close()
- watchJob.cancelAndJoin()
- }
- }
- }
-
- @Test
- fun repeatedStartAndCloseDoesNotCrash() {
- repeat(3) {
- val watcher = DirectoryWatcher(listOf(tempDir), EventRecorder())
- watcher.close()
- }
- }
-
- @Test
- fun invalidatingOnlyWatchKeyFailsWatch() {
- runBlocking(Dispatchers.IO) {
- val watchService = TestWatchService(queueSize = 8)
- val watcher = DirectoryWatcher(
- listOf(tempDir),
- EventRecorder(),
- watchService,
- watchablePathFactory = { path -> WatchablePath(path) },
- )
- val failure = CompletableDeferred()
- val watchJob = launch {
- try {
- watcher.watch()
- }
- catch (t: Throwable) {
- failure.complete(t)
- }
- }
- try {
- val key = withTimeout(5.seconds) {
- watchService.awaitRegisteredKey()
- }
-
- key.cancel()
- key.signalOverflow(tempDir)
-
- val error = withTimeout(5.seconds) {
- failure.await()
- }
-
- assertThat(error)
- .isInstanceOf(IllegalStateException::class.java)
- .hasMessage("No more directories left to watch")
- }
- finally {
- watcher.close()
- watchJob.cancelAndJoin()
- }
- }
- }
-
- @Test
- fun unsupportedFileTreeModifierFallbackWalksTreeOnce() {
- runBlocking(Dispatchers.IO) {
- val childDir = tempDir.resolve("child")
- val nestedDir = childDir.resolve("nested")
- val fileTreeVisitor = FakeFileTreeVisitor(listOf(tempDir, childDir, nestedDir))
- val watchService = FileTreeUnsupportedWatchService()
- val watcher = DirectoryWatcher(
- listOf(tempDir),
- EventRecorder(),
- watchService,
- fileTreeVisitor,
- watchablePathFactory = { path -> FakeWatchablePath(path, watchService) },
- )
-
- val completed = CompletableDeferred()
- val watchJob = launch {
- watcher.watch()
- completed.complete(Unit)
- }
- try {
- withTimeout(5.seconds) {
- watchService.awaitRegisteredDirectories(3)
- }
-
- assertThat(fileTreeVisitor.visitCount.get()).isEqualTo(1)
- assertThat(watchService.registeredDirectories).containsExactly(tempDir, childDir, nestedDir)
- }
- finally {
- watcher.close()
- watchJob.cancelAndJoin()
- }
- }
- }
-
- @Test
- fun creatingDirectoryDoesNotReportNewFilesAsModified() {
- runBlocking(Dispatchers.IO) {
- val createdDirectory = tempDir.resolve("created")
- val createdFile = createdDirectory.resolve("session.jsonl")
- val fileTreeVisitor = MutableFakeFileTreeVisitor(listOf(tempDir), emptyList())
- val watchService = FileTreeUnsupportedWatchService()
- val recorder = EventRecorder()
- val watcher = DirectoryWatcher(
- listOf(tempDir),
- recorder,
- watchService,
- fileTreeVisitor,
- watchablePathFactory = { path -> FakeWatchablePath(path, watchService) },
- )
-
- val watchJob = launch { watcher.watch() }
- try {
- withTimeout(5.seconds) {
- watchService.awaitRegisteredDirectories(1)
- }
- Files.createDirectory(createdDirectory)
- Files.writeString(createdFile, "created")
- fileTreeVisitor.directories = listOf(createdDirectory)
- fileTreeVisitor.files = listOf(createdFile)
- watchService.signal(tempDir, FakeWatchEvent(ENTRY_CREATE, 1, createdDirectory.fileName))
-
- recorder.awaitEvent { event -> event.eventType == DirectoryChangeEvent.EventType.CREATE && event.path == createdDirectory }
- recorder.awaitEvent { event -> event.eventType == DirectoryChangeEvent.EventType.CREATE && event.path == createdFile }
-
- assertThat(recorder.drainEvents().any { event ->
- event.eventType == DirectoryChangeEvent.EventType.MODIFY && event.path == createdFile
- }).isFalse()
- }
- finally {
- watcher.close()
- watchJob.cancelAndJoin()
- }
- }
- }
-
- @Test
- fun overflowOnlyEventsResignalWatchKeyOnReset() {
- val watchService = TestWatchService(queueSize = 1)
- val key = watchService.register(WatchablePath(tempDir), listOf(ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY))
-
- key.signalEvent(ENTRY_CREATE, tempDir.resolve("file"))
-
- val firstEvents = key.pollEvents()
-
- assertThat(firstEvents.map { it.kind() }).containsExactly(ENTRY_CREATE)
- key.signalOverflow(tempDir)
- assertThat(key.reset()).isTrue()
-
- val secondEvents = watchService.poll()!!.pollEvents()
-
- assertThat(secondEvents.map { it.kind() }).containsExactly(OVERFLOW)
- }
-
-}
-
-private class TestWatchService(private val queueSize: Int) : AbstractWatchService() {
- @Volatile
- private var registeredKey: AbstractWatchKey? = null
-
- override fun register(watchable: WatchablePath, eventTypes: Iterable>): AbstractWatchKey {
- return AbstractWatchKey(this, watchable, eventTypes, queueSize).also { key ->
- registeredKey = key
- }
- }
-
- fun awaitRegisteredKey(): AbstractWatchKey {
- while (true) {
- registeredKey?.let { key -> return key }
- Thread.sleep(10)
- }
- }
-
-}
-
-private class FakeFileTreeVisitor(private val directories: List) : FileTreeVisitor {
- val visitCount = AtomicInteger()
-
- override fun recursiveVisitFiles(root: Path, directoryConsumer: (Path) -> Unit, fileConsumer: (Path) -> Unit) {
- visitCount.incrementAndGet()
- for (directory in directories) {
- directoryConsumer(directory)
- }
- }
-}
-
-private class MutableFakeFileTreeVisitor(
- @Volatile var directories: List,
- @Volatile var files: List,
-) : FileTreeVisitor {
- override fun recursiveVisitFiles(root: Path, directoryConsumer: (Path) -> Unit, fileConsumer: (Path) -> Unit) {
- for (directory in directories) {
- directoryConsumer(directory)
- }
- for (file in files) {
- fileConsumer(file)
- }
- }
-}
-
-private class FakeWatchablePath(private val path: Path, private val watchService: FileTreeUnsupportedWatchService) : Watchable {
- override fun register(watcher: WatchService, events: Array>, vararg modifiers: Modifier): WatchKey {
- check(watcher === watchService)
- if (modifiers.isNotEmpty()) {
- throw UnsupportedOperationException()
- }
- return watchService.register(path, events)
- }
-
- override fun register(watcher: WatchService, vararg events: WatchEvent.Kind<*>): WatchKey {
- return register(watcher, events)
- }
-}
-
-private class FileTreeUnsupportedWatchService : WatchService {
- private val keys = LinkedBlockingQueue()
- private val registered = ArrayList()
-
- val registeredDirectories: List
- get() = ArrayList(registered)
-
- fun awaitRegisteredDirectories(count: Int) {
- while (registered.size < count) {
- Thread.sleep(10)
- }
- }
-
- fun register(directory: Path, @Suppress("unused") events: Array>): FileTreeUnsupportedWatchKey {
- registered.add(directory)
- return FileTreeUnsupportedWatchKey(directory, keys).also { key ->
- watchKeys[directory] = key
- }
- }
-
- private val watchKeys = HashMap()
-
- fun signal(directory: Path, event: WatchEvent<*>) {
- watchKeys.getValue(directory).post(event)
- }
-
- override fun poll(): WatchKey? = keys.poll()
-
- override fun poll(timeout: Long, unit: TimeUnit): WatchKey? = keys.poll(timeout, unit)
-
- override fun take(): WatchKey = keys.take()
-
- override fun close() {
- }
-}
-
-private class FileTreeUnsupportedWatchKey(
- private val directory: Path,
- private val keys: LinkedBlockingQueue,
-) : WatchKey {
- private val events = ArrayList>()
- private var pendingOverflowCount = 0
- private var signalled = false
-
- fun post(event: WatchEvent<*>) {
- events.add(event)
- signal()
- }
-
- private fun signal() {
- if (!signalled) {
- signalled = true
- keys.add(this)
- }
- }
-
- override fun isValid(): Boolean = true
-
- override fun pollEvents(): List> {
- val result = ArrayList(events)
- events.clear()
- if (pendingOverflowCount != 0) {
- result.add(FakeWatchEvent(OVERFLOW, pendingOverflowCount, null))
- pendingOverflowCount = 0
- }
- return result
- }
-
- override fun reset(): Boolean {
- signalled = false
- if (events.isNotEmpty() || pendingOverflowCount != 0) {
- signal()
- }
- return true
- }
-
- override fun cancel() {
- }
-
- override fun watchable(): Watchable = directory
-}
-
-private data class FakeWatchEvent(
- private val kind: WatchEvent.Kind,
- private val count: Int,
- private val context: T?,
-) : WatchEvent {
- override fun kind(): WatchEvent.Kind = kind
-
- override fun count(): Int = count
-
- override fun context(): T? = context
-}
-
-private class EventRecorder : DirectoryChangeListener {
- private val events = LinkedBlockingQueue()
-
- override suspend fun onEvent(event: DirectoryChangeEvent) {
- events.add(event)
- }
-
- suspend fun awaitEvent(predicate: (DirectoryChangeEvent) -> Boolean): DirectoryChangeEvent {
- return withTimeout(5.seconds) {
- lateinit var matchingEvent: DirectoryChangeEvent
- while (true) {
- val event = events.take()
- if (predicate(event)) {
- matchingEvent = event
- break
- }
- }
- matchingEvent
- }
- }
-
- fun drainEvents(): List {
- val result = ArrayList()
- events.drainTo(result)
- return result
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/filewatch/testSrc/impl/watchservice/MacOSXListeningWatchServiceTest.kt b/plugins/agent-workbench/lib-agent/filewatch/testSrc/impl/watchservice/MacOSXListeningWatchServiceTest.kt
deleted file mode 100644
index bf0ee5da4ed6..000000000000
--- a/plugins/agent-workbench/lib-agent/filewatch/testSrc/impl/watchservice/MacOSXListeningWatchServiceTest.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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.platform.ai.agent.filewatch.impl.watchservice
-
-import com.intellij.platform.ai.agent.filewatch.agentWorkbenchImmediateFileChangeFlow
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.cancelAndJoin
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Assumptions.assumeTrue
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import org.junit.jupiter.api.io.TempDir
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.StandardOpenOption
-import java.nio.file.StandardWatchEventKinds.ENTRY_CREATE
-import java.nio.file.StandardWatchEventKinds.ENTRY_DELETE
-import java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY
-import java.nio.file.WatchEvent
-import java.nio.file.WatchKey
-import java.util.concurrent.TimeUnit
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class MacOSXListeningWatchServiceTest {
- @TempDir
- lateinit var tempDir: Path
- private val pendingEvents = ArrayList>()
-
- @Test
- fun createModifyDeleteEventsAreDeliveredByNativeMacWatcher() = runBlocking(Dispatchers.IO) {
- assumeMacOS()
- val watchService = createWatchService()
- val watchKey = WatchablePath(tempDir).register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE)
-
- watchService.use {
- delay(100.milliseconds)
- val file = tempDir.resolve("session.jsonl")
-
- Files.writeString(file, "created")
- awaitEvent(watchService, watchKey, ENTRY_CREATE, file)
-
- Files.writeString(file, "modified")
- awaitEvent(watchService, watchKey, ENTRY_MODIFY, file)
-
- Files.delete(file)
- awaitEvent(watchService, watchKey, ENTRY_DELETE, file)
- }
- }
-
- @Test
- fun nestedFileDeleteIsDeliveredByNativeMacWatcher() = runBlocking(Dispatchers.IO) {
- assumeMacOS()
- val watchService = createWatchService()
- val watchKey = WatchablePath(tempDir).register(watchService, ENTRY_CREATE, ENTRY_DELETE)
-
- watchService.use {
- delay(100.milliseconds)
- val directory = Files.createDirectory(tempDir.resolve("session"))
- val file = directory.resolve("nested.jsonl")
-
- Files.writeString(file, "created")
- awaitEvent(watchService, watchKey, ENTRY_CREATE, file)
-
- Files.delete(file)
- awaitEvent(watchService, watchKey, ENTRY_DELETE, file)
- }
- }
-
- @Test
- fun immediateFileChangeFlowDeliversLongLivedAppendFdBeforeClose(): Unit = runBlocking(Dispatchers.IO) {
- // Codex keeps the rollout JSONL fd open for the entire session lifetime. FSEvents alone
- // withholds MODIFY events until the fd is closed, so active threadView tabs subscribe to their
- // concrete session file with kqueue vnode events.
- assumeMacOS()
- val file = tempDir.resolve("rollout-long-lived.jsonl")
- Files.createFile(file)
- val expectedPath = file.toAbsolutePath().normalize()
- val changes = Channel(Channel.UNLIMITED)
- val watchJob = launch {
- agentWorkbenchImmediateFileChangeFlow(listOf(file)).collect { path ->
- changes.trySend(path)
- }
- }
-
- try {
- delay(200.milliseconds)
- Files.newOutputStream(file, StandardOpenOption.APPEND).use { stream ->
- stream.write("line1\n".toByteArray())
- stream.flush()
- assertThat(withTimeout(5.seconds) { changes.receive() }).isEqualTo(expectedPath)
-
- stream.write("line2\n".toByteArray())
- stream.flush()
- assertThat(withTimeout(5.seconds) { changes.receive() }).isEqualTo(expectedPath)
- }
- }
- finally {
- watchJob.cancelAndJoin()
- changes.close()
- }
- }
-
- @Test
- fun repeatedNativeStartAndCloseDoesNotCrash() {
- assumeMacOS()
- repeat(3) {
- createWatchService().use { watchService ->
- WatchablePath(tempDir).register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE)
- }
- }
- }
-
- private fun createWatchService(): MacOSXListeningWatchService {
- return MacOSXListeningWatchService(object : MacOSXListeningWatchService.Config {
- override val latency: Double = 0.1
- })
- }
-
- private fun awaitEvent(
- watchService: MacOSXListeningWatchService,
- expectedKey: WatchKey,
- expectedKind: WatchEvent.Kind,
- expectedPath: Path,
- ) {
- val deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(5)
- while (System.nanoTime() < deadline) {
- val pendingEvent = pendingEvents.findAndRemove(expectedKind, expectedPath)
- if (pendingEvent != null) {
- assertThat(pendingEvent.context()).isEqualTo(expectedPath)
- return
- }
- val key = watchService.poll(100, TimeUnit.MILLISECONDS) ?: continue
- assertThat(key).isSameAs(expectedKey)
- val events = key.pollEvents()
- val event = events.firstOrNull { event -> event.kind() === expectedKind && event.context() == expectedPath }
- if (event != null) {
- assertThat(event.context()).isEqualTo(expectedPath)
- pendingEvents.addAll(events - event)
- key.reset()
- return
- }
- pendingEvents.addAll(events)
- key.reset()
- }
- throw AssertionError("Expected $expectedKind event for $expectedPath")
- }
-
- private fun ArrayList>.findAndRemove(kind: WatchEvent.Kind, path: Path): WatchEvent<*>? {
- val iterator = iterator()
- while (iterator.hasNext()) {
- val event = iterator.next()
- if (event.kind() === kind && event.context() == path) {
- iterator.remove()
- return event
- }
- }
- return null
- }
-
- private fun assumeMacOS() {
- assumeTrue(System.getProperty("os.name").contains("mac", ignoreCase = true))
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/json/BUILD.bazel b/plugins/agent-workbench/lib-agent/json/BUILD.bazel
deleted file mode 100644
index c0bd956ceb93..000000000000
--- a/plugins/agent-workbench/lib-agent/json/BUILD.bazel
+++ /dev/null
@@ -1,132 +0,0 @@
-load("@community//build:tests-options.bzl", "jps_test")
-load("@rules_jvm//:jvm.bzl", "jvm_library")
-
-### auto-generated section `build intellij.platform.ai.agent.json` start
-
-jvm_library(
- name = "json",
- srcs = glob(
- [
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/*.form",
- ],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.json",
- resource_strip_prefix = "resources",
- resources = glob(
- ["resources/**/*"],
- ),
- visibility = ["//visibility:public"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//libraries/kotlinx/coroutines/core",
- "//platform/core-api:core",
- "//platform/util",
- "//plugins/agent-workbench/lib-agent/filewatch",
- "//libraries/jackson3/jackson:libraries-jackson3",
- ],
-)
-
-jvm_library(
- name = "json_test_lib",
- testonly = True,
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.json",
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":json",
- "//libraries/kotlinx/coroutines/core:core_test_lib",
- "//platform/core-api:core_test_lib",
- "//platform/util:util_test_lib",
- "//plugins/agent-workbench/lib-agent/filewatch:filewatch_test_lib",
- "//libraries/jackson3/jackson:libraries-jackson3_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.json` end
-
-### auto-generated section `iml intellij.platform.ai.agent.json` start
-exports_files(
- [
- "intellij.platform.ai.agent.json.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.json` end
-
-### auto-generated section `build intellij.platform.ai.agent.json.tests` start
-
-jvm_library(
- name = "ai-agent-json-tests",
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.json.tests",
- visibility = ["//visibility:public"],
-)
-
-jvm_library(
- name = "ai-agent-json-tests_test_lib",
- testonly = True,
- srcs = glob(
- [
- "testSrc/**/*.kt",
- "testSrc/**/*.java",
- "testSrc/**/*.form",
- ],
- allow_empty = True,
- ),
- associates = [
- "//plugins/agent-workbench/lib-agent/json",
- "//plugins/agent-workbench/lib-agent/json:json_test_lib",
- ],
- visibility = ["//visibility:public"],
- runtime_deps = [":ai-agent-json-tests"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//libraries/kotlinx/coroutines/core",
- "//libraries/kotlinx/coroutines/core:core_test_lib",
- "//platform/core-api:core",
- "//platform/core-api:core_test_lib",
- "//platform/util",
- "//platform/util:util_test_lib",
- "//plugins/agent-workbench/lib-agent/filewatch",
- "//plugins/agent-workbench/lib-agent/filewatch:filewatch_test_lib",
- "//libraries/jackson3/jackson:libraries-jackson3",
- "//libraries/jackson3/jackson:libraries-jackson3_test_lib",
- "//libraries/junit5",
- "//libraries/junit5:junit5_test_lib",
- "//libraries/assertj-core",
- "//libraries/assertj-core:assertj-core_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.json.tests` end
-
-### auto-generated section `iml intellij.platform.ai.agent.json.tests` start
-exports_files(
- [
- "intellij.platform.ai.agent.json.tests.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.json.tests` end
-
-### auto-generated section `test intellij.platform.ai.agent.json.tests` start
-
-jps_test(
- name = "ai-agent-json-tests_test",
- runtime_deps = [":ai-agent-json-tests_test_lib"],
-)
-### auto-generated section `test intellij.platform.ai.agent.json.tests` end
diff --git a/plugins/agent-workbench/lib-agent/json/api-dump.txt b/plugins/agent-workbench/lib-agent/json/api-dump.txt
deleted file mode 100644
index 23022822c08a..000000000000
--- a/plugins/agent-workbench/lib-agent/json/api-dump.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-f:com.intellij.platform.ai.agent.json.WorkbenchJsonParsingUtilsKt
-- sf:createJsonGenerator(tools.jackson.core.json.JsonFactory,java.io.OutputStream):tools.jackson.core.JsonGenerator
-- sf:createJsonGenerator(tools.jackson.core.json.JsonFactory,java.io.Writer):tools.jackson.core.JsonGenerator
-- sf:createJsonGenerator(tools.jackson.core.json.JsonFactory,java.io.Writer,tools.jackson.core.PrettyPrinter):tools.jackson.core.JsonGenerator
-- sf:createJsonParser(tools.jackson.core.json.JsonFactory,java.io.InputStream):tools.jackson.core.JsonParser
-- sf:createJsonParser(tools.jackson.core.json.JsonFactory,java.io.Reader):tools.jackson.core.JsonParser
-- sf:createJsonParser(tools.jackson.core.json.JsonFactory,java.lang.String):tools.jackson.core.JsonParser
-- sf:createJsonParser(tools.jackson.core.json.JsonFactory,B[]):tools.jackson.core.JsonParser
-- sf:forEachJsonObjectField(tools.jackson.core.JsonParser,kotlin.jvm.functions.Function1):V
-- sf:readJsonLongOrNull(tools.jackson.core.JsonParser):java.lang.Long
-- sf:readJsonStringOrNull(tools.jackson.core.JsonParser):java.lang.String
-f:com.intellij.platform.ai.agent.json.WorkbenchJsonlScanner
-- sf:INSTANCE:com.intellij.platform.ai.agent.json.WorkbenchJsonlScanner
-- f:removeLines(java.nio.file.Path,tools.jackson.core.json.JsonFactory,kotlin.jvm.functions.Function1):V
-- f:scanJsonObjects(java.nio.file.Path,tools.jackson.core.json.JsonFactory,I,kotlin.jvm.functions.Function0,kotlin.jvm.functions.Function2):java.lang.Object
-- bs:scanJsonObjects$default(com.intellij.platform.ai.agent.json.WorkbenchJsonlScanner,java.nio.file.Path,tools.jackson.core.json.JsonFactory,I,kotlin.jvm.functions.Function0,kotlin.jvm.functions.Function2,I,java.lang.Object):java.lang.Object
-- f:scanTailLines(java.nio.file.Path,tools.jackson.core.json.JsonFactory,J,kotlin.jvm.functions.Function0,kotlin.jvm.functions.Function2):java.lang.Object
-- bs:scanTailLines$default(com.intellij.platform.ai.agent.json.WorkbenchJsonlScanner,java.nio.file.Path,tools.jackson.core.json.JsonFactory,J,kotlin.jvm.functions.Function0,kotlin.jvm.functions.Function2,I,java.lang.Object):java.lang.Object
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionCachedFile
-- f:lastModifiedNs:J
-- f:parsedValue:java.lang.Object
-- f:sizeBytes:J
-- (J,J,java.lang.Object):V
-- f:component1():J
-- f:component2():J
-- f:component3():java.lang.Object
-- f:copy(J,J,java.lang.Object):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionCachedFile
-- bs:copy$default(com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionCachedFile,J,J,java.lang.Object,I,java.lang.Object):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionCachedFile
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSet
-- f:changedPaths:java.util.Set
-- f:requiresFullRescan:Z
-- ():V
-- (java.util.Set,Z):V
-- b:(java.util.Set,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.util.Set
-- f:component2():Z
-- f:copy(java.util.Set,Z):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSet
-- bs:copy$default(com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSet,java.util.Set,Z,I,java.lang.Object):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSet
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSetKt
-- sf:normalizeFileBackedSessionPath(java.nio.file.Path):java.nio.file.Path
-- sf:toFileBackedSessionPathKey(java.nio.file.Path):java.lang.String
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionEventClassifierKt
-- sf:classifyFileBackedSessionEvent(com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent,kotlin.jvm.functions.Function1,kotlin.jvm.functions.Function1,kotlin.jvm.functions.Function1):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSet
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionFileStat
-- f:lastModifiedNs:J
-- f:path:java.nio.file.Path
-- f:pathKey:java.lang.String
-- f:sizeBytes:J
-- (java.lang.String,java.nio.file.Path,J,J):V
-- f:component1():java.lang.String
-- f:component2():java.nio.file.Path
-- f:component3():J
-- f:component4():J
-- f:copy(java.lang.String,java.nio.file.Path,J,J):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionFileStat
-- bs:copy$default(com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionFileStat,java.lang.String,java.nio.file.Path,J,J,I,java.lang.Object):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionFileStat
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionInvalidationState
-- (kotlin.jvm.functions.Function1):V
-- f:applyParsedUpdates(java.util.Map):V
-- f:clear():V
-- f:markDirty(com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionChangeSet):I
-- f:planRescan(java.util.Map):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionRescanPlan
-- f:snapshotCachedFiles():java.util.Map
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionInvalidationStateKt
-- sf:buildFileBackedSessionFileStat(java.nio.file.Path,J):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionFileStat
-- bs:buildFileBackedSessionFileStat$default(java.nio.file.Path,J,I,java.lang.Object):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionFileStat
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionRescanPlan
-- f:dirtyPathCount:I
-- f:filesToParse:java.util.List
-- f:fullRescan:Z
-- f:removedAny:Z
-- (java.util.List,Z,Z,I):V
-- f:component1():java.util.List
-- f:component2():Z
-- f:component3():Z
-- f:component4():I
-- f:copy(java.util.List,Z,Z,I):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionRescanPlan
-- bs:copy$default(com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionRescanPlan,java.util.List,Z,Z,I,I,java.lang.Object):com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionRescanPlan
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionUpdatesFlowKt
-- sf:createFileBackedSessionChangeFlow(com.intellij.openapi.diagnostic.Logger,java.lang.String,kotlin.jvm.functions.Function0,Z,kotlin.jvm.functions.Function2):kotlinx.coroutines.flow.Flow
-- bs:createFileBackedSessionChangeFlow$default(com.intellij.openapi.diagnostic.Logger,java.lang.String,kotlin.jvm.functions.Function0,Z,kotlin.jvm.functions.Function2,I,java.lang.Object):kotlinx.coroutines.flow.Flow
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionWatcher
-- java.lang.AutoCloseable
-- (com.intellij.openapi.diagnostic.Logger,java.lang.String,com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionWatcherSpec,kotlinx.coroutines.CoroutineScope,kotlin.jvm.functions.Function1,java.lang.String):V
-- b:(com.intellij.openapi.diagnostic.Logger,java.lang.String,com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionWatcherSpec,kotlinx.coroutines.CoroutineScope,kotlin.jvm.functions.Function1,java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- close():V
-f:com.intellij.platform.ai.agent.json.filebacked.FileBackedSessionWatcherSpec
-- (java.util.Collection,kotlin.jvm.functions.Function1):V
-- f:getEventToChangeSet():kotlin.jvm.functions.Function1
-- f:getRoots():java.util.Collection
diff --git a/plugins/agent-workbench/lib-agent/json/exposed-third-party-api.txt b/plugins/agent-workbench/lib-agent/json/exposed-third-party-api.txt
deleted file mode 100644
index a19ab2693bd8..000000000000
--- a/plugins/agent-workbench/lib-agent/json/exposed-third-party-api.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-kotlin/jvm/internal/DefaultConstructorMarker
-tools/jackson/core/JsonGenerator
-tools/jackson/core/JsonParser
-tools/jackson/core/PrettyPrinter
-tools/jackson/core/json/JsonFactory
diff --git a/plugins/agent-workbench/lib-agent/json/intellij.platform.ai.agent.json.iml b/plugins/agent-workbench/lib-agent/json/intellij.platform.ai.agent.json.iml
deleted file mode 100644
index 7994e2c0d979..000000000000
--- a/plugins/agent-workbench/lib-agent/json/intellij.platform.ai.agent.json.iml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/json/intellij.platform.ai.agent.json.tests.iml b/plugins/agent-workbench/lib-agent/json/intellij.platform.ai.agent.json.tests.iml
deleted file mode 100644
index 35c616dd907a..000000000000
--- a/plugins/agent-workbench/lib-agent/json/intellij.platform.ai.agent.json.tests.iml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/json/resources/intellij.platform.ai.agent.json.xml b/plugins/agent-workbench/lib-agent/json/resources/intellij.platform.ai.agent.json.xml
deleted file mode 100644
index e26d96bb6a7f..000000000000
--- a/plugins/agent-workbench/lib-agent/json/resources/intellij.platform.ai.agent.json.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/json/src/WorkbenchJsonParsingUtils.kt b/plugins/agent-workbench/lib-agent/json/src/WorkbenchJsonParsingUtils.kt
deleted file mode 100644
index bb47e10f5ee6..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/WorkbenchJsonParsingUtils.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-// 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.platform.ai.agent.json
-
-import tools.jackson.core.JsonGenerator
-import tools.jackson.core.JsonParser
-import tools.jackson.core.JsonToken
-import tools.jackson.core.ObjectReadContext
-import tools.jackson.core.ObjectWriteContext
-import tools.jackson.core.PrettyPrinter
-import tools.jackson.core.StreamWriteFeature
-import tools.jackson.core.TokenStreamFactory
-import tools.jackson.core.json.JsonFactory
-import java.io.InputStream
-import java.io.OutputStream
-import java.io.Reader
-import java.io.Writer
-
-fun JsonFactory.createJsonParser(content: String): JsonParser {
- return createParser(ObjectReadContext.empty(), content)
-}
-
-fun JsonFactory.createJsonParser(content: ByteArray): JsonParser {
- return createParser(ObjectReadContext.empty(), content)
-}
-
-fun JsonFactory.createJsonParser(input: InputStream): JsonParser {
- return createParser(ObjectReadContext.empty(), input)
-}
-
-fun JsonFactory.createJsonParser(reader: Reader): JsonParser {
- return createParser(ObjectReadContext.empty(), reader)
-}
-
-fun JsonFactory.createJsonGenerator(output: OutputStream): JsonGenerator {
- return createGenerator(ObjectWriteContext.empty(), output).configure(StreamWriteFeature.AUTO_CLOSE_TARGET, false)
-}
-
-fun JsonFactory.createJsonGenerator(writer: Writer): JsonGenerator {
- return createGenerator(ObjectWriteContext.empty(), writer).configure(StreamWriteFeature.AUTO_CLOSE_TARGET, false)
-}
-
-fun JsonFactory.createJsonGenerator(writer: Writer, prettyPrinter: PrettyPrinter): JsonGenerator {
- return createGenerator(PrettyPrinterWriteContext(this, prettyPrinter), writer).configure(StreamWriteFeature.AUTO_CLOSE_TARGET, false)
-}
-
-private class PrettyPrinterWriteContext(
- private val factory: JsonFactory,
- private val prettyPrinter: PrettyPrinter,
-) : ObjectWriteContext.Base() {
- override fun tokenStreamFactory(): TokenStreamFactory = factory
-
- override fun getPrettyPrinter(): PrettyPrinter = prettyPrinter
-}
-
-inline fun forEachJsonObjectField(parser: JsonParser, onField: (String) -> Boolean) {
- while (true) {
- val token = parser.nextToken() ?: return
- if (token == JsonToken.END_OBJECT) return
- if (token != JsonToken.PROPERTY_NAME) {
- parser.skipChildren()
- continue
- }
- val fieldName = parser.currentName()
- if (parser.nextToken() == null) return
- if (!onField(fieldName)) return
- }
-}
-
-fun readJsonStringOrNull(parser: JsonParser): String? {
- return when (parser.currentToken()) {
- JsonToken.VALUE_STRING -> parser.string
- JsonToken.VALUE_NUMBER_INT, JsonToken.VALUE_NUMBER_FLOAT -> parser.numberValue.toString()
- JsonToken.VALUE_TRUE, JsonToken.VALUE_FALSE -> parser.booleanValue.toString()
- JsonToken.VALUE_NULL -> null
- else -> {
- parser.skipChildren()
- null
- }
- }
-}
-
-fun readJsonLongOrNull(parser: JsonParser): Long? {
- return when (parser.currentToken()) {
- JsonToken.VALUE_NUMBER_INT -> parser.longValue
- JsonToken.VALUE_NUMBER_FLOAT -> parser.doubleValue.toLong()
- JsonToken.VALUE_STRING -> parser.string.toLongOrNull() ?: parser.string.toDoubleOrNull()?.toLong()
- JsonToken.VALUE_NULL -> null
- else -> {
- parser.skipChildren()
- null
- }
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/json/src/WorkbenchJsonlScanner.kt b/plugins/agent-workbench/lib-agent/json/src/WorkbenchJsonlScanner.kt
deleted file mode 100644
index 6835a5f2caa3..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/WorkbenchJsonlScanner.kt
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-@file:Suppress("PackageDirectoryMismatch", "unused")
-
-package com.intellij.platform.ai.agent.json
-
-import tools.jackson.core.JsonParser
-import tools.jackson.core.JsonToken
-import tools.jackson.core.json.JsonFactory
-import java.io.BufferedReader
-import java.io.InputStreamReader
-import java.nio.channels.Channels
-import java.nio.channels.FileChannel
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.StandardOpenOption
-
-object WorkbenchJsonlScanner {
- fun scanJsonObjects(
- path: Path,
- jsonFactory: JsonFactory,
- maxObjects: Int = Int.MAX_VALUE,
- newState: () -> S,
- onObject: (JsonParser, S) -> Boolean,
- ): S {
- if (maxObjects <= 0) return newState()
-
- val fastState = newState()
- val parsedWithSingleParser = try {
- parseWithSingleParser(path, jsonFactory, maxObjects, fastState, onObject)
- true
- }
- catch (_: Throwable) {
- false
- }
- if (parsedWithSingleParser) {
- return fastState
- }
-
- val fallbackState = newState()
- parseLineByLine(path, jsonFactory, maxObjects, fallbackState, onObject)
- return fallbackState
- }
-
- fun scanTailLines(
- path: Path,
- jsonFactory: JsonFactory,
- tailBytes: Long = 16_384L,
- newState: () -> S,
- onObject: (JsonParser, S) -> Boolean,
- ): S {
- val state = newState()
- try {
- FileChannel.open(path, StandardOpenOption.READ).use { channel ->
- val fileSize = channel.size()
- val seekPos = maxOf(0L, fileSize - tailBytes)
- channel.position(seekPos)
- val reader = BufferedReader(InputStreamReader(Channels.newInputStream(channel), Charsets.UTF_8))
- // If we seeked mid-file, skip the first partial line.
- if (seekPos > 0) {
- reader.readLine()
- }
- while (true) {
- val line = reader.readLine() ?: break
- val trimmed = line.trim()
- if (trimmed.isEmpty()) continue
- val shouldContinue = parseLineObject(trimmed, jsonFactory, state, onObject) ?: continue
- if (!shouldContinue) break
- }
- }
- }
- catch (_: Exception) {
- // Tail scan is best-effort; return whatever state we collected.
- }
- return state
- }
-
- /**
- * Removes lines from a JSONL file where [shouldRemove] returns `true`.
- * Deletes the file entirely if no lines remain after removal.
- *
- * @param shouldRemove receives a [JsonParser] positioned at `START_OBJECT`; return `true` to remove the line
- */
- fun removeLines(
- path: Path,
- jsonFactory: JsonFactory,
- shouldRemove: (JsonParser) -> Boolean,
- ) {
- if (!Files.exists(path)) return
- val lines = Files.readAllLines(path)
- val remaining = lines.filter { line ->
- val trimmed = line.trim()
- if (trimmed.isEmpty()) return@filter false
- val remove = try {
- jsonFactory.createJsonParser(trimmed).use { parser ->
- parser.nextToken() == JsonToken.START_OBJECT && shouldRemove(parser)
- }
- }
- catch (_: Throwable) {
- false
- }
- !remove
- }
- if (remaining.isEmpty()) {
- Files.deleteIfExists(path)
- }
- else {
- Files.writeString(path, remaining.joinToString("\n", postfix = "\n"))
- }
- }
-
- private fun parseWithSingleParser(
- path: Path,
- jsonFactory: JsonFactory,
- maxObjects: Int,
- state: S,
- onObject: (JsonParser, S) -> Boolean,
- ) {
- Files.newBufferedReader(path).use { reader ->
- jsonFactory.createJsonParser(reader).use { parser ->
- var parsedObjects = 0
- while (parsedObjects < maxObjects) {
- val token = parser.nextToken() ?: return
- if (token != JsonToken.START_OBJECT) {
- parser.skipChildren()
- continue
- }
-
- parsedObjects++
- if (!onObject(parser, state)) {
- return
- }
- }
- }
- }
- }
-
- private fun parseLineByLine(
- path: Path,
- jsonFactory: JsonFactory,
- maxObjects: Int,
- state: S,
- onObject: (JsonParser, S) -> Boolean,
- ) {
- Files.newBufferedReader(path).use { reader ->
- var parsedObjects = 0
- while (parsedObjects < maxObjects) {
- val line = reader.readLine() ?: return
- val trimmed = line.trim()
- if (trimmed.isEmpty()) continue
-
- val shouldContinue = parseLineObject(trimmed, jsonFactory, state, onObject)
- if (shouldContinue == null) {
- continue
- }
-
- parsedObjects++
- if (!shouldContinue) {
- return
- }
- }
- }
- }
-
- private fun parseLineObject(
- line: String,
- jsonFactory: JsonFactory,
- state: S,
- onObject: (JsonParser, S) -> Boolean,
- ): Boolean? {
- return try {
- jsonFactory.createJsonParser(line).use { parser ->
- if (parser.nextToken() != JsonToken.START_OBJECT) {
- return null
- }
- onObject(parser, state)
- }
- }
- catch (_: Throwable) {
- null
- }
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionChangeSet.kt b/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionChangeSet.kt
deleted file mode 100644
index d463afc4bcc4..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionChangeSet.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import java.nio.file.Path
-import kotlin.io.path.invariantSeparatorsPathString
-
-data class FileBackedSessionChangeSet(
- // Known files that must be reparsed regardless of file stat heuristics.
- @JvmField val changedPaths: Set = emptySet(),
-
- // Overflow/ambiguous events where file-level attribution is not reliable.
- @JvmField val requiresFullRescan: Boolean = false,
-
- // `changedPaths.isEmpty() && !requiresFullRescan` means "refresh ping":
- // re-run stat-based scan without forcing full reparse.
-)
-
-fun normalizeFileBackedSessionPath(path: Path): Path {
- return runCatching {
- path.toAbsolutePath().normalize()
- }.getOrElse {
- path.normalize()
- }
-}
-
-fun toFileBackedSessionPathKey(path: Path): String {
- return normalizeFileBackedSessionPath(path).invariantSeparatorsPathString
-}
diff --git a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionEventClassifier.kt b/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionEventClassifier.kt
deleted file mode 100644
index 00e97ce9e6bb..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionEventClassifier.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent
-import com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEventType
-import java.nio.file.Path
-
-fun classifyFileBackedSessionEvent(
- event: AgentWorkbenchWatchEvent,
- isChangedPath: (Path) -> Boolean,
- isRelevantPath: (Path) -> Boolean,
- isRelevantRoot: (Path) -> Boolean,
-): FileBackedSessionChangeSet? {
- val eventPath = event.path
- val rootPath = event.rootPath
-
- if (event.eventType == AgentWorkbenchWatchEventType.OVERFLOW) {
- val isRelevantOverflow = when {
- eventPath != null && isRelevantPath(eventPath) -> true
- rootPath != null && isRelevantRoot(rootPath) -> true
- eventPath == null && rootPath == null -> true
- else -> false
- }
- return if (isRelevantOverflow) FileBackedSessionChangeSet(requiresFullRescan = true) else null
- }
-
- if (eventPath != null && isChangedPath(eventPath)) {
- return FileBackedSessionChangeSet(changedPaths = setOf(normalizeFileBackedSessionPath(eventPath)))
- }
-
- val isRelevantEvent = when {
- eventPath != null -> isRelevantPath(eventPath)
- rootPath != null -> isRelevantRoot(rootPath)
- else -> false
- }
- if (!isRelevantEvent) return null
-
- val isAmbiguousDirectoryEvent = event.isDirectory || eventPath == null
- if (isAmbiguousDirectoryEvent) {
- return FileBackedSessionChangeSet(requiresFullRescan = true)
- }
-
- return FileBackedSessionChangeSet()
-}
diff --git a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionInvalidationState.kt b/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionInvalidationState.kt
deleted file mode 100644
index 687a99b9de41..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionInvalidationState.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import java.nio.file.Files
-import java.nio.file.Path
-import java.util.concurrent.TimeUnit
-
-data class FileBackedSessionFileStat(
- @JvmField val pathKey: String,
- @JvmField val path: Path,
- @JvmField val lastModifiedNs: Long,
- @JvmField val sizeBytes: Long,
-)
-
-/**
- * Reads the stat (mtime, size) of [candidate] and returns a [FileBackedSessionFileStat],
- * or `null` if the file is not a regular file, cannot be stat'd, or its mtime is below
- * [minLastModifiedNs].
- */
-fun buildFileBackedSessionFileStat(
- candidate: Path,
- minLastModifiedNs: Long = Long.MIN_VALUE,
-): FileBackedSessionFileStat? {
- if (!Files.isRegularFile(candidate)) return null
- val lastModifiedNs = try {
- Files.getLastModifiedTime(candidate).to(TimeUnit.NANOSECONDS)
- }
- catch (_: Throwable) {
- return null
- }
- if (lastModifiedNs < minLastModifiedNs) return null
- val sizeBytes = try {
- Files.size(candidate)
- }
- catch (_: Throwable) {
- return null
- }
- val pathKey = toFileBackedSessionPathKey(candidate)
- return FileBackedSessionFileStat(
- pathKey = pathKey,
- path = candidate,
- lastModifiedNs = lastModifiedNs,
- sizeBytes = sizeBytes,
- )
-}
-
-data class FileBackedSessionCachedFile(
- @JvmField val lastModifiedNs: Long,
- @JvmField val sizeBytes: Long,
- @JvmField val parsedValue: Parsed,
-)
-
-data class FileBackedSessionRescanPlan(
- @JvmField val filesToParse: List,
- @JvmField val removedAny: Boolean,
- @JvmField val fullRescan: Boolean,
- @JvmField val dirtyPathCount: Int,
-)
-
-class FileBackedSessionInvalidationState(
- private val trackedPathPredicate: (Path) -> Boolean,
-) {
- private val cacheLock = Any()
- private val cachedFilesByPath = LinkedHashMap>()
- private val dirtyPathKeys = LinkedHashSet()
- private var forceFullRescan = false
-
- fun markDirty(changeSet: FileBackedSessionChangeSet): Int {
- if (!changeSet.requiresFullRescan && changeSet.changedPaths.isEmpty()) {
- return 0
- }
-
- var markedPaths = 0
- synchronized(cacheLock) {
- forceFullRescan = forceFullRescan || changeSet.requiresFullRescan
- for (path in changeSet.changedPaths) {
- if (!trackedPathPredicate(path)) continue
- if (dirtyPathKeys.add(toFileBackedSessionPathKey(path))) {
- markedPaths++
- }
- }
- }
- return markedPaths
- }
-
- fun planRescan(scannedFiles: Map): FileBackedSessionRescanPlan {
- val filesToParse = ArrayList()
- var removedAny = false
- var fullRescan = false
- var dirtyPathCount = 0
-
- synchronized(cacheLock) {
- val iterator = cachedFilesByPath.entries.iterator()
- while (iterator.hasNext()) {
- if (!scannedFiles.containsKey(iterator.next().key)) {
- iterator.remove()
- removedAny = true
- }
- }
-
- val dirtyPathsSnapshot = dirtyPathKeys.takeIf { it.isNotEmpty() }?.let(::LinkedHashSet)
- fullRescan = forceFullRescan
- dirtyPathCount = dirtyPathsSnapshot?.size ?: 0
-
- forceFullRescan = false
- dirtyPathKeys.clear()
-
- for ((pathKey, stat) in scannedFiles) {
- val cached = cachedFilesByPath[pathKey]
- val parseBecauseDirty = dirtyPathsSnapshot?.contains(pathKey) == true
- val parseBecauseStatsChanged = cached == null || cached.lastModifiedNs != stat.lastModifiedNs || cached.sizeBytes != stat.sizeBytes
- if (fullRescan || parseBecauseDirty || parseBecauseStatsChanged) {
- filesToParse.add(stat)
- }
- }
- }
-
- return FileBackedSessionRescanPlan(
- filesToParse = filesToParse,
- removedAny = removedAny,
- fullRescan = fullRescan,
- dirtyPathCount = dirtyPathCount,
- )
- }
-
- fun applyParsedUpdates(parsedUpdates: Map>) {
- if (parsedUpdates.isEmpty()) return
-
- synchronized(cacheLock) {
- cachedFilesByPath.putAll(parsedUpdates)
- }
- }
-
- fun snapshotCachedFiles(): Map> {
- return synchronized(cacheLock) {
- LinkedHashMap(cachedFilesByPath)
- }
- }
-
- fun clear() {
- synchronized(cacheLock) {
- cachedFilesByPath.clear()
- dirtyPathKeys.clear()
- forceFullRescan = false
- }
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionUpdatesFlow.kt b/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionUpdatesFlow.kt
deleted file mode 100644
index 70ec972c61a6..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionUpdatesFlow.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.diagnostic.debug
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.callbackFlow
-
-fun createFileBackedSessionChangeFlow(
- logger: Logger,
- watcherName: String,
- initContext: (() -> String)? = null,
- emitInitialRefreshPing: Boolean = false,
- createWatcher: (CoroutineScope, onChange: (FileBackedSessionChangeSet) -> Unit) -> AutoCloseable?,
-): Flow = callbackFlow {
- val context = initContext?.invoke()?.takeUnless { it.isBlank() }
- logger.debug {
- "Initializing $watcherName updates watcher${context?.let { " ($it)" } ?: ""}"
- }
-
- val watcher = runCatching {
- createWatcher(this) { changeSet ->
- logger.debug {
- "$watcherName watcher signaled change; emitting update (fullRescan=${changeSet.requiresFullRescan}, changedPaths=${changeSet.changedPaths.size})"
- }
- trySend(changeSet)
- }
- }.onFailure { t ->
- logger.warn("Failed to initialize $watcherName watcher", t)
- }.getOrNull()
-
- if (watcher == null) {
- logger.debug { "$watcherName updates watcher was not initialized; updates flow will stay idle" }
- awaitClose { }
- return@callbackFlow
- }
-
- if (emitInitialRefreshPing) {
- val initialRefreshEmitted = trySend(FileBackedSessionChangeSet()).isSuccess
- logger.debug {
- "$watcherName watcher initialized; initial refresh ping emitted=$initialRefreshEmitted"
- }
- }
-
- awaitClose {
- logger.debug { "Closing $watcherName updates watcher" }
- watcher.close()
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionWatcher.kt b/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionWatcher.kt
deleted file mode 100644
index eb4cbde268e1..000000000000
--- a/plugins/agent-workbench/lib-agent/json/src/filebacked/FileBackedSessionWatcher.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import com.intellij.platform.ai.agent.filewatch.AgentWorkbenchDirectoryWatcher
-import com.intellij.platform.ai.agent.filewatch.AgentWorkbenchWatchEvent
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.diagnostic.debug
-import kotlinx.coroutines.CoroutineScope
-import java.nio.file.Files
-import java.nio.file.Path
-
-class FileBackedSessionWatcherSpec(
- val roots: Collection,
- val eventToChangeSet: (AgentWorkbenchWatchEvent) -> FileBackedSessionChangeSet?,
-)
-
-class FileBackedSessionWatcher(
- private val logger: Logger,
- private val watcherName: String,
- spec: FileBackedSessionWatcherSpec,
- scope: CoroutineScope,
- private val onChange: (FileBackedSessionChangeSet) -> Unit,
- private val failureMessage: String = "$watcherName watcher failed",
-) : AutoCloseable {
- private val watcher: AgentWorkbenchDirectoryWatcher?
-
- init {
- val roots = spec.roots.asSequence()
- .map(::normalizeFileBackedSessionPath)
- .filter { path -> Files.isDirectory(path) }
- .distinct()
- .toList()
- logger.debug { "Registering $watcherName watcher (roots=$roots)" }
-
- watcher = if (roots.isEmpty()) {
- logger.debug { "No watcher roots found; $watcherName watcher will stay idle" }
- null
- }
- else {
- AgentWorkbenchDirectoryWatcher(
- roots = roots,
- scope = scope,
- onWatchEvent = { event -> handleWatchEvent(event, spec.eventToChangeSet) },
- onFailure = { t ->
- logger.warn(failureMessage, t)
- },
- )
- }
-
- if (watcher != null) {
- logger.debug { "Initialized directory watcher for roots=$roots" }
- }
- }
-
- override fun close() {
- logger.debug { "Closing $watcherName watcher" }
- watcher?.close()
- }
-
- private fun handleWatchEvent(
- event: AgentWorkbenchWatchEvent,
- eventToChangeSet: (AgentWorkbenchWatchEvent) -> FileBackedSessionChangeSet?,
- ) {
- val eventPath = event.path
- val rootPath = event.rootPath
- val eventType = event.eventType
- val isDirectory = event.isDirectory
- logger.debug {
- "$watcherName watcher event type=$eventType path=$eventPath root=$rootPath isDirectory=$isDirectory count=${event.count}"
- }
-
- val changeSet = eventToChangeSet(event) ?: return
- logger.debug {
- "$watcherName watcher detected relevant changes; notifying listeners (fullRescan=${changeSet.requiresFullRescan}, changedPaths=${changeSet.changedPaths.size})"
- }
- onChange(changeSet)
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/json/testSrc/filebacked/FileBackedSessionInvalidationStateTest.kt b/plugins/agent-workbench/lib-agent/json/testSrc/filebacked/FileBackedSessionInvalidationStateTest.kt
deleted file mode 100644
index 6d1ae40a1115..000000000000
--- a/plugins/agent-workbench/lib-agent/json/testSrc/filebacked/FileBackedSessionInvalidationStateTest.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import java.util.concurrent.TimeUnit
-import org.junit.jupiter.api.io.TempDir
-import java.nio.file.Path
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class FileBackedSessionInvalidationStateTest {
- @TempDir
- lateinit var tempDir: Path
-
- @Test
- fun refreshPingDoesNotMarkDirtyPaths() {
- val state = newState()
- val sessionPath = tempDir.resolve("refresh/session.jsonl")
- val stat = stat(sessionPath)
- state.applyParsedUpdates(mapOf(stat.pathKey to cachedFile(stat, parsedValue = "initial")))
-
- val markedPaths = state.markDirty(FileBackedSessionChangeSet())
- val plan = state.planRescan(mapOf(stat.pathKey to stat))
-
- assertThat(markedPaths).isZero()
- assertThat(plan.filesToParse).isEmpty()
- assertThat(plan.dirtyPathCount).isZero()
- assertThat(plan.fullRescan).isFalse()
- }
-
- @Test
- fun dirtyPathForcesReparseWhenFileStatsDidNotChange() {
- val state = newState()
- val sessionPath = tempDir.resolve("dirty/session.jsonl")
- val stat = stat(sessionPath)
- state.applyParsedUpdates(mapOf(stat.pathKey to cachedFile(stat, parsedValue = "before")))
-
- val markedPaths = state.markDirty(FileBackedSessionChangeSet(changedPaths = setOf(sessionPath)))
- val plan = state.planRescan(mapOf(stat.pathKey to stat))
-
- assertThat(markedPaths).isEqualTo(1)
- assertThat(plan.filesToParse).containsExactly(stat)
- assertThat(plan.dirtyPathCount).isEqualTo(1)
- assertThat(plan.fullRescan).isFalse()
- }
-
- @Test
- fun fullRescanReparsesAllScannedFiles() {
- val state = newState()
- val firstStat = stat(tempDir.resolve("full/first.jsonl"), lastModifiedNs = 1L)
- val secondStat = stat(tempDir.resolve("full/second.jsonl"), lastModifiedNs = 2L)
- state.applyParsedUpdates(
- mapOf(
- firstStat.pathKey to cachedFile(firstStat, parsedValue = "first"),
- secondStat.pathKey to cachedFile(secondStat, parsedValue = "second"),
- )
- )
-
- state.markDirty(FileBackedSessionChangeSet(requiresFullRescan = true))
- val plan = state.planRescan(
- linkedMapOf(
- firstStat.pathKey to firstStat,
- secondStat.pathKey to secondStat,
- )
- )
-
- assertThat(plan.filesToParse).containsExactly(firstStat, secondStat)
- assertThat(plan.fullRescan).isTrue()
- }
-
- @Test
- fun removedFilesArePrunedFromCache() {
- val state = newState()
- val keptStat = stat(tempDir.resolve("prune/kept.jsonl"), lastModifiedNs = 1L)
- val removedStat = stat(tempDir.resolve("prune/removed.jsonl"), lastModifiedNs = 2L)
- state.applyParsedUpdates(
- mapOf(
- keptStat.pathKey to cachedFile(keptStat, parsedValue = "kept"),
- removedStat.pathKey to cachedFile(removedStat, parsedValue = "removed"),
- )
- )
-
- val plan = state.planRescan(mapOf(keptStat.pathKey to keptStat))
- val cachedFiles = state.snapshotCachedFiles()
-
- assertThat(plan.removedAny).isTrue()
- assertThat(plan.filesToParse).isEmpty()
- assertThat(cachedFiles).containsOnlyKeys(keptStat.pathKey)
- }
-}
-
-private fun newState(): FileBackedSessionInvalidationState {
- return FileBackedSessionInvalidationState { path ->
- path.fileName?.toString()?.endsWith(".jsonl") == true
- }
-}
-
-private fun stat(
- path: Path,
- lastModifiedNs: Long = 1L,
- sizeBytes: Long = 100L,
-): FileBackedSessionFileStat {
- return FileBackedSessionFileStat(
- pathKey = toFileBackedSessionPathKey(path),
- path = normalizeFileBackedSessionPath(path),
- lastModifiedNs = lastModifiedNs,
- sizeBytes = sizeBytes,
- )
-}
-
-private fun cachedFile(
- stat: FileBackedSessionFileStat,
- parsedValue: String,
-): FileBackedSessionCachedFile {
- return FileBackedSessionCachedFile(
- lastModifiedNs = stat.lastModifiedNs,
- sizeBytes = stat.sizeBytes,
- parsedValue = parsedValue,
- )
-}
diff --git a/plugins/agent-workbench/lib-agent/json/testSrc/filebacked/FileBackedSessionUpdatesFlowTest.kt b/plugins/agent-workbench/lib-agent/json/testSrc/filebacked/FileBackedSessionUpdatesFlowTest.kt
deleted file mode 100644
index 06d3a1d442b8..000000000000
--- a/plugins/agent-workbench/lib-agent/json/testSrc/filebacked/FileBackedSessionUpdatesFlowTest.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.platform.ai.agent.json.filebacked
-
-import com.intellij.openapi.diagnostic.logger
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.cancelAndJoin
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
-import kotlinx.coroutines.withTimeoutOrNull
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.Timeout
-import java.util.concurrent.TimeUnit
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
-
-@Timeout(value = 2, unit = TimeUnit.MINUTES)
-class FileBackedSessionUpdatesFlowTest {
- @Test
- fun staysIdleWhenWatcherWasNotInitialized() = runBlocking(Dispatchers.Default) {
- val update = withTimeoutOrNull(1.seconds) {
- createFileBackedSessionChangeFlow(
- logger = logger(),
- watcherName = "test watcher",
- ) { _, _ -> null }.first()
- }
-
- assertThat(update).isNull()
- }
-
- @Test
- fun emitsInitialRefreshPingWhenConfigured() {
- runBlocking(Dispatchers.Default) {
- val update = withTimeout(5.seconds) {
- createFileBackedSessionChangeFlow(
- logger = logger(),
- watcherName = "test watcher",
- emitInitialRefreshPing = true,
- ) { _, _ -> AutoCloseable { } }.first()
- }
-
- assertThat(update).isEqualTo(FileBackedSessionChangeSet())
- }
- }
-
- @Test
- fun closesWatcherWhenCollectorStops() = runBlocking(Dispatchers.Default) {
- val closed = CompletableDeferred()
- val updatesJob = launch {
- createFileBackedSessionChangeFlow(
- logger = logger(),
- watcherName = "test watcher",
- ) { _, _ -> AutoCloseable { closed.complete(Unit) } }.collect { }
- }
-
- try {
- delay(100.milliseconds)
- updatesJob.cancelAndJoin()
- withTimeout(5.seconds) {
- closed.await()
- }
- }
- finally {
- if (updatesJob.isActive) {
- updatesJob.cancelAndJoin()
- }
- }
- }
-}
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/BUILD.bazel b/plugins/agent-workbench/lib-agent/sessions-core/BUILD.bazel
deleted file mode 100644
index 289f5b0ca27e..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/BUILD.bazel
+++ /dev/null
@@ -1,74 +0,0 @@
-load("@rules_jvm//:jvm.bzl", "jvm_library")
-
-### auto-generated section `build intellij.platform.ai.agent.sessions.core` start
-
-jvm_library(
- name = "ai-agent-sessions-core",
- srcs = glob(
- [
- "src/**/*.kt",
- "src/**/*.java",
- "src/**/*.form",
- ],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.sessions.core",
- resource_strip_prefix = "resources",
- resources = glob(
- ["resources/**/*"],
- ),
- visibility = ["//visibility:public"],
- deps = [
- # do not sort,
- "@lib//:kotlin-stdlib",
- "//libraries/kotlinx/serialization/core",
- "//platform/core-api:core",
- "//platform/core-ui",
- "//platform/platform-util-io:ide-util-io",
- "//platform/projectModel-api:projectModel",
- "//platform/util",
- "//platform/util-ex",
- "//platform/util:util-ui",
- "//plugins/agent-workbench/lib-agent/core",
- "//plugins/agent-workbench/prompt/core",
- "//libraries/jackson3/jackson:libraries-jackson3",
- "//plugins/agent-workbench/lib-agent/json",
- ],
-)
-
-jvm_library(
- name = "ai-agent-sessions-core_test_lib",
- testonly = True,
- srcs = glob(
- [],
- allow_empty = True,
- ),
- module_name = "intellij.platform.ai.agent.sessions.core",
- visibility = ["//visibility:public"],
- runtime_deps = [
- # do not sort,
- ":ai-agent-sessions-core",
- "//libraries/kotlinx/serialization/core:core_test_lib",
- "//platform/core-api:core_test_lib",
- "//platform/core-ui:core-ui_test_lib",
- "//platform/platform-util-io:ide-util-io_test_lib",
- "//platform/projectModel-api:projectModel_test_lib",
- "//platform/util:util_test_lib",
- "//platform/util-ex:util-ex_test_lib",
- "//platform/util:util-ui_test_lib",
- "//plugins/agent-workbench/lib-agent/core:core_test_lib",
- "//plugins/agent-workbench/prompt/core:core_test_lib",
- "//libraries/jackson3/jackson:libraries-jackson3_test_lib",
- "//plugins/agent-workbench/lib-agent/json:json_test_lib",
- ],
-)
-### auto-generated section `build intellij.platform.ai.agent.sessions.core` end
-
-### auto-generated section `iml intellij.platform.ai.agent.sessions.core` start
-exports_files(
- [
- "intellij.platform.ai.agent.sessions.core.iml",
- ],
- visibility = ["//visibility:public"],
-)
-### auto-generated section `iml intellij.platform.ai.agent.sessions.core` end
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/api-dump.txt b/plugins/agent-workbench/lib-agent/sessions-core/api-dump.txt
deleted file mode 100644
index 87f1609c232e..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/api-dump.txt
+++ /dev/null
@@ -1,740 +0,0 @@
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadActivityPresentationUpdate
-- f:activityReport:com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:path:java.lang.String
-- f:threadId:java.lang.String
-- f:updatedAt:java.lang.Long
-- (java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):V
-- b:(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3():com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:component4():java.lang.Long
-- f:copy(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadActivityPresentationUpdate
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadActivityPresentationUpdate,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadActivityPresentationUpdate
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadIdsKt
-- sf:isAgentSessionPendingThreadId(java.lang.String):Z
-- sf:normalizeConcreteAgentSessionThreadId(java.lang.String):java.lang.String
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentation
-- f:activityReport:com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:title:java.lang.String
-- f:updatedAt:java.lang.Long
-- (java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:component3():java.lang.Long
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentation
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentation,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentation
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet$Companion
-- f:changedKeys:java.util.Set
-- f:removedKeys:java.util.Set
-- (java.util.Set,java.util.Set):V
-- f:component1():java.util.Set
-- f:component2():java.util.Set
-- f:copy(java.util.Set,java.util.Set):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet,java.util.Set,java.util.Set,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- equals(java.lang.Object):Z
-- hashCode():I
-- f:isEmpty():Z
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet$Companion
-- f:getEMPTY():com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey$Companion
-- f:normalizedProjectPath:java.lang.String
-- f:threadId:java.lang.String
-- f:component1():java.lang.String
-- f:component2-dBzBBrw():java.lang.String
-- f:component3():java.lang.String
-- f:copy-vFUIKBM(java.lang.String,java.lang.String,java.lang.String):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey
-- bs:copy-vFUIKBM$default(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey,java.lang.String,java.lang.String,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey
-- equals(java.lang.Object):Z
-- f:getProvider-dBzBBrw():java.lang.String
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey$Companion
-- f:create-vFUIKBM(java.lang.String,java.lang.String,java.lang.String):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKt
-- sf:formatAgentSessionRelativeTimeShort(J,J,java.lang.String,java.lang.String):java.lang.String
-- sf:formatAgentSessionThreadTitle(java.lang.String,java.lang.String,kotlin.jvm.functions.Function1):java.lang.String
-- sf:formatCompactAgentSessionThreadTitle(java.lang.String,java.lang.String,kotlin.jvm.functions.Function1,I):java.lang.String
-- bs:formatCompactAgentSessionThreadTitle$default(java.lang.String,java.lang.String,kotlin.jvm.functions.Function1,I,I,java.lang.Object):java.lang.String
-- sf:formatCompactAgentSessionTitle(java.lang.String,I):java.lang.String
-- bs:formatCompactAgentSessionTitle$default(java.lang.String,I,I,java.lang.Object):java.lang.String
-- sf:normalizeAgentSessionTitle(java.lang.String):java.lang.String
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationModel
-- ():V
-- f:clearForTests():V
-- f:getChanges():kotlinx.coroutines.flow.SharedFlow
-- f:getState():kotlinx.coroutines.flow.StateFlow
-- f:remove(java.util.Set):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- f:replaceForTests(java.util.Map):V
-- f:resolve(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationKey):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentation
-- f:snapshot():java.util.Map
-- f:updateActivityHints-9c6lQVA(java.lang.String,java.util.Collection):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- f:updatePresentationHints-9c6lQVA(java.lang.String,java.util.Collection):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- f:updateProviderSnapshot-3n3rsyc(java.lang.String,java.util.Set,java.util.Map):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- f:updateThread-RmkVQ7I(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-- bs:updateThread-RmkVQ7I$default(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationModel,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationChangeSet
-f:com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationPatchUpdate
-- f:activityReport:com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:path:java.lang.String
-- f:threadId:java.lang.String
-- f:title:java.lang.String
-- f:updatedAt:java.lang.Long
-- (java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):V
-- b:(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3():java.lang.String
-- f:component4():com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-- f:component5():java.lang.Long
-- f:copy(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationPatchUpdate
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationPatchUpdate,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.AgentThreadActivityReport,java.lang.Long,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.AgentSessionThreadPresentationPatchUpdate
-- equals(java.lang.Object):Z
-- hashCode():I
-com.intellij.platform.ai.agent.sessions.core.SessionActionTarget
-f:com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreProjects
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget
-- f:hiddenCount:I
-- (I):V
-- f:component1():I
-- f:copy(I):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreProjects
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreProjects,I,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreProjects
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreThreads
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget
-- f:hiddenCount:java.lang.Integer
-- f:path:java.lang.String
-- (java.lang.String,java.lang.Integer):V
-- f:component1():java.lang.String
-- f:component2():java.lang.Integer
-- f:copy(java.lang.String,java.lang.Integer):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreThreads
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreThreads,java.lang.String,java.lang.Integer,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$MoreThreads
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Project
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget
-- f:isOpen:Z
-- f:path:java.lang.String
-- (java.lang.String,Z):V
-- f:component1():java.lang.String
-- f:component2():Z
-- f:copy(java.lang.String,Z):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Project
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Project,java.lang.String,Z,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Project
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$SubAgent
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$ThreadTarget
-- f:parentThreadId:java.lang.String
-- f:subAgent:com.intellij.platform.ai.agent.core.session.AgentSubAgent
-- f:subAgentId:java.lang.String
-- f:thread:com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- b:(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,com.intellij.platform.ai.agent.core.session.AgentSubAgent,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2-dBzBBrw():java.lang.String
-- f:component3():java.lang.String
-- f:component4():java.lang.String
-- f:component5():java.lang.String
-- f:component6():com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- f:component7():com.intellij.platform.ai.agent.core.session.AgentSubAgent
-- f:copy-AlqNjB4(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,com.intellij.platform.ai.agent.core.session.AgentSubAgent):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$SubAgent
-- bs:copy-AlqNjB4$default(com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$SubAgent,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,com.intellij.platform.ai.agent.core.session.AgentSubAgent,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$SubAgent
-- equals(java.lang.Object):Z
-- getPath():java.lang.String
-- getProvider-dBzBBrw():java.lang.String
-- getThreadId():java.lang.String
-- getTitle():java.lang.String
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Thread
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$ThreadTarget
-- b:(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2-dBzBBrw():java.lang.String
-- f:component3():java.lang.String
-- f:component4():java.lang.String
-- f:component5():com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- f:copy-TrybPGk(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Thread
-- bs:copy-TrybPGk$default(com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Thread,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Thread
-- equals(java.lang.Object):Z
-- getPath():java.lang.String
-- getProvider-dBzBBrw():java.lang.String
-- f:getThread():com.intellij.platform.ai.agent.core.session.AgentSessionThread
-- getThreadId():java.lang.String
-- getTitle():java.lang.String
-- hashCode():I
-com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$ThreadTarget
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget
-- a:getPath():java.lang.String
-- a:getProvider-dBzBBrw():java.lang.String
-- a:getThreadId():java.lang.String
-- a:getTitle():java.lang.String
-f:com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Worktree
-- com.intellij.platform.ai.agent.sessions.core.SessionActionTarget
-- f:path:java.lang.String
-- (java.lang.String):V
-- f:component1():java.lang.String
-- f:copy(java.lang.String):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Worktree
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Worktree,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.SessionActionTarget$Worktree
-- equals(java.lang.Object):Z
-- hashCode():I
-com.intellij.platform.ai.agent.sessions.core.config.AgentWorkbenchProjectRuntimeConfigProvider
-- a:isRefreshVfsOnStatusUpdatesEnabled(java.lang.String):Z
-f:com.intellij.platform.ai.agent.sessions.core.config.AgentWorkbenchProjectRuntimeConfigs
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.config.AgentWorkbenchProjectRuntimeConfigs
-- f:isRefreshVfsOnStatusUpdatesEnabled(java.lang.String):Z
-com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageCostCalculator
-- a:calculateCost(com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshot):com.intellij.platform.ai.agent.core.session.AgentSessionCost
-f:com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageCostCalculators
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageCostCalculators
-- f:calculateCost(com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshot):com.intellij.platform.ai.agent.core.session.AgentSessionCost
-- f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName
-f:com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshot
-- f:cacheReadTokens:J
-- f:cacheWrite1hTokens:J
-- f:cacheWrite5mTokens:J
-- f:cacheWriteTokens:J
-- f:inputTokens:J
-- f:modelId:java.lang.String
-- f:nativeExactCostUsd:java.math.BigDecimal
-- f:outputTokens:J
-- f:reasoningTokens:J
-- f:requestCount:J
-- (java.lang.String,J,J,J,J,J,J,J,J,java.math.BigDecimal):V
-- b:(java.lang.String,J,J,J,J,J,J,J,J,java.math.BigDecimal,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component10():java.math.BigDecimal
-- f:component2():J
-- f:component3():J
-- f:component4():J
-- f:component5():J
-- f:component6():J
-- f:component7():J
-- f:component8():J
-- f:component9():J
-- f:copy(java.lang.String,J,J,J,J,J,J,J,J,java.math.BigDecimal):com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshot
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshot,java.lang.String,J,J,J,J,J,J,J,J,java.math.BigDecimal,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshot
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.cost.AgentSessionUsageSnapshotKt
-- sf:aggregateAgentSessionUsageCost(java.util.List,kotlin.jvm.functions.Function1):com.intellij.platform.ai.agent.core.session.AgentSessionCost
-com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchContributor
-- a:contribute-rVRrr4o(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchContributors
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchContributors
-- f:applyAll-rVRrr4o(java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation):java.lang.Object
-- bs:applyAll-rVRrr4o$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchContributors,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation,I,java.lang.Object):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent
-- f:generationSettings:com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:launchMode:com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- f:launchTargetId:java.lang.String
-- f:operation:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation
-- f:projectDirectory:java.lang.String
-- f:projectPath:java.lang.String
-- f:sessionId:java.lang.String
-- b:(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3-dBzBBrw():java.lang.String
-- f:component4():com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation
-- f:component5():java.lang.String
-- f:component6():com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- f:component7():java.lang.String
-- f:component8-fi09RKo():java.lang.String
-- f:component9():com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:copy-QUbC3BQ(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent
-- bs:copy-QUbC3BQ$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent
-- equals(java.lang.Object):Z
-- f:getProvider-dBzBBrw():java.lang.String
-- f:getSurfaceId-fi09RKo():java.lang.String
-- hashCode():I
-e:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation
-- java.lang.Enum
-- sf:NEW:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation
-- sf:RESUME:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation
-- s:values():com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchOperation[]
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchPlanner
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchPlanner
-- f:plan(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent,com.intellij.openapi.project.Project,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,java.util.List,java.util.Map,java.util.List,kotlin.jvm.functions.Function4,kotlin.coroutines.Continuation):java.lang.Object
-- bs:plan$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchPlanner,com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent,com.intellij.openapi.project.Project,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,java.util.List,java.util.Map,java.util.List,kotlin.jvm.functions.Function4,kotlin.coroutines.Continuation,I,java.lang.Object):java.lang.Object
-com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecAugmenter
-- a:augment-tFgkW8w(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecAugmenters
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecAugmenters
-- f:augment-tFgkW8w(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation):java.lang.Object
-- bs:augment-tFgkW8w$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecAugmenters,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation,I,java.lang.Object):java.lang.Object
-- f:withAugmenterForTest(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecAugmenter,kotlin.jvm.functions.Function1,kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecs
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecs
-- f:augment-tFgkW8w(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation):java.lang.Object
-- bs:augment-tFgkW8w$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecs,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,kotlin.coroutines.Continuation,I,java.lang.Object):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchSpecsKt
-- sf:insertArgumentsBefore(java.util.List,java.util.List,java.util.Set):java.util.List
-- sf:removeOptions(java.util.List,java.util.Set,java.util.Set):java.util.List
-- bs:removeOptions$default(java.util.List,java.util.Set,java.util.Set,I,java.lang.Object):java.util.List
-- sf:replaceOrAddOption(java.util.List,java.lang.String,java.lang.String,java.util.Set):java.util.List
-- bs:replaceOrAddOption$default(java.util.List,java.lang.String,java.lang.String,java.util.Set,I,java.lang.Object):java.util.List
-com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunch
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunch$Companion
-- handles(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext):Z
-- a:handles-e2Q3-TE(java.lang.String):Z
-- a:launch(com.intellij.openapi.project.Project,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext,java.lang.String,kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunch$Companion
-- f:forContext(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunch
-- f:forProvider-e2Q3-TE(java.lang.String):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunch
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext
-- f:generationSettings:com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:launchMode:com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- f:launchProfileId:java.lang.String
-- f:launchTargetId:java.lang.String
-- f:component1-dBzBBrw():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- f:component3():java.lang.String
-- f:component4():java.lang.String
-- f:component5-CYdv268():java.lang.String
-- f:component6():com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:copy-NwT8XtU(java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext
-- bs:copy-NwT8XtU$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionOutOfBandLaunchContext
-- equals(java.lang.Object):Z
-- f:getProvider-dBzBBrw():java.lang.String
-- f:getSurfaceId-CYdv268():java.lang.String
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionPlannedLaunch
-- f:baseLaunchSpec:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:generationModelCatalog:java.util.List
-- f:intent:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent
-- f:launchSpec:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- (com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.util.List):V
-- f:component1():com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:component3():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:component4():java.util.List
-- f:copy(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.util.List):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionPlannedLaunch
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionPlannedLaunch,com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionLaunchIntent,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.util.List,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionPlannedLaunch
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionThreadViewOpenPlan
-- f:initialMessageDispatchPlan:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- f:launchSpec:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:runtimeThreadId:java.lang.String
-- f:subAgentId:java.lang.String
-- f:threadIdentity:java.lang.String
-- f:threadTitle:java.lang.String
-- (java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:component3():java.lang.String
-- f:component4():java.lang.String
-- f:component5():java.lang.String
-- f:component6():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionThreadViewOpenPlan
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionThreadViewOpenPlan,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionThreadViewOpenPlan
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.launch.AgentSessionThreadViewOpenPlanKt
-- sf:resolveAgentSessionThreadViewOpenPlan-e88xiWE(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,com.intellij.platform.ai.agent.core.session.AgentSubAgent,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,com.intellij.openapi.project.Project,kotlin.jvm.functions.Function4,kotlin.coroutines.Continuation):java.lang.Object
-- bs:resolveAgentSessionThreadViewOpenPlan-e88xiWE$default(java.lang.String,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionThread,com.intellij.platform.ai.agent.core.session.AgentSubAgent,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,java.lang.String,java.lang.String,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,com.intellij.openapi.project.Project,kotlin.jvm.functions.Function4,kotlin.coroutines.Continuation,I,java.lang.Object):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfig
-- (java.util.Set,kotlin.jvm.functions.Function1):V
-- f:component1():java.util.Set
-- f:component2():kotlin.jvm.functions.Function1
-- f:copy(java.util.Set,kotlin.jvm.functions.Function1):com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfig
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfig,java.util.Set,kotlin.jvm.functions.Function1,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfig
-- equals(java.lang.Object):Z
-- f:getBuildCliArgs():kotlin.jvm.functions.Function1
-- f:getMcpServerNames():java.util.Set
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder
-- sf:AWB_DIR:java.lang.String
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder
-- sf:PROJECT_PATH_ENV:java.lang.String
-- f:buildForLaunch-_8s3iU4(java.nio.file.Path,java.lang.String):com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder$LaunchConfig
-- f:configFilePath(java.nio.file.Path):java.nio.file.Path
-- f:getLEGACY_FILTERED_NAMES():java.util.Set
-- f:isDirectHttpEnabled():Z
-- f:isEnabled-e2Q3-TE(java.lang.String):Z
-- f:writeMergedConfigFile(java.nio.file.Path,java.lang.String,java.util.Set,java.util.List):java.nio.file.Path
-- bs:writeMergedConfigFile$default(com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder,java.nio.file.Path,java.lang.String,java.util.Set,java.util.List,I,java.lang.Object):java.nio.file.Path
-f:com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder$LaunchConfig
-- (java.util.List,java.util.Map,java.nio.file.Path):V
-- f:component1():java.util.List
-- f:component2():java.util.Map
-- f:component3():java.nio.file.Path
-- f:copy(java.util.List,java.util.Map,java.nio.file.Path):com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder$LaunchConfig
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder$LaunchConfig,java.util.List,java.util.Map,java.nio.file.Path,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigBuilder$LaunchConfig
-- equals(java.lang.Object):Z
-- f:getConfigFile():java.nio.file.Path
-- f:getEnvVariables():java.util.Map
-- f:getExtraArgs():java.util.List
-- hashCode():I
-com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigProviderContributor
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigProviderContributor$Companion
-- contribute-e2Q3-TE(java.lang.String):com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfig
-- a:getFilteredServerNames():java.util.Set
-f:com.intellij.platform.ai.agent.sessions.core.launch.AwbMcpConfigProviderContributor$Companion
-- f:getEP():com.intellij.openapi.extensions.ExtensionPointName
-com.intellij.platform.ai.agent.sessions.core.launch.McpStreamUrlProvider
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.launch.McpStreamUrlProvider$Companion
-- a:getStreamUrl():java.lang.String
-f:com.intellij.platform.ai.agent.sessions.core.launch.McpStreamUrlProvider$Companion
-- f:resolve():java.lang.String
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction
-- java.lang.Enum
-- sf:PROVIDER:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction
-- sf:SEND_TEXT:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction[]
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchStep
-- f:action:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction
-- f:recordsPrompt:Z
-- f:text:java.lang.String
-- f:timeoutPolicy:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- ():V
-- (java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction,Z):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- f:component3():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction
-- f:component4():Z
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction,Z):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchStep
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchStep,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchAction,Z,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageDispatchStep
-- equals(java.lang.Object):Z
-- hashCode():I
-- f:isDispatchable():Z
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- java.lang.Enum
-- sf:PLAN:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- sf:STANDARD:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode[]
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan$Companion
-- sf:EMPTY:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- f:message:java.lang.String
-- f:mode:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- f:startupPolicy:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy
-- f:timeoutPolicy:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- (java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- f:component3():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy
-- f:component4():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan$Companion
-- f:composeDefault(com.intellij.agent.workbench.prompt.core.AgentPromptInitialMessageRequest):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageProviderDispatchRequest
-- f:generationSettings:com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:message:java.lang.String
-- f:mode:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- f:project:com.intellij.openapi.project.Project
-- f:projectPath:java.lang.String
-- f:threadId:java.lang.String
-- (com.intellij.openapi.project.Project,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings):V
-- f:component1():com.intellij.openapi.project.Project
-- f:component2():java.lang.String
-- f:component3():java.lang.String
-- f:component4():java.lang.String
-- f:component5():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- f:component6():com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:copy(com.intellij.openapi.project.Project,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageProviderDispatchRequest
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageProviderDispatchRequest,com.intellij.openapi.project.Project,java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageProviderDispatchRequest
-- equals(java.lang.Object):Z
-- hashCode():I
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy
-- java.lang.Enum
-- sf:POST_START_ONLY:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy
-- sf:TRY_STARTUP_COMMAND:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy[]
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- java.lang.Enum
-- sf:ALLOW_TIMEOUT_FALLBACK:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- sf:REQUIRE_EXPLICIT_READINESS:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageTimeoutPolicy[]
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- java.lang.Enum
-- sf:APP_SERVER:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- sf:STARTUP_COMMAND:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- sf:TERMINAL:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel[]
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- sf:Companion:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan$Companion
-- sf:EMPTY:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- f:promptRecord:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord
-- f:startupFallbackTerminalDispatch:com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- f:startupLaunchSpecOverride:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:terminalDispatch:com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- ():V
-- (com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch):V
-- b:(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- (com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.util.List,java.lang.String):V
-- b:(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.util.List,java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord
-- f:component3():com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- f:component4():com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- f:copy(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- equals(java.lang.Object):Z
-- f:getInitialMessageToken():java.lang.String
-- f:getPostStartDispatchSteps():java.util.List
-- hashCode():I
-- f:withStartupDeliveryIgnored():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan$Companion
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus
-- java.lang.Enum
-- sf:DELIVERED:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus
-- sf:PENDING:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus[]
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord
-- f:deliveryChannel:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- f:deliveryStatus:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus
-- f:message:java.lang.String
-- f:mode:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- f:token:java.lang.String
-- (java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode
-- f:component3():java.lang.String
-- f:component4():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus
-- f:component5():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageMode,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryStatus,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryChannel,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptRecord
-- equals(java.lang.Object):Z
-- hashCode():I
-com.intellij.platform.ai.agent.sessions.core.providers.AgentOpenTopLevelThreadDispatchService
-- a:dispatchIfPresent-RmkVQ7I(java.lang.String,java.lang.String,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan,kotlin.coroutines.Continuation):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentPendingSessionMetadata
-- f:createdAtMs:J
-- f:launchMode:java.lang.String
-- (J,java.lang.String):V
-- f:component1():J
-- f:component2():java.lang.String
-- f:copy(J,java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentPendingSessionMetadata
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentPendingSessionMetadata,J,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentPendingSessionMetadata
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartNewSessionLaunchRequest
-- f:generationModelCatalog:java.util.List
-- f:generationSettings:com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:initialMessagePlan:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- f:launchMode:com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- f:launchSpec:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:projectPath:java.lang.String
-- (java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,java.util.List,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode
-- f:component3():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- f:component4():com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- f:component5():java.util.List
-- f:component6():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,java.util.List,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec):com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartNewSessionLaunchRequest
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartNewSessionLaunchRequest,java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,java.util.List,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartNewSessionLaunchRequest
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartedNewSessionLaunch
-- f:initialMessageDispatchPlan:com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- f:launchSpec:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- (com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan):V
-- b:(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan
-- f:copy(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan):com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartedNewSessionLaunch
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartedNewSessionLaunch,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialPromptDeliveryPlan,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentPrestartedNewSessionLaunch
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOption
-- f:defaultSelected:Z
-- f:enabledForExistingTask:Z
-- f:enabledForNewTask:Z
-- f:id:java.lang.String
-- f:labelFallback:java.lang.String
-- f:labelKey:java.lang.String
-- (java.lang.String,java.lang.String,java.lang.String,Z,Z,Z):V
-- b:(java.lang.String,java.lang.String,java.lang.String,Z,Z,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:component3():java.lang.String
-- f:component4():Z
-- f:component5():Z
-- f:component6():Z
-- f:copy(java.lang.String,java.lang.String,java.lang.String,Z,Z,Z):com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOption
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOption,java.lang.String,java.lang.String,java.lang.String,Z,Z,Z,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOption
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOptionKt
-- sf:AGENT_PROMPT_PROVIDER_OPTION_PLAN_MODE:java.lang.String
-- sf:getAGENT_PROMPT_PROVIDER_PLAN_MODE_OPTION():com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOption
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOptionTarget
-- java.lang.Enum
-- sf:EXISTING_TASK:com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOptionTarget
-- sf:NEW_TASK:com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOptionTarget
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOptionTarget
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentPromptProviderOptionTarget[]
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionLaunchProfileSnapshot
-- f:builtInProfiles:java.util.List
-- f:userProfiles:java.util.List
-- (java.util.List,java.util.List):V
-- f:component1():java.util.List
-- f:component2():java.util.List
-- f:copy(java.util.List,java.util.List):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionLaunchProfileSnapshot
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionLaunchProfileSnapshot,java.util.List,java.util.List,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionLaunchProfileSnapshot
-- equals(java.lang.Object):Z
-- f:getAllProfiles():java.util.List
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionLaunchProfilesKt
-- sf:BUILT_IN_LAUNCH_PROFILE_PREFIX:java.lang.String
-- sf:builtInLaunchProfileId-9c6lQVA(java.lang.String,com.intellij.platform.ai.agent.core.session.AgentSessionLaunchMode):java.lang.String
-- sf:effectiveLaunchProfiles(java.util.List,java.util.List):java.util.List
-- sf:generationSettingsForPlanMode(com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings,Z):com.intellij.agent.workbench.prompt.core.AgentPromptGenerationSettings
-- sf:initialMessageRequestForLaunchProfile(com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile):com.intellij.agent.workbench.prompt.core.AgentPromptInitialMessageRequest
-- sf:launchProfileEditablePayload(com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile):com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile
-- sf:launchProfileMatchesBuiltIn(com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile,com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile):Z
-- sf:normalizedUserLaunchProfile(com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile):com.intellij.agent.workbench.prompt.core.AgentPromptLaunchProfile
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionMenuCommand
-- f:argumentHint:java.lang.String
-- f:command:java.lang.String
-- (java.lang.String,java.lang.String):V
-- b:(java.lang.String,java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():java.lang.String
-- f:copy(java.lang.String,java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionMenuCommand
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionMenuCommand,java.lang.String,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionMenuCommand
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionEntry
-- f:argumentHint:java.lang.String
-- f:command:java.lang.String
-- f:kind:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- f:sourceKey:java.lang.String
-- f:sourcePath:java.nio.file.Path
-- (java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind,java.lang.String,java.nio.file.Path,java.lang.String):V
-- b:(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind,java.lang.String,java.nio.file.Path,java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:component2():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- f:component3():java.lang.String
-- f:component4():java.nio.file.Path
-- f:component5():java.lang.String
-- f:copy(java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind,java.lang.String,java.nio.file.Path,java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionEntry
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionEntry,java.lang.String,com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind,java.lang.String,java.nio.file.Path,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionEntry
-- equals(java.lang.Object):Z
-- hashCode():I
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- java.lang.Enum
-- sf:COMMAND:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- sf:MENU:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- sf:SKILL:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionPromptCommandCompletionKind[]
-e:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderCliVisibilityPolicy
-- java.lang.Enum
-- sf:DISCOVER_WHEN_AVAILABLE:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderCliVisibilityPolicy
-- sf:PROMINENT:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderCliVisibilityPolicy
-- s:getEntries():kotlin.enums.EnumEntries
-- s:valueOf(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderCliVisibilityPolicy
-- s:values():com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderCliVisibilityPolicy[]
-com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderFeatureSettings
-- isProviderFeatureEnabled-9c6lQVA(java.lang.String,java.lang.String):Z
-- setProviderFeatureEnabled-3n3rsyc(java.lang.String,java.lang.String,Z):V
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderFeatureSettingsExtensions
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderFeatureSettingsExtensions
-- f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName
-- f:isProviderFeatureEnabled-9c6lQVA(java.lang.String,java.lang.String):Z
-- f:setProviderFeatureEnabled-3n3rsyc(java.lang.String,java.lang.String,Z):V
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderPlanModeKt
-- sf:buildPlanModeInitialMessagePlan(com.intellij.agent.workbench.prompt.core.AgentPromptInitialMessageRequest,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- bs:buildPlanModeInitialMessagePlan$default(com.intellij.agent.workbench.prompt.core.AgentPromptInitialMessageRequest,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessageStartupPolicy,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan
-- sf:isBlockedForExistingThreadPlanMode(com.intellij.platform.ai.agent.sessions.core.providers.AgentInitialMessagePlan,com.intellij.platform.ai.agent.core.AgentThreadActivity):Z
-- sf:isBusyForExistingThreadPlanMode(com.intellij.platform.ai.agent.core.AgentThreadActivity):Z
-- sf:isPlanModeRequested(com.intellij.agent.workbench.prompt.core.AgentPromptInitialMessageRequest):Z
-com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderUiContributor
-- createToolWindowNorthComponent(com.intellij.openapi.project.Project):javax.swing.JComponent
-- onThreadViewOpened():V
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderUiContributorBean
-- com.intellij.serviceContainer.BaseKeyedLazyInstance
-- implementation:java.lang.String
-- providerId:java.lang.String
-- ():V
-- f:matches-e2Q3-TE(java.lang.String):Z
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderUiContributors
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionProviderUiContributors
-- f:forProvider-e2Q3-TE(java.lang.String):java.util.List
-- f:getEP_NAME():com.intellij.openapi.extensions.ExtensionPointName
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- f:command:java.util.List
-- f:containerSessionId:java.lang.String
-- f:envVariables:java.util.Map
-- f:preallocatedSessionId:java.lang.String
-- f:useTerminalDefaultShell:Z
-- f:workingDirectory:java.lang.String
-- (java.util.List,java.util.Map,java.lang.String,Z,java.lang.String,java.lang.String):V
-- b:(java.util.List,java.util.Map,java.lang.String,Z,java.lang.String,java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.util.List
-- f:component2():java.util.Map
-- f:component3():java.lang.String
-- f:component4():Z
-- f:component5():java.lang.String
-- f:component6():java.lang.String
-- f:copy(java.util.List,java.util.Map,java.lang.String,Z,java.lang.String,java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec,java.util.List,java.util.Map,java.lang.String,Z,java.lang.String,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalLaunchSpec
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalRestoreContext
-- f:workingDirectory:java.lang.String
-- ():V
-- (java.lang.String):V
-- b:(java.lang.String,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.lang.String
-- f:copy(java.lang.String):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalRestoreContext
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalRestoreContext,java.lang.String,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentSessionTerminalRestoreContext
-- equals(java.lang.Object):Z
-- hashCode():I
-f:com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- f:stepIndex:I
-- f:steps:java.util.List
-- (java.util.List,I):V
-- b:(java.util.List,I,I,kotlin.jvm.internal.DefaultConstructorMarker):V
-- f:component1():java.util.List
-- f:component2():I
-- f:copy(java.util.List,I):com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- bs:copy$default(com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch,java.util.List,I,I,java.lang.Object):com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-- equals(java.lang.Object):Z
-- hashCode():I
-- f:normalized():com.intellij.platform.ai.agent.sessions.core.providers.AgentTerminalPromptDispatch
-f:com.intellij.platform.ai.agent.sessions.core.providers.BaseAgentSessionSourceKt$sam$i$java_util_function_BiFunction$0
-- java.util.function.BiFunction
-- (kotlin.jvm.functions.Function2):V
-- bf:apply(java.lang.Object,java.lang.Object):java.lang.Object
-f:com.intellij.platform.ai.agent.sessions.core.util.JbCentralCliSupport
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.util.JbCentralCliSupport
-- f:findExecutable():java.lang.String
-- f:isAvailable():Z
-f:com.intellij.platform.ai.agent.sessions.core.util.JbCentralCliSupportKt
-- sf:AGENT_WORKBENCH_JBCENTRAL_PATH_PROPERTY:java.lang.String
-f:com.intellij.platform.ai.agent.sessions.core.util.JbCentralCliSupportTestHook
-- sf:INSTANCE:com.intellij.platform.ai.agent.sessions.core.util.JbCentralCliSupportTestHook
-- f:pathLookupOverride():kotlin.jvm.functions.Function0
-- f:replacePathLookupForTest(kotlin.jvm.functions.Function0):kotlin.jvm.functions.Function0
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/exposed-third-party-api.txt b/plugins/agent-workbench/lib-agent/sessions-core/exposed-third-party-api.txt
deleted file mode 100644
index 178e673bf44d..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/exposed-third-party-api.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-com/intellij/agent/workbench/prompt/core/AgentPromptGenerationSettings
-com/intellij/agent/workbench/prompt/core/AgentPromptInitialMessageRequest
-com/intellij/agent/workbench/prompt/core/AgentPromptLaunchProfile
-java/math/BigDecimal
-kotlin/jvm/internal/DefaultConstructorMarker
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/intellij.platform.ai.agent.sessions.core.iml b/plugins/agent-workbench/lib-agent/sessions-core/intellij.platform.ai.agent.sessions.core.iml
deleted file mode 100644
index ff893e67235d..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/intellij.platform.ai.agent.sessions.core.iml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/resources/intellij.platform.ai.agent.sessions.core.xml b/plugins/agent-workbench/lib-agent/sessions-core/resources/intellij.platform.ai.agent.sessions.core.xml
deleted file mode 100644
index 8ad7d41fe769..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/resources/intellij.platform.ai.agent.sessions.core.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadIds.kt b/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadIds.kt
deleted file mode 100644
index 763bdb4deee6..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadIds.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.platform.ai.agent.sessions.core
-
-private const val PENDING_THREAD_ID_PREFIX = "new-"
-
-fun isAgentSessionPendingThreadId(threadId: String): Boolean {
- return threadId.trim().startsWith(PENDING_THREAD_ID_PREFIX)
-}
-
-fun normalizeConcreteAgentSessionThreadId(threadId: String): String? {
- val normalizedThreadId = threadId.trim()
- return normalizedThreadId.takeIf { it.isNotEmpty() && !isAgentSessionPendingThreadId(it) }
-}
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadPresentation.kt b/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadPresentation.kt
deleted file mode 100644
index 232b50d5d90e..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadPresentation.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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.platform.ai.agent.sessions.core
-
-import com.intellij.openapi.util.NlsSafe
-import com.intellij.openapi.util.text.StringUtil
-import kotlin.math.abs
-import kotlin.math.max
-import kotlin.math.roundToLong
-
-private const val COMPACT_AGENT_SESSION_TITLE_LENGTH = 50
-private val THREAD_TITLE_WHITESPACE = Regex("\\s+")
-
-fun normalizeAgentSessionTitle(title: String?): @NlsSafe String? {
- return title
- ?.replace('\n', ' ')
- ?.replace('\r', ' ')
- ?.replace(THREAD_TITLE_WHITESPACE, " ")
- ?.trim()
- ?.takeIf { it.isNotEmpty() }
-}
-
-fun formatCompactAgentSessionTitle(
- title: String,
- maxLength: Int = COMPACT_AGENT_SESSION_TITLE_LENGTH,
-): @NlsSafe String {
- return StringUtil.trimMiddle(title, maxLength)
-}
-
-fun formatCompactAgentSessionThreadTitle(
- threadId: String,
- title: String,
- fallbackTitle: (idPrefix: String) -> String,
- maxLength: Int = COMPACT_AGENT_SESSION_TITLE_LENGTH,
-): @NlsSafe String {
- return formatCompactAgentSessionTitle(
- title = formatAgentSessionThreadTitle(threadId = threadId, title = title, fallbackTitle = fallbackTitle),
- maxLength = maxLength,
- )
-}
-
-fun formatAgentSessionThreadTitle(
- threadId: String,
- title: String,
- fallbackTitle: (idPrefix: String) -> String,
-): @NlsSafe String {
- val normalized = normalizeAgentSessionTitle(title)
- if (normalized != null) {
- return normalized
- }
- val idPrefix = threadId.trim().takeIf { it.isNotEmpty() }?.take(8) ?: "unknown"
- return fallbackTitle(idPrefix)
-}
-
-fun formatAgentSessionRelativeTimeShort(
- timestamp: Long,
- now: Long,
- nowLabel: String,
- unknownLabel: String,
-): String {
- if (timestamp <= 0L) {
- return unknownLabel
- }
-
- val absSeconds = abs(((timestamp - now) / 1000.0).roundToLong())
- if (absSeconds < 60) {
- return nowLabel
- }
- if (absSeconds < 60 * 60) {
- val value = max(1, (absSeconds / 60.0).roundToLong())
- return "${value}m"
- }
- if (absSeconds < 60 * 60 * 24) {
- val value = max(1, (absSeconds / (60.0 * 60.0)).roundToLong())
- return "${value}h"
- }
- if (absSeconds < 60 * 60 * 24 * 7) {
- val value = max(1, (absSeconds / (60.0 * 60.0 * 24.0)).roundToLong())
- return "${value}d"
- }
- if (absSeconds < 60 * 60 * 24 * 30) {
- val value = max(1, (absSeconds / (60.0 * 60.0 * 24.0 * 7.0)).roundToLong())
- return "${value}w"
- }
- if (absSeconds < 60 * 60 * 24 * 365) {
- val value = max(1, (absSeconds / (60.0 * 60.0 * 24.0 * 30.0)).roundToLong())
- return "${value}mo"
- }
- val value = max(1, (absSeconds / (60.0 * 60.0 * 24.0 * 365.0)).roundToLong())
- return "${value}y"
-}
diff --git a/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadPresentationModel.kt b/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadPresentationModel.kt
deleted file mode 100644
index b8bbdbb72f91..000000000000
--- a/plugins/agent-workbench/lib-agent/sessions-core/src/AgentSessionThreadPresentationModel.kt
+++ /dev/null
@@ -1,316 +0,0 @@
-// 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.platform.ai.agent.sessions.core
-
-import com.intellij.platform.ai.agent.core.AgentThreadActivityReport
-import com.intellij.platform.ai.agent.core.normalizeAgentWorkbenchPath
-import com.intellij.platform.ai.agent.core.session.AgentSessionProvider
-import com.intellij.platform.ai.agent.core.session.AgentSessionThread
-import com.intellij.openapi.components.Service
-import com.intellij.openapi.util.NlsSafe
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharedFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asSharedFlow
-import kotlinx.coroutines.flow.asStateFlow
-import org.jetbrains.annotations.TestOnly
-
-data class AgentSessionThreadPresentationKey(
- @JvmField val normalizedProjectPath: String,
- val provider: AgentSessionProvider,
- @JvmField val threadId: String,
-) {
- companion object {
- fun create(projectPath: String, provider: AgentSessionProvider, threadId: String): AgentSessionThreadPresentationKey? {
- val normalizedProjectPath = normalizeAgentWorkbenchPath(projectPath).takeIf { it.isNotBlank() } ?: return null
- val normalizedThreadId = threadId.trim().takeIf { it.isNotEmpty() } ?: return null
- return AgentSessionThreadPresentationKey(
- normalizedProjectPath = normalizedProjectPath,
- provider = provider,
- threadId = normalizedThreadId,
- )
- }
- }
-}
-
-/**
- * Shared thread presentation for editor/tab chrome and fresh title projection.
- * Tool-window activity counters must use canonical [AgentSessionThread.activityReport].
- */
-data class AgentSessionThreadPresentation(
- @JvmField val title: @NlsSafe String,
- @JvmField val activityReport: AgentThreadActivityReport,
- @JvmField val updatedAt: Long? = null,
-)
-
-data class AgentSessionThreadPresentationChangeSet(
- @JvmField val changedKeys: Set,
- @JvmField val removedKeys: Set,
-) {
- companion object {
- val EMPTY: AgentSessionThreadPresentationChangeSet = AgentSessionThreadPresentationChangeSet(
- changedKeys = emptySet(),
- removedKeys = emptySet(),
- )
- }
-
- val isEmpty: Boolean
- get() = changedKeys.isEmpty() && removedKeys.isEmpty()
-}
-
-data class AgentSessionThreadActivityPresentationUpdate(
- @JvmField val path: String,
- @JvmField val threadId: String,
- @JvmField val activityReport: AgentThreadActivityReport,
- @JvmField val updatedAt: Long? = null,
-)
-
-@Service(Service.Level.APP)
-class AgentSessionThreadPresentationModel {
- private val lock = Any()
- private val mutableState = MutableStateFlow