Skip to content

Commit abd1f14

Browse files
committed
Merge remote-tracking branch 'origin/main' into rli/move-cw-tel-service-otel
2 parents 4f2b7c9 + 640c686 commit abd1f14

File tree

17 files changed

+308
-103
lines changed

17 files changed

+308
-103
lines changed

.changes/3.38.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"date" : "2024-11-07",
3+
"version" : "3.38",
4+
"entries" : [ {
5+
"type" : "bugfix",
6+
"description" : "Improve the position that inline chat shortcut hint is shown in editor"
7+
}, {
8+
"type" : "bugfix",
9+
"description" : "Improve `@workspace` index start stop strategy"
10+
}, {
11+
"type" : "bugfix",
12+
"description" : "Fixed an issue where Q inline won't appear in JetBrains remote 2024.2+"
13+
} ]
14+
}

.changes/next-release/bugfix-4fee3628-1445-40f3-b164-2b0d3c12bd19.json

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

.changes/next-release/bugfix-eb803511-b66c-454e-a832-ca189572d1af.json

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

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# _3.38_ (2024-11-07)
2+
- **(Bug Fix)** Improve the position that inline chat shortcut hint is shown in editor
3+
- **(Bug Fix)** Improve `@workspace` index start stop strategy
4+
- **(Bug Fix)** Fixed an issue where Q inline won't appear in JetBrains remote 2024.2+
5+
16
# _3.37_ (2024-10-31)
27
- **(Bug Fix)** Amazon Q /dev: Fix the issue resulting in the first request per conversation to /dev failing
38
- **(Bug Fix)** Fix inline chat shortcut hint breaking text selection on remote editors

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
# Toolkit Version
5-
toolkitVersion=3.38-SNAPSHOT
5+
toolkitVersion=3.39-SNAPSHOT
66

77
# Publish Settings
88
publishToken=

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/inline/InlineChatEditorHint.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,26 @@ import javax.swing.JPanel
1919

