Skip to content

Commit 73fa3ce

Browse files
committed
Merge branch 'feature/standalone' into feature/cw-proactive-scan-merge
2 parents f5b1345 + 8fce296 commit 73fa3ce

File tree

13 files changed

+316
-35
lines changed

13 files changed

+316
-35
lines changed

.changes/2.20.0.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"date": "2024-04-19",
3+
"version": "2.20.0",
4+
"entries": [
5+
{
6+
"type": "Bug Fix",
7+
"description": "Amazon Q CodeTransform may fail if JAVA_HOME has leading or trailing whitespace"
8+
},
9+
{
10+
"type": "Bug Fix",
11+
"description": "Amazon Q FeatureDev: code generation may fail with \"conversation id not found\" error"
12+
},
13+
{
14+
"type": "Bug Fix",
15+
"description": "Amazon Q Code Transformation: show error messages in chat"
16+
},
17+
{
18+
"type": "Bug Fix",
19+
"description": "Amazon Q Code Transformation - Omit Maven metadata files when uploading dependencies to fix certain build failures in backend."
20+
},
21+
{
22+
"type": "Feature",
23+
"description": "Enable Amazon Q feature development and Amazon Q transform capabilities (/dev and /transform) for AWS Builder ID users."
24+
}
25+
]
26+
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/amazonq/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "amazon-q-vscode",
33
"displayName": "Standalone Test",
44
"description": "",
5-
"version": "0.15.0-SNAPSHOT",
5+
"version": "0.16.0-SNAPSHOT",
66
"extensionKind": [
77
"workspace"
88
],

packages/core/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,10 @@
795795
"command": "aws.codecatalyst.listCommands",
796796
"when": "false"
797797
},
798+
{
799+
"command": "aws.codecatalyst.manageConnections",
800+
"when": "false"
801+
},
798802
{
799803
"command": "aws.codecatalyst.openDevEnv",
800804
"when": "!isCloud9"

packages/core/src/amazonq/activation.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { activateBadge } from './util/viewBadgeHandler'
1515
import { amazonQHelpUrl } from '../shared/constants'
1616
import { openAmazonQWalkthrough } from './onboardingPage/walkthrough'
1717
import { listCodeWhispererCommandsWalkthrough } from '../codewhisperer/ui/statusBarMenu'
18+
import { focusAmazonQPanel } from '../codewhispererChat/commands/registerCommands'
1819

1920
export async function activate(context: ExtensionContext) {
2021
const appInitContext = DefaultAmazonQAppInitContext.instance
@@ -36,7 +37,8 @@ export async function activate(context: ExtensionContext) {
3637
}),
3738
focusAmazonQChatWalkthrough.register(),
3839
openAmazonQWalkthrough.register(),
39-
listCodeWhispererCommandsWalkthrough.register()
40+
listCodeWhispererCommandsWalkthrough.register(),
41+
focusAmazonQPanel.register()
4042
)
4143

