diff --git a/package-lock.json b/package-lock.json index 49aac312dde..cec9cd2e05a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11966,9 +11966,10 @@ } }, "node_modules/@aws/mynah-ui": { - "version": "4.25.1", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.26.0.tgz", + "integrity": "sha512-hMdEKX07FO84XFFE+DzW+AJDbozLRU62cWofzZGsSAyrJIRTQlKfoo7ws3rECRqcgYIHtmyif/91ex7vo11byA==", "hasInstallScript": true, - "license": "Apache License 2.0", "dependencies": { "escape-html": "^1.0.3", "highlight.js": "^11.11.0", @@ -26733,7 +26734,7 @@ "@aws-sdk/s3-request-presigner": "<3.696.0", "@aws-sdk/smithy-client": "<3.696.0", "@aws-sdk/util-arn-parser": "<3.696.0", - "@aws/mynah-ui": "^4.25.1", + "@aws/mynah-ui": "^4.26.0", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", "@smithy/fetch-http-handler": "^3.0.0", diff --git a/packages/amazonq/.changes/next-release/Feature-5f829ea1-e33b-4687-bc6d-76ed1558cd7e.json b/packages/amazonq/.changes/next-release/Feature-5f829ea1-e33b-4687-bc6d-76ed1558cd7e.json new file mode 100644 index 00000000000..52370b566ce --- /dev/null +++ b/packages/amazonq/.changes/next-release/Feature-5f829ea1-e33b-4687-bc6d-76ed1558cd7e.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Add support for Code search in Q chat" +} diff --git a/packages/amazonq/test/unit/codewhispererChat/controllers/chat/chatRequest/converter.test.ts b/packages/amazonq/test/unit/codewhispererChat/controllers/chat/chatRequest/converter.test.ts index d18b916229f..ea0c7889426 100644 --- a/packages/amazonq/test/unit/codewhispererChat/controllers/chat/chatRequest/converter.test.ts +++ b/packages/amazonq/test/unit/codewhispererChat/controllers/chat/chatRequest/converter.test.ts @@ -58,6 +58,8 @@ describe('triggerPayloadToChatRequest', () => { relativePath: 'path-prompt', type: 'prompt', innerContext: createLargeString(size, 'prompt-'), + startLine: 0, + endLine: 100, } } @@ -68,6 +70,8 @@ describe('triggerPayloadToChatRequest', () => { relativePath: 'path-rule', type: 'rule', innerContext: createLargeString(size, 'rule-'), + startLine: 0, + endLine: 100, } } @@ -78,6 +82,8 @@ describe('triggerPayloadToChatRequest', () => { relativePath: 'path-file', type: 'file', innerContext: createLargeString(size, 'file-'), + startLine: 0, + endLine: 100, } } @@ -116,13 +122,23 @@ describe('triggerPayloadToChatRequest', () => { const payloadWithEmptyContents: TriggerPayload = { ...mockBasicPayload, additionalContents: [ - { name: 'prompt1', description: 'prompt1', relativePath: 'path1', type: 'prompt', innerContext: '' }, + { + name: 'prompt1', + description: 'prompt1', + relativePath: 'path1', + type: 'prompt', + innerContext: '', + startLine: 0, + endLine: 100, + }, { name: 'prompt2', description: 'prompt2', relativePath: 'path2', type: 'prompt', innerContext: 'valid content', + startLine: 0, + endLine: 100, }, ], } diff --git a/packages/core/package.json b/packages/core/package.json index 325f3256800..288d95fb8a6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -522,7 +522,7 @@ "@aws-sdk/s3-request-presigner": "<3.696.0", "@aws-sdk/smithy-client": "<3.696.0", "@aws-sdk/util-arn-parser": "<3.696.0", - "@aws/mynah-ui": "^4.25.1", + "@aws/mynah-ui": "^4.26.0", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", "@smithy/fetch-http-handler": "^3.0.0", diff --git a/packages/core/package.nls.json b/packages/core/package.nls.json index 63b623d24a9..22d2ce3fc3b 100644 --- a/packages/core/package.nls.json +++ b/packages/core/package.nls.json @@ -330,6 +330,8 @@ "AWS.amazonq.context.files.description": "Add a file to context", "AWS.amazonq.context.prompts.title": "Prompts", "AWS.amazonq.context.prompts.description": "Add a saved prompt to context", + "AWS.amazonq.context.code.title": "Code", + "AWS.amazonq.context.code.description": "Add code to context", "AWS.amazonq.savedPrompts.title": "Prompt name", "AWS.amazonq.savedPrompts.create": "Create", "AWS.amazonq.savedPrompts.action": "Create a new prompt", diff --git a/packages/core/src/amazonq/lsp/config.ts b/packages/core/src/amazonq/lsp/config.ts index 8557d3cff63..6731c8a4bb4 100644 --- a/packages/core/src/amazonq/lsp/config.ts +++ b/packages/core/src/amazonq/lsp/config.ts @@ -15,7 +15,7 @@ export interface LspConfig { export const defaultAmazonQWorkspaceLspConfig: LspConfig = { manifestUrl: 'https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json', - supportedVersions: '0.1.42', + supportedVersions: '0.1.46', id: 'AmazonQ-Workspace', // used for identification in global storage/local disk location. Do not change. path: undefined, } diff --git a/packages/core/src/amazonq/lsp/lspClient.ts b/packages/core/src/amazonq/lsp/lspClient.ts index e895f0fa8c7..6b62208fe38 100644 --- a/packages/core/src/amazonq/lsp/lspClient.ts +++ b/packages/core/src/amazonq/lsp/lspClient.ts @@ -122,7 +122,7 @@ export class LspClient { } } - async updateIndex(filePath: string[], mode: 'update' | 'remove' | 'add') { + async updateIndex(filePath: string[], mode: 'update' | 'remove' | 'add' | 'context_command_symbol_update') { const payload: UpdateIndexV2RequestPayload = { filePaths: filePath, updateMode: mode, diff --git a/packages/core/src/amazonq/lsp/lspController.ts b/packages/core/src/amazonq/lsp/lspController.ts index a789d1dd5cb..f20a415b305 100644 --- a/packages/core/src/amazonq/lsp/lspController.ts +++ b/packages/core/src/amazonq/lsp/lspController.ts @@ -15,6 +15,7 @@ import { isAmazonInternalOs } from '../../shared/vscode/env' import { WorkspaceLspInstaller } from './workspaceInstaller' import { lspSetupStage } from '../../shared/lsp/utils/setupStage' import { RelevantTextDocumentAddition } from '../../codewhispererChat/controllers/chat/model' +import { waitUntil } from '../../shared/utilities/timeoutUtils' export interface Chunk { readonly filePath: string @@ -45,6 +46,7 @@ export interface BuildIndexConfig { export class LspController { static #instance: LspController private _isIndexingInProgress = false + private _contextCommandSymbolsUpdated = false private logger = getLogger('amazonqWorkspaceLsp') public static get instance() { @@ -192,6 +194,38 @@ export class LspController { } }) } + /** + * Updates context command symbols once per session by synchronizing with the LSP client index. + * Context menu will contain file and folders to begin with, + * then this asynchronous function should be invoked after the files and folders are found + * the LSP then further starts to parse workspace and find symbols, which takes + * anywhere from 5 seconds to about 40 seconds, depending on project size. + * @returns {Promise} + */ + async updateContextCommandSymbolsOnce() { + if (this._contextCommandSymbolsUpdated) { + return + } + this._contextCommandSymbolsUpdated = true + getLogger().debug(`LspController: Start adding symbols to context picker menu`) + try { + const indexSeqNum = await LspClient.instance.getIndexSequenceNumber() + await LspClient.instance.updateIndex([], 'context_command_symbol_update') + await waitUntil( + async () => { + const newIndexSeqNum = await LspClient.instance.getIndexSequenceNumber() + if (newIndexSeqNum > indexSeqNum) { + await vscode.commands.executeCommand(`aws.amazonq.updateContextCommandItems`) + return true + } + return false + }, + { interval: 1000, timeout: 60_000, truthy: true } + ) + } catch (err) { + getLogger().error(`LspController: Failed to find symbols`) + } + } private async setupLsp(context: vscode.ExtensionContext) { await lspSetupStage('all', async () => { diff --git a/packages/core/src/amazonq/lsp/types.ts b/packages/core/src/amazonq/lsp/types.ts index 1da8dfb00de..2940ce240c8 100644 --- a/packages/core/src/amazonq/lsp/types.ts +++ b/packages/core/src/amazonq/lsp/types.ts @@ -88,12 +88,44 @@ export const GetIndexSequenceNumberRequestType: RequestType