@aws/lsp-codewhisperer 0.0.4 → 0.0.5

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 (159) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/out/client/sigv4/service.json +1 -1
  3. package/out/client/token/bearer-token-service.json +1 -1
  4. package/out/index.d.ts +1 -0
  5. package/out/index.js +1 -0
  6. package/out/index.js.map +1 -1
  7. package/out/language-server/chat/chatController.d.ts +25 -0
  8. package/out/language-server/chat/chatController.js +117 -0
  9. package/out/language-server/chat/chatController.js.map +1 -0
  10. package/out/language-server/chat/chatController.test.d.ts +1 -0
  11. package/out/language-server/chat/chatController.test.js +240 -0
  12. package/out/language-server/chat/chatController.test.js.map +1 -0
  13. package/out/language-server/chat/chatEventParser.d.ts +24 -0
  14. package/out/language-server/chat/chatEventParser.js +84 -0
  15. package/out/language-server/chat/chatEventParser.js.map +1 -0
  16. package/out/language-server/chat/chatEventParser.test.d.ts +1 -0
  17. package/out/language-server/chat/chatEventParser.test.js +189 -0
  18. package/out/language-server/chat/chatEventParser.test.js.map +1 -0
  19. package/out/language-server/chat/chatSessionManagementService.d.ts +16 -0
  20. package/out/language-server/chat/chatSessionManagementService.js +92 -0
  21. package/out/language-server/chat/chatSessionManagementService.js.map +1 -0
  22. package/out/language-server/chat/chatSessionManagementService.test.d.ts +1 -0
  23. package/out/language-server/chat/chatSessionManagementService.test.js +73 -0
  24. package/out/language-server/chat/chatSessionManagementService.test.js.map +1 -0
  25. package/out/language-server/chat/chatSessionService.d.ts +13 -0
  26. package/out/language-server/chat/chatSessionService.js +63 -0
  27. package/out/language-server/chat/chatSessionService.js.map +1 -0
  28. package/out/language-server/chat/chatSessionService.test.d.ts +1 -0
  29. package/out/language-server/chat/chatSessionService.test.js +80 -0
  30. package/out/language-server/chat/chatSessionService.test.js.map +1 -0
  31. package/out/language-server/chat/contexts/documentContext.d.ts +17 -0
  32. package/out/language-server/chat/contexts/documentContext.js +59 -0
  33. package/out/language-server/chat/contexts/documentContext.js.map +1 -0
  34. package/out/language-server/chat/contexts/documentContext.test.d.ts +1 -0
  35. package/out/language-server/chat/contexts/documentContext.test.js +147 -0
  36. package/out/language-server/chat/contexts/documentContext.test.js.map +1 -0
  37. package/out/language-server/chat/contexts/utils.d.ts +10 -0
  38. package/out/language-server/chat/contexts/utils.js +71 -0
  39. package/out/language-server/chat/contexts/utils.js.map +1 -0
  40. package/out/language-server/chat/contexts/utils.test.d.ts +1 -0
  41. package/out/language-server/chat/contexts/utils.test.js +72 -0
  42. package/out/language-server/chat/contexts/utils.test.js.map +1 -0
  43. package/out/language-server/chat/utils.d.ts +4 -0
  44. package/out/language-server/chat/utils.js +34 -0
  45. package/out/language-server/chat/utils.js.map +1 -0
  46. package/out/language-server/codeWhispererSecurityScanServer.d.ts +1 -1
  47. package/out/language-server/codeWhispererSecurityScanServer.js +41 -26
  48. package/out/language-server/codeWhispererSecurityScanServer.js.map +1 -1
  49. package/out/language-server/codeWhispererServer.js +1 -1
  50. package/out/language-server/codeWhispererServer.js.map +1 -1
  51. package/out/language-server/languageDetection.d.ts +9 -2
  52. package/out/language-server/languageDetection.js +84 -20
  53. package/out/language-server/languageDetection.js.map +1 -1
  54. package/out/language-server/languageDetection.test.d.ts +1 -0
  55. package/out/language-server/languageDetection.test.js +31 -0
  56. package/out/language-server/languageDetection.test.js.map +1 -0
  57. package/out/language-server/proxy-server.d.ts +1 -0
  58. package/out/language-server/proxy-server.js +35 -1
  59. package/out/language-server/proxy-server.js.map +1 -1
  60. package/out/language-server/qChatServer.d.ts +3 -0
  61. package/out/language-server/qChatServer.js +31 -0
  62. package/out/language-server/qChatServer.js.map +1 -0
  63. package/out/language-server/qChatServer.test.d.ts +1 -0
  64. package/out/language-server/qChatServer.test.js +51 -0
  65. package/out/language-server/qChatServer.test.js.map +1 -0
  66. package/out/language-server/securityScan/securityScanDiagnosticsProvider.d.ts +2 -3
  67. package/out/language-server/securityScan/securityScanDiagnosticsProvider.js +5 -23
  68. package/out/language-server/securityScan/securityScanDiagnosticsProvider.js.map +1 -1
  69. package/out/language-server/securityScan/types.d.ts +8 -6
  70. package/out/language-server/testUtils.d.ts +1 -0
  71. package/out/language-server/testUtils.js +17 -1
  72. package/out/language-server/testUtils.js.map +1 -1
  73. package/out/language-server/types.d.ts +13 -0
  74. package/out/language-server/types.js +3 -0
  75. package/out/language-server/types.js.map +1 -0
  76. package/out/language-server/utils.d.ts +3 -0
  77. package/out/language-server/utils.js +19 -1
  78. package/out/language-server/utils.js.map +1 -1
  79. package/out/language-server/utils.test.d.ts +1 -0
  80. package/out/language-server/utils.test.js +33 -0
  81. package/out/language-server/utils.test.js.map +1 -0
  82. package/package.json +13 -4
  83. package/src.gen/@amzn/codewhisperer-streaming/LICENSE +201 -0
  84. package/src.gen/@amzn/codewhisperer-streaming/README.md +464 -0
  85. package/src.gen/@amzn/codewhisperer-streaming/api-extractor.json +4 -0
  86. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/CodeWhispererStreaming.js +17 -0
  87. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/CodeWhispererStreamingClient.js +42 -0
  88. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/commands/ExportResultArchiveCommand.js +42 -0
  89. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/commands/GenerateAssistantResponseCommand.js +42 -0
  90. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/commands/GenerateTaskAssistPlanCommand.js +42 -0
  91. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/commands/index.js +6 -0
  92. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/endpoints.js +165 -0
  93. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/extensionConfiguration.js +2 -0
  94. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/index.js +10 -0
  95. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/models/CodeWhispererStreamingServiceException.js +12 -0
  96. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/models/index.js +4 -0
  97. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/models/models_0.js +361 -0
  98. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/protocols/Aws_restJson1.js +458 -0
  99. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/runtimeConfig.browser.js +38 -0
  100. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/runtimeConfig.js +46 -0
  101. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/runtimeConfig.native.js +15 -0
  102. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/runtimeConfig.shared.js +22 -0
  103. package/src.gen/@amzn/codewhisperer-streaming/dist-cjs/runtimeExtensions.js +22 -0
  104. package/src.gen/@amzn/codewhisperer-streaming/dist-es/CodeWhispererStreaming.js +13 -0
  105. package/src.gen/@amzn/codewhisperer-streaming/dist-es/CodeWhispererStreamingClient.js +38 -0
  106. package/src.gen/@amzn/codewhisperer-streaming/dist-es/commands/ExportResultArchiveCommand.js +38 -0
  107. package/src.gen/@amzn/codewhisperer-streaming/dist-es/commands/GenerateAssistantResponseCommand.js +38 -0
  108. package/src.gen/@amzn/codewhisperer-streaming/dist-es/commands/GenerateTaskAssistPlanCommand.js +38 -0
  109. package/src.gen/@amzn/codewhisperer-streaming/dist-es/commands/index.js +3 -0
  110. package/src.gen/@amzn/codewhisperer-streaming/dist-es/endpoints.js +161 -0
  111. package/src.gen/@amzn/codewhisperer-streaming/dist-es/extensionConfiguration.js +1 -0
  112. package/src.gen/@amzn/codewhisperer-streaming/dist-es/index.js +5 -0
  113. package/src.gen/@amzn/codewhisperer-streaming/dist-es/models/CodeWhispererStreamingServiceException.js +8 -0
  114. package/src.gen/@amzn/codewhisperer-streaming/dist-es/models/index.js +1 -0
  115. package/src.gen/@amzn/codewhisperer-streaming/dist-es/models/models_0.js +328 -0
  116. package/src.gen/@amzn/codewhisperer-streaming/dist-es/protocols/Aws_restJson1.js +449 -0
  117. package/src.gen/@amzn/codewhisperer-streaming/dist-es/runtimeConfig.browser.js +33 -0
  118. package/src.gen/@amzn/codewhisperer-streaming/dist-es/runtimeConfig.js +41 -0
  119. package/src.gen/@amzn/codewhisperer-streaming/dist-es/runtimeConfig.native.js +11 -0
  120. package/src.gen/@amzn/codewhisperer-streaming/dist-es/runtimeConfig.shared.js +18 -0
  121. package/src.gen/@amzn/codewhisperer-streaming/dist-es/runtimeExtensions.js +18 -0
  122. package/src.gen/@amzn/codewhisperer-streaming/dist-types/CodeWhispererStreaming.d.ts +30 -0
  123. package/src.gen/@amzn/codewhisperer-streaming/dist-types/CodeWhispererStreamingClient.d.ts +169 -0
  124. package/src.gen/@amzn/codewhisperer-streaming/dist-types/commands/ExportResultArchiveCommand.d.ts +103 -0
  125. package/src.gen/@amzn/codewhisperer-streaming/dist-types/commands/GenerateAssistantResponseCommand.d.ts +294 -0
  126. package/src.gen/@amzn/codewhisperer-streaming/dist-types/commands/GenerateTaskAssistPlanCommand.d.ts +304 -0
  127. package/src.gen/@amzn/codewhisperer-streaming/dist-types/commands/index.d.ts +3 -0
  128. package/src.gen/@amzn/codewhisperer-streaming/dist-types/endpoints.d.ts +2 -0
  129. package/src.gen/@amzn/codewhisperer-streaming/dist-types/extensionConfiguration.d.ts +8 -0
  130. package/src.gen/@amzn/codewhisperer-streaming/dist-types/index.d.ts +5 -0
  131. package/src.gen/@amzn/codewhisperer-streaming/dist-types/models/CodeWhispererStreamingServiceException.d.ts +13 -0
  132. package/src.gen/@amzn/codewhisperer-streaming/dist-types/models/index.d.ts +1 -0
  133. package/src.gen/@amzn/codewhisperer-streaming/dist-types/models/models_0.d.ts +1173 -0
  134. package/src.gen/@amzn/codewhisperer-streaming/dist-types/protocols/Aws_restJson1.d.ts +29 -0
  135. package/src.gen/@amzn/codewhisperer-streaming/dist-types/runtimeConfig.browser.d.ts +39 -0
  136. package/src.gen/@amzn/codewhisperer-streaming/dist-types/runtimeConfig.d.ts +39 -0
  137. package/src.gen/@amzn/codewhisperer-streaming/dist-types/runtimeConfig.native.d.ts +38 -0
  138. package/src.gen/@amzn/codewhisperer-streaming/dist-types/runtimeConfig.shared.d.ts +17 -0
  139. package/src.gen/@amzn/codewhisperer-streaming/dist-types/runtimeExtensions.d.ts +17 -0
  140. package/src.gen/@amzn/codewhisperer-streaming/package.json +87 -0
  141. package/src.gen/@amzn/codewhisperer-streaming/src/CodeWhispererStreaming.ts +84 -0
  142. package/src.gen/@amzn/codewhisperer-streaming/src/CodeWhispererStreamingClient.ts +304 -0
  143. package/src.gen/@amzn/codewhisperer-streaming/src/commands/ExportResultArchiveCommand.ts +177 -0
  144. package/src.gen/@amzn/codewhisperer-streaming/src/commands/GenerateAssistantResponseCommand.ts +369 -0
  145. package/src.gen/@amzn/codewhisperer-streaming/src/commands/GenerateTaskAssistPlanCommand.ts +379 -0
  146. package/src.gen/@amzn/codewhisperer-streaming/src/commands/index.ts +4 -0
  147. package/src.gen/@amzn/codewhisperer-streaming/src/endpoints.ts +170 -0
  148. package/src.gen/@amzn/codewhisperer-streaming/src/extensionConfiguration.ts +12 -0
  149. package/src.gen/@amzn/codewhisperer-streaming/src/index.ts +8 -0
  150. package/src.gen/@amzn/codewhisperer-streaming/src/models/CodeWhispererStreamingServiceException.ts +22 -0
  151. package/src.gen/@amzn/codewhisperer-streaming/src/models/index.ts +2 -0
  152. package/src.gen/@amzn/codewhisperer-streaming/src/models/models_0.ts +1518 -0
  153. package/src.gen/@amzn/codewhisperer-streaming/src/protocols/Aws_restJson1.ts +740 -0
  154. package/src.gen/@amzn/codewhisperer-streaming/src/runtimeConfig.browser.ts +42 -0
  155. package/src.gen/@amzn/codewhisperer-streaming/src/runtimeConfig.native.ts +17 -0
  156. package/src.gen/@amzn/codewhisperer-streaming/src/runtimeConfig.shared.ts +24 -0
  157. package/src.gen/@amzn/codewhisperer-streaming/src/runtimeConfig.ts +55 -0
  158. package/src.gen/@amzn/codewhisperer-streaming/src/runtimeExtensions.ts +44 -0
  159. package/src.gen/@amzn/codewhisperer-streaming/typedoc.json +5 -0
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _DocumentContextExtractor_characterLimits;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DocumentContextExtractor = void 0;
16
+ const languageDetection_1 = require("../../languageDetection");
17
+ const utils_1 = require("./utils");
18
+ class DocumentContextExtractor {
19
+ constructor(characterLimits = DocumentContextExtractor.DEFAULT_CHARACTER_LIMIT) {
20
+ _DocumentContextExtractor_characterLimits.set(this, void 0);
21
+ __classPrivateFieldSet(this, _DocumentContextExtractor_characterLimits, characterLimits, "f");
22
+ }
23
+ /**
24
+ * From the given the cursor state, we want to give Q context up to the characters limit
25
+ * on both sides of the cursor.
26
+ */
27
+ async extractEditorState(document, cursorState) {
28
+ const targetRange = 'position' in cursorState
29
+ ? {
30
+ start: cursorState.position,
31
+ end: cursorState.position,
32
+ }
33
+ : cursorState.range;
34
+ const codeBlockRange = (0, utils_1.getExtendedCodeBlockRange)(document, targetRange, __classPrivateFieldGet(this, _DocumentContextExtractor_characterLimits, "f"));
35
+ const rangeWithinCodeBlock = (0, utils_1.getSelectionWithinExtendedRange)(targetRange, codeBlockRange);
36
+ return {
37
+ document: await this.extractDocumentContext(document, codeBlockRange),
38
+ cursorState: rangeWithinCodeBlock ? { range: rangeWithinCodeBlock } : undefined,
39
+ };
40
+ }
41
+ /**
42
+ * Extract document context from the given range inside a document
43
+ */
44
+ async extractDocumentContext(document, codeBlockRange) {
45
+ const text = document.getText(codeBlockRange);
46
+ const languageId = (0, languageDetection_1.getLanguageId)(document);
47
+ const relativeFilePath = document.uri;
48
+ return {
49
+ text,
50
+ programmingLanguage: languageId ? { languageName: languageId } : undefined,
51
+ relativeFilePath,
52
+ documentSymbols: [],
53
+ };
54
+ }
55
+ }
56
+ exports.DocumentContextExtractor = DocumentContextExtractor;
57
+ _DocumentContextExtractor_characterLimits = new WeakMap();
58
+ DocumentContextExtractor.DEFAULT_CHARACTER_LIMIT = 9000;
59
+ //# sourceMappingURL=documentContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentContext.js","sourceRoot":"","sources":["../../../../src/language-server/chat/contexts/documentContext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAGA,+DAAuD;AACvD,mCAAoF;AAEpF,MAAa,wBAAwB;IAKjC,YAAY,kBAA0B,wBAAwB,CAAC,uBAAuB;QAFtF,4DAAwB;QAGpB,uBAAA,IAAI,6CAAoB,eAAe,MAAA,CAAA;IAC3C,CAAC;IACD;;;OAGG;IACI,KAAK,CAAC,kBAAkB,CAAC,QAAsB,EAAE,WAAwB;QAC5E,MAAM,WAAW,GACb,UAAU,IAAI,WAAW;YACrB,CAAC,CAAC;gBACI,KAAK,EAAE,WAAW,CAAC,QAAQ;gBAC3B,GAAG,EAAE,WAAW,CAAC,QAAQ;aAC5B;YACH,CAAC,CAAC,WAAW,CAAC,KAAK,CAAA;QAE3B,MAAM,cAAc,GAAG,IAAA,iCAAyB,EAAC,QAAQ,EAAE,WAAW,EAAE,uBAAA,IAAI,iDAAiB,CAAC,CAAA;QAE9F,MAAM,oBAAoB,GAAG,IAAA,uCAA+B,EAAC,WAAW,EAAE,cAAc,CAAC,CAAA;QAEzF,OAAO;YACH,QAAQ,EAAE,MAAM,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,cAAc,CAAC;YACrE,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,SAAS;SAClF,CAAA;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,sBAAsB,CAC/B,QAAsB,EACtB,cAAqB;QAErB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;QAC7C,MAAM,UAAU,GAAG,IAAA,iCAAa,EAAC,QAAQ,CAAC,CAAA;QAC1C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,GAAG,CAAA;QAErC,OAAO;YACH,IAAI;YACJ,mBAAmB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;YAC1E,gBAAgB;YAChB,eAAe,EAAE,EAAE;SACtB,CAAA;IACL,CAAC;;AAhDL,4DAiDC;;AAhD2B,gDAAuB,GAAG,IAAI,AAAP,CAAO"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const assert = require("assert");
4
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
5
+ const documentContext_1 = require("./documentContext");
6
+ describe('DocumentContext', () => {
7
+ const mockTypescriptCodeBlock = `function test() {
8
+ console.log('test')
9
+ }`;
10
+ const mockTSDocument = vscode_languageserver_textdocument_1.TextDocument.create('file://test.ts', 'typescript', 1, mockTypescriptCodeBlock);
11
+ describe('documentContextExtractor.extractEditorState', () => {
12
+ it('extracts editor state for range selection', async () => {
13
+ const documentContextExtractor = new documentContext_1.DocumentContextExtractor(19);
14
+ const expected = {
15
+ document: {
16
+ programmingLanguage: { languageName: 'typescript' },
17
+ relativeFilePath: 'file://test.ts',
18
+ documentSymbols: [],
19
+ text: "console.log('test')",
20
+ },
21
+ cursorState: {
22
+ range: {
23
+ start: {
24
+ line: 0,
25
+ character: 8,
26
+ },
27
+ end: {
28
+ line: 0,
29
+ character: 11,
30
+ },
31
+ },
32
+ },
33
+ };
34
+ const result = await documentContextExtractor.extractEditorState(mockTSDocument, {
35
+ // highlighting "log"
36
+ range: {
37
+ start: {
38
+ line: 1,
39
+ character: 12,
40
+ },
41
+ end: {
42
+ line: 1,
43
+ character: 15,
44
+ },
45
+ },
46
+ });
47
+ assert.deepStrictEqual(result, expected);
48
+ });
49
+ it('extracts editor state for collapsed position', async () => {
50
+ const documentContextExtractor = new documentContext_1.DocumentContextExtractor(19);
51
+ const expected = {
52
+ document: {
53
+ programmingLanguage: { languageName: 'typescript' },
54
+ relativeFilePath: 'file://test.ts',
55
+ documentSymbols: [],
56
+ text: "console.log('test')",
57
+ },
58
+ cursorState: {
59
+ range: {
60
+ start: {
61
+ line: 0,
62
+ character: 9,
63
+ },
64
+ end: {
65
+ line: 0,
66
+ character: 10,
67
+ },
68
+ },
69
+ },
70
+ };
71
+ const result = await documentContextExtractor.extractEditorState(mockTSDocument, {
72
+ // highlighting "o" in "log"
73
+ range: {
74
+ start: {
75
+ line: 1,
76
+ character: 13,
77
+ },
78
+ end: {
79
+ line: 1,
80
+ character: 14,
81
+ },
82
+ },
83
+ });
84
+ assert.deepStrictEqual(result, expected);
85
+ });
86
+ it('returns undefined cursorState if the end position was collapsed', async () => {
87
+ const documentContextExtractor = new documentContext_1.DocumentContextExtractor(0);
88
+ const expected = {
89
+ document: {
90
+ programmingLanguage: { languageName: 'typescript' },
91
+ relativeFilePath: 'file://test.ts',
92
+ documentSymbols: [],
93
+ text: '',
94
+ },
95
+ cursorState: undefined,
96
+ };
97
+ const result = await documentContextExtractor.extractEditorState(mockTSDocument, {
98
+ range: {
99
+ start: {
100
+ line: 1,
101
+ character: 13,
102
+ },
103
+ end: {
104
+ line: 1,
105
+ character: 13,
106
+ },
107
+ },
108
+ });
109
+ assert.deepStrictEqual(result, expected);
110
+ });
111
+ });
112
+ describe('extractDocumentContext', () => {
113
+ it('extract document context with the code block range correctly', async () => {
114
+ const documentContextExtractor = new documentContext_1.DocumentContextExtractor();
115
+ const expectedResult = {
116
+ programmingLanguage: { languageName: 'typescript' },
117
+ relativeFilePath: 'file://test.ts',
118
+ documentSymbols: [],
119
+ text: "console.log('test')",
120
+ };
121
+ const result = await documentContextExtractor.extractDocumentContext(mockTSDocument, {
122
+ start: { line: 1, character: 4 },
123
+ end: { line: 1, character: 23 },
124
+ });
125
+ assert.deepStrictEqual(result, expectedResult);
126
+ });
127
+ it('handles other languages correctly', async () => {
128
+ const documentContextExtractor = new documentContext_1.DocumentContextExtractor();
129
+ const mockGoCodeBLock = `func main() {
130
+ fmt.Println("test")
131
+ }`;
132
+ const mockDocument = vscode_languageserver_textdocument_1.TextDocument.create('file://test.go', 'go', 1, mockGoCodeBLock);
133
+ const expectedResult = {
134
+ programmingLanguage: { languageName: 'go' },
135
+ relativeFilePath: 'file://test.go',
136
+ documentSymbols: [],
137
+ text: 'fmt.Println("test")',
138
+ };
139
+ const result = await documentContextExtractor.extractDocumentContext(mockDocument, {
140
+ start: { line: 1, character: 4 },
141
+ end: { line: 1, character: 23 },
142
+ });
143
+ assert.deepStrictEqual(result, expectedResult);
144
+ });
145
+ });
146
+ });
147
+ //# sourceMappingURL=documentContext.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentContext.test.js","sourceRoot":"","sources":["../../../../src/language-server/chat/contexts/documentContext.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Range, TextDocument } from 'vscode-languageserver-textdocument';
2
+ /**
3
+ * Extend the cursor range on both ends up to charactersLimit for context (if applicable)
4
+ */
5
+ export declare function getExtendedCodeBlockRange(document: TextDocument, originalRange: Range, charactersLimit: number): Range;
6
+ /**
7
+ * Since we are only sending over the code block, the selection that
8
+ * reflects the position in the entire document needs to be adjusted.
9
+ */
10
+ export declare function getSelectionWithinExtendedRange(selection: Range, extendedRange: Range): Range | undefined;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSelectionWithinExtendedRange = exports.getExtendedCodeBlockRange = void 0;
4
+ /**
5
+ * Extend the cursor range on both ends up to charactersLimit for context (if applicable)
6
+ */
7
+ function getExtendedCodeBlockRange(document, originalRange, charactersLimit) {
8
+ let startOffset = document.offsetAt(originalRange.start);
9
+ let endOffset = document.offsetAt(originalRange.end);
10
+ const totalSelectedCharacters = endOffset - startOffset;
11
+ // if the total selected characters are greater than the character limit, trims the characters
12
+ if (totalSelectedCharacters >= charactersLimit) {
13
+ return {
14
+ start: document.positionAt(startOffset),
15
+ end: document.positionAt(startOffset + charactersLimit),
16
+ };
17
+ }
18
+ // lineCount + 1 puts us outside the bound so `.offsetAt` returns the max offset
19
+ const maxOffset = document.offsetAt({
20
+ line: document.lineCount + 1,
21
+ character: 0,
22
+ });
23
+ const extraCharactersAllowed = charactersLimit - totalSelectedCharacters;
24
+ // Accounting for the edge case when there is an odd number of characters
25
+ const prependCharacterCount = Math.ceil(extraCharactersAllowed / 2);
26
+ const appendCharacterCount = Math.floor(extraCharactersAllowed / 2);
27
+ // Try adding number of extra characters "equally" on both end first
28
+ startOffset = Math.max(0, startOffset - prependCharacterCount);
29
+ endOffset = Math.min(endOffset + appendCharacterCount, maxOffset);
30
+ // If there are remaining characters, which means that we reached at least one end of the document
31
+ const remainingCharacters = charactersLimit - (endOffset - startOffset);
32
+ if (remainingCharacters > 0) {
33
+ // Since we are at the beginning on the document, try adding the remaining characters to the end, and vice versa.
34
+ if (startOffset === 0) {
35
+ endOffset = Math.min(endOffset + remainingCharacters, maxOffset);
36
+ }
37
+ else {
38
+ startOffset = Math.max(startOffset - remainingCharacters, 0);
39
+ }
40
+ }
41
+ return {
42
+ start: document.positionAt(startOffset),
43
+ end: document.positionAt(endOffset),
44
+ };
45
+ }
46
+ exports.getExtendedCodeBlockRange = getExtendedCodeBlockRange;
47
+ /**
48
+ * Since we are only sending over the code block, the selection that
49
+ * reflects the position in the entire document needs to be adjusted.
50
+ */
51
+ function getSelectionWithinExtendedRange(selection, extendedRange) {
52
+ if (selection.start.line === selection.end.line && selection.start.character === selection.end.character) {
53
+ return undefined;
54
+ }
55
+ return {
56
+ start: {
57
+ line: selection.start.line - extendedRange.start.line,
58
+ character: selection.start.line === extendedRange.start.line
59
+ ? selection.start.character - extendedRange.start.character
60
+ : selection.start.character,
61
+ },
62
+ end: {
63
+ line: selection.end.line - extendedRange.start.line,
64
+ character: selection.end.line === extendedRange.end.line
65
+ ? selection.end.character - extendedRange.start.character
66
+ : selection.end.character,
67
+ },
68
+ };
69
+ }
70
+ exports.getSelectionWithinExtendedRange = getSelectionWithinExtendedRange;
71
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/language-server/chat/contexts/utils.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AAEH,SAAgB,yBAAyB,CACrC,QAAsB,EACtB,aAAoB,EACpB,eAAuB;IAEvB,IAAI,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IACxD,IAAI,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IAEpD,MAAM,uBAAuB,GAAG,SAAS,GAAG,WAAW,CAAA;IAEvD,8FAA8F;IAC9F,IAAI,uBAAuB,IAAI,eAAe,EAAE,CAAC;QAC7C,OAAO;YACH,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC;YACvC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,GAAG,eAAe,CAAC;SAC1D,CAAA;IACL,CAAC;IAED,gFAAgF;IAChF,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAChC,IAAI,EAAE,QAAQ,CAAC,SAAS,GAAG,CAAC;QAC5B,SAAS,EAAE,CAAC;KACf,CAAC,CAAA;IAEF,MAAM,sBAAsB,GAAG,eAAe,GAAG,uBAAuB,CAAA;IAExE,yEAAyE;IACzE,MAAM,qBAAqB,GAAG,IAAI,CAAC,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC,CAAA;IACnE,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,CAAC,CAAA;IAEnE,oEAAoE;IACpE,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,qBAAqB,CAAC,CAAA;IAC9D,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,oBAAoB,EAAE,SAAS,CAAC,CAAA;IAEjE,kGAAkG;IAClG,MAAM,mBAAmB,GAAG,eAAe,GAAG,CAAC,SAAS,GAAG,WAAW,CAAC,CAAA;IAEvE,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;QAC1B,iHAAiH;QACjH,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACpB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,mBAAmB,EAAE,SAAS,CAAC,CAAA;QACpE,CAAC;aAAM,CAAC;YACJ,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,mBAAmB,EAAE,CAAC,CAAC,CAAA;QAChE,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC;QACvC,GAAG,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;KACtC,CAAA;AACL,CAAC;AAlDD,8DAkDC;AAED;;;GAGG;AACH,SAAgB,+BAA+B,CAAC,SAAgB,EAAE,aAAoB;IAClF,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACvG,OAAO,SAAS,CAAA;IACpB,CAAC;IAED,OAAO;QACH,KAAK,EAAE;YACH,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI;YACrD,SAAS,EACL,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,KAAK,CAAC,IAAI;gBAC7C,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,SAAS;gBAC3D,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS;SACtC;QACD,GAAG,EAAE;YACD,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI;YACnD,SAAS,EACL,SAAS,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,CAAC,GAAG,CAAC,IAAI;gBACzC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,SAAS;gBACzD,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS;SACpC;KACJ,CAAA;AACL,CAAC;AArBD,0EAqBC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const assert = require("assert");
4
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
5
+ const utils_1 = require("./utils");
6
+ describe('getExtendedCodeBlockRange', () => {
7
+ const mockDocument = vscode_languageserver_textdocument_1.TextDocument.create('file://test.ts', 'typescript', 1, `const fs = require('node:fs/promises');
8
+ async function example(file: string) {
9
+ try {
10
+ const data = await fs.readFile(file, { encoding: 'utf8' });
11
+ console.log(data);
12
+ } catch (err) {
13
+ console.error(err);
14
+ }
15
+ }
16
+ example('/Users/user1/test.txt');`);
17
+ it('able to extend a code block range up to the character limit', () => {
18
+ const result = (0, utils_1.getExtendedCodeBlockRange)(mockDocument, {
19
+ // highlightling "console"
20
+ start: { line: 4, character: 8 },
21
+ end: { line: 4, character: 14 },
22
+ }, 10);
23
+ assert.deepStrictEqual(result, {
24
+ start: { line: 4, character: 6 },
25
+ end: { line: 4, character: 16 },
26
+ });
27
+ });
28
+ it('able to extend a code block range correctly if character limit is an odd number', () => {
29
+ const result = (0, utils_1.getExtendedCodeBlockRange)(mockDocument, {
30
+ // highlightling "console"
31
+ start: { line: 4, character: 8 },
32
+ end: { line: 4, character: 14 },
33
+ }, 9);
34
+ assert.deepStrictEqual(result, {
35
+ start: { line: 4, character: 6 },
36
+ end: { line: 4, character: 15 },
37
+ });
38
+ });
39
+ it('does not extend beyond the lower document bound', () => {
40
+ const result = (0, utils_1.getExtendedCodeBlockRange)(mockDocument, {
41
+ // highlighting "fs" in document
42
+ start: { line: 0, character: 6 },
43
+ end: { line: 0, character: 8 },
44
+ }, 20);
45
+ assert.deepStrictEqual(result, {
46
+ start: { line: 0, character: 0 },
47
+ end: { line: 0, character: 20 },
48
+ });
49
+ });
50
+ it('does not extend beyond the upper document bound', () => {
51
+ const result = (0, utils_1.getExtendedCodeBlockRange)(mockDocument, {
52
+ // highlighting "test" on the last line in document
53
+ start: { line: 9, character: 26 },
54
+ end: { line: 9, character: 30 },
55
+ }, 20);
56
+ assert.deepStrictEqual(result, {
57
+ start: { line: 9, character: 17 },
58
+ end: { line: 9, character: 37 },
59
+ });
60
+ });
61
+ it('trims text if already exceeds character limit', () => {
62
+ const result = (0, utils_1.getExtendedCodeBlockRange)(mockDocument, {
63
+ start: { line: 3, character: 8 },
64
+ end: { line: 3, character: 60 },
65
+ }, 40);
66
+ assert.deepStrictEqual(result, {
67
+ start: { line: 3, character: 8 },
68
+ end: { line: 3, character: 48 },
69
+ });
70
+ });
71
+ });
72
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../../../src/language-server/chat/contexts/utils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { EditorState, GenerateAssistantResponseCommandInput } from '@amzn/codewhisperer-streaming';
2
+ import { ChatParams } from '@aws/language-server-runtimes/server-interface';
3
+ import { Result } from '../types';
4
+ export declare function convertChatParamsToRequestInput(params: ChatParams, editorState?: EditorState): Result<GenerateAssistantResponseCommandInput, string>;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertChatParamsToRequestInput = void 0;
4
+ const codewhisperer_streaming_1 = require("@amzn/codewhisperer-streaming");
5
+ function convertChatParamsToRequestInput(params, editorState) {
6
+ const { prompt } = params;
7
+ if (prompt.prompt || prompt.escapedPrompt) {
8
+ // TODO: implement userInputMessageContext state when that is available, and diagnostic trigger type
9
+ return {
10
+ success: true,
11
+ data: {
12
+ conversationState: {
13
+ chatTriggerType: codewhisperer_streaming_1.ChatTriggerType.MANUAL,
14
+ currentMessage: {
15
+ userInputMessage: {
16
+ content: prompt.escapedPrompt ?? prompt.prompt,
17
+ userInputMessageContext: editorState
18
+ ? {
19
+ editorState,
20
+ }
21
+ : undefined,
22
+ },
23
+ },
24
+ },
25
+ },
26
+ };
27
+ }
28
+ return {
29
+ success: false,
30
+ error: 'Invalid request input',
31
+ };
32
+ }
33
+ exports.convertChatParamsToRequestInput = convertChatParamsToRequestInput;
34
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/language-server/chat/utils.ts"],"names":[],"mappings":";;;AAAA,2EAAmH;AAInH,SAAgB,+BAA+B,CAC3C,MAAkB,EAClB,WAAyB;IAEzB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAEzB,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACxC,oGAAoG;QACpG,OAAO;YACH,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACF,iBAAiB,EAAE;oBACf,eAAe,EAAE,yCAAe,CAAC,MAAM;oBACvC,cAAc,EAAE;wBACZ,gBAAgB,EAAE;4BACd,OAAO,EAAE,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,MAAM;4BAC9C,uBAAuB,EAAE,WAAW;gCAChC,CAAC,CAAC;oCACI,WAAW;iCACd;gCACH,CAAC,CAAC,SAAS;yBAClB;qBACJ;iBACJ;aACJ;SACJ,CAAA;IACL,CAAC;IAED,OAAO;QACH,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,uBAAuB;KACjC,CAAA;AACL,CAAC;AAhCD,0EAgCC"}
@@ -1,3 +1,3 @@
1
- import { Server, CredentialsProvider } from '@aws/language-server-runtimes/server-interface';
1
+ import { CredentialsProvider, Server } from '@aws/language-server-runtimes/server-interface';
2
2
  import { CodeWhispererServiceToken } from './codeWhispererService';
