|
3 | 3 | * SPDX-License-Identifier: Apache-2.0
|
4 | 4 | */
|
5 | 5 |
|
| 6 | +import { AuthUtils, CredentialsStore, LoginManager, SsoConnection, initializeAuth } from 'aws-core-vscode/auth' |
| 7 | +import { |
| 8 | + AuthUtil, |
| 9 | + activate as activateCodeWhisperer, |
| 10 | + shutdown as shutdownCodeWhisperer, |
| 11 | +} from 'aws-core-vscode/codewhisperer' |
| 12 | +import { makeEndpointsProvider, registerGenericCommands } from 'aws-core-vscode' |
| 13 | +import { CommonAuthWebview } from 'aws-core-vscode/login' |
| 14 | +import { |
| 15 | + DefaultAWSClientBuilder, |
| 16 | + DefaultAwsContext, |
| 17 | + ExtContext, |
| 18 | + RegionProvider, |
| 19 | + Settings, |
| 20 | + activateLogger, |
| 21 | + activateTelemetry, |
| 22 | + env, |
| 23 | + errors, |
| 24 | + fs, |
| 25 | + getLogger, |
| 26 | + getMachineId, |
| 27 | + globals, |
| 28 | + initialize, |
| 29 | + initializeComputeRegion, |
| 30 | + messages, |
| 31 | + setContext, |
| 32 | +} from 'aws-core-vscode/shared' |
| 33 | +import { ExtStartUpSources, telemetry } from 'aws-core-vscode/telemetry' |
| 34 | +import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils' |
| 35 | +import { join } from 'path' |
| 36 | +import * as semver from 'semver' |
6 | 37 | import * as vscode from 'vscode'
|
7 |
| -import { activateAmazonQCommon, amazonQContextPrefix, deactivateCommon } from './extensionCommon' |
8 |
| -import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq' |
9 |
| -import { activate as activateQGumby } from 'aws-core-vscode/amazonqGumby' |
10 |
| -import { ExtContext } from 'aws-core-vscode/shared' |
11 |
| -import { updateDevMode } from 'aws-core-vscode/dev' |
12 |
| -import { CommonAuthViewProvider } from 'aws-core-vscode/login' |
13 |
| -import { isExtensionActive, VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils' |
14 |
| -import { registerSubmitFeedback } from 'aws-core-vscode/feedback' |
15 |
| -import { DevOptions } from 'aws-core-vscode/dev' |
16 |
| -import { Auth } from 'aws-core-vscode/auth' |
17 |
| -import api from './api' |
18 |
| -import { activate as activateCWChat } from './app/chat/activation' |
19 |
| - |
20 |
| -export async function activate(context: vscode.ExtensionContext) { |
21 |
| - // IMPORTANT: No other code should be added to this function. Place it in one of the following 2 functions where appropriate. |
22 |
| - await activateAmazonQCommon(context, false) |
23 |
| - await activateAmazonQNonCommon(context) |
24 |
| - |
25 |
| - return api |
26 |
| -} |
| 38 | +import { registerCommands } from './commands' |
| 39 | + |
| 40 | +export const amazonQContextPrefix = 'amazonq' |
27 | 41 |
|
28 | 42 | /**
|
29 |
| - * The code in this function is not common, implying it only works in Node.js and not web. |
30 |
| - * The goal should be for this to not exist and that all code is "common". So if possible make |
31 |
| - * the code compatible with web and move it to {@link activateAmazonQCommon}. |
| 43 | + * Activation code for Amazon Q that will we want in all environments (eg Node.js, web mode) |
32 | 44 | */
|
33 |
| -async function activateAmazonQNonCommon(context: vscode.ExtensionContext) { |
| 45 | +export async function activateAmazonQCommon(context: vscode.ExtensionContext, isWeb: boolean) { |
| 46 | + initialize(context, isWeb) |
| 47 | + const homeDirLogs = await fs.init(context, (homeDir) => { |
| 48 | + void messages.showViewLogsMessage(`Invalid home directory (check $HOME): "${homeDir}"`) |
| 49 | + }) |
| 50 | + errors.init(fs.getUsername(), env.isAutomation()) |
| 51 | + await initializeComputeRegion() |
| 52 | + |
| 53 | + globals.contextPrefix = 'amazonq.' //todo: disconnect from above line |
| 54 | + |
| 55 | + // Avoid activation if older toolkit is installed |
| 56 | + // Amazon Q is only compatible with AWS Toolkit >= 3.0.0 |
| 57 | + // Or AWS Toolkit with a development version. Example: 2.19.0-3413gv |
| 58 | + const toolkit = vscode.extensions.getExtension(VSCODE_EXTENSION_ID.awstoolkit) |
| 59 | + if (toolkit) { |
| 60 | + const toolkitVersion = semver.coerce(toolkit.packageJSON.version) |
| 61 | + // XXX: can't use `SemVer.prerelease` because Toolkit "prerelease" (git sha) is not a valid |
| 62 | + // semver prerelease: it may start with a number. |
| 63 | + const isDevVersion = toolkit.packageJSON.version.toString().includes('-') |
| 64 | + if (toolkitVersion && toolkitVersion.major < 3 && !isDevVersion) { |
| 65 | + await vscode.commands |
| 66 | + .executeCommand('workbench.extensions.installExtension', VSCODE_EXTENSION_ID.awstoolkit) |
| 67 | + .then( |
| 68 | + () => |
| 69 | + vscode.window |
| 70 | + .showInformationMessage( |
| 71 | + `The Amazon Q extension is incompatible with AWS Toolkit ${ |
| 72 | + toolkitVersion as any |
| 73 | + } and older. Your AWS Toolkit was updated to version 3.0 or later.`, |
| 74 | + 'Reload Now' |
| 75 | + ) |
| 76 | + .then(async (resp) => { |
| 77 | + if (resp === 'Reload Now') { |
| 78 | + await vscode.commands.executeCommand('workbench.action.reloadWindow') |
| 79 | + } |
| 80 | + }), |
| 81 | + (reason) => { |
| 82 | + getLogger().error('workbench.extensions.installExtension failed: %O', reason) |
| 83 | + } |
| 84 | + ) |
| 85 | + return |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + globals.machineId = await getMachineId() |
| 90 | + globals.awsContext = new DefaultAwsContext() |
| 91 | + globals.sdkClientBuilder = new DefaultAWSClientBuilder(globals.awsContext) |
| 92 | + globals.manifestPaths.endpoints = context.asAbsolutePath(join('resources', 'endpoints.json')) |
| 93 | + globals.regionProvider = RegionProvider.fromEndpointsProvider(makeEndpointsProvider()) |
| 94 | + |
| 95 | + const qOutputChannel = vscode.window.createOutputChannel('Amazon Q', { log: true }) |
| 96 | + const qLogChannel = vscode.window.createOutputChannel('Amazon Q Logs', { log: true }) |
| 97 | + await activateLogger(context, amazonQContextPrefix, qOutputChannel, qLogChannel) |
| 98 | + globals.outputChannel = qOutputChannel |
| 99 | + globals.logOutputChannel = qLogChannel |
| 100 | + globals.loginManager = new LoginManager(globals.awsContext, new CredentialsStore()) |
| 101 | + |
| 102 | + if (homeDirLogs.length > 0) { |
| 103 | + getLogger().error('fs.init: invalid env vars found: %O', homeDirLogs) |
| 104 | + } |
| 105 | + |
| 106 | + await activateTelemetry(context, globals.awsContext, Settings.instance, 'Amazon Q For VS Code') |
| 107 | + |
| 108 | + await initializeAuth(globals.loginManager) |
| 109 | + |
34 | 110 | const extContext = {
|
35 | 111 | extensionContext: context,
|
36 | 112 | }
|
37 |
| - await activateCWChat(context) |
38 |
| - await activateQGumby(extContext as ExtContext) |
39 |
| - |
40 |
| - const authProvider = new CommonAuthViewProvider( |
41 |
| - context, |
42 |
| - amazonQContextPrefix, |
43 |
| - DefaultAmazonQAppInitContext.instance.onDidChangeAmazonQVisibility |
44 |
| - ) |
45 |
| - context.subscriptions.push( |
46 |
| - vscode.window.registerWebviewViewProvider(authProvider.viewType, authProvider, { |
47 |
| - webviewOptions: { |
48 |
| - retainContextWhenHidden: true, |
49 |
| - }, |
50 |
| - }), |
51 |
| - registerSubmitFeedback(context, 'Amazon Q', amazonQContextPrefix) |
52 |
| - ) |
53 |
| - |
54 |
| - await setupDevMode(context) |
55 |
| -} |
| 113 | + await activateCodeWhisperer(extContext as ExtContext) |
56 | 114 |
|
57 |
| -/** |
58 |
| - * Some parts of this do not work in Web mode so we need to set Dev Mode up here. |
59 |
| - * |
60 |
| - * TODO: Get the following working in web mode as well and then move this function. |
61 |
| - */ |
62 |
| -async function setupDevMode(context: vscode.ExtensionContext) { |
63 |
| - // At some point this imports CodeCatalyst code which breaks in web mode. |
64 |
| - // TODO: Make this work in web mode and move it to extensionCommon.ts |
65 |
| - await updateDevMode() |
66 |
| - |
67 |
| - const devOptions: DevOptions = { |
68 |
| - context, |
69 |
| - auth: Auth.instance, |
70 |
| - menuOptions: [ |
71 |
| - 'editStorage', |
72 |
| - 'showEnvVars', |
73 |
| - 'deleteSsoConnections', |
74 |
| - 'expireSsoConnections', |
75 |
| - 'editAuthConnections', |
76 |
| - ], |
| 115 | + // Generic extension commands |
| 116 | + registerGenericCommands(context, amazonQContextPrefix) |
| 117 | + |
| 118 | + // Amazon Q specific commands |
| 119 | + registerCommands(context) |
| 120 | + |
| 121 | + // Hide the Amazon Q tree in toolkit explorer |
| 122 | + await setContext('aws.toolkit.amazonq.dismissed', true) |
| 123 | + |
| 124 | + // reload webviews |
| 125 | + await vscode.commands.executeCommand('workbench.action.webview.reloadWebviewAction') |
| 126 | + |
| 127 | + if (AuthUtils.ExtensionUse.instance.isFirstUse()) { |
| 128 | + CommonAuthWebview.authSource = ExtStartUpSources.firstStartUp |
| 129 | + await vscode.commands.executeCommand('workbench.view.extension.amazonq') |
77 | 130 | }
|
78 | 131 |
|
79 |
| - context.subscriptions.push( |
80 |
| - vscode.commands.registerCommand('amazonq.dev.openMenu', async () => { |
81 |
| - if (!isExtensionActive(VSCODE_EXTENSION_ID.awstoolkit)) { |
82 |
| - void vscode.window.showErrorMessage('AWS Toolkit must be installed to access the Developer Menu.') |
83 |
| - return |
84 |
| - } |
85 |
| - await vscode.commands.executeCommand('_aws.dev.invokeMenu', devOptions) |
| 132 | + await telemetry.auth_userState.run(async () => { |
| 133 | + telemetry.record({ passive: true }) |
| 134 | + |
| 135 | + const firstUse = AuthUtils.ExtensionUse.instance.isFirstUse() |
| 136 | + const wasUpdated = AuthUtils.ExtensionUse.instance.wasUpdated() |
| 137 | + |
| 138 | + if (firstUse) { |
| 139 | + telemetry.record({ source: ExtStartUpSources.firstStartUp }) |
| 140 | + } else if (wasUpdated) { |
| 141 | + telemetry.record({ source: ExtStartUpSources.update }) |
| 142 | + } else { |
| 143 | + telemetry.record({ source: ExtStartUpSources.reload }) |
| 144 | + } |
| 145 | + |
| 146 | + const authState = (await AuthUtil.instance.getChatAuthState()).codewhispererChat |
| 147 | + telemetry.record({ |
| 148 | + authStatus: authState === 'connected' || authState === 'expired' ? authState : 'notConnected', |
| 149 | + authEnabledConnections: AuthUtils.getAuthFormIdsFromConnection(AuthUtil.instance.conn).join(','), |
| 150 | + authScopes: ((AuthUtil.instance.conn as SsoConnection)?.scopes ?? []).join(','), |
86 | 151 | })
|
87 |
| - ) |
| 152 | + }) |
88 | 153 | }
|
89 | 154 |
|
90 |
| -export async function deactivate() { |
91 |
| - await deactivateCommon() |
| 155 | +export async function deactivateCommon() { |
| 156 | + await shutdownCodeWhisperer() |
92 | 157 | }
|
0 commit comments