Skip to content

Commit 6a3164a

Browse files
authored
Merge branch 'master' into reRoute
2 parents 6c5eb12 + d33bc14 commit 6a3164a

File tree

8 files changed

+129
-8
lines changed

8 files changed

+129
-8
lines changed

packages/amazonq/src/app/inline/cursorUpdateManager.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { LanguageClient } from 'vscode-languageclient'
88
import { getLogger } from 'aws-core-vscode/shared'
99
import { globals } from 'aws-core-vscode/shared'
1010
import { AmazonQInlineCompletionItemProvider } from './completion'
11+
import { CodeSuggestionsState } from 'aws-core-vscode/codewhisperer'
1112

1213
// Configuration section for cursor updates
1314
export const cursorUpdateConfigurationSection = 'aws.q.cursorUpdate'
@@ -32,11 +33,23 @@ export class CursorUpdateManager implements vscode.Disposable, ICursorUpdateReco
3233
private lastSentDocumentUri?: string
3334
private isActive = false
3435
private lastRequestTime = 0
36+
private autotriggerStateDisposable?: vscode.Disposable
3537

3638
constructor(
3739
private readonly languageClient: LanguageClient,
3840
private readonly inlineCompletionProvider?: AmazonQInlineCompletionItemProvider
39-
) {}
41+
) {
42+
// Listen for autotrigger state changes to enable/disable the timer
43+
this.autotriggerStateDisposable = CodeSuggestionsState.instance.onDidChangeState((isEnabled: boolean) => {
44+
if (isEnabled && this.isActive) {
45+
// If autotrigger is enabled and we're active, ensure timer is running
46+
this.setupUpdateTimer()
47+
} else {
48+
// If autotrigger is disabled, clear the timer but keep isActive state
49+
this.clearUpdateTimer()
50+
}
51+
})
52+
}
4053

4154
/**
4255
* Start tracking cursor positions and sending periodic updates
@@ -66,7 +79,9 @@ export class CursorUpdateManager implements vscode.Disposable, ICursorUpdateReco
6679
}
6780

6881
this.isActive = true
69-
this.setupUpdateTimer()
82+
if (CodeSuggestionsState.instance.isSuggestionsEnabled()) {
83+
this.setupUpdateTimer()
84+
}
7085
}
7186

7287
/**
@@ -130,7 +145,7 @@ export class CursorUpdateManager implements vscode.Disposable, ICursorUpdateReco
130145
}
131146

132147
/**
133-
* Send a cursor position update to the language server
148+
* Request LSP generate a completion for the current cursor position.
134149
*/
135150
private async sendCursorUpdate(): Promise<void> {
136151
// Don't send an update if a regular request was made recently
@@ -185,6 +200,12 @@ export class CursorUpdateManager implements vscode.Disposable, ICursorUpdateReco
185200
* Dispose of resources
186201
*/
187202
public dispose(): void {
203+
// Dispose of the autotrigger state change listener
204+
if (this.autotriggerStateDisposable) {
205+
this.autotriggerStateDisposable.dispose()
206+
this.autotriggerStateDisposable = undefined
207+
}
208+
188209
this.stop()
189210
}
190211
}