3
3
  export declare const SecurityScanServerToken: (service: (credentialsProvider: CredentialsProvider) => CodeWhispererServiceToken) => Server;
@@ -1,21 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SecurityScanServerToken = void 0;
4
+ const perf_hooks_1 = require("perf_hooks");
4
5
  const url_1 = require("url");
5
6
  const dependencyGraphFactory_1 = require("./dependencyGraph/dependencyGraphFactory");
6
7
  const languageDetection_1 = require("./languageDetection");
7
8
  const securityScanDiagnosticsProvider_1 = require("./securityScan/securityScanDiagnosticsProvider");
8
9
  const securityScanHandler_1 = require("./securityScan/securityScanHandler");
9
10
  const utils_1 = require("./utils");
11
+ const RunSecurityScanCommand = 'aws/codewhisperer/runSecurityScan';
12
+ const CancelSecurityScanCommand = 'aws/codewhisperer/cancelSecurityScan';
10
13
  const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace, logging, lsp, telemetry }) => {
11
14
  const codewhispererclient = service(credentialsProvider);
12
15
  const diagnosticsProvider = new securityScanDiagnosticsProvider_1.default(lsp, logging);
13
16
  const scanHandler = new securityScanHandler_1.SecurityScanHandler(codewhispererclient, workspace, logging);
14
17
  const runSecurityScan = async (params, token) => {
15
18
  logging.log(`Starting security scan`);
16
- diagnosticsProvider.resetDiagnostics();
19
+ await diagnosticsProvider.resetDiagnostics();
17
20
  let jobStatus;
18
- const securityScanStartTime = performance.now();
21
+ const securityScanStartTime = perf_hooks_1.performance.now();
19
22
  let serviceInvocationStartTime = 0;
20
23
  const securityScanTelemetryEntry = {
21
24
  codewhispererCodeScanSrcPayloadBytes: 0,
@@ -28,11 +31,11 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
28
31
  result: 'Succeeded',
29
32
  codewhispererCodeScanTotalIssues: 0,
30
33
  codewhispererCodeScanIssuesWithFixes: 0,
31
- credentialStartUrl: credentialsProvider.getConnectionMetadata()?.sso?.startUrl ?? undefined,
34
+ credentialStartUrl: credentialsProvider.getConnectionMetadata?.()?.sso?.startUrl ?? undefined,
32
35
  };
33
36
  try {
34
37
  if (!credentialsProvider.hasCredentials('bearer')) {
35
- throw new Error('credentialsrProvider does not have bearer token credentials');
38
+ throw new Error('credentialsProvider does not have bearer token credentials');
36
39
  }
37
40
  if (!params.arguments || params.arguments.length === 0) {
38
41
  throw new Error(`Incorrect params provided. Params: ${params}`);
@@ -58,9 +61,9 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
58
61
  if (dependencyGraph.exceedsSizeLimit((await workspace.fs.getFileSize(activeFilePath)).size)) {
59
62
  throw new Error(`Selected file larger than ${dependencyGraph.getReadableSizeLimit()}. Try a different file.`);
60
63
  }
61
- const contextTruncationStartTime = performance.now();
64
+ const contextTruncationStartTime = perf_hooks_1.performance.now();
62
65
  const truncation = await dependencyGraph.generateTruncation(activeFilePath);
63
- securityScanTelemetryEntry.contextTruncationDuration = performance.now() - contextTruncationStartTime;
66
+ securityScanTelemetryEntry.contextTruncationDuration = perf_hooks_1.performance.now() - contextTruncationStartTime;
64
67
  securityScanTelemetryEntry.codewhispererCodeScanSrcPayloadBytes = truncation.srcPayloadSizeInBytes;
65
68
  securityScanTelemetryEntry.codewhispererCodeScanBuildPayloadBytes = truncation.buildPayloadSizeInBytes;
66
69
  securityScanTelemetryEntry.codewhispererCodeScanSrcZipFileBytes = truncation.zipFileSizeInBytes;
@@ -70,7 +73,7 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
70
73
  /**
71
74
  * Step 2: Get presigned Url, upload and clean up
72
75
  */
73
- const uploadStartTime = performance.now();
76
+ const uploadStartTime = perf_hooks_1.performance.now();
74
77
  let artifactMap = {};
75
78
  try {
76
79
  artifactMap = await scanHandler.createCodeResourcePresignedUrlHandler(truncation.zipFileBuffer);
@@ -81,13 +84,13 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
81
84
  }
82
85
  finally {
83
86
  await dependencyGraph.removeTmpFiles();
84
- securityScanTelemetryEntry.artifactsUploadDuration = performance.now() - uploadStartTime;
87
+ securityScanTelemetryEntry.artifactsUploadDuration = perf_hooks_1.performance.now() - uploadStartTime;
85
88
  }
86
89
  scanHandler.throwIfCancelled(token);
87
90
  /**
88
91
  * Step 3: Create scan job
89
92
  */
90
- serviceInvocationStartTime = performance.now();
93
+ serviceInvocationStartTime = perf_hooks_1.performance.now();
91
94
  const scanJob = await scanHandler.createScanJob(artifactMap, document.languageId.toLowerCase());
92
95
  logging.log(`Created security scan job id: ${scanJob.jobId}`);
93
96
  securityScanTelemetryEntry.codewhispererCodeScanJobId = scanJob.jobId;
@@ -109,7 +112,7 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
109
112
  total: accumulator.total + current.issues.length,
110
113
  withFixes: accumulator.withFixes + current.issues.filter(i => i.suggestedFixes.length > 0).length,
111
114
  }), { total: 0, withFixes: 0 });
112
- logging.log(`Security scan totally found ${total} issues. ${withFixes} of them have fixes.`);
115
+ logging.log(`Security scan found ${total} issues, ${withFixes} have suggested fixes.`);
113
116
  securityScanTelemetryEntry.codewhispererCodeScanTotalIssues = total;
114
117
  securityScanTelemetryEntry.codewhispererCodeScanIssuesWithFixes = withFixes;
115
118
  scanHandler.throwIfCancelled(token);
@@ -120,8 +123,10 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
120
123
  logging.log(`Security scan completed.`);
121
124
  truncation.scannedFiles.forEach(file => logging.log(`Scanned file: ${file}`));
122
125
  return {
123
- result: {
124
- status: jobStatus,
126
+ status: 'Succeeded',
127
+ findings: {
128
+ totalFindings: total,
129
+ findingsWithFixes: withFixes,
125
130
  scannedFiles: Array.from(truncation.scannedFiles.values()).join(','),
126
131
  },
127
132
  };
@@ -131,24 +136,21 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
131
136
  logging.log(`Security scan has been cancelled. ${error}`);
132
137
  securityScanTelemetryEntry.result = 'Cancelled';
133
138
  return {
134
- result: {
135
- status: 'Cancelled',
136
- },
139
+ status: 'Cancelled',
137
140
  };
138
141
  }
139
142
  logging.log(`Security scan failed. ${error}`);
140
143
  securityScanTelemetryEntry.result = 'Failed';
144
+ const err = (0, utils_1.getErrorMessage)(error);
141
145
  return {
142
- result: {
143
- status: 'Failed',
144
- },
145
- error,
146
+ status: 'Failed',
147
+ error: err,
146
148
  };
147
149
  }
