diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 087d6e838ab..af930a3a34d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -368,31 +368,28 @@ The `aws.dev.forceDevMode` setting enables or disables Toolkit "dev mode". Witho
```
tail -F ~/awstoolkit.log
```
-- Use the `AWS (Developer): Watch Logs` command to watch and filter Toolkit logs (including
- telemetry) in VSCode.
- - Only available if you enabled "dev mode" (`aws.dev.forceDevMode` setting, see above).
- - Enter text in the Debug Console filter box to show only log messages with that text.
-
+- Use the Output panel to watch and filter Toolkit logs (including telemetry) in VSCode.
+ - Enter text in the Output panel filter box to show only log messages with that text.
#### Enabling Debug Logs
How to enable more detailed debug logs in the extensions.
If you need to report an issue attach these to give the most detailed information.
-1. Open the Command Palette (`cmd/ctrl` + `shift` + `p`), then search for "View Logs". Choose the correct option for the extension you want, eg: `AWS: View Logs` or `Amazon Q: View Logs`
- 
+1. Open the Command Palette (`cmd/ctrl` + `shift` + `p`), then search for "View Logs". Choose either `AWS: View Logs` or `Amazon Q: View Logs`.
+ - 
2. Click the gear icon on the bottom right and select `Debug`
- 
+ - 
3. Click the gear icon again and select `Set As Default`. This will ensure we stay in `Debug` until explicitly changed
- 
+ - 
4. Open the Command Palette again and select `Reload Window`.
5. Now you should see additional `[debug]` prefixed logs in the output.
- 
+ - 
### Telemetry
- See [docs/telemetry.md](./docs/telemetry.md) for guidelines on developing telemetry in this project.
-- To watch Toolkit telemetry events, use the `AWS (Developer): Watch Logs` command (see [Logging](#logging) above) and enter "telemetry" in the Debug Console filter box.
+- To watch Toolkit telemetry events, use the `Amazon Q: View Logs` command (see [Logging](#logging) above) and enter "telemetry" in the filter box.
### Service Endpoints
diff --git a/docs/images/debug-console-filter.png b/docs/images/debug-console-filter.png
deleted file mode 100644
index 06703ab4149..00000000000
Binary files a/docs/images/debug-console-filter.png and /dev/null differ
diff --git a/packages/amazonq/.changes/next-release/Bug Fix-704d175a-a99f-4ce7-bf08-b94d6f7218c0.json b/packages/amazonq/.changes/next-release/Bug Fix-704d175a-a99f-4ce7-bf08-b94d6f7218c0.json
new file mode 100644
index 00000000000..01d6ec7c8b0
--- /dev/null
+++ b/packages/amazonq/.changes/next-release/Bug Fix-704d175a-a99f-4ce7-bf08-b94d6f7218c0.json
@@ -0,0 +1,4 @@
+{
+ "type": "Bug Fix",
+ "description": "`Send to prompt` and other context menu options not sent if chat was closed"
+}
diff --git a/packages/amazonq/.changes/next-release/Feature-d86356a0-bc42-4187-a7f8-205afbc25d76.json b/packages/amazonq/.changes/next-release/Feature-d86356a0-bc42-4187-a7f8-205afbc25d76.json
new file mode 100644
index 00000000000..510dd1c150d
--- /dev/null
+++ b/packages/amazonq/.changes/next-release/Feature-d86356a0-bc42-4187-a7f8-205afbc25d76.json
@@ -0,0 +1,4 @@
+{
+ "type": "Feature",
+ "description": "Amazon Q /dev: support `.hbs`, `.gjs`, `.gts`, `.astro`, `.mdx`, `.svelte`, `.erb`, `.rake` files"
+}
diff --git a/packages/amazonq/.changes/next-release/Feature-d9128dff-2867-4bf4-9046-2a52a36803d7.json b/packages/amazonq/.changes/next-release/Feature-d9128dff-2867-4bf4-9046-2a52a36803d7.json
new file mode 100644
index 00000000000..add00c79b5e
--- /dev/null
+++ b/packages/amazonq/.changes/next-release/Feature-d9128dff-2867-4bf4-9046-2a52a36803d7.json
@@ -0,0 +1,4 @@
+{
+ "type": "Feature",
+ "description": "/transform: automatically download results when ready"
+}
diff --git a/packages/core/src/amazonq/apps/initContext.ts b/packages/core/src/amazonq/apps/initContext.ts
index e33fafca7c3..f8b06e4b46a 100644
--- a/packages/core/src/amazonq/apps/initContext.ts
+++ b/packages/core/src/amazonq/apps/initContext.ts
@@ -4,20 +4,20 @@
*/
import { EventEmitter } from 'vscode'
-import { MessagePublisher } from '../messages/messagePublisher'
+import { MessagePublisher, UiMessagePublisher } from '../messages/messagePublisher'
import { MessageListener } from '../messages/messageListener'
import { TabType } from '../webview/ui/storages/tabsStorage'
export interface AmazonQAppInitContext {
registerWebViewToAppMessagePublisher(eventEmitter: MessagePublisher, tabType: TabType): void
- getAppsToWebViewMessagePublisher(): MessagePublisher
+ getAppsToWebViewMessagePublisher(): UiMessagePublisher
onDidChangeAmazonQVisibility: EventEmitter
}
export class DefaultAmazonQAppInitContext implements AmazonQAppInitContext {
private readonly appsToWebViewEventEmitter = new EventEmitter()
private readonly appsToWebViewMessageListener = new MessageListener(this.appsToWebViewEventEmitter)
- private readonly appsToWebViewMessagePublisher = new MessagePublisher(this.appsToWebViewEventEmitter)
+ private readonly appsToWebViewMessagePublisher = new UiMessagePublisher(this.appsToWebViewEventEmitter)
private readonly webViewToAppsMessagePublishers: Map> = new Map()
public readonly onDidChangeAmazonQVisibility = new EventEmitter()
@@ -41,7 +41,7 @@ export class DefaultAmazonQAppInitContext implements AmazonQAppInitContext {
return this.appsToWebViewMessageListener
}
- getAppsToWebViewMessagePublisher(): MessagePublisher {
+ getAppsToWebViewMessagePublisher(): UiMessagePublisher {
return this.appsToWebViewMessagePublisher
}
}
diff --git a/packages/core/src/amazonq/messages/messagePublisher.ts b/packages/core/src/amazonq/messages/messagePublisher.ts
index d2987a99536..7fa6976b9a9 100644
--- a/packages/core/src/amazonq/messages/messagePublisher.ts
+++ b/packages/core/src/amazonq/messages/messagePublisher.ts
@@ -12,3 +12,48 @@ export class MessagePublisher {
this.eventEmitter.fire(event)
}
}
+
+/**
+ * Same as {@link MessagePublisher}, but will wait until the UI indicates it
+ * is ready to recieve messages, before the message is published.
+ *
+ * This solves a problem when running a right click menu option like
+ * "Send To Prompt" BUT chat is not opened yet, it would result in the prompt failing to
+ * be recieved by chat.
+ */
+export class UiMessagePublisher extends MessagePublisher {
+ private isUiReady: boolean = false
+ private buffer: T[] = []
+
+ constructor(eventEmitter: EventEmitter) {
+ super(eventEmitter)
+ }
+
+ public override publish(event: T): void {
+ // immediately send if Chat UI is ready
+ if (this.isUiReady) {
+ super.publish(event)
+ return
+ }
+
+ this.buffer.push(event)
+ }
+
+ /**
+ * Indicate the Q Chat UI is ready to recieve messages.
+ */
+ public setUiReady() {
+ this.isUiReady = true
+ this.flush()
+ }
+
+ /**
+ * Publishes all blocked messages
+ */
+ private flush() {
+ for (const msg of this.buffer) {
+ super.publish(msg)
+ }
+ this.buffer = []
+ }
+}
diff --git a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts
index 8acd04e8953..fdd1584b767 100644
--- a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts
+++ b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts
@@ -13,6 +13,7 @@ import { telemetry } from '../../../shared/telemetry'
import { AmazonQChatMessageDuration } from '../../messages/chatMessageDuration'
import { globals, openUrl } from '../../../shared'
import { isClickTelemetry, isOpenAgentTelemetry } from '../ui/telemetry/actions'
+import { DefaultAmazonQAppInitContext } from '../../apps/initContext'
export function dispatchWebViewMessagesToApps(
webview: Webview,
@@ -21,12 +22,12 @@ export function dispatchWebViewMessagesToApps(
webview.onDidReceiveMessage((msg) => {
switch (msg.command) {
case 'ui-is-ready': {
+ DefaultAmazonQAppInitContext.instance.getAppsToWebViewMessagePublisher().setUiReady()
/**
* ui-is-ready isn't associated to any tab so just record the telemetry event and continue.
* This would be equivalent of the duration between "user clicked open q" and "ui has become available"
* NOTE: Amazon Q UI is only loaded ONCE. The state is saved between each hide/show of the webview.
*/
-
telemetry.webview_load.emit({
webviewName: 'amazonq',
duration: performance.measure(amazonqMark.uiReady, amazonqMark.open).duration,
diff --git a/packages/core/src/codewhisperer/commands/startTransformByQ.ts b/packages/core/src/codewhisperer/commands/startTransformByQ.ts
index 50be99b7fcf..cec513d4f58 100644
--- a/packages/core/src/codewhisperer/commands/startTransformByQ.ts
+++ b/packages/core/src/codewhisperer/commands/startTransformByQ.ts
@@ -775,6 +775,12 @@ export async function postTransformationJob() {
if (transformByQState.getPayloadFilePath() !== '') {
fs.rmSync(transformByQState.getPayloadFilePath(), { recursive: true, force: true }) // delete ZIP if it exists
}
+
+ // attempt download for user
+ // TODO: refactor as explained here https://github.com/aws/aws-toolkit-vscode/pull/6519/files#r1946873107
+ if (transformByQState.isSucceeded() || transformByQState.isPartiallySucceeded()) {
+ await vscode.commands.executeCommand('aws.amazonq.transformationHub.reviewChanges.startReview')
+ }
}
export async function transformationJobErrorHandler(error: any) {
diff --git a/packages/core/src/dev/activation.ts b/packages/core/src/dev/activation.ts
index 0033eaa8548..15baf1bc294 100644
--- a/packages/core/src/dev/activation.ts
+++ b/packages/core/src/dev/activation.ts
@@ -199,20 +199,6 @@ export async function activate(ctx: vscode.ExtensionContext): Promise {
.filter((e) => (opts.menuOptions ?? Object.keys(options)).includes(e[0]))
.map((e) => e[1])
)
- }),
- // "AWS (Developer): Watch Logs"
- Commands.register('aws.dev.viewLogs', async () => {
- // HACK: Use startDebugging() so we can use the DEBUG CONSOLE (which supports
- // user-defined filtering, unlike the OUTPUT panel).
- await vscode.debug.startDebugging(undefined, {
- name: 'aws-dev-log',
- request: 'launch',
- type: 'node', // Nonsense, to force the debugger to start.
- })
- getLogger().enableDebugConsole()
- if (!getLogger().logLevelEnabled('debug')) {
- getLogger().setLogLevel('debug')
- }
})
)
diff --git a/packages/core/src/shared/filetypes.ts b/packages/core/src/shared/filetypes.ts
index 843397e6a17..9457592c8b2 100644
--- a/packages/core/src/shared/filetypes.ts
+++ b/packages/core/src/shared/filetypes.ts
@@ -155,6 +155,7 @@ export const codefileExtensions = new Set([
'.ads',
'.apl',
'.asm',
+ '.astro',
'.awk',
'.b',
'.bas',
@@ -195,6 +196,7 @@ export const codefileExtensions = new Set([
'.el',
'.elm',
'.env',
+ '.erb',
'.erl',
'.ex',
'.exs',
@@ -211,6 +213,7 @@ export const codefileExtensions = new Set([
'.fsx',
'.gd',
'.gitignore',
+ '.gjs',
'.go',
'.gql',
'.gradle',
@@ -220,9 +223,11 @@ export const codefileExtensions = new Set([
'.gsp',
'.gst',
'.gsx',
+ '.gts',
'.gvy',
'.h',
'.hack',
+ '.hbs',
'.hh',
'.hpp',
'.hrl',
@@ -253,6 +258,7 @@ export const codefileExtensions = new Set([
'.mak',
'.makefile',
'.md',
+ '.mdx',
'.mjs',
'.ml',
'.mli',
@@ -289,6 +295,7 @@ export const codefileExtensions = new Set([
'.pyw',
'.qs',
'.r',
+ '.rake',
'.raku',
'.rakumod',
'.rakutest',
@@ -331,6 +338,7 @@ export const codefileExtensions = new Set([
'.ss',
'.st',
'.sv',
+ '.svelte',
'.svg',
'.swift',
'.t',
diff --git a/packages/core/src/shared/logger/logger.ts b/packages/core/src/shared/logger/logger.ts
index 98a7e29d48e..ccc5e912d27 100644
--- a/packages/core/src/shared/logger/logger.ts
+++ b/packages/core/src/shared/logger/logger.ts
@@ -5,7 +5,15 @@
import * as vscode from 'vscode'
-export type LogTopic = 'crashMonitoring' | 'dev/beta' | 'notifications' | 'test' | 'childProcess' | 'lsp' | 'unknown'
+export type LogTopic =
+ | 'crashMonitoring'
+ | 'dev/beta'
+ | 'notifications'
+ | 'test'
+ | 'childProcess'
+ | 'unknown'
+ | 'chat'
+ | 'lsp'
class ErrorLog {
constructor(
@@ -35,8 +43,6 @@ export interface Logger {
/** Returns true if the given log level is being logged. */
logLevelEnabled(logLevel: LogLevel): boolean
getLogById(logID: number, file: vscode.Uri): string | undefined
- /** HACK: Enables logging to vscode Debug Console. */
- enableDebugConsole(): void
sendToLog(
logLevel: 'debug' | 'verbose' | 'info' | 'warn' | 'error',
message: string | Error,
@@ -74,8 +80,6 @@ export abstract class BaseLogger implements Logger {
abstract setLogLevel(logLevel: LogLevel): void
abstract logLevelEnabled(logLevel: LogLevel): boolean
abstract getLogById(logID: number, file: vscode.Uri): string | undefined
- /** HACK: Enables logging to vscode Debug Console. */
- abstract enableDebugConsole(): void
}
/**
@@ -166,7 +170,6 @@ export class NullLogger extends BaseLogger {
public getLogById(logID: number, file: vscode.Uri): string | undefined {
return undefined
}
- public enableDebugConsole(): void {}
override sendToLog(
logLevel: 'error' | 'warn' | 'info' | 'verbose' | 'debug',
message: string | Error,
@@ -190,7 +193,6 @@ export class ConsoleLogger extends BaseLogger {
public getLogById(logID: number, file: vscode.Uri): string | undefined {
return undefined
}
- public enableDebugConsole(): void {}
override sendToLog(
logLevel: 'error' | 'warn' | 'info' | 'verbose' | 'debug',
message: string | Error,
@@ -244,10 +246,6 @@ export class TopicLogger extends BaseLogger implements vscode.Disposable {
return this.logger.getLogById(logID, file)
}
- override enableDebugConsole(): void {
- this.logger.enableDebugConsole()
- }
-
override sendToLog(level: LogLevel, message: string | Error, ...meta: any[]): number {
if (typeof message === 'string') {
message = prependTopic(this.topic, message) as string
diff --git a/packages/core/src/shared/logger/toolkitLogger.ts b/packages/core/src/shared/logger/toolkitLogger.ts
index d525fb7cf20..0fdf58dc939 100644
--- a/packages/core/src/shared/logger/toolkitLogger.ts
+++ b/packages/core/src/shared/logger/toolkitLogger.ts
@@ -48,10 +48,6 @@ export class ToolkitLogger extends BaseLogger implements vscode.Disposable {
})
}
- public enableDebugConsole(): void {
- this.logToConsole()
- }
-
public setLogLevel(logLevel: LogLevel) {
if (this.logger.level === logLevel) {
return
diff --git a/packages/core/src/shared/lsp/utils/platform.ts b/packages/core/src/shared/lsp/utils/platform.ts
index 44e68c423d2..4d242c3833e 100644
--- a/packages/core/src/shared/lsp/utils/platform.ts
+++ b/packages/core/src/shared/lsp/utils/platform.ts
@@ -36,8 +36,11 @@ export function createServerOptions({
execArgv: string[]
}) {
return async () => {
- const debugArgs = isDebugInstance() ? '--inspect=6080' : ''
- const lspProcess = new ChildProcess(executable, [debugArgs, serverModule, ...execArgv])
+ const args = [serverModule, ...execArgv]
+ if (isDebugInstance()) {
+ args.unshift('--inspect=6080')
+ }
+ const lspProcess = new ChildProcess(executable, args)
// this is a long running process, awaiting it will never resolve
void lspProcess.run()
diff --git a/packages/core/src/shared/regions/regionProvider.ts b/packages/core/src/shared/regions/regionProvider.ts
index 00d13942196..426e27d73c5 100644
--- a/packages/core/src/shared/regions/regionProvider.ts
+++ b/packages/core/src/shared/regions/regionProvider.ts
@@ -162,25 +162,30 @@ export class RegionProvider {
remote: () => Endpoints | Promise
}): RegionProvider {
const instance = new this()
+ void instance.init(endpointsProvider)
+ return instance
+ }
- async function load() {
- getLogger().info('endpoints: retrieving AWS endpoints data')
- instance.loadFromEndpoints(await endpointsProvider.local())
-
- try {
- instance.loadFromEndpoints(await endpointsProvider.remote())
- } catch (err) {
- getLogger().warn(
- `endpoints: failed to load from remote source, region data may appear outdated: %s`,
- err
- )
- }
+ async init(endpointsProvider: {
+ local: () => Endpoints | Promise
+ remote: () => Endpoints | Promise
+ }) {
+ getLogger().info('endpoints: retrieving AWS endpoints data')
+
+ try {
+ this.loadFromEndpoints(await endpointsProvider.local())
+ } catch (err) {
+ getLogger().warn(`endpoints: failed to load from local source: %s`, err)
}
- load().catch((err) => {
- getLogger().error('Failure while loading Endpoints Manifest: %s', err)
+ try {
+ this.loadFromEndpoints(await endpointsProvider.remote())
+ } catch (err) {
+ getLogger().warn(`endpoints: failed to load from remote source, region data may appear outdated: %s`, err)
+ }
- return vscode.window.showErrorMessage(
+ if (this.getRegions().length === 0) {
+ void vscode.window.showErrorMessage(
`${localize(
'AWS.error.endpoint.load.failure',
'The {0} Toolkit was unable to load endpoints data.',
@@ -190,9 +195,7 @@ export class RegionProvider {
'Toolkit functionality may be impacted until VS Code is restarted.'
)}`
)
- })
-
- return instance
+ }
}
}
diff --git a/packages/core/src/test/testLogger.ts b/packages/core/src/test/testLogger.ts
index db9d460652c..a2970c37d8b 100644
--- a/packages/core/src/test/testLogger.ts
+++ b/packages/core/src/test/testLogger.ts
@@ -23,8 +23,6 @@ export class TestLogger extends BaseLogger {
super()
}
- public enableDebugConsole(): void {}
-
public getLoggedEntries(...logLevels: LogLevel[]): Loggable[] {
return this.loggedEntries
.filter((loggedEntry) => logLevels.length === 0 || logLevels.includes(loggedEntry.logLevel))
diff --git a/packages/core/src/testInteg/regionProvider.test.ts b/packages/core/src/testInteg/regionProvider.test.ts
new file mode 100644
index 00000000000..a3486c2bac0
--- /dev/null
+++ b/packages/core/src/testInteg/regionProvider.test.ts
@@ -0,0 +1,37 @@
+/*!
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert'
+import { makeEndpointsProvider } from '../extension'
+import { RegionProvider } from '../shared/regions/regionProvider'
+import globals from '../shared/extensionGlobals'
+import path from 'path'
+import { TestFolder } from '../test/testUtil'
+
+describe('Region Provider', async function () {
+ let tempFolder: TestFolder
+
+ before(async () => {
+ tempFolder = await TestFolder.create()
+ })
+
+ it('resolves from remote', async function () {
+ /**
+ * Make sure the local file doesn't resolve to any endpoints.
+ * That way we can make sure remote contents are fetched
+ */
+ await tempFolder.write('foo.json', '{}')
+ globals.manifestPaths.endpoints = path.join(tempFolder.path, 'foo.json')
+
+ await assert.doesNotReject(async () => {
+ const endpointProvider = makeEndpointsProvider()
+ const regionProvider = new RegionProvider()
+ await regionProvider.init(endpointProvider)
+
+ // regions loaded from the remote
+ assert.ok(regionProvider.getRegions().length > 0)
+ })
+ })
+})
diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json
index 21dbc06f185..e152c8a2c9f 100644
--- a/packages/toolkit/package.json
+++ b/packages/toolkit/package.json
@@ -3895,11 +3895,6 @@
"category": "AWS (Developer)",
"enablement": "aws.isDevMode"
},
- {
- "command": "aws.dev.viewLogs",
- "title": "Watch Logs",
- "category": "AWS (Developer)"
- },
{
"command": "aws.openInApplicationComposerDialog",
"title": "%AWS.command.applicationComposer.openDialog%",