Skip to content

Commit a0d810e

Browse files
authored
Merge branch 'feature/remote-chat-lsp' into autoMerge/feature/remote-chat-lsp
2 parents 1211c41 + 57cd4d5 commit a0d810e

File tree

49 files changed

+538
-965
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+538
-965
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "feature",
3+
"description" : "Add support for using Amazon Q chat through a remote IDE instance on 2024.2+"
4+
}

buildSrc/src/main/kotlin/software/aws/toolkits/gradle/intellij/IdeVersions.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object IdeVersions {
2222
private val commonPlugins = listOf(
2323
"Git4Idea",
2424
"org.jetbrains.plugins.terminal",
25-
"org.jetbrains.plugins.yaml"
25+
"org.jetbrains.plugins.yaml",
2626
)
2727

2828
private val ideProfiles = listOf(
@@ -34,6 +34,7 @@ object IdeVersions {
3434
"com.intellij.java",
3535
"com.intellij.gradle",
3636
"org.jetbrains.idea.maven",
37+
"com.jetbrains.codeWithMe",
3738
),
3839
marketplacePlugins = listOf(
3940
"org.toml.lang:242.20224.155",
@@ -71,6 +72,7 @@ object IdeVersions {
7172
"com.intellij.java",
7273
"com.intellij.gradle",
7374
"org.jetbrains.idea.maven",
75+
"com.jetbrains.codeWithMe",
7476
),
7577
marketplacePlugins = listOf(
7678
"org.toml.lang:243.21565.122",
@@ -114,6 +116,7 @@ object IdeVersions {
114116
"com.intellij.java",
115117
"com.intellij.gradle",
116118
"org.jetbrains.idea.maven",
119+
"com.jetbrains.codeWithMe",
117120
),
118121
marketplacePlugins = listOf(
119122
"org.toml.lang:251.26927.47",

buildSrc/src/main/kotlin/toolkit-publish-root-conventions.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
55
import org.jetbrains.intellij.platform.gradle.tasks.PatchPluginXmlTask
6+
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
67
import software.aws.toolkits.gradle.intellij.IdeFlavor
78
import software.aws.toolkits.gradle.intellij.toolkitIntelliJ
89

@@ -75,3 +76,8 @@ tasks.runIde {
7576
systemProperty("user.home", home)
7677
environment("HOME", home)
7778
}
79+
80+
val runSplitIde by intellijPlatformTesting.runIde.registering {
81+
splitMode = true
82+
splitModeTarget = SplitModeAware.SplitModeTarget.BACKEND
83+
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QLoginWebview.kt

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import kotlinx.coroutines.CoroutineScope
2222
import kotlinx.coroutines.flow.distinctUntilChanged
2323
import kotlinx.coroutines.flow.launchIn
2424
import kotlinx.coroutines.flow.onEach
25-
import org.cef.CefApp
2625
import software.aws.toolkits.core.utils.debug
2726
import software.aws.toolkits.core.utils.error
2827
import software.aws.toolkits.core.utils.getLogger
@@ -37,8 +36,8 @@ import software.aws.toolkits.jetbrains.core.credentials.sono.isSono
3736
import software.aws.toolkits.jetbrains.core.region.AwsRegionProvider
3837
import software.aws.toolkits.jetbrains.core.webview.BrowserMessage
3938
import software.aws.toolkits.jetbrains.core.webview.BrowserState
39+
import software.aws.toolkits.jetbrains.core.webview.LocalAssetJBCefRequestHandler
4040
import software.aws.toolkits.jetbrains.core.webview.LoginBrowser
41-
import software.aws.toolkits.jetbrains.core.webview.WebviewResourceHandlerFactory
4241
import software.aws.toolkits.jetbrains.isDeveloperMode
4342
import software.aws.toolkits.jetbrains.services.amazonq.profile.QProfileSwitchIntent
4443
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfile
@@ -131,25 +130,14 @@ class QWebviewPanel private constructor(val project: Project, private val scope:
131130
class QWebviewBrowser(val project: Project, private val parentDisposable: Disposable) :
132131
LoginBrowser(
133132
project,
134-
QWebviewBrowser.DOMAIN,
135-
QWebviewBrowser.WEB_SCRIPT_URI
136133
),
137134
Disposable {
138135
// TODO: confirm if we need such configuration or the default is fine
139136
override val jcefBrowser = createBrowser(parentDisposable)
140137
private val query = JBCefJSQuery.create(jcefBrowser)
138+
private val assetHandler = LocalAssetJBCefRequestHandler(jcefBrowser)
141139

142140
init {
143-
CefApp.getInstance()
144-
.registerSchemeHandlerFactory(
145-
"http",
146-
domain,
147-
WebviewResourceHandlerFactory(
148-
domain = "http://$domain/",
149-
assetUri = "/webview/assets/"
150-
),
151-
)
152-
153141
loadWebView(query)
154142

155143
query.addHandler(jcefHandler)
@@ -332,7 +320,12 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
332320
}
333321

334322
override fun loadWebView(query: JBCefJSQuery) {
335-
jcefBrowser.loadHTML(getWebviewHTML(webScriptUri, query))
323+
val webScriptUri = assetHandler.createResource(
324+
WEB_SCRIPT,
325+
QWebviewBrowser::class.java.getResourceAsStream("/webview/assets/$WEB_SCRIPT")
326+
)
327+
328+
jcefBrowser.loadURL(assetHandler.createResource("content.html", getWebviewHTML(webScriptUri, query)))
336329
}
337330

338331
private fun handleListProfilesMessage() {
@@ -383,7 +376,6 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
383376

384377
companion object {
385378
private val LOG = getLogger<QWebviewBrowser>()
386-
private const val WEB_SCRIPT_URI = "http://webview/js/getStart.js"
387-
private const val DOMAIN = "webview"
379+
private const val WEB_SCRIPT = "js/getStart.js"
388380
}
389381
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QOpenPanelAction.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,20 @@ import icons.AwsIcons
1111
import software.aws.toolkits.jetbrains.services.amazonq.toolwindow.AMAZON_Q_WINDOW_ID
1212
import software.aws.toolkits.jetbrains.services.amazonq.toolwindow.AmazonQToolWindow
1313
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.runScanKey
14-
import software.aws.toolkits.jetbrains.utils.isRunningOnRemoteBackend
1514
import software.aws.toolkits.resources.message
1615
import software.aws.toolkits.telemetry.UiTelemetry
1716

1817
class QOpenPanelAction : AnAction(message("action.q.openchat.text"), null, AwsIcons.Logos.AWS_Q) {
1918
override fun actionPerformed(e: AnActionEvent) {
20-
if (isRunningOnRemoteBackend()) return
2119
val project = e.getRequiredData(CommonDataKeys.PROJECT)
2220
UiTelemetry.click(project, "q_openChat")
2321
ToolWindowManager.getInstance(project).getToolWindow(AMAZON_Q_WINDOW_ID)?.activate(null, true)
2422
if (e.getData(runScanKey) == true) {
2523
AmazonQToolWindow.openScanTab(project)
2624
}
2725
}
26+
27+
override fun update(e: AnActionEvent) {
28+
e.presentation.isEnabled = e.getData(CommonDataKeys.PROJECT) != null
29+
}
2830
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/gettingstarted/QGettingStartedContent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import org.cef.browser.CefBrowser
1818
import org.cef.browser.CefFrame
1919
import org.cef.handler.CefLoadHandlerAdapter
2020
import software.aws.toolkits.jetbrains.core.coroutines.disposableCoroutineScope
21+
import software.aws.toolkits.jetbrains.core.webview.LocalAssetJBCefRequestHandler
2122
import software.aws.toolkits.jetbrains.services.amazonq.toolwindow.AmazonQToolWindow
2223
import software.aws.toolkits.jetbrains.services.amazonq.webview.theme.EditorThemeAdapter
2324
import software.aws.toolkits.resources.message
@@ -72,7 +73,7 @@ class QGettingStartedContent(val project: Project) : Disposable {
7273

7374
private fun loadWebView() {
7475
// load the web app
75-
jcefBrowser.loadHTML(getWebviewHTML())
76+
jcefBrowser.loadURL(LocalAssetJBCefRequestHandler(jcefBrowser).createResource("content.html", getWebviewHTML()))
7677
}
7778

7879
private fun getWebviewHTML(): String {

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/toolwindow/AmazonQPanel.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
package software.aws.toolkits.jetbrains.services.amazonq.toolwindow
55

66
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
7-
import com.intellij.idea.AppMode
87
import com.intellij.openapi.Disposable
98
import com.intellij.openapi.components.service
109
import com.intellij.openapi.project.Project
1110
import com.intellij.openapi.util.Disposer
1211
import com.intellij.ui.components.JBLoadingPanel
1312
import com.intellij.ui.components.JBTextArea
13+
import com.intellij.ui.components.ProgressBarLoadingDecorator
1414
import com.intellij.ui.components.panels.Wrapper
1515
import com.intellij.ui.dsl.builder.Align
1616
import com.intellij.ui.dsl.builder.AlignX
@@ -47,6 +47,7 @@ import software.aws.toolkits.jetbrains.services.amazonqCodeTest.auth.isCodeTestA
4747
import software.aws.toolkits.jetbrains.services.amazonqDoc.auth.isDocAvailable
4848
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.auth.isFeatureDevAvailable
4949
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.isCodeTransformAvailable
50+
import software.aws.toolkits.jetbrains.utils.isRunningOnRemoteBackend
5051
import software.aws.toolkits.resources.message
5152
import java.awt.datatransfer.DataFlavor
5253
import java.awt.dnd.DropTarget
@@ -110,8 +111,8 @@ class AmazonQPanel(val project: Project, private val scope: CoroutineScope) : Di
110111
init {
111112
if (!JBCefApp.isSupported()) {
112113
// Fallback to an alternative browser-less solution
113-
if (AppMode.isRemoteDevHost()) {
114-
webviewContainer.add(JBTextArea("Amazon Q chat is not supported in remote dev environment."))
114+
if (isRunningOnRemoteBackend()) {
115+
webviewContainer.add(JBTextArea("Amazon Q chat is not supported in this remote dev environment because it lacks JCEF webview support."))
115116
} else {
116117
webviewContainer.add(JBTextArea("JCEF not supported"))
117118
}
@@ -120,21 +121,28 @@ class AmazonQPanel(val project: Project, private val scope: CoroutineScope) : Di
120121
webviewContainer.add(JBTextArea("${message("q.unavailable")}\n ${message("q.unavailable.node")}"))
121122
browser.complete(null)
122123
} else {
123-
val loadingPanel = JBLoadingPanel(null, this)
124+
val loadingPanel = if (isRunningOnRemoteBackend()) {
125+
JBLoadingPanel(null) {
126+
ProgressBarLoadingDecorator(it, this, -1)
127+
}
128+
} else {
129+
JBLoadingPanel(null, this)
130+
}
131+
124132
val wrapper = Wrapper()
125133
loadingPanel.startLoading()
126134

127135
webviewContainer.add(wrapper)
128136
wrapper.setContent(loadingPanel)
129137

130138
scope.launch {
131-
val webUri = service<ArtifactManager>().fetchArtifact(project).resolve("amazonq-ui.js").toUri()
139+
val mynahAsset = service<ArtifactManager>().fetchArtifact(project).resolve("amazonq-ui.js")
132140
// wait for server to be running
133141
AmazonQLspService.getInstance(project).instanceFlow.first()
134142

135143
withContext(EDT) {
136144
browser.complete(
137-
Browser(this@AmazonQPanel, webUri, project).also { browserInstance ->
145+
Browser(this@AmazonQPanel, mynahAsset, project).also { browserInstance ->
138146
wrapper.setContent(browserInstance.component())
139147

140148
// Register direct callback instead of using message bus

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/AssetResourceHandler.kt

Lines changed: 0 additions & 96 deletions
This file was deleted.

0 commit comments

Comments
 (0)