4244
Commands.register('aws.amazonq.learnMore', () => {
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
import globals from '../../shared/extensionGlobals'
8+
import path from 'path'
9+
import { MessagePublisher } from '../messages/messagePublisher'
10+
import { telemetry } from '../../shared/telemetry/telemetry'
11+
import { getLogger } from '../../shared/logger'
12+
import { placeholder } from '../../shared/vscode/commands2'
13+
import { focusAmazonQPanel } from '../../codewhispererChat/commands/registerCommands'
14+
15+
export function welcome(context: vscode.ExtensionContext, cwcWebViewToAppsPublisher: MessagePublisher<any>): void {
16+
const panel = vscode.window.createWebviewPanel(
17+
'amazonQWelcome',
18+
'Meet Amazon Q (Preview)',
19+
vscode.ViewColumn.Active,
20+
{
21+
enableScripts: true,
22+
}
23+
)
24+
25+
// TODO: get svg gradient icon and use `getIcon` (currently only works with svg)
26+
panel.iconPath = vscode.Uri.file(
27+
globals.context.asAbsolutePath(path.join('resources', 'icons', 'aws', 'amazonq', 'q-gradient.svg'))
28+
)
29+
30+
panel.webview.html = getWebviewContent(panel.webview)
31+
32+
// Handle messages from the webview
33+
panel.webview.onDidReceiveMessage(
34+
message => {
35+
telemetry.ui_click.run(() => {
36+
switch (message.command) {
37+
case 'sendToQ':
38+
telemetry.record({ elementId: 'amazonq_meet_askq' })
39+
focusAmazonQPanel.execute(placeholder, 'sendToQ').then(
40+
() => {
41+
cwcWebViewToAppsPublisher.publish({
42+
type: 'onboarding-page-cwc-button-clicked',
43+
command: 'onboarding-page-interaction',
44+
})
45+
},
46+
e => {
47+
getLogger().error('focusAmazonQPanel failed: %s', (e as Error).message)
48+
}
49+
)
50+
51+
return
52+
53+
case 'goToHelp':
54+
telemetry.record({ elementId: 'amazonq_tryExamples' })
55+
void vscode.commands.executeCommand('aws.codeWhisperer.gettingStarted')
56+
return
57+
}
58+
})
59+
},
60+
undefined,
61+
context.subscriptions
62+
)
63+
64+
// user closes webview
65+
// does this fire on IDE shutdown?
66+
panel.onDidDispose(() => {
67+
telemetry.ui_click.emit({
68+
elementId: 'amazonq_closeWebview',
69+
passive: true,
70+
})
71+
})
72+
}
73+
74+
function getWebviewContent(webview: vscode.Webview): string {
75+
const logo = webview.asWebviewUri(
76+
vscode.Uri.file(
77+
globals.context.asAbsolutePath(path.join('resources', 'icons', 'aws', 'amazonq', 'q-gradient.svg'))
78+
)
79+
)
80+
const bgLogoLight = webview.asWebviewUri(
81+
vscode.Uri.file(
82+
globals.context.asAbsolutePath(path.join('resources', 'icons', 'aws', 'amazonq', 'q-squid-ink.svg'))
83+
)
84+
)
85+
const bgLogoDark = webview.asWebviewUri(
86+
vscode.Uri.file(
87+
globals.context.asAbsolutePath(path.join('resources', 'icons', 'aws', 'amazonq', 'q-white.svg'))
88+
)
89+
)
90+
const cwLogoLight = webview.asWebviewUri(
91+
vscode.Uri.file(
92+
globals.context.asAbsolutePath(path.join('resources', 'icons', 'aws', 'codewhisperer', 'icon-black.svg'))
93+
)
94+
)
95+
const cwLogoDark = webview.asWebviewUri(
96+
vscode.Uri.file(
97+
globals.context.asAbsolutePath(path.join('resources', 'icons', 'aws', 'codewhisperer', 'icon-white.svg'))
98+
)
99+
)
100+
return `
101+
<!DOCTYPE html>
102+
<html lang="en">
103+
<head>
104+
<meta charset="UTF-8">
105+
<meta http-equiv="Content-Security-Policy"
106+
content="default-src 'none';
107+
font-src ${webview.cspSource};
108+
script-src 'self' 'unsafe-inline';
109+
style-src 'self' 'unsafe-inline' ${webview.cspSource};
110+
img-src ${webview.cspSource}"
111+
>
112+
<meta name="viewport" content="width=device-width, initial-scale=1">
113+
<style>
114+
body.vscode-light #bg {
115+
content: url(${bgLogoLight});
116+
opacity: 0.05;
117+
}
118+
body.vscode-dark #bg {
119+
content: url(${bgLogoDark});
120+
opacity: 0.05;
121+
}
122+
body.vscode-light #codewhispererLogo {
123+
content: url(${cwLogoLight})
124+
}
125+
body.vscode-dark #codewhispererLogo {
126+
content: url(${cwLogoDark})
127+
}
128+
body {
129+
height: 100vh;
130+
}
131+
#bg {
132+
position: fixed;
133+
left: 70%;
134+
top: -10%;
135+
overflow: hidden;
136+
transform: scale(2);
137+
pointer-events:none;
138+
user-select: none;
139+
}
140+
#sendToQButton {
141+
background: linear-gradient(14deg, rgba(52,20,120,1) 0%, rgba(91,41,196,1) 25%, rgba(117,55,247,1) 50%, rgba(73,125,254,1) 75%, rgba(170,233,255,1) 100%);
142+
color: white;
143+
border-radius: 6px;
144+
border: none;
145+
font-size: 20px;
146+
padding: 0.5em 1em;
147+
text-align: center;
148+
cursor: pointer;
149+
}
150+
#wrapper {
151+
height: 100%;
152+
width: 100%;
153+
min-width: 600px;
154+
overflow-y: auto;
155+
overflow-x: auto;
156+
display: flex;
157+
flex-direction: row;
158+
justify-content: center;
159+
align-items: center;
160+
}
161+
#content {
162+
max-width: 550px;
163+
padding: 30px;
164+
display: flex;
165+
flex-direction: column;
166+
gap: 30px;
167+
align-items: center;
168+
}
169+
#codewhisperer {
170+
display: flex;
171+
align-items: center;
172+
flex-direction: row;
173+
gap: 40px;
174+
flex-wrap: nowrap;
175+
}
176+
#codewhisperer div p {
177+
margin: 0px;
178+
font-size: 12pt;
179+
}
180+
#qLogo {
181+
width: 70px
182+
}
183+
#imageContainer {
184+
width: 40px;
185+
height: auto;
186+
flex-shrink: 0;
187+
flex-grow: 0;
188+
}
189+
#textWrapper {
190+
flex-shrink: 1;
191+
flex-grow: 1;
192+
}
193+
#header {
194+
text-align: center;
195+
margin: 0;
196+
}
197+
a {
198+
cursor: pointer;
199+
}
200+
.spacingrow {
201+
display: flex;
202+
flex-direction: row;
203+
gap: 40px;
204+
flex-wrap: nowrap;
205+
}
206+
</style>
207+
</head>
208+
<body>
209+
<img id="bg">
210+
<div id="wrapper">
211+
<div id="content">
212+
<img id="qLogo" src="${logo}"/>
213+
<h1 id="header">Hello! I'm Amazon Q, your generative AI assistant.</h1>
214+
<div id="buttonContainer">
215+
<button id="sendToQButton">Ask a question</button>
216+
</div>
217+
<!-- spacing -->
218+
<div class="spacingrow"> </div>
219+
<div class="spacingrow"> </div>
220+
<!-- end spacing -->
221+
<div id="codewhisperer">
222+
<div id="imageContainer">
223+
<img id="codewhispererLogo"/>
224+
</div>
225+
<div id="textWrapper">
226+
<p>CodeWhisperer inline suggestions are also enabled.<br><a id="goToHelpLink">Try examples</a></p>
227+
</div>
228+
</div>
229+
</div>
230+
</div>
231+
<script>
232+
(function() {
233+
const vscode = acquireVsCodeApi()
234+
const sendToQ = () => { vscode.postMessage({ command: "sendToQ" }) }
235+
const goToHelp = () => { vscode.postMessage({ command: "goToHelp" }) }
236+
const sendToQButton = document.getElementById('sendToQButton')
237+
sendToQButton.onclick = sendToQ
238+
const goToHelpLink = document.getElementById('goToHelpLink')
239+
goToHelpLink.onclick = goToHelp
240+
}())
241+
</script>
242+
</body>
243+
</html>
244+
`
245+
}

packages/core/src/auth/ui/vue/show.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import { debounce } from 'lodash'
5454
import { submitFeedback } from '../../../feedback/vue/submitFeedback'
5555
import { InvalidGrantException } from '@aws-sdk/client-sso-oidc'
5656
import { ExtStartUpSources } from '../../../shared/telemetry'
57+
import { focusAmazonQPanel } from '../../../codewhispererChat/commands/registerCommands'
5758

5859
export class AuthWebview extends VueWebview {
5960
public static readonly sourcePath: string = 'src/auth/ui/vue/index.js'
@@ -183,7 +184,7 @@ export class AuthWebview extends VueWebview {
183184
}
184185

185186
async showAmazonQChat(): Promise<void> {
186-
return focusAmazonQPanel()
187+
return focusAmazonQPanel.execute(placeholder, 'addConnectionPage')
187188
}
188189

189190
async getIdentityCenterRegion(): Promise<Region | undefined> {
@@ -857,12 +858,3 @@ export async function emitWebviewClosed(authWebview: ClassToInterfaceType<AuthWe
857858
return result
858859
}
859860
}
860-
861-
/**
862-
* Forces focus to Amazon Q panel - USE THIS SPARINGLY (don't betray customer trust by hijacking the IDE)
863-
* Used on first load, and any time we want to directly populate chat.
864-
*/
865-
export async function focusAmazonQPanel(): Promise<void> {
866-
await vscode.commands.executeCommand('aws.AmazonQChatView.focus')
867-
await vscode.commands.executeCommand('aws.amazonq.AmazonCommonAuth.focus')
868-
}

packages/core/src/codewhisperer/service/inlineCompletionService.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,30 +223,31 @@ export class CodeWhispererStatusBar {
223223
statusBar.command = listCodeWhispererCommandsId
224224
statusBar.backgroundColor = undefined
225225

226+
const title = 'Amazon Q'
226227
switch (status) {
227228
case 'loading': {
228229
const selectedCustomization = getSelectedCustomization()
229-
statusBar.text = codicon` ${getIcon('vscode-loading~spin')} CodeWhisperer${
230+
statusBar.text = codicon` ${getIcon('vscode-loading~spin')} ${title}${
230231
selectedCustomization.arn === '' ? '' : ` | ${selectedCustomization.name}`
231232
}`
232233
break
233234
}
234235
case 'ok': {
235236
const selectedCustomization = getSelectedCustomization()
236237
const icon = isSuggestionsEnabled ? getIcon('vscode-debug-start') : getIcon('vscode-debug-pause')
237-
statusBar.text = codicon`${icon} CodeWhisperer${
238+
statusBar.text = codicon`${icon} ${title}${
238239
selectedCustomization.arn === '' ? '' : ` | ${selectedCustomization.name}`
239240
}`
240241
break
241242
}
242243

243244
case 'expired': {
244-
statusBar.text = codicon` ${getIcon('vscode-debug-disconnect')} CodeWhisperer`
245+
statusBar.text = codicon` ${getIcon('vscode-debug-disconnect')} ${title}`
245246
statusBar.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground')
246247
break
247248
}
248249
case 'notConnected':
249-
statusBar.text = codicon` ${getIcon('vscode-chrome-close')} CodeWhisperer`
250+
statusBar.text = codicon` ${getIcon('vscode-chrome-close')} ${title}`
250251
break
251252
}
252253

0 commit comments

Comments
 (0)