@aws/lsp-codewhisperer 0.0.52 → 0.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/out/language-server/agenticChat/agenticChatController.js +29 -14
  3. package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
  4. package/out/language-server/agenticChat/context/agenticChatTriggerContext.d.ts +31 -2
  5. package/out/language-server/agenticChat/context/agenticChatTriggerContext.js +88 -4
  6. package/out/language-server/agenticChat/context/agenticChatTriggerContext.js.map +1 -1
  7. package/out/language-server/agenticChat/tools/fsReplace.d.ts +60 -0
  8. package/out/language-server/agenticChat/tools/fsReplace.js +131 -0
  9. package/out/language-server/agenticChat/tools/fsReplace.js.map +1 -0
  10. package/out/language-server/agenticChat/tools/fsWrite.d.ts +5 -29
  11. package/out/language-server/agenticChat/tools/fsWrite.js +18 -105
  12. package/out/language-server/agenticChat/tools/fsWrite.js.map +1 -1
  13. package/out/language-server/agenticChat/tools/grepSearch.d.ts +2 -2
  14. package/out/language-server/agenticChat/tools/grepSearch.js +2 -2
  15. package/out/language-server/agenticChat/tools/grepSearch.js.map +1 -1
  16. package/out/language-server/agenticChat/tools/mcp/mcpManager.js +12 -2
  17. package/out/language-server/agenticChat/tools/mcp/mcpManager.js.map +1 -1
  18. package/out/language-server/agenticChat/tools/toolServer.js +6 -0
  19. package/out/language-server/agenticChat/tools/toolServer.js.map +1 -1
  20. package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.js +8 -3
  21. package/out/shared/amazonQServiceManager/AmazonQTokenServiceManager.js.map +1 -1
  22. package/out/shared/codeWhispererService.js +3 -0
  23. package/out/shared/codeWhispererService.js.map +1 -1
  24. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.54](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.53...lsp-codewhisperer/v0.0.54) (2025-06-19)