2020
class InlineChatEditorHint {
2121
private val hint = createHint()
22+
private val hintXOffset = 20
2223

2324
private fun getHintLocation(editor: Editor): Point {
2425
val range = editor.calculateVisibleRange()
2526
val document = editor.document
2627
val selectionEnd = editor.selectionModel.selectionEnd
2728
val isOneLineSelection = isOneLineSelection(editor)
28-
val isBelow = editor.offsetToXY(selectionEnd) !in editor.scrollingModel.visibleArea
29+
val offset = document.getLineEndOffset(document.getLineNumber(selectionEnd))
30+
val offsetXy = editor.offsetToXY(offset)
31+
val potentialXy = Point(offsetXy.x + hintXOffset, offsetXy.y)
32+
val isBelow = potentialXy !in editor.scrollingModel.visibleArea
2933
val areEdgesOutsideOfVisibleArea = editor.selectionModel.selectionStart !in range && editor.selectionModel.selectionEnd !in range
3034
val offsetForHint = when {
31-
isOneLineSelection -> selectionEnd
3235
areEdgesOutsideOfVisibleArea -> document.getLineEndOffset(getLineByVisualStart(editor, editor.caretModel.offset, true))
3336
isBelow -> document.getLineEndOffset(getLineByVisualStart(editor, selectionEnd, true))
3437
else -> document.getLineEndOffset(getLineByVisualStart(editor, selectionEnd, false))
3538
}
3639
val visualPosition = editor.offsetToVisualPosition(offsetForHint)
37-
val hintPoint = HintManagerImpl.getHintPosition(hint, editor, visualPosition, HintManager.RIGHT)
38-
hintPoint.translate(0, if (isBelow) editor.lineHeight else 0)
40+
val hintPoint = HintManagerImpl.getHintPosition(hint, editor, visualPosition, HintManager.RIGHT_UNDER)
41+
hintPoint.translate(if (!isBelow) hintXOffset else 0, if (!isOneLineSelection || isBelow) editor.lineHeight else 0)
3942
return hintPoint
4043
}
4144

plugins/core/jetbrains-community/resources/telemetryOverride.json

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -755,25 +755,6 @@
755755
],
756756
"passive": true
757757
},
758-
{
759-
"name": "auth_userState",
760-
"description": "The state of the user's authentication.",
761-
"metadata": [
762-
{
763-
"type": "source",
764-
"required": true
765-
},
766-
{
767-
"type": "authStatus",
768-
"required": true
769-
},
770-
{
771-
"type": "authEnabledConnections",
772-
"required": true
773-
}
774-
],
775-
"passive": true
776-
},
777758
{
778759
"name": "webview_amazonqSignInOpened",
779760
"description": "Called when a Amazon Q sign in webview is opened.",

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/DiskCache.kt

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
2222
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
2323
import com.fasterxml.jackson.module.kotlin.readValue
2424
import software.aws.toolkits.core.utils.createParentDirectories
25-
import software.aws.toolkits.core.utils.debug
2625
import software.aws.toolkits.core.utils.deleteIfExists
2726
import software.aws.toolkits.core.utils.getLogger
27+
import software.aws.toolkits.core.utils.info
2828
import software.aws.toolkits.core.utils.inputStreamIfExists
2929
import software.aws.toolkits.core.utils.outputStream
3030
import software.aws.toolkits.core.utils.toHexString
3131
import software.aws.toolkits.core.utils.touch
3232
import software.aws.toolkits.core.utils.tryDirOp
3333
import software.aws.toolkits.core.utils.tryFileOp
3434
import software.aws.toolkits.core.utils.tryOrNull
35-
import software.aws.toolkits.core.utils.warn
35+
import software.aws.toolkits.jetbrains.services.telemetry.scrubNames
3636
import software.aws.toolkits.telemetry.AuthTelemetry
3737
import software.aws.toolkits.telemetry.Result
3838
import java.io.InputStream
@@ -97,38 +97,38 @@ class DiskCache(
9797
}
9898

9999
override fun invalidateClientRegistration(ssoRegion: String) {
100-
LOG.debug { "invalidateClientRegistration for $ssoRegion" }
100+
LOG.info { "invalidateClientRegistration for $ssoRegion" }
101101
clientRegistrationCache(ssoRegion).tryDeleteIfExists()
102102
}
103103

104104
override fun loadClientRegistration(cacheKey: ClientRegistrationCacheKey): ClientRegistration? {
105-
LOG.debug { "loadClientRegistration for $cacheKey" }
105+
LOG.info { "loadClientRegistration for $cacheKey" }
106106
val inputStream = clientRegistrationCache(cacheKey).tryInputStreamIfExists()
107107
if (inputStream == null) {
108108
val stage = LoadCredentialStage.ACCESS_FILE
109-
LOG.warn { "Failed to load Client Registration: cache file does not exist" }
109+
LOG.info { "Failed to load Client Registration: cache file does not exist" }
110110
AuthTelemetry.modifyConnection(
111111
action = "Load cache file",
112112
source = "loadClientRegistration",
113113
result = Result.Failed,
114114
reason = "Failed to load Client Registration",
115-
reasonDesc = "Load Step:$stage failed. Unable to load file"
115+
reasonDesc = "Load Step:$stage failed. Cache file does not exist"
116116
)
117117
return null
118118
}
119119
return loadClientRegistration(inputStream)
120120
}
121121

122122
override fun saveClientRegistration(cacheKey: ClientRegistrationCacheKey, registration: ClientRegistration) {
123-
LOG.debug { "saveClientRegistration for $cacheKey" }
123+
LOG.info { "saveClientRegistration for $cacheKey" }
124124
val registrationCache = clientRegistrationCache(cacheKey)
125125
writeKey(registrationCache) {
126126
objectMapper.writeValue(it, registration)
127127
}
128128
}
129129

130130
override fun invalidateClientRegistration(cacheKey: ClientRegistrationCacheKey) {
131-
LOG.debug { "invalidateClientRegistration for $cacheKey" }
131+
LOG.info { "invalidateClientRegistration for $cacheKey" }
132132
try {
133133
clientRegistrationCache(cacheKey).tryDeleteIfExists()
134134
} catch (e: Exception) {
@@ -137,14 +137,14 @@ class DiskCache(
137137
source = "invalidateClientRegistration",
138138
result = Result.Failed,
139139
reason = "Failed to invalidate Client Registration",
140-
reasonDesc = e.message ?: e::class.java.name
140+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name
141141
)
142142
throw e
143143
}
144144
}
145145

146146
override fun invalidateAccessToken(ssoUrl: String) {
147-
LOG.debug { "invalidateAccessToken for $ssoUrl" }
147+
LOG.info { "invalidateAccessToken for $ssoUrl" }
148148
try {
149149
accessTokenCache(ssoUrl).tryDeleteIfExists()
150150
} catch (e: Exception) {
@@ -153,14 +153,14 @@ class DiskCache(
153153
source = "invalidateAccessToken",
154154
result = Result.Failed,
155155
reason = "Failed to invalidate Access Token",
156-
reasonDesc = e.message ?: e::class.java.name
156+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name
157157
)
158158
throw e
159159
}
160160
}
161161

162162
override fun loadAccessToken(cacheKey: AccessTokenCacheKey): AccessToken? {
163-
LOG.debug { "loadAccessToken for $cacheKey" }
163+
LOG.info { "loadAccessToken for $cacheKey" }
164164
val cacheFile = accessTokenCache(cacheKey)
165165
val inputStream = cacheFile.tryInputStreamIfExists() ?: return null
166166

@@ -170,15 +170,15 @@ class DiskCache(
170170
}
171171

172172
override fun saveAccessToken(cacheKey: AccessTokenCacheKey, accessToken: AccessToken) {
173-
LOG.debug { "saveAccessToken for $cacheKey" }
173+
LOG.info { "saveAccessToken for $cacheKey" }
174174
val accessTokenCache = accessTokenCache(cacheKey)
175175
writeKey(accessTokenCache) {
176176
objectMapper.writeValue(it, accessToken)
177177
}
178178
}
179179

180180
override fun invalidateAccessToken(cacheKey: AccessTokenCacheKey) {
181-
LOG.debug { "invalidateAccessToken for $cacheKey" }
181+
LOG.info { "invalidateAccessToken for $cacheKey" }
182182
try {
183183
accessTokenCache(cacheKey).tryDeleteIfExists()
184184
} catch (e: Exception) {
@@ -187,7 +187,7 @@ class DiskCache(
187187
source = "invalidateAccessToken",
188188
result = Result.Failed,
189189
reason = "Failed to invalidate Access Token",
190-
reasonDesc = e.message ?: e::class.java.name
190+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name
191191
)
192192
throw e
193193
}
@@ -203,7 +203,7 @@ class DiskCache(
203203
val sha = sha1(cacheNameMapper.writeValueAsString(it))
204204

205205
cacheDir.resolve("$sha.json").also {
206-
LOG.debug { "$cacheKey resolves to $it" }
206+
LOG.info { "$cacheKey resolves to $it" }
207207
}
208208
}
209209

@@ -225,7 +225,7 @@ class DiskCache(
225225
if (clientRegistration.expiresAt.isNotExpired()) {
226226
return clientRegistration
227227
} else {
228-
LOG.warn { "Client Registration is expired" }
228+
LOG.info { "Client Registration is expired" }
229229
AuthTelemetry.modifyConnection(
230230
action = "Validate Credentials",
231231
source = "loadClientRegistration",
@@ -236,7 +236,7 @@ class DiskCache(
236236
return null
237237
}
238238
} catch (e: Exception) {
239-
LOG.warn { "Client Registration could not be read" }
239+
LOG.info { "Client Registration could not be read" }
240240
AuthTelemetry.modifyConnection(
241241
action = "Validate Credentials",
242242
source = "loadClientRegistration",
@@ -269,7 +269,7 @@ class DiskCache(
269269
}
270270

271271
private fun writeKey(path: Path, consumer: (OutputStream) -> Unit) {
272-
LOG.debug { "writing to $path" }
272+
LOG.info { "writing to $path" }
273273
try {
274274
path.tryDirOp(LOG) { createParentDirectories() }
275275

@@ -283,7 +283,7 @@ class DiskCache(
283283
source = "writeKey",
284284
result = Result.Failed,
285285
reason = "Failed to write to cache",
286-
reasonDesc = e.message ?: e::class.java.name
286+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name
287287
)
288288
throw e
289289
}

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoAccessTokenProvider.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ import software.amazon.awssdk.services.ssooidc.model.InvalidClientException
1818
import software.amazon.awssdk.services.ssooidc.model.InvalidRequestException
1919
import software.amazon.awssdk.services.ssooidc.model.SlowDownException
2020
import software.aws.toolkits.core.utils.getLogger
21+
import software.aws.toolkits.core.utils.info
2122
import software.aws.toolkits.core.utils.warn
2223
import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_URL
2324
import software.aws.toolkits.jetbrains.core.credentials.sso.pkce.PKCE_CLIENT_NAME
2425
import software.aws.toolkits.jetbrains.core.credentials.sso.pkce.ToolkitOAuthService
2526
import software.aws.toolkits.jetbrains.core.webview.getAuthType
27+
import software.aws.toolkits.jetbrains.services.telemetry.scrubNames
2628
import software.aws.toolkits.jetbrains.utils.assertIsNonDispatchThread
2729
import software.aws.toolkits.jetbrains.utils.sleepWithCancellation
2830
import software.aws.toolkits.resources.AwsCoreBundle
@@ -182,7 +184,7 @@ class SsoAccessTokenProvider(
182184
source = "accessToken",
183185
result = Result.Failed,
184186
reason = "Failed to write AccessToken to cache",
185-
reasonDesc = e.message ?: e::class.java.name,
187+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name,
186188
)
187189
throw e
188190
}
@@ -224,7 +226,7 @@ class SsoAccessTokenProvider(
224226
source = "registerDAGClient",
225227
result = Result.Failed,
226228
reason = "Failed to write DeviceAuthorizationClientRegistration to cache",
227-
reasonDesc = e.message ?: e::class.java.name
229+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name
228230
)
229231
throw e
230232
}
@@ -276,7 +278,7 @@ class SsoAccessTokenProvider(
276278
source = "registerPkceClient",
277279
result = Result.Failed,
278280
reason = "Failed to write PKCEClientRegistration to cache",
279-
reasonDesc = e.message ?: e::class.java.name
281+
reasonDesc = e.message?.let { scrubNames(it) } ?: e::class.java.name
280282
)
281283
throw e
282284
}
@@ -498,7 +500,7 @@ class SsoAccessTokenProvider(
498500
requestId = requestId,
499501
result = Result.Failed
500502
)
501-
LOG.warn { "RefreshAccessTokenFailed: ${e.message}" }
503+
LOG.info { "RefreshAccessTokenFailed: ${e.message}" }
502504
throw e
503505
}
504506
}

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/pkce/ToolkitOAuthService.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ import software.aws.toolkits.jetbrains.core.credentials.sso.PKCEAuthorizationGra
3232
import software.aws.toolkits.jetbrains.core.credentials.sso.PKCEClientRegistration
3333
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.buildUnmanagedSsoOidcClient
3434
import software.aws.toolkits.resources.AwsCoreBundle
35+
import software.aws.toolkits.telemetry.AuthType
36+
import software.aws.toolkits.telemetry.AwsTelemetry
37+
import software.aws.toolkits.telemetry.MetricResult
3538
import java.math.BigInteger
3639
import java.time.Instant
3740
import java.util.Base64
@@ -189,13 +192,23 @@ internal class ToolkitOAuthCallbackHandler : OAuthCallbackHandlerBase() {
189192
"scopes" to ApplicationNamesInfo.getInstance().fullProductName
190193
)
191194
} else {
192-
val (error, errorDescription) = (oAuthResult.request as? ToolkitOAuthRequest)?.error ?: OAuthError(null, null)
195+
val toolkitRequest = (oAuthResult.request as? ToolkitOAuthRequest)
196+
val (error, errorDescription) = toolkitRequest?.error ?: OAuthError(null, null)
193197
val errorString = if (error != null && errorDescription != null) {
194198
"$error: $errorDescription"
195199
} else {
196200
errorDescription ?: error ?: AwsCoreBundle.message("general.unknown_error")
197201
}
198202

203+
AwsTelemetry.loginWithBrowser(
204+
project = null,
205+
credentialStartUrl = toolkitRequest?.registration?.issuerUrl,
206+
result = MetricResult.Failed,
207+
reason = error,
208+
reasonDesc = errorDescription,
209+
authType = AuthType.PKCE
210+
)
211+
199212
mapOf(
200213
"error" to errorString
201214
)

0 commit comments

Comments
 (0)