148
150
  finally {
149
- securityScanTelemetryEntry.duration = performance.now() - securityScanStartTime;
151
+ securityScanTelemetryEntry.duration = perf_hooks_1.performance.now() - securityScanStartTime;
150
152
  securityScanTelemetryEntry.codeScanServiceInvocationsDuration =
151
- performance.now() - serviceInvocationStartTime;
153
+ perf_hooks_1.performance.now() - serviceInvocationStartTime;
152
154
  telemetry.emitMetric({
153
155
  name: 'codewhisperer_securityScan',
154
156
  result: securityScanTelemetryEntry.result,
@@ -159,25 +161,38 @@ const SecurityScanServerToken = (service) => ({ credentialsProvider, workspace,
159
161
  const onExecuteCommandHandler = async (params, _token) => {
160
162
  logging.log(params.command);
161
163
  switch (params.command) {
162
- case 'aws/codewhisperer/runSecurityScan':
164
+ case RunSecurityScanCommand:
163
165
  return runSecurityScan(params, scanHandler.tokenSource.token);
164
- case 'aws/codewhisperer/cancelSecurityScan':
166
+ case CancelSecurityScanCommand:
165
167
  scanHandler.cancelSecurityScan();
166
168
  }
167
169
  return;
168
170
  };
169
- diagnosticsProvider.handleHover();
171
+ const onInitializeHandler = () => {
172
+ return {
173
+ capabilities: {
174
+ executeCommandProvider: {
175
+ commands: [RunSecurityScanCommand, CancelSecurityScanCommand],
176
+ },
177
+ },
178
+ };
179
+ };
170
180
  lsp.onExecuteCommand(onExecuteCommandHandler);
181
+ lsp.addInitializer(onInitializeHandler);
171
182
  lsp.onDidChangeTextDocument(async (p) => {
172
183
  const textDocument = await workspace.getTextDocument(p.textDocument.uri);
173
- const languageId = (0, languageDetection_1.getSupportedLanguageId)(textDocument);
174
- if (!textDocument || !languageId || !languageDetection_1.supportedSecurityScanLanguages.includes(languageId)) {
184
+ const languageId = (0, languageDetection_1.getSupportedLanguageId)(textDocument, languageDetection_1.supportedSecurityScanLanguages);
185
+ if (!textDocument || !languageId) {
175
186
  return;
176
187
  }
177
188
  p.contentChanges.forEach(async (change) => {
178
189
  await diagnosticsProvider.validateDiagnostics(p.textDocument.uri, change);
179
190
  });
180
191
  });
192
+ lsp.workspace.onDidChangeWorkspaceFolders(async (event) => {
193
+ // clear security scan diagnostics for previous run when a workspace change event occurs
194
+ await diagnosticsProvider.resetDiagnostics();
195
+ });
181
196
  logging.log('SecurityScan server has been initialized');
182
197
  return () => {
183
198
  // dispose function