4
+
5
+
6
+ ### Features
7
+
8
+ * adding current working directory to the stdio transport for mcp… ([#1691](https://github.com/aws/language-servers/issues/1691)) ([02c4d64](https://github.com/aws/language-servers/commit/02c4d645a8c2778deab7af9f5377c26e99d01f20))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * add fsReplace tool to batch edits ([#1533](https://github.com/aws/language-servers/issues/1533)) ([4125134](https://github.com/aws/language-servers/commit/4125134f6e7eee8276d6146a507834b3309c2ec5))
14
+ * **amazonq:** itemid was accidentally removed by [#1689](https://github.com/aws/language-servers/issues/1689) ([#1698](https://github.com/aws/language-servers/issues/1698)) ([33524c0](https://github.com/aws/language-servers/commit/33524c092af8088705a3cbae09c6249ad5940ce6))
15
+ * **amazonq:** profile is not set after re-auth ([#1690](https://github.com/aws/language-servers/issues/1690)) ([2a445ee](https://github.com/aws/language-servers/commit/2a445eef4cc2a70471fd1fc49e6ca4e301051442))
16
+ * diff reports no lines added or removed ([#1549](https://github.com/aws/language-servers/issues/1549)) ([562f13e](https://github.com/aws/language-servers/commit/562f13e0223a8a01fefc9ca449aad02da9734709))
17
+ * thinking doesn't get removed if response is empty ([#1699](https://github.com/aws/language-servers/issues/1699)) ([9a63c99](https://github.com/aws/language-servers/commit/9a63c99b3195c9da0f537980324998138f25a3fa))
18
+
19
+
20
+ ### Reverts
21
+
22
+ * **amazonq:** bring back [#1684](https://github.com/aws/language-servers/issues/1684) ([#1697](https://github.com/aws/language-servers/issues/1697)) ([5e7aa76](https://github.com/aws/language-servers/commit/5e7aa76b6ebcf8e0a7489d3574cc14ed3d0ceebe))
23
+ * **amazonq:** bring back [#1689](https://github.com/aws/language-servers/issues/1689) ([5b84b0e](https://github.com/aws/language-servers/commit/5b84b0e4c42c344d91ef9c99a04d3a2671221aa1))
24
+
25
+ ## [0.0.53](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.52...lsp-codewhisperer/v0.0.53) (2025-06-18)
26
+
27
+
28
+ ### Reverts
29
+
30
+ * **amazonq:** fix filter languages at workspace context server onDeleteFiles ([403c26a](https://github.com/aws/language-servers/commit/403c26a91f25d0035d92bfd21835b747a0dbafce))
31
+ * **amazonq:** nep cherrypick codewhispererService.ts ([#1689](https://github.com/aws/language-servers/issues/1689))" ([#1692](https://github.com/aws/language-servers/issues/1692)) ([69f1071](https://github.com/aws/language-servers/commit/69f10717c2eff8d4479ffa8a18220e15c03f865d))
32
+
3
33
  ## [0.0.52](https://github.com/aws/language-servers/compare/lsp-codewhisperer/v0.0.51...lsp-codewhisperer/v0.0.52) (2025-06-17)
4
34
 
5
35
 
@@ -40,6 +40,7 @@ const executeBash_1 = require("./tools/executeBash");
40
40
  const toolShared_1 = require("./tools/toolShared");
41
41
  const grepSearch_1 = require("./tools/grepSearch");
42
42
  const fileSearch_1 = require("./tools/fileSearch");
43
+ const fsReplace_1 = require("./tools/fsReplace");
43
44
  const lsp_core_2 = require("@aws/lsp-core");
44
45
  const diff_1 = require("diff");
45
46
  const constants_2 = require("./constants");
@@ -718,11 +719,11 @@ class AgenticChatController {
718
719
  // remove progress UI
719
720
  await chatResultStream.removeResultBlockAndUpdateUI(agenticChatResultStream_1.progressPrefix + toolUse.toolUseId);
720
721
  // fsRead and listDirectory write to an existing card and could show nothing in the current position
721
- if (!['fsWrite', 'fsRead', 'listDirectory'].includes(toolUse.name)) {
722
+ if (!['fsWrite', 'fsReplace', 'fsRead', 'listDirectory'].includes(toolUse.name)) {
722
723
  await this.#showUndoAllIfRequired(chatResultStream, session);
723
724
  }
724
725
  // fsWrite can take a long time, so we render fsWrite Explanatory upon partial streaming responses.
725
- if (toolUse.name !== 'fsWrite') {
726
+ if (toolUse.name !== 'fsWrite' && toolUse.name !== 'fsReplace') {
726
727
  const { explanation } = toolUse.input;
727
728
  if (explanation) {
728
729
  await chatResultStream.writeResultBlock({
@@ -738,11 +739,13 @@ class AgenticChatController {
738
739
  case 'grepSearch':
739
740
  case 'fileSearch':
740
741
  case 'fsWrite':
742
+ case 'fsReplace':
741
743
  case 'executeBash': {
742
744
  const toolMap = {
743
745
  fsRead: { Tool: fsRead_1.FsRead },
744
746
  listDirectory: { Tool: listDirectory_1.ListDirectory },
745
747
  fsWrite: { Tool: fsWrite_1.FsWrite },
748
+ fsReplace: { Tool: fsReplace_1.FsReplace },
746
749
  executeBash: { Tool: executeBash_1.ExecuteBash },
747
750
  grepSearch: { Tool: grepSearch_1.GrepSearch },
748
751
  fileSearch: { Tool: fileSearch_1.FileSearch },
@@ -776,9 +779,6 @@ class AgenticChatController {
776
779
  }
777
780
  break;
778
781
  }
779
- case 'codeSearch':
780
- // no need to write tool message for code search.
781
- break;
782
782
  // — DEFAULT ⇒ Only MCP tools, but can also handle generic tool execution messages
783
783
  default:
784
784
  // Get original server and tool names from the mapping
@@ -811,9 +811,9 @@ class AgenticChatController {
811
811
  }
812
812
  break;
813
813
  }
814
- if (toolUse.name === 'fsWrite') {
814
+ if (toolUse.name === 'fsWrite' || toolUse.name === 'fsReplace') {
815
815
  const input = toolUse.input;
816
- const document = await this.#triggerContext.getTextDocument(input.path);
816
+ const document = await this.#triggerContext.getTextDocumentFromPath(input.path, true, true);
817
817
  session.toolUseLookup.set(toolUse.toolUseId, {
818
818
  ...toolUse,
819
819
  fileChange: { before: document?.getText() },
@@ -864,9 +864,16 @@ class AgenticChatController {
864
864
  await chatResultStream.writeResultBlock(grepSearchResult);
865
865
  }
866
866
  break;
867
+ case 'fsReplace':
867
868
  case 'fsWrite':
868
869
  const input = toolUse.input;
869
- const doc = await this.#triggerContext.getTextDocument(input.path);
870
+ // Load from the filesystem instead of workspace.
871
+ // Workspace is likely out of date - when files
872
+ // are modified external to the IDE, many IDEs
873
+ // will only update their file contents (which
874
+ // then propagates to the LSP) if/when that
875
+ // document receives focus.
876
+ const doc = await this.#triggerContext.getTextDocumentFromPath(input.path, false, true);
870
877
  const chatResult = await this.#getFsWriteChatResult(toolUse, doc, session);
871
878
  const cachedToolUse = session.toolUseLookup.get(toolUse.toolUseId);
872
879
  if (cachedToolUse) {
@@ -934,7 +941,7 @@ class AgenticChatController {
934
941
  }
935
942
  }
936
943
  // display fs write failure status in the UX of that file card
937
- if (toolUse.name === 'fsWrite' && toolUse.toolUseId) {
944
+ if ((toolUse.name === 'fsWrite' || toolUse.name === 'fsReplace') && toolUse.toolUseId) {
938
945
  const existingCard = chatResultStream.getMessageBlockId(toolUse.toolUseId);
939
946
  const fsParam = toolUse.input;
940
947
  const fileName = path.basename(fsParam.path);
@@ -1025,7 +1032,7 @@ class AgenticChatController {
1025
1032
  if (toolUse.name === 'fsRead' || toolUse.name === 'listDirectory') {
1026
1033
  return;
1027
1034
  }
1028
- if (toolUse.name === 'fsWrite') {
1035
+ if (toolUse.name === 'fsWrite' || toolUse.name === 'fsReplace') {
1029
1036
  if (session.currentUndoAllId === undefined) {
1030
1037
  session.currentUndoAllId = toolUse.toolUseId;
1031
1038
  }
@@ -1203,6 +1210,7 @@ class AgenticChatController {
1203
1210
  let header;
1204
1211
  let body;
1205
1212
  switch (toolName) {
1213
+ case 'fsReplace':
1206
1214
  case 'fsWrite':
1207
1215
  case 'fsRead':
1208
1216
  case 'listDirectory':
@@ -1336,6 +1344,7 @@ class AgenticChatController {
1336
1344
  body = '```shell\n' + commandString;
1337
1345
  break;
1338
1346
  }
1347
+ case 'fsReplace':
1339
1348
  case 'fsWrite': {
1340
1349
  const writeFilePath = toolUse.input.path;
1341
1350
  buttons = [{ id: 'allow-tools', text: 'Allow', icon: 'ok', status: 'clear' }];
@@ -1890,7 +1899,7 @@ class AgenticChatController {
1890
1899
  const session = this.#chatSessionManagementService.getSession(params.tabId);
1891
1900
  const toolUseId = params.messageId;
1892
1901
  const toolUse = toolUseId ? session.data?.toolUseLookup.get(toolUseId) : undefined;
1893
- if (toolUse?.name === 'fsWrite') {
1902
+ if (toolUse?.name === 'fsWrite' || toolUse?.name === 'fsReplace') {
1894
1903
  const input = toolUse.input;
1895
1904
  this.#features.lsp.workspace.openFileDiff({
1896
1905
  originalFileUri: input.path,
@@ -2355,7 +2364,7 @@ class AgenticChatController {
2355
2364
  }
2356
2365
  const toolUses = Object.values(data.toolUses);
2357
2366
  for (const toolUse of toolUses) {
2358
- if (toolUse.name === 'fsWrite' && typeof toolUse.input === 'string') {
2367
+ if ((toolUse.name === 'fsWrite' || toolUse.name === 'fsReplace') && typeof toolUse.input === 'string') {
2359
2368
  const filepath = extractKey(toolUse.input, 'path');
2360
2369
  const msgId = agenticChatResultStream_1.progressPrefix + toolUse.toolUseId;
2361
2370
  // render fs write UI as soon as fs write starts
@@ -2382,7 +2391,7 @@ class AgenticChatController {
2382
2391
  },
2383
2392
  });
2384
2393
  }
2385
- // render the tool use explanatory as soon as this is received for fsWrite
2394
+ // render the tool use explanatory as soon as this is received for fsWrite/fsReplace
2386
2395
  const explanation = extractKey(toolUse.input, 'explanation');
2387
2396
  const messageId = agenticChatResultStream_1.progressPrefix + toolUse.toolUseId + '_explanation';
2388
2397
  if (explanation && !chatResultStream.hasMessage(messageId)) {
@@ -2407,7 +2416,9 @@ class AgenticChatController {
2407
2416
  }
2408
2417
  const toolUseStartTimes = {};
2409
2418
  const toolUseLoadingTimeouts = {};
2419
+ let isEmptyResponse = true;
2410
2420
  for await (const chatEvent of response.generateAssistantResponseResponse) {
2421
+ isEmptyResponse = false;
2411
2422
  if (abortSignal?.aborted) {
2412
2423
  throw new Error('Operation was aborted');
2413
2424
  }
@@ -2433,6 +2444,10 @@ class AgenticChatController {
2433
2444
  await this.#showToolUseIntermediateResult(result.data, chatResultStream, streamWriter);
2434
2445
  }
2435
2446
  }
2447
+ if (isEmptyResponse) {
2448
+ // If the response is empty, we need to send an empty answer message to remove the Thinking... indicator
2449
+ await streamWriter.write({ type: 'answer', body: '', messageId: (0, uuid_1.v4)() });
2450
+ }
2436
2451
  await streamWriter.close();
2437
2452
  metric.mergeWith({
2438
2453
  cwsprChatFullResponseLatency: metric.getTimeElapsed(),
@@ -2538,7 +2553,7 @@ class AgenticChatController {
2538
2553
  const allTools = this.#features.agent.getTools({ format: 'bedrock' });
2539
2554
  if (!(0, mcpUtils_1.enabledMCP)(this.#features.lsp.getClientInitializeParams())) {
2540
2555
  if (!session.pairProgrammingMode) {
2541
- return allTools.filter(tool => !['fsWrite', 'executeBash'].includes(tool.toolSpecification?.name || ''));
2556
+ return allTools.filter(tool => !['fsWrite', 'fsReplace', 'executeBash'].includes(tool.toolSpecification?.name || ''));
2542
2557
  }
2543
2558
  return allTools;
2544
2559
  }