packages/amazonq/src/lsp/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export async function startLanguageServer(
165165
pinnedContextEnabled: true,
166166
mcp: true,
167167
reroute: true,
168+
workspaceFilePath: vscode.workspace.workspaceFile?.fsPath,
168169
},
169170
window: {
170171
notifications: true,

packages/amazonq/test/unit/app/inline/cursorUpdateManager.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { CursorUpdateManager } from '../../../../src/app/inline/cursorUpdateMana
1010
import { globals } from 'aws-core-vscode/shared'
1111
import assert from 'assert'
1212
import { AmazonQInlineCompletionItemProvider } from '../../../../src/app/inline/completion'
13+
import { CodeSuggestionsState } from 'aws-core-vscode/codewhisperer'
1314

1415
describe('CursorUpdateManager', () => {
1516
let cursorUpdateManager: CursorUpdateManager
@@ -236,4 +237,93 @@ describe('CursorUpdateManager', () => {
236237
// Verify the provider was called again
237238
assert.strictEqual(provideStub.callCount, 1, 'Update should be sent when position has changed')
238239
})
240+
241+
describe('autotrigger state handling', () => {
242+
class TestCodeSuggestionsState extends CodeSuggestionsState {
243+
private _isEnabled: boolean
244+
private _onDidChangeStateEmitter = new vscode.EventEmitter<boolean>()
245+
246+
public constructor(initialState: boolean = true) {
247+
super(initialState)
248+
this._isEnabled = initialState
249+
}
250+
251+
public override onDidChangeState = this._onDidChangeStateEmitter.event
252+
253+
public override isSuggestionsEnabled(): boolean {
254+
return this._isEnabled
255+
}
256+
257+
public override async setSuggestionsEnabled(enabled: boolean): Promise<void> {
258+
if (this._isEnabled !== enabled) {
259+
this._isEnabled = enabled
260+
this._onDidChangeStateEmitter.fire(enabled)
261+
}
262+
}
263+
}
264+
265+
let testCodeSuggestionsState: TestCodeSuggestionsState
266+
let instanceStub: sinon.SinonStub
267+
let testCursorUpdateManager: CursorUpdateManager
268+
269+
beforeEach(() => {
270+
// Create test instance
271+
testCodeSuggestionsState = new TestCodeSuggestionsState(true)
272+
273+
// Stub the static getter to return our test instance
274+
instanceStub = sinon.stub(CodeSuggestionsState, 'instance').get(() => testCodeSuggestionsState)
275+
276+
// Create the manager AFTER the stub is in place so it uses the test instance
277+
const mockInlineCompletionProvider = {
278+
provideInlineCompletionItems: sinon.stub().resolves([]),
279+
} as unknown as AmazonQInlineCompletionItemProvider
280+
testCursorUpdateManager = new CursorUpdateManager(languageClient, mockInlineCompletionProvider)
281+
})
282+
283+
afterEach(() => {
284+
// Dispose the test manager
285+
testCursorUpdateManager.dispose()
286+
// Restore the original getter
287+
instanceStub.restore()
288+
})
289+
290+
it('should not start timer when autotrigger is disabled', async () => {
291+
// Test the new behavior: timer doesn't start when autotrigger is disabled
292+
await testCodeSuggestionsState.setSuggestionsEnabled(false)
293+
sendRequestStub.resolves({})
294+
295+
await testCursorUpdateManager.start()
296+
297+
// Manager should be active but timer should not be started
298+
assert.strictEqual((testCursorUpdateManager as any).isActive, true)
299+
assert.ok(!setIntervalStub.called, 'Timer should NOT be started when autotrigger is disabled')
300+
})
301+
302+
it('should start/stop timer when autotrigger state changes', async () => {
303+
// Start with autotrigger enabled
304+
await testCodeSuggestionsState.setSuggestionsEnabled(true)
305+
sendRequestStub.resolves({})
306+
await testCursorUpdateManager.start()
307+
308+
// Reset stubs to test state changes
309+
setIntervalStub.resetHistory()
310+
clearIntervalStub.resetHistory()
311+
312+
// Simulate autotrigger being disabled
313+
await testCodeSuggestionsState.setSuggestionsEnabled(false)
314+
assert.ok(clearIntervalStub.called, 'Timer should be stopped when autotrigger is disabled')
315+
316+
// Simulate autotrigger being enabled again
317+
await testCodeSuggestionsState.setSuggestionsEnabled(true)
318+
assert.ok(setIntervalStub.called, 'Timer should be started when autotrigger is re-enabled')
319+
})
320+
321+
it('should dispose autotrigger state listener on dispose', () => {
322+
testCursorUpdateManager.dispose()
323+
// The dispose method should clean up the state listener
324+
// We can't easily test the disposal without more complex mocking,
325+
// but we can at least verify dispose doesn't throw
326+
assert.ok(true, 'Dispose should complete without errors')
327+
})
328+
})
239329
})

packages/core/scripts/build/copyFiles.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ const tasks: CopyTask[] = [
3131
{ target: path.join('src', 'testFixtures') },
3232
{ target: 'src/auth/sso/vue' },
3333

34+
// Vue.js for webviews
35+
{
36+
target: path.join('../../node_modules', 'vue', 'dist', 'vue.global.prod.js'),
37+
destination: path.join('libs', 'vue.min.js'),
38+
},
3439
// SSM
3540
{
3641
target: path.join('../../node_modules', 'aws-ssm-document-language-service', 'dist', 'server.js'),

packages/core/src/amazonq/webview/ui/tabs/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ To learn more, visit the [User Guide](${userGuideURL}).`,
6464
title: 'Q - Code Transformation',
6565
placeholder: 'Open a new tab to chat with Q',
6666
welcome:
67-
'Welcome to Code Transformation! You can also run transformations from the command line. To install the tool, see the [documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/run-CLI-transformations.html).',
67+
'Welcome to Code Transformation! **You can also run transformations from the command line. To install the tool, see the [documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/run-CLI-transformations.html).**',
6868
},
6969
review: {
7070
title: 'Q - Review',

packages/core/src/codewhisperer/models/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ If you'd like to update and test your code with fewer changes at a time, I can d
515515

516516
export const uploadingCodeStepMessage = 'Upload your code'
517517

518-
export const buildCodeStepMessage = 'Build uploaded code in secure build environment'
518+
export const buildCodeStepMessage = 'Analyze uploaded code in secure environment'
519519

520520
export const generatePlanStepMessage = 'Generate transformation plan'
521521

@@ -734,7 +734,7 @@ export const cleanTestCompileErrorNotification = `Amazon Q could not run \`mvn c
734734
export const enterJavaHomeChatMessage = 'Enter the path to JDK'
735735

736736
export const projectPromptChatMessage =
737-
"I can upgrade your Java project. To start the transformation, I need some information from you. Choose the project you want to upgrade and the target code version to upgrade to. Then, choose Confirm.\n\nAfter successfully transforming to Java 17 or 21, an additional transformation is required to upgrade your libraries and dependencies. Choose the same source code version and target code version (for example, 17 to 17) to do this.\n\nI will perform the transformation based on your project's requests, descriptions, and content. To maintain security, avoid including external, unvetted artifacts in your project repository prior to starting the transformation and always validate transformed code for both functionality and security."
737+
"I can upgrade your Java project. To start the transformation, I need some information from you. Choose the project you want to upgrade and the target code version to upgrade to. Then, choose Confirm.\n\nAfter successfully transforming to Java 17 or 21, an additional transformation is required to upgrade your libraries and dependencies. Choose the same source code version and target code version (for example, 17 to 17) to do this.\n\nI will perform the transformation based on your project's requests, descriptions, and content. To maintain security, avoid including external, unvetted artifacts in your project repository prior to starting the transformation and always validate transformed code for both functionality and security. Do not turn off or close your machine during the transformation because a stable network connection is required."
738738

739739
export const windowsJavaHomeHelpChatMessage =
740740
'To find the JDK path, run the following commands in a new terminal: `cd "C:/Program Files/Java"` and then `dir`. If you see your JDK version, run `cd <version>` and then `cd` to show the path.'

packages/core/src/codewhisperer/models/model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ export class ZipManifest {
680680
dependenciesRoot: string = 'dependencies/'
681681
version: string = '1.0'
682682
hilCapabilities: string[] = ['HIL_1pDependency_VersionUpgrade']
683-
transformCapabilities: string[] = ['EXPLAINABILITY_V1', 'SELECTIVE_TRANSFORMATION_V2', 'CLIENT_SIDE_BUILD']
683+
transformCapabilities: string[] = ['EXPLAINABILITY_V1', 'SELECTIVE_TRANSFORMATION_V2', 'CLIENT_SIDE_BUILD', 'IDE']
684684
noInteractiveMode: boolean = true
685685
dependencyUpgradeConfigFile?: string = undefined
686686
compilationsJsonFile: string = 'compilations.json'

packages/core/src/login/webview/commonAuthViewProvider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ export class CommonAuthViewProvider implements WebviewViewProvider {
148148
const entrypoint =
149149
serverHostname !== undefined ? Uri.parse(serverHostname).with({ path: `/${this.source}` }) : scriptUri
150150

151+
// Get Vue.js from dist/libs directory
152+
const vueUri = Uri.joinPath(assetsPath, 'dist', 'libs', 'vue.min.js')
153+
const vueScript = webview.asWebviewUri(vueUri)
154+
151155
return `
152156
<!DOCTYPE html>
153157
<html lang="en">
@@ -158,7 +162,7 @@ export class CommonAuthViewProvider implements WebviewViewProvider {
158162
<title>Base View Extension</title>
159163
</head>
160164
<body>
161-
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.4/vue.global.prod.min.js"></script>
165+
<script src="${vueScript.toString()}"></script>
162166
<script>
163167
const vscode = acquireVsCodeApi();
164168
</script>

0 commit comments

Comments
 (0)