diff --git a/docs/lsp.md b/docs/lsp.md index 22ada2175fa..a0c7a25d8cb 100644 --- a/docs/lsp.md +++ b/docs/lsp.md @@ -26,9 +26,7 @@ sequenceDiagram ## Language Server Debugging -1. Clone https://github.com/aws/language-servers.git and set it up in the same workspace as this project - - e.g. +1. Clone https://github.com/aws/language-servers.git and set it up in the same workspace as this project by cmd+shift+p and "add folder to workspace" and selecting the language-servers folder that you just cloned. Your VS code folder structure should look like below. ``` /aws-toolkit-vscode @@ -52,9 +50,9 @@ sequenceDiagram "amazonqLSPChat": true // optional: enables chat from flare } ``` -4. Uncomment the `__AMAZONQLSP_PATH` variable in `amazonq/.vscode/launch.json` Extension configuration - 1. Uncomment the `__AMAZONQLSP_UI` variable in `amazonq/.vscode/launch.json` Extension configuration if you want to debug the flare chat-client as well +4. Uncomment the `__AMAZONQLSP_PATH` and `__AMAZONQLSP_UI` variables in the `amazonq/.vscode/launch.json` extension configuration 5. Use the `Launch LSP with Debugging` configuration and set breakpoints in VSCode or the language server +6. (Optional): Enable `"amazonq.trace.server": "on"` or `"amazonq.trace.server": "verbose"` in your VSCode settings to view detailed log messages sent to/from the language server. These log messages will show up in the "Amazon Q Language Server" output channel ## Amazon Q Inline Activation diff --git a/package-lock.json b/package-lock.json index 35e15539e63..8511e57e140 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "vscode-nls-dev": "^4.0.4" }, "devDependencies": { - "@aws-toolkits/telemetry": "^1.0.312", + "@aws-toolkits/telemetry": "^1.0.317", "@playwright/browser-chromium": "^1.43.1", "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", @@ -70,8 +70,6 @@ }, "node_modules/@apidevtools/json-schema-ref-parser": { "version": "11.9.3", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.3.tgz", - "integrity": "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -642,8 +640,6 @@ }, "node_modules/@aws-sdk/client-apprunner": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-apprunner/-/client-apprunner-3.693.0.tgz", - "integrity": "sha512-6q3yxzp+1fZ2+O7NC8skDz7GSRH6fCcRfT9UU1nX3+kIx/C9cbutnM/WxU35vqJrnT4hq45cUoWj52xZgxFgAA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -694,8 +690,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/client-sso": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.693.0.tgz", - "integrity": "sha512-QEynrBC26x6TG9ZMzApR/kZ3lmt4lEIs2D+cHuDxt6fDGzahBUsQFBwJqhizzsM97JJI5YvmJhmihoYjdSSaXA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -743,8 +737,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/client-sso-oidc": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.693.0.tgz", - "integrity": "sha512-UEDbYlYtK/e86OOMyFR4zEPyenIxDzO2DRdz3fwVW7RzZ94wfmSwBh/8skzPTuY1G7sI064cjHW0b0QG01Sdtg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -796,8 +788,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/client-sts": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.693.0.tgz", - "integrity": "sha512-4S2y7VEtvdnjJX4JPl4kDQlslxXEZFnC50/UXVUYSt/AMc5A/GgspFNA5FVz4E3Gwpfobbf23hR2NBF8AGvYoQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -847,8 +837,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/core": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.693.0.tgz", - "integrity": "sha512-v6Z/kWmLFqRLDPEwl9hJGhtTgIFHjZugSfF1Yqffdxf4n1AWgtHS7qSegakuMyN5pP4K2tvUD8qHJ+gGe2Bw2A==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -869,8 +857,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/credential-provider-http": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.693.0.tgz", - "integrity": "sha512-sL8MvwNJU7ZpD7/d2VVb3by1GknIJUxzTIgYtVkDVA/ojo+KRQSSHxcj0EWWXF5DTSh2Tm+LrEug3y1ZyKHsDA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -890,8 +876,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/credential-provider-ini": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.693.0.tgz", - "integrity": "sha512-kvaa4mXhCCOuW7UQnBhYqYfgWmwy7WSBSDClutwSLPZvgrhYj2l16SD2lN4IfYdxARYMJJ1lFYp3/jJG/9Yk4Q==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -916,8 +900,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/credential-provider-node": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.693.0.tgz", - "integrity": "sha512-42WMsBjTNnjYxYuM3qD/Nq+8b7UdMopUq5OduMDxoM3mFTV6PXMMnfI4Z1TNnR4tYRvPXAnuNltF6xmjKbSJRA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.693.0", @@ -939,8 +921,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/credential-provider-sso": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.693.0.tgz", - "integrity": "sha512-479UlJxY+BFjj3pJFYUNC0DCMrykuG7wBAXfsvZqQxKUa83DnH5Q1ID/N2hZLkxjGd4ZW0AC3lTOMxFelGzzpQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-sso": "3.693.0", @@ -958,8 +938,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/credential-provider-web-identity": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.693.0.tgz", - "integrity": "sha512-8LB210Pr6VeCiSb2hIra+sAH4KUBLyGaN50axHtIgufVK8jbKIctTZcVY5TO9Se+1107TsruzeXS7VeqVdJfFA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -977,8 +955,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/middleware-host-header": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.693.0.tgz", - "integrity": "sha512-BCki6sAZ5jYwIN/t3ElCiwerHad69ipHwPsDCxJQyeiOnJ8HG+lEpnVIfrnI8A0fLQNSF3Gtx6ahfBpKiv1Oug==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -992,8 +968,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/middleware-logger": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.693.0.tgz", - "integrity": "sha512-dXnXDPr+wIiJ1TLADACI1g9pkSB21KkMIko2u4CJ2JCBoxi5IqeTnVoa6YcC8GdFNVRl+PorZ3Zqfmf1EOTC6w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -1006,8 +980,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.693.0.tgz", - "integrity": "sha512-0LDmM+VxXp0u3rG0xQRWD/q6Ubi7G8I44tBPahevD5CaiDZTkmNTrVUf0VEJgVe0iCKBppACMBDkLB0/ETqkFw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -1021,8 +993,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/middleware-user-agent": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.693.0.tgz", - "integrity": "sha512-/KUq/KEpFFbQmNmpp7SpAtFAdViquDfD2W0QcG07zYBfz9MwE2ig48ALynXm5sMpRmnG7sJXjdvPtTsSVPfkiw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.693.0", @@ -1039,8 +1009,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/region-config-resolver": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.693.0.tgz", - "integrity": "sha512-YLUkMsUY0GLW/nfwlZ69cy1u07EZRmsv8Z9m0qW317/EZaVx59hcvmcvb+W4bFqj5E8YImTjoGfE4cZ0F9mkyw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -1056,8 +1024,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/token-providers": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.693.0.tgz", - "integrity": "sha512-nDBTJMk1l/YmFULGfRbToOA2wjf+FkQT4dMgYCv+V9uSYsMzQj8A7Tha2dz9yv4vnQgYaEiErQ8d7HVyXcVEoA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -1075,8 +1041,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/util-endpoints": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.693.0.tgz", - "integrity": "sha512-eo4F6DRQ/kxS3gxJpLRv+aDNy76DxQJL5B3DPzpr9Vkq0ygVoi4GT5oIZLVaAVIJmi6k5qq9dLsYZfWLUxJJSg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -1090,8 +1054,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.693.0.tgz", - "integrity": "sha512-6EUfuKOujtddy18OLJUaXfKBgs+UcbZ6N/3QV4iOkubCUdeM1maIqs++B9bhCbWeaeF5ORizJw5FTwnyNjE/mw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.692.0", @@ -1102,8 +1064,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@aws-sdk/util-user-agent-node": { "version": "3.693.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.693.0.tgz", - "integrity": "sha512-td0OVX8m5ZKiXtecIDuzY3Y3UZIzvxEr57Hp21NOwieqKCG2UeyQWWeGPv0FQaU7dpTkvFmVNI+tx9iB8V/Nhg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/middleware-user-agent": "3.693.0", @@ -1126,8 +1086,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@smithy/is-array-buffer": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -1138,8 +1096,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@smithy/util-buffer-from": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", @@ -1151,8 +1107,6 @@ }, "node_modules/@aws-sdk/client-apprunner/node_modules/@smithy/util-utf8": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^3.0.0", @@ -10806,9 +10760,9 @@ } }, "node_modules/@aws-toolkits/telemetry": { - "version": "1.0.312", - "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-1.0.312.tgz", - "integrity": "sha512-Ufr24XeVrkBrsyUZyGRXprclkGsF/5O16IXP0dW7LC2DMqFyMuvmcHhIkQDN9D8ydnsHdutj/ZxTyvpkHpXQJw==", + "version": "1.0.317", + "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-1.0.317.tgz", + "integrity": "sha512-QFLBFfHZjuB2pBd1p0Tn/GMKTYYQu3/nrlj0Co7EkqozvDNDG0nTjxtkXxotbwjrqVD5Sv8i46gEdgsyQ7at3w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10821,25 +10775,35 @@ "yargs": "^17.0.1" } }, + "node_modules/@aws/chat-client": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws/chat-client-ui-types": "^0.1.12", + "@aws/language-server-runtimes-types": "^0.1.10", + "@aws/mynah-ui": "^4.28.0" + } + }, "node_modules/@aws/chat-client-ui-types": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@aws/chat-client-ui-types/-/chat-client-ui-types-0.1.12.tgz", - "integrity": "sha512-2yfRwElcJOwJ8dBR8aLcWAy9HlULRluaVCerCHXV+LstiIvkS0cd92l248Y+RQlKAvbGZXpnEzUOrlkNWVa80Q==", + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@aws/chat-client-ui-types/-/chat-client-ui-types-0.1.26.tgz", + "integrity": "sha512-WlF0fP1nojueknr815dg6Ivs+Q3e5onvWTH1nI05jysSzUHjsWwFDBrsxqJXfaPIFhPrbQzHqoxHbhIwQ1OLuw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@aws/language-server-runtimes-types": "^0.1.10" + "@aws/language-server-runtimes-types": "^0.1.22" } }, "node_modules/@aws/language-server-runtimes": { - "version": "0.2.58", - "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes/-/language-server-runtimes-0.2.58.tgz", - "integrity": "sha512-gb1oLKACFpmDKkzSdDAqMdpo63m+Kul4B/uVNNO1IFN4+wEP7zPVgmd1dLDPlLKHrxsAEQDxoYDaYVyQ+yJKqQ==", + "version": "0.2.70", "dev": true, + "license": "Apache-2.0", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.9.3", "@aws-crypto/sha256-js": "^5.2.0", "@aws-sdk/client-cognito-identity": "^3.758.0", - "@aws/language-server-runtimes-types": "^0.1.13", + "@aws/language-server-runtimes-types": "^0.1.21", "@opentelemetry/api": "^1.9.0", "@opentelemetry/resources": "^1.30.1", "@opentelemetry/sdk-metrics": "^1.30.1", @@ -10853,7 +10817,7 @@ "aws-sdk": "^2.1692.0", "axios": "^1.8.4", "hpagent": "^1.2.0", - "jose": "^6.0.10", + "jose": "^5.9.6", "mac-ca": "^3.1.1", "rxjs": "^7.8.2", "vscode-languageserver": "^9.0.1", @@ -10865,10 +10829,11 @@ } }, "node_modules/@aws/language-server-runtimes-types": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes-types/-/language-server-runtimes-types-0.1.13.tgz", - "integrity": "sha512-+FJREN6qyNcOwbu0fxAKt0QUh6x10xg2a9fLL722yVisXV0p4ElgHuXssOWhwALJrmy47DF7bRunZYNpFR9mqw==", + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes-types/-/language-server-runtimes-types-0.1.26.tgz", + "integrity": "sha512-c63rpUbcrtLqaC33t6elRApQqLbQvFgKzIQ2z/VCavE5F7HSLBfzhHkhgUFd775fBpsF4MHrIzwNitYLhDGobw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "^3.17.5" @@ -10876,8 +10841,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/client-cognito-identity": { "version": "3.768.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.768.0.tgz", - "integrity": "sha512-h/WOvKhuXVIhNKjDcsF6oY2oJuBusspnmEaX20h+GUzIrNMlf6qkJrWziT58KzzESyzeYZcGNWjcOfbVRpH6NA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10927,8 +10890,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/client-sso": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.758.0.tgz", - "integrity": "sha512-BoGO6IIWrLyLxQG6txJw6RT2urmbtlwfggapNCrNPyYjlXpzTSJhBYjndg7TpDATFd0SXL0zm8y/tXsUXNkdYQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10977,8 +10938,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/core": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.758.0.tgz", - "integrity": "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11000,8 +10959,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/credential-provider-env": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.758.0.tgz", - "integrity": "sha512-N27eFoRrO6MeUNumtNHDW9WOiwfd59LPXPqDrIa3kWL/s+fOKFHb9xIcF++bAwtcZnAxKkgpDCUP+INNZskE+w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11017,8 +10974,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/credential-provider-http": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.758.0.tgz", - "integrity": "sha512-Xt9/U8qUCiw1hihztWkNeIR+arg6P+yda10OuCHX6kFVx3auTlU7+hCqs3UxqniGU4dguHuftf3mRpi5/GJ33Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11039,8 +10994,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/credential-provider-node": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.758.0.tgz", - "integrity": "sha512-+DaMv63wiq7pJrhIQzZYMn4hSarKiizDoJRvyR7WGhnn0oQ/getX9Z0VNCV3i7lIFoLNTb7WMmQ9k7+z/uD5EQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11063,8 +11016,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/credential-provider-process": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.758.0.tgz", - "integrity": "sha512-AzcY74QTPqcbXWVgjpPZ3HOmxQZYPROIBz2YINF0OQk0MhezDWV/O7Xec+K1+MPGQO3qS6EDrUUlnPLjsqieHA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11081,8 +11032,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/credential-provider-sso": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.758.0.tgz", - "integrity": "sha512-x0FYJqcOLUCv8GLLFDYMXRAQKGjoM+L0BG4BiHYZRDf24yQWFCAZsCQAYKo6XZYh2qznbsW6f//qpyJ5b0QVKQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11101,8 +11050,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/middleware-host-header": { "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.734.0.tgz", - "integrity": "sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11117,8 +11064,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/middleware-logger": { "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.734.0.tgz", - "integrity": "sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11132,8 +11077,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.734.0.tgz", - "integrity": "sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11148,8 +11091,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/middleware-user-agent": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.758.0.tgz", - "integrity": "sha512-iNyehQXtQlj69JCgfaOssgZD4HeYGOwxcaKeG6F+40cwBjTAi0+Ph1yfDwqk2qiBPIRWJ/9l2LodZbxiBqgrwg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11167,8 +11108,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/region-config-resolver": { "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.734.0.tgz", - "integrity": "sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11185,8 +11124,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/token-providers": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.758.0.tgz", - "integrity": "sha512-ckptN1tNrIfQUaGWm/ayW1ddG+imbKN7HHhjFdS4VfItsP0QQOB0+Ov+tpgb4MoNR4JaUghMIVStjIeHN2ks1w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11203,8 +11140,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/types": { "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.734.0.tgz", - "integrity": "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11217,8 +11152,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/util-endpoints": { "version": "3.743.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.743.0.tgz", - "integrity": "sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11233,8 +11166,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.734.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.734.0.tgz", - "integrity": "sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11246,8 +11177,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@aws-sdk/util-user-agent-node": { "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.758.0.tgz", - "integrity": "sha512-A5EZw85V6WhoKMV2hbuFRvb9NPlxEErb4HPO6/SPXYY4QrjprIzScHxikqcWv1w4J3apB1wto9LPU3IMsYtfrw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11271,8 +11200,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/abort-controller": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.1.tgz", - "integrity": "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11285,8 +11212,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/config-resolver": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.0.1.tgz", - "integrity": "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11302,8 +11227,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/core": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.5.tgz", - "integrity": "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11322,8 +11245,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/credential-provider-imds": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.1.tgz", - "integrity": "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11339,8 +11260,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/fetch-http-handler": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.1.tgz", - "integrity": "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11356,8 +11275,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/hash-node": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.1.tgz", - "integrity": "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11372,8 +11289,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/invalid-dependency": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.1.tgz", - "integrity": "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11386,8 +11301,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/is-array-buffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11399,8 +11312,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/middleware-content-length": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.1.tgz", - "integrity": "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11414,8 +11325,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/middleware-endpoint": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.6.tgz", - "integrity": "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11434,8 +11343,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/middleware-retry": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.7.tgz", - "integrity": "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11455,8 +11362,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/middleware-serde": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.2.tgz", - "integrity": "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11469,8 +11374,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/middleware-stack": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.1.tgz", - "integrity": "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11483,8 +11386,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/node-config-provider": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.1.tgz", - "integrity": "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11499,8 +11400,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/node-http-handler": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.3.tgz", - "integrity": "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11516,8 +11415,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/property-provider": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.1.tgz", - "integrity": "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11530,8 +11427,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/protocol-http": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.0.1.tgz", - "integrity": "sha512-TE4cpj49jJNB/oHyh/cRVEgNZaoPaxd4vteJNB0yGidOCVR0jCw/hjPVsT8Q8FRmj8Bd3bFZt8Dh7xGCT+xMBQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11544,8 +11439,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/querystring-builder": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.1.tgz", - "integrity": "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11559,8 +11452,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/querystring-parser": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.1.tgz", - "integrity": "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11573,8 +11464,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/service-error-classification": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.1.tgz", - "integrity": "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11586,8 +11475,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/shared-ini-file-loader": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.1.tgz", - "integrity": "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11600,8 +11487,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/signature-v4": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.1.tgz", - "integrity": "sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11620,8 +11505,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/smithy-client": { "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.6.tgz", - "integrity": "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11639,8 +11522,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/types": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.1.0.tgz", - "integrity": "sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11652,8 +11533,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/url-parser": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.1.tgz", - "integrity": "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11667,8 +11546,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-base64": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11682,8 +11559,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-body-length-browser": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11695,8 +11570,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-body-length-node": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", - "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11708,8 +11581,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-buffer-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11722,8 +11593,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-config-provider": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", - "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11735,8 +11604,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-defaults-mode-browser": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.7.tgz", - "integrity": "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11752,8 +11619,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-defaults-mode-node": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.7.tgz", - "integrity": "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11771,8 +11636,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-endpoints": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.1.tgz", - "integrity": "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11786,8 +11649,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-hex-encoding": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11799,8 +11660,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-middleware": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.1.tgz", - "integrity": "sha512-HiLAvlcqhbzhuiOa0Lyct5IIlyIz0PQO5dnMlmQ/ubYM46dPInB+3yQGkfxsk6Q24Y0n3/JmcA1v5iEhmOF5mA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11813,8 +11672,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-retry": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.1.tgz", - "integrity": "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11828,8 +11685,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-stream": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.2.tgz", - "integrity": "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11848,8 +11703,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-uri-escape": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11861,8 +11714,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/@smithy/util-utf8": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11875,8 +11726,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { @@ -11891,35 +11740,30 @@ } }, "node_modules/@aws/language-server-runtimes/node_modules/jose": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.0.10.tgz", - "integrity": "sha512-skIAxZqcMkOrSwjJvplIPYrlXGpxTPnro2/QWTDCxAdWQrSTV5/KqspMWmi5WAx5+ULswASJiZ0a+1B/Lxt9cw==", + "version": "5.10.0", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } }, "node_modules/@aws/language-server-runtimes/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/@aws/language-server-runtimes/node_modules/vscode-jsonrpc": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/@aws/language-server-runtimes/node_modules/vscode-languageserver": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", - "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", "dev": true, + "license": "MIT", "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, @@ -11929,19 +11773,19 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/vscode-languageserver-protocol": { "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", - "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", "dev": true, + "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "node_modules/@aws/mynah-ui": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.30.1.tgz", - "integrity": "sha512-ZBtvmHYjlJXzIUCeDmNu1cFfJyO86S/+UCuM/LFbAV5mf4Qm1o8i0Gmpw/4ngKx3ZXdFGnVT1Iq2bCGSYhuoSw==", + "version": "4.30.3", + "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.30.3.tgz", + "integrity": "sha512-Xy22dzCaFUqpdSHMpLa8Dsq98DiAUq49dm7Iu8Yj2YZXSCyfKQiYMJOfwU8IoqeNcEney5JRMJpf+/RysWugbA==", "hasInstallScript": true, + "license": "Apache License 2.0", "dependencies": { "escape-html": "^1.0.3", "highlight.js": "^11.11.0", @@ -12267,8 +12111,6 @@ }, "node_modules/@grpc/grpc-js": { "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.0.tgz", - "integrity": "sha512-pMuxInZjUnUkgMT2QLZclRqwk2ykJbIU05aZgPgJYXEpN9+2I7z7aNwcjWZSycRPl232FfhPszyBFJyOxTHNog==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12281,8 +12123,6 @@ }, "node_modules/@grpc/proto-loader": { "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12475,8 +12315,6 @@ }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", "dev": true, "license": "MIT", "funding": { @@ -12557,8 +12395,6 @@ }, "node_modules/@opentelemetry/api": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -12567,8 +12403,6 @@ }, "node_modules/@opentelemetry/api-logs": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", - "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12580,8 +12414,6 @@ }, "node_modules/@opentelemetry/context-async-hooks": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", - "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -12593,8 +12425,6 @@ }, "node_modules/@opentelemetry/core": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12609,8 +12439,6 @@ }, "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -12619,8 +12447,6 @@ }, "node_modules/@opentelemetry/exporter-logs-otlp-grpc": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.57.2.tgz", - "integrity": "sha512-eovEy10n3umjKJl2Ey6TLzikPE+W4cUQ4gCwgGP1RqzTGtgDra0WjIqdy29ohiUKfvmbiL3MndZww58xfIvyFw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12640,8 +12466,6 @@ }, "node_modules/@opentelemetry/exporter-logs-otlp-http": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.57.2.tgz", - "integrity": "sha512-0rygmvLcehBRp56NQVLSleJ5ITTduq/QfU7obOkyWgPpFHulwpw2LYTqNIz5TczKZuy5YY+5D3SDnXZL1tXImg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12660,8 +12484,6 @@ }, "node_modules/@opentelemetry/exporter-logs-otlp-proto": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.57.2.tgz", - "integrity": "sha512-ta0ithCin0F8lu9eOf4lEz9YAScecezCHkMMyDkvd9S7AnZNX5ikUmC5EQOQADU+oCcgo/qkQIaKcZvQ0TYKDw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12682,8 +12504,6 @@ }, "node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.57.2.tgz", - "integrity": "sha512-r70B8yKR41F0EC443b5CGB4rUaOMm99I5N75QQt6sHKxYDzSEc6gm48Diz1CI1biwa5tDPznpylTrywO/pT7qw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12705,8 +12525,6 @@ }, "node_modules/@opentelemetry/exporter-metrics-otlp-http": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.57.2.tgz", - "integrity": "sha512-ttb9+4iKw04IMubjm3t0EZsYRNWr3kg44uUuzfo9CaccYlOh8cDooe4QObDUkvx9d5qQUrbEckhrWKfJnKhemA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12725,8 +12543,6 @@ }, "node_modules/@opentelemetry/exporter-metrics-otlp-proto": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.57.2.tgz", - "integrity": "sha512-HX068Q2eNs38uf7RIkNN9Hl4Ynl+3lP0++KELkXMCpsCbFO03+0XNNZ1SkwxPlP9jrhQahsMPMkzNXpq3fKsnw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12746,8 +12562,6 @@ }, "node_modules/@opentelemetry/exporter-prometheus": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.57.2.tgz", - "integrity": "sha512-VqIqXnuxWMWE/1NatAGtB1PvsQipwxDcdG4RwA/umdBcW3/iOHp0uejvFHTRN2O78ZPged87ErJajyUBPUhlDQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12764,8 +12578,6 @@ }, "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.57.2.tgz", - "integrity": "sha512-gHU1vA3JnHbNxEXg5iysqCWxN9j83d7/epTYBZflqQnTyCC4N7yZXn/dMM+bEmyhQPGjhCkNZLx4vZuChH1PYw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12786,8 +12598,6 @@ }, "node_modules/@opentelemetry/exporter-trace-otlp-http": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.57.2.tgz", - "integrity": "sha512-sB/gkSYFu+0w2dVQ0PWY9fAMl172PKMZ/JrHkkW8dmjCL0CYkmXeE+ssqIL/yBUTPOvpLIpenX5T9RwXRBW/3g==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12806,8 +12616,6 @@ }, "node_modules/@opentelemetry/exporter-trace-otlp-proto": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.57.2.tgz", - "integrity": "sha512-awDdNRMIwDvUtoRYxRhja5QYH6+McBLtoz1q9BeEsskhZcrGmH/V1fWpGx8n+Rc+542e8pJA6y+aullbIzQmlw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12826,8 +12634,6 @@ }, "node_modules/@opentelemetry/exporter-zipkin": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.30.1.tgz", - "integrity": "sha512-6S2QIMJahIquvFaaxmcwpvQQRD/YFaMTNoIxrfPIPOeITN+a8lfEcPDxNxn8JDAaxkg+4EnXhz8upVDYenoQjA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12845,8 +12651,6 @@ }, "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -12855,8 +12659,6 @@ }, "node_modules/@opentelemetry/instrumentation": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", - "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12876,8 +12678,6 @@ }, "node_modules/@opentelemetry/otlp-exporter-base": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.57.2.tgz", - "integrity": "sha512-XdxEzL23Urhidyebg5E6jZoaiW5ygP/mRjxLHixogbqwDy2Faduzb5N0o/Oi+XTIJu+iyxXdVORjXax+Qgfxag==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12893,8 +12693,6 @@ }, "node_modules/@opentelemetry/otlp-grpc-exporter-base": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.57.2.tgz", - "integrity": "sha512-USn173KTWy0saqqRB5yU9xUZ2xdgb1Rdu5IosJnm9aV4hMTuFFRTUsQxbgc24QxpCHeoKzzCSnS/JzdV0oM2iQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12912,8 +12710,6 @@ }, "node_modules/@opentelemetry/otlp-transformer": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.57.2.tgz", - "integrity": "sha512-48IIRj49gbQVK52jYsw70+Jv+JbahT8BqT2Th7C4H7RCM9d0gZ5sgNPoMpWldmfjvIsSgiGJtjfk9MeZvjhoig==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12934,8 +12730,6 @@ }, "node_modules/@opentelemetry/propagator-b3": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.30.1.tgz", - "integrity": "sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12950,8 +12744,6 @@ }, "node_modules/@opentelemetry/propagator-jaeger": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.30.1.tgz", - "integrity": "sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12966,8 +12758,6 @@ }, "node_modules/@opentelemetry/resources": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", - "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -12983,8 +12773,6 @@ }, "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -12993,8 +12781,6 @@ }, "node_modules/@opentelemetry/sdk-logs": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.57.2.tgz", - "integrity": "sha512-TXFHJ5c+BKggWbdEQ/inpgIzEmS2BGQowLE9UhsMd7YYlUfBQJ4uax0VF/B5NYigdM/75OoJGhAV3upEhK+3gg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13011,8 +12797,6 @@ }, "node_modules/@opentelemetry/sdk-metrics": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", - "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13028,8 +12812,6 @@ }, "node_modules/@opentelemetry/sdk-node": { "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.57.2.tgz", - "integrity": "sha512-8BaeqZyN5sTuPBtAoY+UtKwXBdqyuRKmekN5bFzAO40CgbGzAxfTpiL3PBerT7rhZ7p2nBdq7FaMv/tBQgHE4A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13063,8 +12845,6 @@ }, "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -13073,8 +12853,6 @@ }, "node_modules/@opentelemetry/sdk-trace-base": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", - "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13091,8 +12869,6 @@ }, "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -13101,8 +12877,6 @@ }, "node_modules/@opentelemetry/sdk-trace-node": { "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.30.1.tgz", - "integrity": "sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13122,8 +12896,6 @@ }, "node_modules/@opentelemetry/semantic-conventions": { "version": "1.30.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.30.0.tgz", - "integrity": "sha512-4VlGgo32k2EQ2wcCY3vEU28A0O13aOtHz3Xt2/2U5FAh9EfhD6t6DqL5Z6yAnRCntbTFDU4YfbpyzSlHNWycPw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -13163,36 +12935,26 @@ }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -13202,36 +12964,26 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true, "license": "BSD-3-Clause" }, @@ -14366,13 +14118,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tsconfig/node18": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.4.tgz", - "integrity": "sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/adm-zip": { "version": "0.4.34", "dev": true, @@ -14547,8 +14292,6 @@ }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, "license": "MIT" }, @@ -14571,9 +14314,8 @@ }, "node_modules/@types/lokijs": { "version": "1.5.14", - "resolved": "https://registry.npmjs.org/@types/lokijs/-/lokijs-1.5.14.tgz", - "integrity": "sha512-4Fic47BX3Qxr8pd12KT6/T1XWU8dOlJBIp1jGoMbaDbiEvdv50rAii+B3z1b/J2pvMywcVP+DBPGP5/lgLOKGA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/markdown-it": { "version": "13.0.2", @@ -14704,8 +14446,6 @@ }, "node_modules/@types/shimmer": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", - "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", "dev": true, "license": "MIT" }, @@ -16142,8 +15882,6 @@ }, "node_modules/axios": { "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "dev": true, "license": "MIT", "dependencies": { @@ -16865,8 +16603,6 @@ }, "node_modules/cjs-module-lexer": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "dev": true, "license": "MIT" }, @@ -18833,8 +18569,6 @@ }, "node_modules/fast-uri": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true, "funding": [ { @@ -19611,8 +19345,6 @@ }, "node_modules/hpagent": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", - "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", "dev": true, "license": "MIT", "engines": { @@ -19905,8 +19637,6 @@ }, "node_modules/import-in-the-middle": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.13.1.tgz", - "integrity": "sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -20091,8 +19821,6 @@ }, "node_modules/is-core-module": { "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -20147,8 +19875,6 @@ }, "node_modules/is-electron": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", - "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==", "dev": true, "license": "MIT" }, @@ -21103,8 +20829,6 @@ }, "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "dev": true, "license": "MIT" }, @@ -21146,13 +20870,10 @@ }, "node_modules/lokijs": { "version": "1.5.12", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz", - "integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==" + "license": "MIT" }, "node_modules/long": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", - "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", "dev": true, "license": "Apache-2.0" }, @@ -21184,8 +20905,6 @@ }, "node_modules/mac-ca": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/mac-ca/-/mac-ca-3.1.1.tgz", - "integrity": "sha512-OmXW0O2HdZrL+CPbjvDJ68UxNdAtRfzzUaGqzRqwaFoU+BXlk6BFoJmNJSZv9wEAjMClIFoRA/GtGcbqgHY3kQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -21768,8 +21487,6 @@ }, "node_modules/module-details-from-path": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==", "dev": true, "license": "MIT" }, @@ -22519,8 +22236,6 @@ }, "node_modules/pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, "license": "MIT", "engines": { @@ -22894,8 +22609,6 @@ }, "node_modules/protobufjs": { "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "dev": true, "hasInstallScript": true, "license": "BSD-3-Clause", @@ -22939,8 +22652,6 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true, "license": "MIT" }, @@ -23461,8 +23172,6 @@ }, "node_modules/require-in-the-middle": { "version": "7.5.2", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", - "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -23476,8 +23185,6 @@ }, "node_modules/require-in-the-middle/node_modules/debug": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { @@ -23494,8 +23201,6 @@ }, "node_modules/require-in-the-middle/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, @@ -23506,8 +23211,6 @@ }, "node_modules/resolve": { "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { @@ -23686,8 +23389,6 @@ }, "node_modules/rxjs": { "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -24084,8 +23785,6 @@ }, "node_modules/shimmer": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", "dev": true, "license": "BSD-2-Clause" }, @@ -25173,8 +24872,6 @@ }, "node_modules/typescript": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "license": "Apache-2.0", "bin": { @@ -25243,8 +24940,6 @@ }, "node_modules/undici": { "version": "6.21.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz", - "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==", "dev": true, "license": "MIT", "engines": { @@ -25525,8 +25220,7 @@ }, "node_modules/vscode-languageserver-textdocument": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", - "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" + "license": "MIT" }, "node_modules/vscode-languageserver-types": { "version": "3.17.5", @@ -26216,8 +25910,6 @@ }, "node_modules/win-ca": { "version": "3.5.1", - "resolved": "https://registry.npmjs.org/win-ca/-/win-ca-3.5.1.tgz", - "integrity": "sha512-RNy9gpBS6cxWHjfbqwBA7odaHyT+YQNhtdpJZwYCFoxB/Dq22oeOZ9YCXMwjhLytKpo7JJMnKdJ/ve7N12zzfQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -26230,8 +25922,6 @@ }, "node_modules/win-ca/node_modules/make-dir": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -26694,7 +26384,7 @@ }, "packages/amazonq": { "name": "amazon-q-vscode", - "version": "1.61.0-SNAPSHOT", + "version": "1.65.0-SNAPSHOT", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" @@ -26737,7 +26427,7 @@ "@aws-sdk/s3-request-presigner": "<3.731.0", "@aws-sdk/smithy-client": "<3.731.0", "@aws-sdk/util-arn-parser": "<3.731.0", - "@aws/mynah-ui": "^4.30.1", + "@aws/mynah-ui": "^4.30.3", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", "@smithy/fetch-http-handler": "^5.0.1", @@ -26792,9 +26482,10 @@ }, "devDependencies": { "@aws-sdk/types": "^3.13.1", - "@aws/chat-client-ui-types": "^0.1.12", - "@aws/language-server-runtimes": "^0.2.58", - "@aws/language-server-runtimes-types": "^0.1.13", + "@aws/chat-client": "^0.1.4", + "@aws/chat-client-ui-types": "^0.1.24", + "@aws/language-server-runtimes": "^0.2.70", + "@aws/language-server-runtimes-types": "^0.1.26", "@cspotcode/source-map-support": "^0.8.1", "@sinonjs/fake-timers": "^10.0.2", "@types/adm-zip": "^0.4.34", @@ -26970,8 +26661,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb-elastic/node_modules/@smithy/middleware-retry": { "version": "3.0.34", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.34.tgz", - "integrity": "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.12", @@ -26990,8 +26679,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb-elastic/node_modules/@smithy/node-http-handler": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", - "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.9", @@ -27006,8 +26693,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb-elastic/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27019,8 +26704,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb-elastic/node_modules/@smithy/service-error-classification": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", - "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2" @@ -27031,8 +26714,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb-elastic/node_modules/@smithy/util-retry": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^3.0.11", @@ -27056,8 +26737,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb/node_modules/@smithy/middleware-retry": { "version": "3.0.34", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.34.tgz", - "integrity": "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.12", @@ -27076,8 +26755,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb/node_modules/@smithy/node-http-handler": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", - "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.9", @@ -27092,8 +26769,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27105,8 +26780,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb/node_modules/@smithy/service-error-classification": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", - "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2" @@ -27117,8 +26790,6 @@ }, "packages/core/node_modules/@aws-sdk/client-docdb/node_modules/@smithy/util-retry": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^3.0.11", @@ -27240,8 +26911,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/middleware-retry": { "version": "3.0.34", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.34.tgz", - "integrity": "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.12", @@ -27260,8 +26929,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/node-http-handler": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", - "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.9", @@ -27276,8 +26943,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27289,8 +26954,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/service-error-classification": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", - "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2" @@ -27301,8 +26964,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/util-retry": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^3.0.11", @@ -27326,8 +26987,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso/node_modules/@smithy/middleware-retry": { "version": "3.0.34", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.34.tgz", - "integrity": "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.12", @@ -27346,8 +27005,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso/node_modules/@smithy/node-http-handler": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", - "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.9", @@ -27362,8 +27019,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27375,8 +27030,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso/node_modules/@smithy/service-error-classification": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", - "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2" @@ -27387,8 +27040,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sso/node_modules/@smithy/util-retry": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^3.0.11", @@ -27461,8 +27112,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sts/node_modules/@smithy/middleware-retry": { "version": "3.0.34", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.34.tgz", - "integrity": "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^3.1.12", @@ -27481,8 +27130,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sts/node_modules/@smithy/node-http-handler": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", - "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.9", @@ -27497,8 +27144,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sts/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27510,8 +27155,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sts/node_modules/@smithy/service-error-classification": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", - "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2" @@ -27522,8 +27165,6 @@ }, "packages/core/node_modules/@aws-sdk/client-sts/node_modules/@smithy/util-retry": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", - "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^3.0.11", @@ -27556,8 +27197,6 @@ }, "packages/core/node_modules/@aws-sdk/core/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27599,8 +27238,6 @@ }, "packages/core/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.3.tgz", - "integrity": "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^3.1.9", @@ -27615,8 +27252,6 @@ }, "packages/core/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27652,8 +27287,6 @@ }, "packages/core/node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/shared-ini-file-loader": { "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", - "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27686,8 +27319,6 @@ }, "packages/core/node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/shared-ini-file-loader": { "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", - "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27716,8 +27347,6 @@ }, "packages/core/node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/shared-ini-file-loader": { "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", - "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27759,8 +27388,6 @@ }, "packages/core/node_modules/@aws-sdk/middleware-host-header/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27797,8 +27424,6 @@ }, "packages/core/node_modules/@aws-sdk/middleware-recursion-detection/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27826,8 +27451,6 @@ }, "packages/core/node_modules/@aws-sdk/middleware-sdk-rds/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27855,8 +27478,6 @@ }, "packages/core/node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/protocol-http": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27900,8 +27521,6 @@ }, "packages/core/node_modules/@aws-sdk/token-providers/node_modules/@smithy/shared-ini-file-loader": { "version": "3.1.12", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", - "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^3.7.2", @@ -27958,8 +27577,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz", - "integrity": "sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==", "license": "Apache-2.0", "dependencies": { "@smithy/protocol-http": "^5.1.0", @@ -27974,8 +27591,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/is-array-buffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -27986,8 +27601,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/querystring-builder": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz", - "integrity": "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28000,8 +27613,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28012,8 +27623,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/util-base64": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -28026,8 +27635,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/util-buffer-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", @@ -28039,8 +27646,6 @@ }, "packages/core/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/util-utf8": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -28062,8 +27667,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz", - "integrity": "sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.0.2", @@ -28082,8 +27685,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/core": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.2.0.tgz", - "integrity": "sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q==", "license": "Apache-2.0", "dependencies": { "@smithy/middleware-serde": "^4.0.3", @@ -28101,8 +27702,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/is-array-buffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28113,8 +27712,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/middleware-endpoint": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.0.tgz", - "integrity": "sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.2.0", @@ -28132,8 +27729,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/middleware-serde": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz", - "integrity": "sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28145,8 +27740,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/middleware-stack": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz", - "integrity": "sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28158,8 +27751,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/node-config-provider": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz", - "integrity": "sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.0.2", @@ -28173,8 +27764,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/property-provider": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.2.tgz", - "integrity": "sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28186,8 +27775,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/smithy-client": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.2.0.tgz", - "integrity": "sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw==", "license": "Apache-2.0", "dependencies": { "@smithy/core": "^3.2.0", @@ -28204,8 +27791,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28216,8 +27801,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/url-parser": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.2.tgz", - "integrity": "sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==", "license": "Apache-2.0", "dependencies": { "@smithy/querystring-parser": "^4.0.2", @@ -28230,8 +27813,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-base64": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -28244,8 +27825,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-body-length-browser": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28256,8 +27835,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-buffer-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", @@ -28269,8 +27846,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-middleware": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.2.tgz", - "integrity": "sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28282,8 +27857,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-stream": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.0.tgz", - "integrity": "sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==", "license": "Apache-2.0", "dependencies": { "@smithy/fetch-http-handler": "^5.0.2", @@ -28301,8 +27874,6 @@ }, "packages/core/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-utf8": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -28314,8 +27885,6 @@ }, "packages/core/node_modules/@smithy/node-http-handler": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz", - "integrity": "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.2", @@ -28330,8 +27899,6 @@ }, "packages/core/node_modules/@smithy/node-http-handler/node_modules/@smithy/abort-controller": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.2.tgz", - "integrity": "sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28343,8 +27910,6 @@ }, "packages/core/node_modules/@smithy/node-http-handler/node_modules/@smithy/querystring-builder": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz", - "integrity": "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28357,8 +27922,6 @@ }, "packages/core/node_modules/@smithy/node-http-handler/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28369,8 +27932,6 @@ }, "packages/core/node_modules/@smithy/protocol-http": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.0.tgz", - "integrity": "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28382,8 +27943,6 @@ }, "packages/core/node_modules/@smithy/protocol-http/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28394,8 +27953,6 @@ }, "packages/core/node_modules/@smithy/querystring-parser": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz", - "integrity": "sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28407,8 +27964,6 @@ }, "packages/core/node_modules/@smithy/querystring-parser/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28419,8 +27974,6 @@ }, "packages/core/node_modules/@smithy/service-error-classification": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz", - "integrity": "sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0" @@ -28431,8 +27984,6 @@ }, "packages/core/node_modules/@smithy/service-error-classification/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28443,8 +27994,6 @@ }, "packages/core/node_modules/@smithy/shared-ini-file-loader": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz", - "integrity": "sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -28456,8 +28005,6 @@ }, "packages/core/node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28479,8 +28026,6 @@ }, "packages/core/node_modules/@smithy/util-hex-encoding": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28491,8 +28036,6 @@ }, "packages/core/node_modules/@smithy/util-retry": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.2.tgz", - "integrity": "sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg==", "license": "Apache-2.0", "dependencies": { "@smithy/service-error-classification": "^4.0.2", @@ -28505,8 +28048,6 @@ }, "packages/core/node_modules/@smithy/util-retry/node_modules/@smithy/types": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28517,8 +28058,6 @@ }, "packages/core/node_modules/@smithy/util-uri-escape": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -28559,7 +28098,7 @@ }, "packages/toolkit": { "name": "aws-toolkit-vscode", - "version": "3.56.0-SNAPSHOT", + "version": "3.59.0-SNAPSHOT", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" @@ -28638,6 +28177,18 @@ "node": ">=18.0.0" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", "license": "Apache-2.0", @@ -28745,8 +28296,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/client-sso": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.731.0.tgz", - "integrity": "sha512-O4C/UYGgqMsBg21MMApFdgyh8BX568hQhbdoNFmRVTBoSnCZ3w+H4a1wBPX4Gyl0NX+ab6Xxo9rId8HiyPXJ0A==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -28794,8 +28343,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/core": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.731.0.tgz", - "integrity": "sha512-ithBN1VWASkvAIlozJmenqDvNnFddr/SZXAs58+jCnBHgy3tXLHABZGVNCjetZkHRqNdXEO1kirnoxaFeXMeDA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -28816,8 +28363,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-env": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.731.0.tgz", - "integrity": "sha512-h0WWZg4QMLgFVyIvQrC43zpVqsUWg1mPM1clpogP43B8+wEhDEQ4qWRzvFs3dQ4cqx/FLyDUZZF4cqgd94z7kw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -28832,8 +28377,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-http": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.731.0.tgz", - "integrity": "sha512-iRtrjtcYaWgbvtu2cvDhIsPWXZGvhy1Hgks4682MEBNTc9AUwlfvDrYz2EEnTtJJyrbOdEHVrYrzqD8qPyVLCg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -28853,8 +28396,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-ini": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.731.1.tgz", - "integrity": "sha512-0M0ejuqW8iHNcTH2ZXSY9m+I7Y06qVkj6k3vfQU9XaB//mTUCxxfGfqWAtgfr7Yi73egABTcPc0jyPdcvSW4Kw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -28877,8 +28418,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-node": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.731.1.tgz", - "integrity": "sha512-5c0ZiagMTPmWilXNffeXJCLoCEz97jilHr3QJWwf2GaTay4tzN+Ld71rpdfEenzUR7fuxEWFfVlwQbFOzFNYHg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.731.0", @@ -28900,8 +28439,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-process": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.731.0.tgz", - "integrity": "sha512-6yNMY6q3xHLbs2f2+C6GhvMrjTgtFBiPJJqKaPLsTIhlTRvh4sK8pGm3ITcma0jOxtPDIuoPfBAV8N8XVMBlZg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -28917,8 +28454,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-sso": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.731.1.tgz", - "integrity": "sha512-p1tp+rMUf5YNQLr8rVRmDgNtKGYLL0KCdq3K2hwwvFnx9MjReF1sA4lfm3xWsxBQM+j3QN9AvMQqBzDJ+NOSdw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-sso": "3.731.0", @@ -28936,8 +28471,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/credential-provider-web-identity": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.731.1.tgz", - "integrity": "sha512-+ynAvEGWDR5ZJFxgpwwzhvlQ3WQ7BleWXU6JwpIw3yFrD4eZEn85b8DZC1aEz7C9kb1HSV6B3gpqHqlyS6wj8g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -28953,8 +28486,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/middleware-host-header": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.731.0.tgz", - "integrity": "sha512-ndAJsm5uWPPJRZowLKpB1zuL17qWlWVtCJP4I/ynBkq1PU1DijDXBul2UZaG6Mpvsgms1NXo/h9noHuK7T3v8w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -28968,8 +28499,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/middleware-logger": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.731.0.tgz", - "integrity": "sha512-IIZrOdjbY2vKzPJPrwE7FoFQCIPEL6UqURi8LEaiVyCag4p2fvaTN5pgKuQtGC2+iYd/HHcGT4qn2bAqF5Jmmw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -28982,8 +28511,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.731.0.tgz", - "integrity": "sha512-y6FLASB1iKWuR5tUipMyo77bt0lEl3OnCrrd2xw/H24avq1HhJjjPR0HHhJE6QKJzF/FYXeV88tcyPSMe32VDw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -28997,8 +28524,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/middleware-user-agent": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.731.0.tgz", - "integrity": "sha512-Ngr2Gz0aec/uduoKaO3srN52SYkEHndYtFzkK/gDUyQwQzi4ha2eIisxPiuHEX6RvXT31V9ouqn/YtVkt0R76A==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -29015,8 +28540,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/nested-clients": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.731.1.tgz", - "integrity": "sha512-/L8iVrulnXZl+kgmTn+oxRxNnhcSIbf+r12C06vGUq60w0YMidLvxJZN7vt8H9SnCAGCHqud2MS7ExCEvhc0gA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -29064,8 +28587,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/region-config-resolver": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.731.0.tgz", - "integrity": "sha512-XlDpRNkDVHF59f07JmkuAidEv//m3hT6/JL85h0l3+zrpaRWhf8n8lVUyAPNq35ZujK8AcorYM+93u7hdWsliQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -29081,8 +28602,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/token-providers": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.731.1.tgz", - "integrity": "sha512-t34GOPwBZsX7zGHjiTXmMHGY3kHM7fLiQ60Jqk0On9P0ASHTDE5U75RgCXboE3u+qEv9wyKyaqMNyMWj9qQlFg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/nested-clients": "3.731.1", @@ -29098,8 +28617,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/types": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.731.0.tgz", - "integrity": "sha512-NrdkJg6oOUbXR2r9WvHP408CLyvST8cJfp1/jP9pemtjvjPoh6NukbCtiSFdOOb1eryP02CnqQWItfJC1p2Y/Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.0.0", @@ -29111,8 +28628,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/util-endpoints": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.731.0.tgz", - "integrity": "sha512-riztxTAfncFS9yQWcBJffGgOgLoKSa63ph+rxWJxKl6BHAmWEvHICj1qDcVmnWfIcvJ5cClclY75l9qKaUH7rQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -29125,19 +28640,17 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/util-locate-window": { - "version": "3.693.0", + "version": "3.723.0", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.731.0.tgz", - "integrity": "sha512-EnYXxTkCNCjTTBjW/pelRPv4Thsi9jepoB6qQjPMA9/ixrZ71BhhQecz9kgqzZLR9BPCwb6hgJ/Yd702jqJ4aQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -29148,8 +28661,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@aws-sdk/util-user-agent-node": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.731.0.tgz", - "integrity": "sha512-Rze78Ym5Bx7aWMvmZE2iL3JPo2INNCC5N9rLVx98Gg1G0ZaxclVRUvJrh1AojNlOFxU+otkxAe7FA3Foy2iLLQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/middleware-user-agent": "3.731.0", @@ -29171,7 +28682,7 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@babel/runtime": { - "version": "7.26.0", + "version": "7.26.9", "dev": true, "license": "MIT", "dependencies": { @@ -29182,12 +28693,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/abort-controller": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.2.tgz", - "integrity": "sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29195,15 +28704,13 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/config-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.0.tgz", - "integrity": "sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" }, "engines": { @@ -29211,17 +28718,15 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.2.0.tgz", - "integrity": "sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q==", + "version": "3.1.5", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.3", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-stream": "^4.2.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -29230,15 +28735,13 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/credential-provider-imds": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz", - "integrity": "sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" }, "engines": { @@ -29246,13 +28749,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/eventstream-codec": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.2.tgz", - "integrity": "sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" }, @@ -29261,13 +28762,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/eventstream-serde-browser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.2.tgz", - "integrity": "sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-serde-universal": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29275,12 +28774,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.0.tgz", - "integrity": "sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29288,13 +28785,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/eventstream-serde-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.2.tgz", - "integrity": "sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-serde-universal": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29302,13 +28797,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/eventstream-serde-universal": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.2.tgz", - "integrity": "sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-codec": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29316,14 +28809,12 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/fetch-http-handler": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz", - "integrity": "sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==", + "version": "5.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.0", - "@smithy/querystring-builder": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" }, @@ -29332,12 +28823,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/hash-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.2.tgz", - "integrity": "sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" @@ -29347,12 +28836,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/invalid-dependency": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz", - "integrity": "sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29361,8 +28848,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/is-array-buffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29372,13 +28857,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/middleware-content-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz", - "integrity": "sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29386,18 +28869,16 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/middleware-endpoint": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.0.tgz", - "integrity": "sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA==", + "version": "4.0.6", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.2.0", - "@smithy/middleware-serde": "^4.0.3", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", - "@smithy/util-middleware": "^4.0.2", + "@smithy/core": "^3.1.5", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" }, "engines": { @@ -29405,18 +28886,16 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/middleware-retry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz", - "integrity": "sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg==", + "version": "4.0.7", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/service-error-classification": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-retry": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/service-error-classification": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -29425,12 +28904,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/middleware-serde": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz", - "integrity": "sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==", + "version": "4.0.2", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29438,12 +28915,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/middleware-stack": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz", - "integrity": "sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29451,14 +28926,12 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/node-config-provider": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz", - "integrity": "sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29466,15 +28939,13 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/node-http-handler": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz", - "integrity": "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==", + "version": "4.0.3", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/querystring-builder": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/abort-controller": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29482,12 +28953,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/property-provider": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.2.tgz", - "integrity": "sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29495,12 +28964,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/protocol-http": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.0.tgz", - "integrity": "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==", + "version": "5.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29508,12 +28975,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/querystring-builder": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz", - "integrity": "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" }, @@ -29522,12 +28987,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/querystring-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz", - "integrity": "sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29535,24 +28998,20 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/service-error-classification": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz", - "integrity": "sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0" + "@smithy/types": "^4.1.0" }, "engines": { "node": ">=18.0.0" } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/shared-ini-file-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz", - "integrity": "sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29560,16 +29019,14 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/signature-v4": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.2.tgz", - "integrity": "sha512-Mz+mc7okA73Lyz8zQKJNyr7lIcHLiPYp0+oiqiMNc/t7/Kf2BENs5d63pEj7oPqdjaum6g0Fc8wC78dY1TgtXw==", + "version": "5.0.1", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.1", "@smithy/util-uri-escape": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" @@ -29579,17 +29036,15 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/smithy-client": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.2.0.tgz", - "integrity": "sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw==", + "version": "4.1.6", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.2.0", - "@smithy/middleware-endpoint": "^4.1.0", - "@smithy/middleware-stack": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", - "@smithy/util-stream": "^4.2.0", + "@smithy/core": "^3.1.5", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" }, "engines": { @@ -29597,9 +29052,7 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/types": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", + "version": "4.1.0", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29609,13 +29062,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/url-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.2.tgz", - "integrity": "sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/querystring-parser": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29624,8 +29075,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-base64": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -29638,8 +29087,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-body-length-browser": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29650,8 +29097,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-body-length-node": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", - "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29662,8 +29107,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-buffer-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", @@ -29675,8 +29118,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-config-provider": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", - "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29686,14 +29127,12 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.8.tgz", - "integrity": "sha512-ZTypzBra+lI/LfTYZeop9UjoJhhGRTg3pxrNpfSTQLd3AJ37r2z4AXTKpq1rFXiiUIJsYyFgNJdjWRGP/cbBaQ==", + "version": "4.0.7", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -29702,17 +29141,15 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.8.tgz", - "integrity": "sha512-Rgk0Jc/UDfRTzVthye/k2dDsz5Xxs9LZaKCNPgJTRyoyBoeiNCnHsYGOyu1PKN+sDyPnJzMOz22JbwxzBp9NNA==", + "version": "4.0.7", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.1.0", - "@smithy/credential-provider-imds": "^4.0.2", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "@smithy/config-resolver": "^4.0.1", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29720,13 +29157,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-endpoints": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz", - "integrity": "sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ==", + "version": "3.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29735,8 +29170,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-hex-encoding": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29746,12 +29179,10 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-middleware": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.2.tgz", - "integrity": "sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29759,13 +29190,11 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-retry": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.2.tgz", - "integrity": "sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/service-error-classification": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -29773,14 +29202,12 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-stream": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.0.tgz", - "integrity": "sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==", + "version": "4.1.2", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/types": "^4.2.0", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", @@ -29793,8 +29220,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-uri-escape": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -29805,8 +29230,6 @@ }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@smithy/util-utf8": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -29816,10 +29239,13 @@ "node": ">=18.0.0" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@tsconfig/node18": { + "version": "18.2.4", + "dev": true, + "license": "MIT" + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/@types/node": { - "version": "18.19.83", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.83.tgz", - "integrity": "sha512-D69JeR5SfFS5H6FLbUaS0vE4r1dGhmMBbG4Ed6BNS4wkDK8GZjsdCShT5LCN59vOHEUHnFCY9J4aclXlIphMkA==", + "version": "18.19.80", "dev": true, "license": "MIT", "dependencies": { @@ -29857,6 +29283,10 @@ "dev": true, "license": "MIT" }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/bowser": { + "version": "2.11.0", + "license": "MIT" + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -29973,7 +29403,7 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/downlevel-dts/node_modules/typescript": { - "version": "5.8.0-dev.20250129", + "version": "5.9.0-dev.20250324", "dev": true, "license": "Apache-2.0", "bin": { @@ -30022,6 +29452,14 @@ "dev": true, "license": "ISC" }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/get-caller-file": { "version": "2.0.5", "dev": true, @@ -30057,6 +29495,17 @@ "node": ">=8" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/inflight": { "version": "1.0.6", "dev": true, @@ -30079,6 +29528,20 @@ "node": ">= 0.10" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -30119,6 +29582,11 @@ "node": ">=0.10.0" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/rechoir": { "version": "0.6.2", "dev": true, @@ -30142,6 +29610,25 @@ "node": ">=0.10.0" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/resolve": { + "version": "1.22.10", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/rimraf": { "version": "3.0.2", "dev": true, @@ -30173,7 +29660,7 @@ "license": "0BSD" }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/semver": { - "version": "7.6.3", + "version": "7.7.1", "dev": true, "license": "ISC", "bin": { @@ -30228,7 +29715,13 @@ } }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/strnum": { - "version": "1.0.5", + "version": "1.1.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT" }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/supports-color": { @@ -30245,6 +29738,17 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/tree-kill": { "version": "1.2.2", "dev": true, @@ -30257,10 +29761,20 @@ "version": "2.8.1", "license": "0BSD" }, + "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/typescript": { + "version": "5.2.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, "license": "MIT" }, @@ -30387,6 +29901,18 @@ "node": ">=18.0.0" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", "license": "Apache-2.0", @@ -30494,8 +30020,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/core": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.731.0.tgz", - "integrity": "sha512-ithBN1VWASkvAIlozJmenqDvNnFddr/SZXAs58+jCnBHgy3tXLHABZGVNCjetZkHRqNdXEO1kirnoxaFeXMeDA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30516,8 +30040,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/middleware-host-header": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.731.0.tgz", - "integrity": "sha512-ndAJsm5uWPPJRZowLKpB1zuL17qWlWVtCJP4I/ynBkq1PU1DijDXBul2UZaG6Mpvsgms1NXo/h9noHuK7T3v8w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30531,8 +30053,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/middleware-logger": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.731.0.tgz", - "integrity": "sha512-IIZrOdjbY2vKzPJPrwE7FoFQCIPEL6UqURi8LEaiVyCag4p2fvaTN5pgKuQtGC2+iYd/HHcGT4qn2bAqF5Jmmw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30545,8 +30065,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/middleware-recursion-detection": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.731.0.tgz", - "integrity": "sha512-y6FLASB1iKWuR5tUipMyo77bt0lEl3OnCrrd2xw/H24avq1HhJjjPR0HHhJE6QKJzF/FYXeV88tcyPSMe32VDw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30560,8 +30078,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/middleware-user-agent": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.731.0.tgz", - "integrity": "sha512-Ngr2Gz0aec/uduoKaO3srN52SYkEHndYtFzkK/gDUyQwQzi4ha2eIisxPiuHEX6RvXT31V9ouqn/YtVkt0R76A==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.731.0", @@ -30578,8 +30094,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/nested-clients": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.731.1.tgz", - "integrity": "sha512-/L8iVrulnXZl+kgmTn+oxRxNnhcSIbf+r12C06vGUq60w0YMidLvxJZN7vt8H9SnCAGCHqud2MS7ExCEvhc0gA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -30627,8 +30141,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/region-config-resolver": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.731.0.tgz", - "integrity": "sha512-XlDpRNkDVHF59f07JmkuAidEv//m3hT6/JL85h0l3+zrpaRWhf8n8lVUyAPNq35ZujK8AcorYM+93u7hdWsliQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30644,8 +30156,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/token-providers": { "version": "3.731.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.731.1.tgz", - "integrity": "sha512-t34GOPwBZsX7zGHjiTXmMHGY3kHM7fLiQ60Jqk0On9P0ASHTDE5U75RgCXboE3u+qEv9wyKyaqMNyMWj9qQlFg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/nested-clients": "3.731.1", @@ -30661,8 +30171,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/types": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.731.0.tgz", - "integrity": "sha512-NrdkJg6oOUbXR2r9WvHP408CLyvST8cJfp1/jP9pemtjvjPoh6NukbCtiSFdOOb1eryP02CnqQWItfJC1p2Y/Q==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.0.0", @@ -30674,8 +30182,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/util-endpoints": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.731.0.tgz", - "integrity": "sha512-riztxTAfncFS9yQWcBJffGgOgLoKSa63ph+rxWJxKl6BHAmWEvHICj1qDcVmnWfIcvJ5cClclY75l9qKaUH7rQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30688,19 +30194,17 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/util-locate-window": { - "version": "3.693.0", + "version": "3.723.0", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/util-user-agent-browser": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.731.0.tgz", - "integrity": "sha512-EnYXxTkCNCjTTBjW/pelRPv4Thsi9jepoB6qQjPMA9/ixrZ71BhhQecz9kgqzZLR9BPCwb6hgJ/Yd702jqJ4aQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.731.0", @@ -30711,8 +30215,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@aws-sdk/util-user-agent-node": { "version": "3.731.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.731.0.tgz", - "integrity": "sha512-Rze78Ym5Bx7aWMvmZE2iL3JPo2INNCC5N9rLVx98Gg1G0ZaxclVRUvJrh1AojNlOFxU+otkxAe7FA3Foy2iLLQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/middleware-user-agent": "3.731.0", @@ -30734,7 +30236,7 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@babel/runtime": { - "version": "7.26.0", + "version": "7.26.9", "dev": true, "license": "MIT", "dependencies": { @@ -30745,12 +30247,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/abort-controller": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.2.tgz", - "integrity": "sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30758,15 +30258,13 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/config-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.0.tgz", - "integrity": "sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" }, "engines": { @@ -30774,17 +30272,15 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.2.0.tgz", - "integrity": "sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q==", + "version": "3.1.5", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.3", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-stream": "^4.2.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -30793,15 +30289,13 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/credential-provider-imds": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz", - "integrity": "sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" }, "engines": { @@ -30809,13 +30303,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/eventstream-codec": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.2.tgz", - "integrity": "sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" }, @@ -30824,13 +30316,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/eventstream-serde-browser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.2.tgz", - "integrity": "sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-serde-universal": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30838,12 +30328,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.0.tgz", - "integrity": "sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30851,13 +30339,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/eventstream-serde-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.2.tgz", - "integrity": "sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-serde-universal": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30865,13 +30351,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/eventstream-serde-universal": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.2.tgz", - "integrity": "sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/eventstream-codec": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30879,14 +30363,12 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/fetch-http-handler": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz", - "integrity": "sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==", + "version": "5.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.0", - "@smithy/querystring-builder": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" }, @@ -30895,12 +30377,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/hash-node": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.2.tgz", - "integrity": "sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" @@ -30910,12 +30390,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/invalid-dependency": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz", - "integrity": "sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30924,8 +30402,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/is-array-buffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -30935,13 +30411,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/middleware-content-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz", - "integrity": "sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -30949,18 +30423,16 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/middleware-endpoint": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.0.tgz", - "integrity": "sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA==", + "version": "4.0.6", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.2.0", - "@smithy/middleware-serde": "^4.0.3", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", - "@smithy/url-parser": "^4.0.2", - "@smithy/util-middleware": "^4.0.2", + "@smithy/core": "^3.1.5", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" }, "engines": { @@ -30968,18 +30440,16 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/middleware-retry": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz", - "integrity": "sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg==", + "version": "4.0.7", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/service-error-classification": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", - "@smithy/util-middleware": "^4.0.2", - "@smithy/util-retry": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/service-error-classification": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -30988,12 +30458,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/middleware-serde": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz", - "integrity": "sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==", + "version": "4.0.2", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31001,12 +30469,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/middleware-stack": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz", - "integrity": "sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31014,14 +30480,12 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/node-config-provider": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz", - "integrity": "sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.2", - "@smithy/shared-ini-file-loader": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31029,15 +30493,13 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/node-http-handler": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz", - "integrity": "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==", + "version": "4.0.3", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/querystring-builder": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/abort-controller": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31045,12 +30507,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/property-provider": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.2.tgz", - "integrity": "sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31058,12 +30518,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/protocol-http": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.0.tgz", - "integrity": "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==", + "version": "5.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31071,12 +30529,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/querystring-builder": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz", - "integrity": "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" }, @@ -31085,12 +30541,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/querystring-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz", - "integrity": "sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31098,24 +30552,20 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/service-error-classification": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz", - "integrity": "sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0" + "@smithy/types": "^4.1.0" }, "engines": { "node": ">=18.0.0" } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/shared-ini-file-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz", - "integrity": "sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31123,16 +30573,14 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/signature-v4": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.2.tgz", - "integrity": "sha512-Mz+mc7okA73Lyz8zQKJNyr7lIcHLiPYp0+oiqiMNc/t7/Kf2BENs5d63pEj7oPqdjaum6g0Fc8wC78dY1TgtXw==", + "version": "5.0.1", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.2", + "@smithy/util-middleware": "^4.0.1", "@smithy/util-uri-escape": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" @@ -31142,17 +30590,15 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/smithy-client": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.2.0.tgz", - "integrity": "sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw==", + "version": "4.1.6", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.2.0", - "@smithy/middleware-endpoint": "^4.1.0", - "@smithy/middleware-stack": "^4.0.2", - "@smithy/protocol-http": "^5.1.0", - "@smithy/types": "^4.2.0", - "@smithy/util-stream": "^4.2.0", + "@smithy/core": "^3.1.5", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" }, "engines": { @@ -31160,9 +30606,7 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/types": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", - "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", + "version": "4.1.0", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -31172,13 +30616,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/url-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.2.tgz", - "integrity": "sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/querystring-parser": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31187,8 +30629,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-base64": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -31201,8 +30641,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-body-length-browser": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -31213,8 +30651,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-body-length-node": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", - "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -31225,8 +30661,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-buffer-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.0.0", @@ -31238,8 +30672,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-config-provider": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", - "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -31249,14 +30681,12 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.8.tgz", - "integrity": "sha512-ZTypzBra+lI/LfTYZeop9UjoJhhGRTg3pxrNpfSTQLd3AJ37r2z4AXTKpq1rFXiiUIJsYyFgNJdjWRGP/cbBaQ==", + "version": "4.0.7", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -31265,17 +30695,15 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.8.tgz", - "integrity": "sha512-Rgk0Jc/UDfRTzVthye/k2dDsz5Xxs9LZaKCNPgJTRyoyBoeiNCnHsYGOyu1PKN+sDyPnJzMOz22JbwxzBp9NNA==", + "version": "4.0.7", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.1.0", - "@smithy/credential-provider-imds": "^4.0.2", - "@smithy/node-config-provider": "^4.0.2", - "@smithy/property-provider": "^4.0.2", - "@smithy/smithy-client": "^4.2.0", - "@smithy/types": "^4.2.0", + "@smithy/config-resolver": "^4.0.1", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31283,13 +30711,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-endpoints": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz", - "integrity": "sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ==", + "version": "3.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31298,8 +30724,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-hex-encoding": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -31309,12 +30733,10 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-middleware": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.2.tgz", - "integrity": "sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.2.0", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31322,13 +30744,11 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-retry": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.2.tgz", - "integrity": "sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg==", + "version": "4.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.0.2", - "@smithy/types": "^4.2.0", + "@smithy/service-error-classification": "^4.0.1", + "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "engines": { @@ -31336,14 +30756,12 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-stream": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.0.tgz", - "integrity": "sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==", + "version": "4.1.2", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.0.2", - "@smithy/node-http-handler": "^4.0.4", - "@smithy/types": "^4.2.0", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", @@ -31356,8 +30774,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-uri-escape": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -31368,8 +30784,6 @@ }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@smithy/util-utf8": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "license": "Apache-2.0", "dependencies": { "@smithy/util-buffer-from": "^4.0.0", @@ -31379,10 +30793,13 @@ "node": ">=18.0.0" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/@tsconfig/node18": { + "version": "18.2.4", + "dev": true, + "license": "MIT" + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/@types/node": { - "version": "18.19.83", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.83.tgz", - "integrity": "sha512-D69JeR5SfFS5H6FLbUaS0vE4r1dGhmMBbG4Ed6BNS4wkDK8GZjsdCShT5LCN59vOHEUHnFCY9J4aclXlIphMkA==", + "version": "18.19.80", "dev": true, "license": "MIT", "dependencies": { @@ -31540,7 +30957,7 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/downlevel-dts/node_modules/typescript": { - "version": "5.9.0-dev.20250314", + "version": "5.9.0-dev.20250324", "dev": true, "license": "Apache-2.0", "bin": { @@ -31589,6 +31006,14 @@ "dev": true, "license": "ISC" }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/get-caller-file": { "version": "2.0.5", "dev": true, @@ -31624,6 +31049,17 @@ "node": ">=8" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/inflight": { "version": "1.0.6", "dev": true, @@ -31646,6 +31082,20 @@ "node": ">= 0.10" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -31686,6 +31136,11 @@ "node": ">=0.10.0" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/rechoir": { "version": "0.6.2", "dev": true, @@ -31709,6 +31164,25 @@ "node": ">=0.10.0" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/resolve": { + "version": "1.22.10", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/rimraf": { "version": "3.0.2", "dev": true, @@ -31740,7 +31214,7 @@ "license": "0BSD" }, "src.gen/@amzn/codewhisperer-streaming/node_modules/semver": { - "version": "7.6.3", + "version": "7.7.1", "dev": true, "license": "ISC", "bin": { @@ -31795,7 +31269,13 @@ } }, "src.gen/@amzn/codewhisperer-streaming/node_modules/strnum": { - "version": "1.0.5", + "version": "1.1.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT" }, "src.gen/@amzn/codewhisperer-streaming/node_modules/supports-color": { @@ -31812,6 +31292,17 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/tree-kill": { "version": "1.2.2", "dev": true, @@ -31824,10 +31315,20 @@ "version": "2.8.1", "license": "0BSD" }, + "src.gen/@amzn/codewhisperer-streaming/node_modules/typescript": { + "version": "5.2.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "src.gen/@amzn/codewhisperer-streaming/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 637fc21649a..30f0497cdb2 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "skippedTestReport": "ts-node ./scripts/skippedTestReport.ts ./packages/amazonq/test/e2e/" }, "devDependencies": { - "@aws-toolkits/telemetry": "^1.0.312", + "@aws-toolkits/telemetry": "^1.0.317", "@playwright/browser-chromium": "^1.43.1", "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", diff --git a/packages/amazonq/.changes/1.61.0.json b/packages/amazonq/.changes/1.61.0.json new file mode 100644 index 00000000000..64b0f4da610 --- /dev/null +++ b/packages/amazonq/.changes/1.61.0.json @@ -0,0 +1,14 @@ +{ + "date": "2025-04-22", + "version": "1.61.0", + "entries": [ + { + "type": "Bug Fix", + "description": "Some users not signaled they needed to select a Region Profile to get features working" + }, + { + "type": "bugfix", + "description": "/review: disable auto-review by default" + } + ] +} \ No newline at end of file diff --git a/packages/amazonq/.changes/1.62.0.json b/packages/amazonq/.changes/1.62.0.json new file mode 100644 index 00000000000..530f26ccb29 --- /dev/null +++ b/packages/amazonq/.changes/1.62.0.json @@ -0,0 +1,14 @@ +{ + "date": "2025-04-25", + "version": "1.62.0", + "entries": [ + { + "type": "Bug Fix", + "description": "Toast message to warn users if Developer Profile is not selected" + }, + { + "type": "Bug Fix", + "description": "Fix users can not log in successfully with 2+ IDE instnaces open due to throttle error throw by the service" + } + ] +} \ No newline at end of file diff --git a/packages/amazonq/.changes/1.63.0.json b/packages/amazonq/.changes/1.63.0.json new file mode 100644 index 00000000000..10020659c5a --- /dev/null +++ b/packages/amazonq/.changes/1.63.0.json @@ -0,0 +1,14 @@ +{ + "date": "2025-05-01", + "version": "1.63.0", + "entries": [ + { + "type": "Bug Fix", + "description": "Q profile selection hangs when a region is blocked" + }, + { + "type": "Feature", + "description": "Agentic coding experience: Amazon Q can now write code and run shell commands on your behalf" + } + ] +} \ No newline at end of file diff --git a/packages/amazonq/.changes/1.64.0.json b/packages/amazonq/.changes/1.64.0.json new file mode 100644 index 00000000000..461ad140c01 --- /dev/null +++ b/packages/amazonq/.changes/1.64.0.json @@ -0,0 +1,10 @@ +{ + "date": "2025-05-02", + "version": "1.64.0", + "entries": [ + { + "type": "Bug Fix", + "description": "Enable Amazon Q LSP in AL2 instances" + } + ] +} \ No newline at end of file diff --git a/packages/amazonq/.vscode/launch.json b/packages/amazonq/.vscode/launch.json index 47a87b7d6f9..b00c5071ce5 100644 --- a/packages/amazonq/.vscode/launch.json +++ b/packages/amazonq/.vscode/launch.json @@ -14,7 +14,8 @@ "env": { "SSMDOCUMENT_LANGUAGESERVER_PORT": "6010", "WEBPACK_DEVELOPER_SERVER": "http://localhost:8080" - // "__AMAZONQLSP_PATH": "${workspaceFolder}/../../../language-servers/app/aws-lsp-codewhisperer-runtimes/out/token-standalone.js", + // Below allows for overrides used during development + // "__AMAZONQLSP_PATH": "${workspaceFolder}/../../../language-servers/app/aws-lsp-codewhisperer-runtimes/out/agent-standalone.js", // "__AMAZONQLSP_UI": "${workspaceFolder}/../../../language-servers/chat-client/build/amazonq-ui.js" }, "envFile": "${workspaceFolder}/.local.env", diff --git a/packages/amazonq/CHANGELOG.md b/packages/amazonq/CHANGELOG.md index 64753856884..0a3613017aa 100644 --- a/packages/amazonq/CHANGELOG.md +++ b/packages/amazonq/CHANGELOG.md @@ -1,3 +1,22 @@ +## 1.64.0 2025-05-02 + +- **Bug Fix** Enable Amazon Q LSP in AL2 instances + +## 1.63.0 2025-05-01 + +- **Bug Fix** Q profile selection hangs when a region is blocked +- **Feature** Agentic coding experience: Amazon Q can now write code and run shell commands on your behalf + +## 1.62.0 2025-04-25 + +- **Bug Fix** Toast message to warn users if Developer Profile is not selected +- **Bug Fix** Fix users can not log in successfully with 2+ IDE instnaces open due to throttle error throw by the service + +## 1.61.0 2025-04-22 + +- **Bug Fix** Some users not signaled they needed to select a Region Profile to get features working +- **bugfix** /review: disable auto-review by default + ## 1.60.0 2025-04-18 - **Bug Fix** Users might be bound to a customization which they dont have access with the selected profile and it causes service throwing 403 when using inline suggestion and chat features diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index fbcab15a174..3c487095c76 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -2,7 +2,7 @@ "name": "amazon-q-vscode", "displayName": "Amazon Q", "description": "The most capable generative AI-powered assistant for building, operating, and transforming software, with advanced capabilities for managing data and AI", - "version": "1.61.0-SNAPSHOT", + "version": "1.65.0-SNAPSHOT", "extensionKind": [ "workspace" ], @@ -131,6 +131,14 @@ "amazonQChatDisclaimer": { "type": "boolean", "default": false + }, + "amazonQChatPairProgramming": { + "type": "boolean", + "default": false + }, + "amazonQSelectDeveloperProfile": { + "type": "boolean", + "default": false } }, "additionalProperties": false @@ -177,7 +185,25 @@ "amazonQ.workspaceIndexMaxSize": { "type": "number", "markdownDescription": "%AWS.configuration.description.amazonq.workspaceIndexMaxSize%", - "default": 250, + "default": 2048, + "scope": "application" + }, + "amazonQ.workspaceIndexMaxFileSize": { + "type": "number", + "markdownDescription": "%AWS.configuration.description.amazonq.workspaceIndexMaxFileSize%", + "default": 10, + "scope": "application" + }, + "amazonQ.workspaceIndexCacheDirPath": { + "type": "string", + "markdownDescription": "%AWS.configuration.description.amazonq.workspaceIndexCacheDirPath%", + "default": null, + "scope": "application" + }, + "amazonQ.workspaceIndexIgnoreFilePatterns": { + "type": "array", + "markdownDescription": "%AWS.configuration.description.amazonq.workspaceIndexIgnoreFilePatterns%", + "default": [], "scope": "application" }, "amazonQ.ignoredSecurityIssues": { diff --git a/packages/amazonq/src/app/chat/activation.ts b/packages/amazonq/src/app/chat/activation.ts index 2cd7a494a83..2b5f01ee23c 100644 --- a/packages/amazonq/src/app/chat/activation.ts +++ b/packages/amazonq/src/app/chat/activation.ts @@ -4,46 +4,32 @@ */ import * as vscode from 'vscode' -import { ExtensionContext, window } from 'vscode' +import { ExtensionContext } from 'vscode' import { telemetry } from 'aws-core-vscode/telemetry' import { AuthUtil, CodeWhispererSettings } from 'aws-core-vscode/codewhisperer' import { Commands, placeholder, funcUtil } from 'aws-core-vscode/shared' import * as amazonq from 'aws-core-vscode/amazonq' -import { scanChatAppInit } from '../amazonqScan' export async function activate(context: ExtensionContext) { const appInitContext = amazonq.DefaultAmazonQAppInitContext.instance - - registerApps(appInitContext, context) - - const provider = new amazonq.AmazonQChatViewProvider( - context, - appInitContext.getWebViewToAppsMessagePublishers(), - appInitContext.getAppsToWebViewMessageListener(), - appInitContext.onDidChangeAmazonQVisibility - ) - await amazonq.TryChatCodeLensProvider.register(appInitContext.onDidChangeAmazonQVisibility.event) const setupLsp = funcUtil.debounce(async () => { void amazonq.LspController.instance.trySetupLsp(context, { startUrl: AuthUtil.instance.connection?.startUrl, maxIndexSize: CodeWhispererSettings.instance.getMaxIndexSize(), - isVectorIndexEnabled: CodeWhispererSettings.instance.isLocalIndexEnabled(), + isVectorIndexEnabled: false, }) }, 5000) context.subscriptions.push( - window.registerWebviewViewProvider(amazonq.AmazonQChatViewProvider.viewType, provider, { - webviewOptions: { - retainContextWhenHidden: true, - }, - }), amazonq.focusAmazonQChatWalkthrough.register(), amazonq.walkthroughInlineSuggestionsExample.register(), amazonq.walkthroughSecurityScanExample.register(), amazonq.openAmazonQWalkthrough.register(), amazonq.listCodeWhispererCommandsWalkthrough.register(), + amazonq.focusAmazonQPanel.register(), + amazonq.focusAmazonQPanelKeybinding.register(), amazonq.tryChatCodeLensCommand.register(), vscode.workspace.onDidChangeConfiguration(async (configurationChangeEvent) => { if (configurationChangeEvent.affectsConfiguration('amazonQ.workspaceIndex')) { @@ -62,15 +48,6 @@ export async function activate(context: ExtensionContext) { void setupAuthNotification() } -function registerApps(appInitContext: amazonq.AmazonQAppInitContext, context: ExtensionContext) { - amazonq.cwChatAppInit(appInitContext) - amazonq.featureDevChatAppInit(appInitContext) - amazonq.gumbyChatAppInit(appInitContext) - amazonq.testChatAppInit(appInitContext) - scanChatAppInit(appInitContext) - amazonq.docChatAppInit(appInitContext) -} - /** * Display a notification to user for Log In. * diff --git a/packages/amazonq/src/app/chat/node/activateAgents.ts b/packages/amazonq/src/app/chat/node/activateAgents.ts new file mode 100644 index 00000000000..954f2892eda --- /dev/null +++ b/packages/amazonq/src/app/chat/node/activateAgents.ts @@ -0,0 +1,19 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as amazonqNode from 'aws-core-vscode/amazonq/node' +import { scanChatAppInit } from '../../amazonqScan' +import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq' + +export function activateAgents() { + const appInitContext = DefaultAmazonQAppInitContext.instance + + amazonqNode.cwChatAppInit(appInitContext) + amazonqNode.featureDevChatAppInit(appInitContext) + amazonqNode.gumbyChatAppInit(appInitContext) + amazonqNode.testChatAppInit(appInitContext) + amazonqNode.docChatAppInit(appInitContext) + scanChatAppInit(appInitContext) +} diff --git a/packages/amazonq/src/extension.ts b/packages/amazonq/src/extension.ts index 8c469b737e0..d489f694d34 100644 --- a/packages/amazonq/src/extension.ts +++ b/packages/amazonq/src/extension.ts @@ -4,7 +4,12 @@ */ import { CredentialsStore, LoginManager, authUtils, initializeAuth } from 'aws-core-vscode/auth' -import { activate as activateCodeWhisperer, shutdown as shutdownCodeWhisperer } from 'aws-core-vscode/codewhisperer' +import { Auth, AuthUtils, CredentialsStore, LoginManager, initializeAuth } from 'aws-core-vscode/auth' +import { + activate as activateCodeWhisperer, + AuthUtil, + shutdown as shutdownCodeWhisperer, +} from 'aws-core-vscode/codewhisperer' import { makeEndpointsProvider, registerGenericCommands } from 'aws-core-vscode' import { CommonAuthWebview } from 'aws-core-vscode/login' import { @@ -34,6 +39,7 @@ import { Experiments, isSageMaker, Commands, + isAmazonInternalOs, } from 'aws-core-vscode/shared' import { ExtStartUpSources } from 'aws-core-vscode/telemetry' import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils' @@ -45,6 +51,7 @@ import { focusAmazonQPanel } from 'aws-core-vscode/codewhispererChat' import { activate as activateAmazonqLsp } from './lsp/activation' import { activate as activateInlineCompletion } from './app/inline/activation' import { isAmazonInternalOs } from 'aws-core-vscode/shared' +import { hasGlibcPatch } from './lsp/client' export const amazonQContextPrefix = 'amazonq' @@ -120,11 +127,17 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is extensionContext: context, } - await activateAmazonqLsp(context) - // This contains every lsp agnostic things (auth, security scan, code scan) await activateCodeWhisperer(extContext as ExtContext) + if ( + (Experiments.instance.get('amazonqLSP', true) || AuthUtil.instance.isInternalAmazonUser()) && + (!isAmazonInternalOs() || (await hasGlibcPatch())) + ) { + // start the Amazon Q LSP for internal users first + // for AL2, start LSP if glibc patch is found + await activateAmazonqLsp(context) + } if (!Experiments.instance.get('amazonqLSPInline', false)) { await activateInlineCompletion() } diff --git a/packages/amazonq/src/extensionNode.ts b/packages/amazonq/src/extensionNode.ts index f11a3e14f1d..98be79c1920 100644 --- a/packages/amazonq/src/extensionNode.ts +++ b/packages/amazonq/src/extensionNode.ts @@ -5,8 +5,8 @@ import * as vscode from 'vscode' import { activateAmazonQCommon, amazonQContextPrefix, deactivateCommon } from './extension' -import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq' -import { activate as activateQGumby } from 'aws-core-vscode/amazonqGumby' +import { DefaultAmazonQAppInitContext, AmazonQChatViewProvider } from 'aws-core-vscode/amazonq' +import { activate as activateTransformationHub } from 'aws-core-vscode/amazonqGumby' import { ExtContext, globals, CrashMonitoring, getLogger, isSageMaker, Experiments } from 'aws-core-vscode/shared' import { filetypes, SchemaService } from 'aws-core-vscode/sharedNode' import { updateDevMode } from 'aws-core-vscode/dev' @@ -22,7 +22,8 @@ import { beta } from 'aws-core-vscode/dev' import * as amazonq from 'aws-core-vscode/amazonq' import { activate as activateNotifications, NotificationsController } from 'aws-core-vscode/notifications' import { AuthUtil } from 'aws-core-vscode/codewhisperer' -import { telemetry, AuthUserState, AuthStatus } from 'aws-core-vscode/telemetry' +import { telemetry, AuthUserState } from 'aws-core-vscode/telemetry' +import { activateAgents } from './app/chat/node/activateAgents' export async function activate(context: vscode.ExtensionContext) { // IMPORTANT: No other code should be added to this function. Place it in one of the following 2 functions where appropriate. @@ -45,10 +46,26 @@ async function activateAmazonQNode(context: vscode.ExtensionContext) { extensionContext: context, } - if (!Experiments.instance.get('amazonqChatLSP', false)) { + if (!Experiments.instance.get('amazonqChatLSP', true)) { + const appInitContext = DefaultAmazonQAppInitContext.instance + const provider = new AmazonQChatViewProvider( + context, + appInitContext.getWebViewToAppsMessagePublishers(), + appInitContext.getAppsToWebViewMessageListener(), + appInitContext.onDidChangeAmazonQVisibility + ) + context.subscriptions.push( + vscode.window.registerWebviewViewProvider(AmazonQChatViewProvider.viewType, provider, { + webviewOptions: { + retainContextWhenHidden: true, + }, + }) + ) + // this is registered inside of lsp/chat/activation.ts when the chat experiment is enabled await activateCWChat(context) - await activateQGumby(extContext as ExtContext) } + activateAgents() + await activateTransformationHub(extContext as ExtContext) activateInlineChat(context) context.subscriptions.push(amazonq.focusAmazonQPanel.register(), amazonq.focusAmazonQPanelKeybinding.register()) diff --git a/packages/amazonq/src/lsp/chat/activation.ts b/packages/amazonq/src/lsp/chat/activation.ts index 406b753716f..9dd1d31c3de 100644 --- a/packages/amazonq/src/lsp/chat/activation.ts +++ b/packages/amazonq/src/lsp/chat/activation.ts @@ -8,12 +8,27 @@ import { LanguageClient } from 'vscode-languageclient' import { AmazonQChatViewProvider } from './webviewProvider' import { registerCommands } from './commands' import { registerLanguageServerEventListener, registerMessageListeners } from './messages' -import { globals } from 'aws-core-vscode/shared' +import { Commands, getLogger, globals, undefinedIfEmpty } from 'aws-core-vscode/shared' +import { activate as registerLegacyChatListeners } from '../../app/chat/activation' +import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq' +import { AuthUtil, getSelectedCustomization } from 'aws-core-vscode/codewhisperer' +import { + DidChangeConfigurationNotification, + updateConfigurationRequestType, +} from '@aws/language-server-runtimes/protocol' + +export async function activate(languageClient: LanguageClient, encryptionKey: Buffer, mynahUIPath: string) { + const disposables = globals.context.subscriptions + + // Make sure we've sent an auth profile to the language server before even initializing the UI + await pushConfigUpdate(languageClient, { + type: 'profile', + profileArn: AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn, + }) -export function activate(languageClient: LanguageClient, encryptionKey: Buffer, mynahUIPath: string) { const provider = new AmazonQChatViewProvider(mynahUIPath) - globals.context.subscriptions.push( + disposables.push( window.registerWebviewViewProvider(AmazonQChatViewProvider.viewType, provider, { webviewOptions: { retainContextWhenHidden: true, @@ -29,6 +44,95 @@ export function activate(languageClient: LanguageClient, encryptionKey: Buffer, registerLanguageServerEventListener(languageClient, provider) provider.onDidResolveWebview(() => { + const disposable = DefaultAmazonQAppInitContext.instance.getAppsToWebViewMessageListener().onMessage((msg) => { + /** + * codewhispers app handler is still registered because the activation flow hasn't been refactored. + * We need to explicitly deny events like restoreTabMessage, otherwise they will be forwarded to the frontend + * + */ + if (msg.sender === 'CWChat' && ['restoreTabMessage', 'contextCommandData'].includes(msg.type)) { + return + } + provider.webview?.postMessage(msg).then(undefined, (e) => { + getLogger().error('webView.postMessage failed: %s', (e as Error).message) + }) + }) + + if (provider.webviewView) { + disposables.push( + provider.webviewView.onDidDispose(() => { + disposable.dispose() + }) + ) + } + registerMessageListeners(languageClient, provider, encryptionKey) }) + + // register event listeners from the legacy agent flow + await registerLegacyChatListeners(globals.context) + + disposables.push( + AuthUtil.instance.regionProfileManager.onDidChangeRegionProfile(async () => { + void pushConfigUpdate(languageClient, { + type: 'profile', + profileArn: AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn, + }) + await provider.refreshWebview() + }), + Commands.register('aws.amazonq.updateCustomizations', () => { + void pushConfigUpdate(languageClient, { + type: 'customization', + customization: undefinedIfEmpty(getSelectedCustomization().arn), + }) + }), + globals.logOutputChannel.onDidChangeLogLevel((logLevel) => { + getLogger('amazonqLsp').info(`Local log level changed to ${logLevel}, notifying LSP`) + void pushConfigUpdate(languageClient, { + type: 'logLevel', + }) + }) + ) +} + +/** + * Push a config value to the language server, effectively updating it with the + * latest configuration from the client. + * + * The issue is we need to push certain configs to different places, since there are + * different handlers for specific configs. So this determines the correct place to + * push the given config. + */ +async function pushConfigUpdate(client: LanguageClient, config: QConfigs) { + switch (config.type) { + case 'profile': + await client.sendRequest(updateConfigurationRequestType.method, { + section: 'aws.q', + settings: { profileArn: config.profileArn }, + }) + break + case 'customization': + client.sendNotification(DidChangeConfigurationNotification.type.method, { + section: 'aws.q', + settings: { customization: config.customization }, + }) + break + case 'logLevel': + client.sendNotification(DidChangeConfigurationNotification.type.method, { + section: 'aws.logLevel', + }) + break + } +} +type ProfileConfig = { + type: 'profile' + profileArn: string | undefined +} +type CustomizationConfig = { + type: 'customization' + customization: string | undefined +} +type LogLevelConfig = { + type: 'logLevel' } +type QConfigs = ProfileConfig | CustomizationConfig | LogLevelConfig diff --git a/packages/amazonq/src/lsp/chat/commands.ts b/packages/amazonq/src/lsp/chat/commands.ts index dd495d1bfbf..74c63592a4f 100644 --- a/packages/amazonq/src/lsp/chat/commands.ts +++ b/packages/amazonq/src/lsp/chat/commands.ts @@ -6,13 +6,66 @@ import { Commands, globals } from 'aws-core-vscode/shared' import { window } from 'vscode' import { AmazonQChatViewProvider } from './webviewProvider' +import { CodeScanIssue } from 'aws-core-vscode/codewhisperer' +import { EditorContextExtractor } from 'aws-core-vscode/codewhispererChat' +import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq' +/** + * TODO: Re-enable these once we can figure out which path they're going to live in + * In hybrid chat mode they were being registered twice causing a registration error + */ export function registerCommands(provider: AmazonQChatViewProvider) { globals.context.subscriptions.push( registerGenericCommand('aws.amazonq.explainCode', 'Explain', provider), registerGenericCommand('aws.amazonq.refactorCode', 'Refactor', provider), registerGenericCommand('aws.amazonq.fixCode', 'Fix', provider), registerGenericCommand('aws.amazonq.optimizeCode', 'Optimize', provider), + Commands.register('aws.amazonq.generateUnitTests', async () => { + DefaultAmazonQAppInitContext.instance.getAppsToWebViewMessagePublisher().publish({ + sender: 'testChat', + command: 'test', + type: 'chatMessage', + }) + }), + Commands.register('aws.amazonq.explainIssue', async (issue: CodeScanIssue) => { + void focusAmazonQPanel().then(async () => { + const editorContextExtractor = new EditorContextExtractor() + const extractedContext = await editorContextExtractor.extractContextForTrigger('ContextMenu') + const selectedCode = + extractedContext?.activeFileContext?.fileText + ?.split('\n') + .slice(issue.startLine, issue.endLine) + .join('\n') ?? '' + + // The message that gets sent to the UI + const uiMessage = [ + 'Explain the ', + issue.title, + ' issue in the following code:', + '\n```\n', + selectedCode, + '\n```', + ].join('') + + // The message that gets sent to the backend + const contextMessage = `Explain the issue "${issue.title}" (${JSON.stringify( + issue + )}) and generate code demonstrating the fix` + + void provider.webview?.postMessage({ + command: 'sendToPrompt', + params: { + selection: '', + triggerType: 'contextMenu', + prompt: { + prompt: uiMessage, // what gets sent to the user + escapedPrompt: contextMessage, // what gets sent to the backend + }, + autoSubmit: true, + }, + }) + }) + }), Commands.register('aws.amazonq.sendToPrompt', (data) => { const triggerType = getCommandTriggerType(data) const selection = getSelectedText() diff --git a/packages/amazonq/src/lsp/chat/error.ts b/packages/amazonq/src/lsp/chat/error.ts new file mode 100644 index 00000000000..fc2e0211b0f --- /dev/null +++ b/packages/amazonq/src/lsp/chat/error.ts @@ -0,0 +1,23 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { ChatResult } from '@aws/language-server-runtimes/protocol' +import { ResponseError } from '@aws/language-server-runtimes/protocol' +/** + * Perform a sanity check that the error we got from the LSP can be safely cast to the expected type. + * @param error + * @returns + */ +export function isValidResponseError(error: unknown): error is ResponseError & { data: ChatResult } { + return ( + typeof error === 'object' && + error !== null && + 'code' in error && + typeof error.code === 'number' && + 'message' in error && + typeof error.message === 'string' && + 'data' in error && + error.data !== undefined + ) +} diff --git a/packages/amazonq/src/lsp/chat/messages.ts b/packages/amazonq/src/lsp/chat/messages.ts index 7d557b5f338..81dd9e13515 100644 --- a/packages/amazonq/src/lsp/chat/messages.ts +++ b/packages/amazonq/src/lsp/chat/messages.ts @@ -12,6 +12,10 @@ import { AuthFollowUpType, DISCLAIMER_ACKNOWLEDGED, UiMessageResultParams, + CHAT_PROMPT_OPTION_ACKNOWLEDGED, + ChatPromptOptionAcknowledgedMessage, + STOP_CHAT_RESPONSE, + StopChatResponseMessage, } from '@aws/chat-client-ui-types' import { ChatResult, @@ -37,14 +41,33 @@ import { ShowDocumentRequest, contextCommandsNotificationType, ContextCommandParams, + openFileDiffNotificationType, + OpenFileDiffParams, + LINK_CLICK_NOTIFICATION_METHOD, + LinkClickParams, + INFO_LINK_CLICK_NOTIFICATION_METHOD, + buttonClickRequestType, + ButtonClickResult, + CancellationTokenSource, + chatUpdateNotificationType, + ChatUpdateParams, } from '@aws/language-server-runtimes/protocol' import { v4 as uuidv4 } from 'uuid' import * as vscode from 'vscode' import { Disposable, LanguageClient, Position, TextDocumentIdentifier } from 'vscode-languageclient' import * as jose from 'jose' import { AmazonQChatViewProvider } from './webviewProvider' -import { AuthUtil } from 'aws-core-vscode/codewhisperer' -import { AmazonQPromptSettings, messages } from 'aws-core-vscode/shared' +import { AuthUtil, ReferenceLogViewProvider } from 'aws-core-vscode/codewhisperer' +import { amazonQDiffScheme, AmazonQPromptSettings, messages, openUrl } from 'aws-core-vscode/shared' +import { + DefaultAmazonQAppInitContext, + messageDispatcher, + EditorContentController, + ViewDiffMessage, + referenceLogText, +} from 'aws-core-vscode/amazonq' +import { telemetry, TelemetryBase } from 'aws-core-vscode/telemetry' +import { isValidResponseError } from './error' export function registerLanguageServerEventListener(languageClient: LanguageClient, provider: AmazonQChatViewProvider) { languageClient.info( @@ -54,9 +77,10 @@ export function registerLanguageServerEventListener(languageClient: LanguageClie const chatOptions = languageClient.initializeResult?.awsServerCapabilities?.chatOptions - // Enable the history/export feature flags - chatOptions.history = true - chatOptions.export = true + // overide the quick action commands provided by flare server initialization, which doesn't provide the group header + if (chatOptions?.quickActions?.quickActionsCommandGroups?.[0]) { + chatOptions.quickActions.quickActionsCommandGroups[0].groupName = 'Quick Actions' + } provider.onDidResolveWebview(() => { void provider.webview?.postMessage({ @@ -65,19 +89,49 @@ export function registerLanguageServerEventListener(languageClient: LanguageClie }) }) + // This passes through metric data from LSP events to Toolkit telemetry with all fields from the LSP server languageClient.onTelemetry((e) => { - languageClient.info(`[VSCode Client] Received telemetry event from server ${JSON.stringify(e)}`) + const telemetryName: string = e.name + + if (telemetryName in telemetry) { + telemetry[telemetryName as keyof TelemetryBase].emit(e.data) + } }) } +function getCursorState(selection: readonly vscode.Selection[]) { + return selection.map((s) => ({ + range: { + start: { + line: s.start.line, + character: s.start.character, + }, + end: { + line: s.end.line, + character: s.end.character, + }, + }, + })) +} + export function registerMessageListeners( languageClient: LanguageClient, provider: AmazonQChatViewProvider, encryptionKey: Buffer ) { + const chatStreamTokens = new Map() // tab id -> token provider.webview?.onDidReceiveMessage(async (message) => { languageClient.info(`[VSCode Client] Received ${JSON.stringify(message)} from chat`) + if ((message.tabType && message.tabType !== 'cwc') || messageDispatcher.isLegacyEvent(message.command)) { + // handle the mynah ui -> agent legacy flow + messageDispatcher.handleWebviewEvent( + message, + DefaultAmazonQAppInitContext.instance.getWebViewToAppsMessagePublishers() + ) + return + } + const webview = provider.webview switch (message.command) { case COPY_TO_CLIPBOARD: @@ -132,35 +186,100 @@ export function registerMessageListeners( break } case DISCLAIMER_ACKNOWLEDGED: { - void AmazonQPromptSettings.instance.disablePrompt('amazonQChatDisclaimer') + void AmazonQPromptSettings.instance.update('amazonQChatDisclaimer', true) + break + } + case CHAT_PROMPT_OPTION_ACKNOWLEDGED: { + const acknowledgedMessage = message as ChatPromptOptionAcknowledgedMessage + switch (acknowledgedMessage.params.messageId) { + case 'programmerModeCardId': { + void AmazonQPromptSettings.instance.disablePrompt('amazonQChatPairProgramming') + } + } + break + } + case INFO_LINK_CLICK_NOTIFICATION_METHOD: + case LINK_CLICK_NOTIFICATION_METHOD: { + const linkParams = message.params as LinkClickParams + void openUrl(vscode.Uri.parse(linkParams.link)) + break + } + case STOP_CHAT_RESPONSE: { + const tabId = (message as StopChatResponseMessage).params.tabId + const token = chatStreamTokens.get(tabId) + token?.cancel() + token?.dispose() + chatStreamTokens.delete(tabId) break } case chatRequestType.method: { + const chatParams: ChatParams = { ...message.params } const partialResultToken = uuidv4() - const chatDisposable = languageClient.onProgress(chatRequestType, partialResultToken, (partialResult) => - handlePartialResult(partialResult, encryptionKey, provider, message.params.tabId) + let lastPartialResult: ChatResult | undefined + const cancellationToken = new CancellationTokenSource() + chatStreamTokens.set(chatParams.tabId, cancellationToken) + + const chatDisposable = languageClient.onProgress( + chatRequestType, + partialResultToken, + (partialResult) => { + // Store the latest partial result + if (typeof partialResult === 'string' && encryptionKey) { + void decodeRequest(partialResult, encryptionKey).then( + (decoded) => (lastPartialResult = decoded) + ) + } else { + lastPartialResult = partialResult as ChatResult + } + + void handlePartialResult(partialResult, encryptionKey, provider, chatParams.tabId) + } ) const editor = vscode.window.activeTextEditor || vscode.window.visibleTextEditors.find((editor) => editor.document.languageId !== 'Log') if (editor) { - message.params.cursorPosition = [editor.selection.active] - message.params.textDocument = { uri: editor.document.uri.toString() } + chatParams.cursorState = getCursorState(editor.selections) + chatParams.textDocument = { uri: editor.document.uri.toString() } } - const chatRequest = await encryptRequest(message.params, encryptionKey) - const chatResult = (await languageClient.sendRequest(chatRequestType.method, { - ...chatRequest, - partialResultToken, - })) as string | ChatResult - void handleCompleteResult( - chatResult, - encryptionKey, - provider, - message.params.tabId, - chatDisposable - ) + const chatRequest = await encryptRequest(chatParams, encryptionKey) + try { + const chatResult = await languageClient.sendRequest( + chatRequestType.method, + { + ...chatRequest, + partialResultToken, + }, + cancellationToken.token + ) + await handleCompleteResult( + chatResult, + encryptionKey, + provider, + chatParams.tabId, + chatDisposable + ) + } catch (e) { + const errorMsg = `Error occurred during chat request: ${e}` + languageClient.info(errorMsg) + languageClient.info( + `Last result from langauge server: ${JSON.stringify(lastPartialResult, undefined, 2)}` + ) + if (!isValidResponseError(e)) { + throw e + } + await handleCompleteResult( + e.data, + encryptionKey, + provider, + chatParams.tabId, + chatDisposable + ) + } finally { + chatStreamTokens.delete(chatParams.tabId) + } break } case quickActionRequestType.method: { @@ -201,6 +320,18 @@ export function registerMessageListeners( languageClient.sendNotification(followUpClickNotificationType.method, message.params) } break + case buttonClickRequestType.method: { + const buttonResult = await languageClient.sendRequest( + buttonClickRequestType.method, + message.params + ) + if (!buttonResult.success) { + languageClient.error( + `[VSCode Client] Failed to execute action associated with button with reason: ${buttonResult.failureReason}` + ) + } + break + } default: if (isServerEvent(message.command)) { languageClient.sendNotification(message.command, message.params) @@ -315,6 +446,41 @@ export function registerMessageListeners( params: params, }) }) + + languageClient.onNotification(openFileDiffNotificationType.method, async (params: OpenFileDiffParams) => { + const ecc = new EditorContentController() + const uri = params.originalFileUri + const doc = await vscode.workspace.openTextDocument(uri) + const entireDocumentSelection = new vscode.Selection( + new vscode.Position(0, 0), + new vscode.Position(doc.lineCount - 1, doc.lineAt(doc.lineCount - 1).text.length) + ) + const viewDiffMessage: ViewDiffMessage = { + context: { + activeFileContext: { + filePath: params.originalFileUri, + fileText: params.originalFileContent ?? '', + fileLanguage: undefined, + matchPolicy: undefined, + }, + focusAreaContext: { + selectionInsideExtendedCodeBlock: entireDocumentSelection, + codeBlock: '', + extendedCodeBlock: '', + names: undefined, + }, + }, + code: params.fileContent ?? '', + } + await ecc.viewDiff(viewDiffMessage, amazonQDiffScheme) + }) + + languageClient.onNotification(chatUpdateNotificationType.method, (params: ChatUpdateParams) => { + void provider.webview?.postMessage({ + command: chatUpdateNotificationType.method, + params: params, + }) + }) } function isServerEvent(command: string) { @@ -358,7 +524,7 @@ async function handlePartialResult( ? await decodeRequest(partialResult, encryptionKey) : (partialResult as T) - if (decryptedMessage.body) { + if (decryptedMessage.body !== undefined) { void provider.webview?.postMessage({ command: chatRequestType.method, params: decryptedMessage, @@ -372,7 +538,7 @@ async function handlePartialResult( * Decodes the final chat responses from the language server before sending it to mynah UI. * Once this is called the answer response is finished */ -async function handleCompleteResult( +async function handleCompleteResult( result: string | T, encryptionKey: Buffer | undefined, provider: AmazonQChatViewProvider, @@ -380,13 +546,17 @@ async function handleCompleteResult( disposable: Disposable ) { const decryptedMessage = - typeof result === 'string' && encryptionKey ? await decodeRequest(result, encryptionKey) : result - + typeof result === 'string' && encryptionKey ? await decodeRequest(result, encryptionKey) : (result as T) void provider.webview?.postMessage({ command: chatRequestType.method, params: decryptedMessage, tabId: tabId, }) + + // only add the reference log once the request is complete, otherwise we will get duplicate log items + for (const ref of decryptedMessage.codeReference ?? []) { + ReferenceLogViewProvider.instance.addReferenceLog(referenceLogText(ref)) + } disposable.dispose() } diff --git a/packages/amazonq/src/lsp/chat/webviewProvider.ts b/packages/amazonq/src/lsp/chat/webviewProvider.ts index ee73a599867..1a513f1df3f 100644 --- a/packages/amazonq/src/lsp/chat/webviewProvider.ts +++ b/packages/amazonq/src/lsp/chat/webviewProvider.ts @@ -6,40 +6,34 @@ import { EventEmitter, CancellationToken, - Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, Uri, + Webview, } from 'vscode' -import { QuickActionCommandGroup } from '@aws/mynah-ui' import * as path from 'path' -import { AmazonQPromptSettings, LanguageServerResolver } from 'aws-core-vscode/shared' +import { + globals, + isSageMaker, + AmazonQPromptSettings, + LanguageServerResolver, + amazonqMark, +} from 'aws-core-vscode/shared' +import { AuthUtil, RegionProfile } from 'aws-core-vscode/codewhisperer' +import { featureConfig } from 'aws-core-vscode/amazonq' +import { getAmazonQLspConfig } from '../config' export class AmazonQChatViewProvider implements WebviewViewProvider { public static readonly viewType = 'aws.amazonq.AmazonQChatView' private readonly onDidResolveWebviewEmitter = new EventEmitter() public readonly onDidResolveWebview = this.onDidResolveWebviewEmitter.event - webview: Webview | undefined - - private readonly quickActionCommands: QuickActionCommandGroup[] = [ - { - groupName: 'Quick Actions', - commands: [ - { - command: '/help', - icon: 'help', - description: 'Learn more about Amazon Q', - }, - { - command: '/clear', - icon: 'trash', - description: 'Clear this session', - }, - ], - }, - ] + webviewView?: WebviewView + webview?: Webview + + connectorAdapterPath?: string + uiPath?: string constructor(private readonly mynahUIPath: string) {} @@ -48,28 +42,79 @@ export class AmazonQChatViewProvider implements WebviewViewProvider { context: WebviewViewResolveContext, _token: CancellationToken ) { - this.webview = webviewView.webview + const lspDir = Uri.file(LanguageServerResolver.defaultDir()) + const dist = Uri.joinPath(globals.context.extensionUri, 'dist') + + const resourcesRoots = [lspDir, dist] + + /** + * if the mynah chat client is defined, then make sure to add it to the resource roots, otherwise + * it will 401 when trying to load + */ + const mynahUIPath = getAmazonQLspConfig().ui + if (process.env.WEBPACK_DEVELOPER_SERVER && mynahUIPath) { + const dir = path.dirname(mynahUIPath) + resourcesRoots.push(Uri.file(dir)) + } - const lspDir = Uri.parse(LanguageServerResolver.defaultDir()) webviewView.webview.options = { enableScripts: true, enableCommandUris: true, - localResourceRoots: [lspDir, Uri.parse(path.dirname(this.mynahUIPath))], + localResourceRoots: resourcesRoots, } - const uiPath = webviewView.webview.asWebviewUri(Uri.parse(this.mynahUIPath)).toString() - webviewView.webview.html = await this.getWebviewContent(uiPath) + const source = 'vue/src/amazonq/webview/ui/amazonq-ui-connector-adapter.js' // Sent to dist/vue folder in webpack. + const serverHostname = process.env.WEBPACK_DEVELOPER_SERVER + + this.connectorAdapterPath = + serverHostname !== undefined + ? `${serverHostname}/${source}` + : webviewView.webview.asWebviewUri(Uri.joinPath(dist, source)).toString() + this.uiPath = webviewView.webview.asWebviewUri(Uri.file(this.mynahUIPath)).toString() + + webviewView.webview.html = await this.getWebviewContent() + + this.webviewView = webviewView + this.webview = this.webviewView.webview this.onDidResolveWebviewEmitter.fire() + performance.mark(amazonqMark.open) } - private async getWebviewContent(mynahUIPath: string) { + private async getWebviewContent() { + const featureConfigData = await featureConfig.getFeatureConfigs() + + const isSM = isSageMaker('SMAI') + const isSMUS = isSageMaker('SMUS') + const disabledCommands = isSM ? `['/dev', '/transform', '/test', '/review', '/doc']` : '[]' const disclaimerAcknowledged = !AmazonQPromptSettings.instance.isPromptEnabled('amazonQChatDisclaimer') + const pairProgrammingAcknowledged = + !AmazonQPromptSettings.instance.isPromptEnabled('amazonQChatPairProgramming') + const welcomeCount = globals.globalState.tryGet('aws.amazonq.welcomeChatShowCount', Number, 0) + + // only show profile card when the two conditions + // 1. profile count >= 2 + // 2. not default (fallback) which has empty arn + let regionProfile: RegionProfile | undefined = AuthUtil.instance.regionProfileManager.activeRegionProfile + if (AuthUtil.instance.regionProfileManager.profiles.length === 1) { + regionProfile = undefined + } + + const regionProfileString: string = JSON.stringify(regionProfile) + + const entrypoint = process.env.WEBPACK_DEVELOPER_SERVER + ? 'http://localhost:8080' + : 'https://file+.vscode-resource.vscode-cdn.net' + + const contentPolicy = `default-src ${entrypoint} data: blob: 'unsafe-inline'; + script-src ${entrypoint} filesystem: file: vscode-resource: https: ws: wss: 'unsafe-inline';` + return ` + Chat - + + ` } + + async refreshWebview() { + if (this.webview) { + // post a message to the webview telling it to reload + void this.webview?.postMessage({ + command: 'reload', + }) + } + } } diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index deadadcdc82..5f6f548b951 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -7,11 +7,9 @@ import vscode, { env, version } from 'vscode' import * as nls from 'vscode-nls' import * as crypto from 'crypto' import * as jose from 'jose' -import { LanguageClient, LanguageClientOptions, RequestType } from 'vscode-languageclient' import { InlineCompletionManager } from '../app/inline/completion' -import { AuthUtil } from 'aws-core-vscode/codewhisperer' +import { LanguageClient, LanguageClientOptions, RequestType, State } from 'vscode-languageclient' import { - ConnectionMetadata, CreateFilesParams, DeleteFilesParams, DidChangeWorkspaceFoldersParams, @@ -30,10 +28,11 @@ import { ShowDocumentResult, ShowMessageRequest, ShowMessageRequestParams, + ConnectionMetadata, } from '@aws/language-server-runtimes/protocol' +import { AuthUtil, CodeWhispererSettings, getSelectedCustomization } from 'aws-core-vscode/codewhisperer' import { Settings, - oidcClientName, createServerOptions, globals, Experiments, @@ -41,10 +40,17 @@ import { openUrl, validateNodeExe, getLogger, + undefinedIfEmpty, + getOptOutPreference, + isAmazonInternalOs, + fs, + oidcClientName, } from 'aws-core-vscode/shared' +import { processUtils } from 'aws-core-vscode/shared' import { activate } from './chat/activation' import { AmazonQResourcePaths } from './lspInstaller' import { auth2 } from 'aws-core-vscode/auth' +import { ConfigSection, isValidConfigSection, toAmazonQLSPLogLevel } from './config' const localize = nls.loadMessageBundle() const logger = getLogger('amazonqLsp.lspClient') @@ -53,6 +59,10 @@ export const clientId = 'amazonq' export const clientName = oidcClientName() export const encryptionKey = crypto.randomBytes(32) +export async function hasGlibcPatch(): Promise { + return await fs.exists('/opt/vsc-sysroot/lib64/ld-linux-x86-64.so.2') +} + export async function startLanguageServer( extensionContext: vscode.ExtensionContext, resourcePaths: AmazonQResourcePaths @@ -68,41 +78,77 @@ export async function startLanguageServer( '--pre-init-encryption', '--set-credentials-encryption-key', ] + + const documentSelector = [{ scheme: 'file', language: '*' }] + const traceServerEnabled = Settings.instance.isSet(`${clientId}.trace.server`) + let executable: string[] = [] + // apply the GLIBC 2.28 path to node js runtime binary + if (isAmazonInternalOs() && (await hasGlibcPatch())) { + executable = [ + '/opt/vsc-sysroot/lib64/ld-linux-x86-64.so.2', + '--library-path', + '/opt/vsc-sysroot/lib64', + resourcePaths.node, + ] + getLogger('amazonqLsp').info(`Patched node runtime with GLIBC to ${executable}`) + } else { + executable = [resourcePaths.node] + } + + const memoryWarnThreshold = 1024 * processUtils.oneMB const serverOptions = createServerOptions({ encryptionKey, - executable: resourcePaths.node, + executable: executable, serverModule, execArgv: argv, + warnThresholds: { memory: memoryWarnThreshold }, }) - const documentSelector = [{ scheme: 'file', language: '*' }] - const traceServerEnabled = Settings.instance.isSet(`${clientId}.trace.server`) - - await validateNodeExe(resourcePaths.node, resourcePaths.lsp, argv, logger) + await validateNodeExe(executable, resourcePaths.lsp, argv, logger) // Options to control the language client const clientOptions: LanguageClientOptions = { // Register the server for json documents documentSelector, + middleware: { + workspace: { + /** + * Convert VSCode settings format to be compatible with flare's configs + */ + configuration: async (params, token, next) => { + const config = await next(params, token) + const section = params.items[0].section + if (!isValidConfigSection(section)) { + return config + } + return getConfigSection(section) + }, + }, + }, initializationOptions: { aws: { clientInfo: { name: env.appName, version: version, extension: { - name: oidcClientName(), + name: 'AmazonQ-For-VSCode', version: '0.0.1', }, clientId: crypto.randomUUID(), }, awsClientCapabilities: { + q: { + developerProfiles: true, + }, window: { notifications: true, + showSaveFileDialog: true, }, q: { developerProfiles: true, }, }, + logLevel: toAmazonQLSPLogLevel(globals.logOutputChannel.logLevel), }, credentials: { providesBearerToken: true, @@ -155,6 +201,23 @@ export async function startLanguageServer( } ) + const sendProfileToLsp = async () => { + try { + const result = await client.sendRequest(updateConfigurationRequestType.method, { + section: 'aws.q', + settings: { + profileArn: AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn, + }, + }) + client.info( + `Client: Updated Amazon Q Profile ${AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn} to Amazon Q LSP`, + result + ) + } catch (err) { + client.error('Error when setting Q Developer Profile to Amazon Q LSP', err) + } + } + let promise: Promise | undefined let resolver: () => void = () => {} client.onProgress(GetSsoTokenProgressType, GetSsoTokenProgressToken, async (partialResult: GetSsoTokenProgress) => { @@ -174,23 +237,6 @@ export async function startLanguageServer( return } - const sendProfileToLsp = async () => { - try { - const result = await client.sendRequest(updateConfigurationRequestType.method, { - section: 'aws.q', - settings: { - profileArn: AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn, - }, - }) - client.info( - `Client: Updated Amazon Q Profile ${AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn} to Amazon Q LSP`, - result - ) - } catch (err) { - client.error('Error when setting Q Developer Profile to Amazon Q LSP', err) - } - } - // send profile to lsp once. void sendProfileToLsp() @@ -214,69 +260,9 @@ export async function startLanguageServer( Commands.register({ id: 'aws.amazonq.invokeInlineCompletion', autoconnect: true }, async () => { await vscode.commands.executeCommand('editor.action.inlineSuggest.trigger') }), - - AuthUtil.instance.regionProfileManager.onDidChangeRegionProfile(sendProfileToLsp), - vscode.commands.registerCommand('aws.amazonq.getWorkspaceId', async () => { - const requestType = new RequestType( - 'aws/getConfigurationFromServer' - ) - const workspaceIdResp = await client.sendRequest(requestType.method, { - section: 'aws.q.workspaceContext', - }) - return workspaceIdResp - }), - vscode.workspace.onDidCreateFiles((e) => { - client.sendNotification('workspace/didCreateFiles', { - files: e.files.map((it) => { - return { uri: it.fsPath } - }), - } as CreateFilesParams) - }), - vscode.workspace.onDidDeleteFiles((e) => { - client.sendNotification('workspace/didDeleteFiles', { - files: e.files.map((it) => { - return { uri: it.fsPath } - }), - } as DeleteFilesParams) - }), - vscode.workspace.onDidRenameFiles((e) => { - client.sendNotification('workspace/didRenameFiles', { - files: e.files.map((it) => { - return { oldUri: it.oldUri.fsPath, newUri: it.newUri.fsPath } - }), - } as RenameFilesParams) - }), - vscode.workspace.onDidSaveTextDocument((e) => { - client.sendNotification('workspace/didSaveTextDocument', { - textDocument: { - uri: e.uri.fsPath, - }, - } as DidSaveTextDocumentParams) - }), - vscode.workspace.onDidChangeWorkspaceFolders((e) => { - client.sendNotification('workspace/didChangeWorkspaceFolder', { - event: { - added: e.added.map((it) => { - return { - name: it.name, - uri: it.uri.fsPath, - } as WorkspaceFolder - }), - removed: e.removed.map((it) => { - return { - name: it.name, - uri: it.uri.fsPath, - } as WorkspaceFolder - }), - }, - } as DidChangeWorkspaceFoldersParams) - }), - { dispose: () => clearInterval(refreshInterval) } - vscode.workspace.onDidCloseTextDocument(async () => { await vscode.commands.executeCommand('aws.amazonq.rejectCodeSuggestion') }) - ) } @@ -284,5 +270,121 @@ export async function startLanguageServer( activate(client, encryptionKey, resourcePaths.ui) } + toDispose.push( + AuthUtil.instance.regionProfileManager.onDidChangeRegionProfile(sendProfileToLsp), + vscode.commands.registerCommand('aws.amazonq.getWorkspaceId', async () => { + const requestType = new RequestType( + 'aws/getConfigurationFromServer' + ) + const workspaceIdResp = await client.sendRequest(requestType.method, { + section: 'aws.q.workspaceContext', + }) + return workspaceIdResp + }), + vscode.workspace.onDidCreateFiles((e) => { + client.sendNotification('workspace/didCreateFiles', { + files: e.files.map((it) => { + return { uri: it.fsPath } + }), + } as CreateFilesParams) + }), + vscode.workspace.onDidDeleteFiles((e) => { + client.sendNotification('workspace/didDeleteFiles', { + files: e.files.map((it) => { + return { uri: it.fsPath } + }), + } as DeleteFilesParams) + }), + vscode.workspace.onDidRenameFiles((e) => { + client.sendNotification('workspace/didRenameFiles', { + files: e.files.map((it) => { + return { oldUri: it.oldUri.fsPath, newUri: it.newUri.fsPath } + }), + } as RenameFilesParams) + }), + vscode.workspace.onDidSaveTextDocument((e) => { + client.sendNotification('workspace/didSaveTextDocument', { + textDocument: { + uri: e.uri.fsPath, + }, + } as DidSaveTextDocumentParams) + }), + vscode.workspace.onDidChangeWorkspaceFolders((e) => { + client.sendNotification('workspace/didChangeWorkspaceFolder', { + event: { + added: e.added.map((it) => { + return { + name: it.name, + uri: it.uri.fsPath, + } as WorkspaceFolder + }), + removed: e.removed.map((it) => { + return { + name: it.name, + uri: it.uri.fsPath, + } as WorkspaceFolder + }), + }, + } as DidChangeWorkspaceFoldersParams) + }), + // Set this inside onReady so that it only triggers on subsequent language server starts (not the first) + onServerRestartHandler(client) + ) + return client } + +/** + * When the server restarts (likely due to a crash, then the LanguageClient automatically starts it again) + * we need to run some server intialization again. + */ +function onServerRestartHandler(client: LanguageClient) { + return client.onDidChangeState(async (e) => { + // Ensure we are in a "restart" state + if (!(e.oldState === State.Starting && e.newState === State.Running)) { + return + } + + // Need to set the auth token in the again + await AuthUtil.instance.restore() + }) +} + +function getConfigSection(section: ConfigSection) { + getLogger('amazonqLsp').debug('Fetching config section %s for language server', section) + switch (section) { + case 'aws.q': + /** + * IMPORTANT: This object is parsed by the following code in the language server, **so + * it must match that expected shape**. + * https://github.com/aws/language-servers/blob/1d2ca018f2248106690438b860d40a7ee67ac728/server/aws-lsp-codewhisperer/src/shared/amazonQServiceManager/configurationUtils.ts#L114 + */ + return [ + { + customization: undefinedIfEmpty(getSelectedCustomization().arn), + optOutTelemetry: getOptOutPreference() === 'OPTOUT', + projectContext: { + enableLocalIndexing: CodeWhispererSettings.instance.isLocalIndexEnabled(), + enableGpuAcceleration: CodeWhispererSettings.instance.isLocalIndexGPUEnabled(), + indexWorkerThreads: CodeWhispererSettings.instance.getIndexWorkerThreads(), + localIndexing: { + ignoreFilePatterns: CodeWhispererSettings.instance.getIndexIgnoreFilePatterns(), + maxFileSizeMB: CodeWhispererSettings.instance.getMaxIndexFileSize(), + maxIndexSizeMB: CodeWhispererSettings.instance.getMaxIndexSize(), + indexCacheDirPath: CodeWhispererSettings.instance.getIndexCacheDirPath(), + }, + }, + }, + ] + case 'aws.codeWhisperer': + return [ + { + includeSuggestionsWithCodeReferences: + CodeWhispererSettings.instance.isSuggestionsWithCodeReferencesEnabled(), + shareCodeWhispererContentWithAWS: !CodeWhispererSettings.instance.isOptoutEnabled(), + }, + ] + case 'aws.logLevel': + return [toAmazonQLSPLogLevel(globals.logOutputChannel.logLevel)] + } +} diff --git a/packages/amazonq/src/lsp/config.ts b/packages/amazonq/src/lsp/config.ts index a98afa44008..bb6870cb561 100644 --- a/packages/amazonq/src/lsp/config.ts +++ b/packages/amazonq/src/lsp/config.ts @@ -2,7 +2,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ - +import * as vscode from 'vscode' import { DevSettings, getServiceEnvVarConfig } from 'aws-core-vscode/shared' import { LspConfig } from 'aws-core-vscode/amazonq' @@ -10,9 +10,29 @@ export interface ExtendedAmazonQLSPConfig extends LspConfig { ui?: string } +// Taken from language server runtimes since they are not exported: +// https://github.com/aws/language-server-runtimes/blob/eae85672c345d8adaf4c8cbd741260b8a59750c4/runtimes/runtimes/util/loggingUtil.ts#L4-L10 +const validLspLogLevels = ['error', 'warn', 'info', 'log', 'debug'] as const +export type LspLogLevel = (typeof validLspLogLevels)[number] +const lspLogLevelMapping: Map = new Map([ + [vscode.LogLevel.Error, 'error'], + [vscode.LogLevel.Warning, 'warn'], + [vscode.LogLevel.Info, 'info'], + [vscode.LogLevel.Debug, 'log'], + [vscode.LogLevel.Trace, 'debug'], + [vscode.LogLevel.Off, 'error'], // TODO: once the language server supports a no-log setting, we can map to that. +]) + +const configSections = ['aws.q', 'aws.codeWhisperer', 'aws.logLevel'] as const +export type ConfigSection = (typeof configSections)[number] + +export function isValidConfigSection(section: unknown): section is ConfigSection { + return typeof section === 'string' && configSections.includes(section as ConfigSection) +} + export const defaultAmazonQLspConfig: ExtendedAmazonQLSPConfig = { - manifestUrl: 'https://aws-toolkit-language-servers.amazonaws.com/remoteWorkspaceContext/0/manifest.json', - supportedVersions: '^1.0.0', + manifestUrl: 'https://aws-toolkit-language-servers.amazonaws.com/qAgenticChatServer/0/manifest.json', + supportedVersions: '1.*.*', id: 'AmazonQ', // used across IDEs for identifying global storage/local disk locations. Do not change. suppressPromptPrefix: 'amazonQ', path: undefined, @@ -26,3 +46,11 @@ export function getAmazonQLspConfig(): ExtendedAmazonQLSPConfig { ...getServiceEnvVarConfig('amazonqLsp', Object.keys(defaultAmazonQLspConfig)), } } +/** + * The language server logging levels do not directly match those used in VSC. Therefore, we must perform a mapping defined by {@link lspLogLevelMapping} + * @param logLevel vscode log level (0-5) + * @returns language server log level + */ +export function toAmazonQLSPLogLevel(logLevel: vscode.LogLevel): LspLogLevel { + return lspLogLevelMapping.get(logLevel) ?? 'info' +} diff --git a/packages/amazonq/src/lsp/lspInstaller.ts b/packages/amazonq/src/lsp/lspInstaller.ts index 6374e609ec0..72fa091f027 100644 --- a/packages/amazonq/src/lsp/lspInstaller.ts +++ b/packages/amazonq/src/lsp/lspInstaller.ts @@ -40,4 +40,6 @@ export class AmazonQLspInstaller extends BaseLspInstaller.BaseLspInstaller< ui: path.join(assetDirectory, 'clients/amazonq-ui.js'), } } + + protected override downloadMessageOverride: string | undefined = 'Updating Amazon Q plugin' } diff --git a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts index 784aed4884c..74f788732dd 100644 --- a/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts +++ b/packages/amazonq/test/e2e/amazonq/transformByQ.test.ts @@ -75,6 +75,9 @@ describe('Amazon Q Code Transformation', function () { }, ]) + transformByQState.setSourceJDKVersion(JDKVersion.JDK8) + transformByQState.setTargetJDKVersion(JDKVersion.JDK17) + tab.addChatMessage({ command: '/transform' }) // wait for /transform to respond with some intro messages and the first user input form @@ -141,16 +144,34 @@ describe('Amazon Q Code Transformation', function () { formItemValues: oneOrMultipleDiffsFormValues, }) - // 2 additional chat messages (including message with 4th form) get sent after 3rd form submitted; wait for both of them + // 2 additional chat messages get sent after 3rd form submitted; wait for both of them await tab.waitForEvent(() => tab.getChatItems().length > 11, { waitTimeoutInMs: 5000, waitIntervalInMs: 1000, }) - const jdkPathPrompt = tab.getChatItems().pop() - assert.strictEqual(jdkPathPrompt?.body?.includes('Enter the path to JDK'), true) - // 2 additional chat messages get sent after 4th form submitted; wait for both of them + // TO-DO: add this back when releasing CSB + /* + const customDependencyVersionPrompt = tab.getChatItems().pop() + assert.strictEqual( + customDependencyVersionPrompt?.body?.includes('You can optionally upload a YAML file'), + true + ) + tab.clickCustomFormButton({ id: 'gumbyTransformFormContinue' }) + + // 2 additional chat messages get sent after Continue button clicked; wait for both of them + await tab.waitForEvent(() => tab.getChatItems().length > 13, { + waitTimeoutInMs: 5000, + waitIntervalInMs: 1000, + }) + */ + + const sourceJdkPathPrompt = tab.getChatItems().pop() + assert.strictEqual(sourceJdkPathPrompt?.body?.includes('Enter the path to JDK 8'), true) + tab.addChatMessage({ prompt: '/dummy/path/to/jdk8' }) + + // 2 additional chat messages get sent after JDK path submitted; wait for both of them await tab.waitForEvent(() => tab.getChatItems().length > 13, { waitTimeoutInMs: 5000, waitIntervalInMs: 1000, @@ -401,7 +422,7 @@ describe('Amazon Q Code Transformation', function () { it('WHEN transforming a Java 8 project E2E THEN job is successful', async function () { transformByQState.setTransformationType(TransformationType.LANGUAGE_UPGRADE) - await setMaven() + setMaven() await startTransformByQ.processLanguageUpgradeTransformFormInput(tempDir, JDKVersion.JDK8, JDKVersion.JDK17) await startTransformByQ.startTransformByQ() assert.strictEqual(transformByQState.getPolledJobStatus(), 'COMPLETED') diff --git a/packages/amazonq/test/e2e/inline/inline.test.ts b/packages/amazonq/test/e2e/inline/inline.test.ts index 57c6e1c4996..43a9f67ab73 100644 --- a/packages/amazonq/test/e2e/inline/inline.test.ts +++ b/packages/amazonq/test/e2e/inline/inline.test.ts @@ -122,7 +122,7 @@ describe('Amazon Q Inline', async function () { .query({ metricName: 'codewhisperer_userTriggerDecision', }) - .map((e) => collectionUtil.partialClone(e, 3, ['credentialStartUrl'], '[omitted]')) + .map((e) => collectionUtil.partialClone(e, 3, ['credentialStartUrl'], { replacement: '[omitted]' })) } for (const [name, invokeCompletion] of [ diff --git a/packages/amazonq/test/unit/amazonq/lsp/chat/error.test.ts b/packages/amazonq/test/unit/amazonq/lsp/chat/error.test.ts new file mode 100644 index 00000000000..80bfe657cc1 --- /dev/null +++ b/packages/amazonq/test/unit/amazonq/lsp/chat/error.test.ts @@ -0,0 +1,15 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { isValidResponseError } from '../../../../../src/lsp/chat/error' +import { ResponseError } from '@aws/language-server-runtimes/protocol' +import * as assert from 'assert' + +describe('isValidResponseError', async function () { + it('requires the data field', function () { + assert.ok(isValidResponseError(new ResponseError(0, 'this one has data', {}))) + assert.ok(!isValidResponseError(new ResponseError(0, 'this one does not have data'))) + }) +}) diff --git a/packages/amazonq/test/unit/amazonqGumby/transformApiHandler.test.ts b/packages/amazonq/test/unit/amazonqGumby/transformApiHandler.test.ts index 6ee0f05391d..1441171bafc 100644 --- a/packages/amazonq/test/unit/amazonqGumby/transformApiHandler.test.ts +++ b/packages/amazonq/test/unit/amazonqGumby/transformApiHandler.test.ts @@ -6,6 +6,7 @@ import assert from 'assert' import { TransformationProgressUpdate, TransformationStep, + findDownloadArtifactProgressUpdate, findDownloadArtifactStep, getArtifactsFromProgressUpdate, } from 'aws-core-vscode/codewhisperer/node' @@ -95,4 +96,55 @@ describe('Amazon Q Transform - transformApiHandler tests', function () { assert.strictEqual(progressUpdate, undefined) }) }) + + describe('findDownloadArtifactProgressUpdate', function () { + it('will return correct progress update from transformationStep', function () { + const transformationStepsFixture: TransformationStep[] = [ + { + id: 'dummy-id', + name: 'Step name', + description: 'Step description', + status: 'TRANSFORMING', + progressUpdates: [ + { + name: 'Progress update name', + status: 'AWAITING_CLIENT_ACTION', + description: 'Client-side build happening now', + startTime: new Date(), + endTime: new Date(), + downloadArtifacts: [ + { + downloadArtifactId: 'some-download-artifact-id', + downloadArtifactType: 'some-download-artifact-type', + }, + ], + }, + ], + startTime: new Date(), + endTime: new Date(), + }, + ] + const progressUpdate = findDownloadArtifactProgressUpdate(transformationStepsFixture) + assert.strictEqual(progressUpdate, transformationStepsFixture[0].progressUpdates?.[0]) + }) + + it('will return undefined if step status is NOT AWAITING_CLIENT_ACTION', function () { + const transformationStepsFixture: TransformationStep[] = [ + { + id: 'random-id', + name: 'not-awaiting-client-action step name', + description: 'not-awaiting-client-action step description', + status: 'TRANSFORMING', + progressUpdates: [ + { + name: 'some progress update name', + status: 'SOMETHING-BESIDES-AWAITING_CLIENT_ACTION', + }, + ], + }, + ] + const progressUpdate = findDownloadArtifactProgressUpdate(transformationStepsFixture) + assert.strictEqual(progressUpdate, undefined) + }) + }) }) diff --git a/packages/amazonq/test/unit/codewhisperer/region/regionProfileManager.test.ts b/packages/amazonq/test/unit/codewhisperer/region/regionProfileManager.test.ts index 1429618b6e4..9a4bed381d1 100644 --- a/packages/amazonq/test/unit/codewhisperer/region/regionProfileManager.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/region/regionProfileManager.test.ts @@ -61,7 +61,7 @@ describe('RegionProfileManager', function () { } const createClientStub = sinon.stub(regionProfileManager, 'createQClient').resolves(mockClient) - const r = await regionProfileManager.listRegionProfiles() + const r = await regionProfileManager.listRegionProfile() assert.strictEqual(r.length, 2) assert.deepStrictEqual(r, [ @@ -177,7 +177,7 @@ describe('RegionProfileManager', function () { }) it(`restoreRegionProfile`, async function () { - sinon.stub(regionProfileManager, 'listRegionProfiles').resolves([profileFoo]) + sinon.stub(regionProfileManager, 'listRegionProfile').resolves([profileFoo]) await setupConnection('idc') if (!AuthUtil.instance.isConnected()) { fail('connection should not be undefined') diff --git a/packages/core/package.json b/packages/core/package.json index 8df2aa2b653..0ed5e368121 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -13,6 +13,7 @@ "./web": "./dist/src/extensionWeb.js", "./webShared": "./dist/src/extensionWebShared.js", "./amazonq": "./dist/src/amazonq/index.js", + "./amazonq/node": "./dist/src/amazonq/indexNode.js", "./codewhisperer": "./dist/src/codewhisperer/index.js", "./codewhisperer/node": "./dist/src/codewhisperer/indexNode.js", "./shared": "./dist/src/shared/index.js", @@ -440,9 +441,10 @@ }, "devDependencies": { "@aws-sdk/types": "^3.13.1", - "@aws/chat-client-ui-types": "^0.1.12", - "@aws/language-server-runtimes": "^0.2.58", - "@aws/language-server-runtimes-types": "^0.1.13", + "@aws/chat-client": "^0.1.4", + "@aws/chat-client-ui-types": "^0.1.24", + "@aws/language-server-runtimes": "^0.2.70", + "@aws/language-server-runtimes-types": "^0.1.26", "@cspotcode/source-map-support": "^0.8.1", "@sinonjs/fake-timers": "^10.0.2", "@types/adm-zip": "^0.4.34", @@ -524,7 +526,7 @@ "@aws-sdk/s3-request-presigner": "<3.731.0", "@aws-sdk/smithy-client": "<3.731.0", "@aws-sdk/util-arn-parser": "<3.731.0", - "@aws/mynah-ui": "^4.30.1", + "@aws/mynah-ui": "^4.30.3", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", "@smithy/fetch-http-handler": "^5.0.1", diff --git a/packages/core/package.nls.json b/packages/core/package.nls.json index 9c6ebe66067..81f56a32c57 100644 --- a/packages/core/package.nls.json +++ b/packages/core/package.nls.json @@ -93,7 +93,10 @@ "AWS.configuration.description.amazonq.workspaceIndex": "When you add @workspace to your question in Amazon Q chat, Amazon Q will index your workspace files locally to use as context for its response. Extra CPU usage is expected while indexing a workspace. This will not impact Amazon Q features or your IDE, but you may manage CPU usage by setting the number of local threads in 'Local Workspace Index Threads'.", "AWS.configuration.description.amazonq.workspaceIndexWorkerThreads": "Number of worker threads of Amazon Q local index process. '0' will use the system default worker threads for balance performance. You may increase this number to more quickly index your workspace, but only up to your hardware's number of CPU cores. Please restart VS Code or reload the VS Code window after changing worker threads.", "AWS.configuration.description.amazonq.workspaceIndexUseGPU": "Enable GPU to help index your local workspace files. Only applies to Linux and Windows.", - "AWS.configuration.description.amazonq.workspaceIndexMaxSize": "The maximum size of local workspace files to be indexed in MB", + "AWS.configuration.description.amazonq.workspaceIndexMaxSize": "The maximum size of local workspace to be indexed in MB", + "AWS.configuration.description.amazonq.workspaceIndexMaxFileSize": "The maximum size of local workspace files to be indexed in MB", + "AWS.configuration.description.amazonq.workspaceIndexIgnoreFilePatterns": "File patterns to ignore when indexing your workspace files", + "AWS.configuration.description.amazonq.workspaceIndexCacheDirPath": "The path to the directory that contains the cache of the index of your workspace files", "AWS.configuration.description.amazonq.ignoredSecurityIssues": "Specifies a list of code issue identifiers that Amazon Q should ignore when reviewing your workspace. Each item in the array should be a unique string identifier for a specific code issue. This allows you to suppress notifications for known issues that you've assessed and determined to be false positives or not applicable to your project. Use this setting with caution, as it may cause you to miss important security alerts.", "AWS.command.apig.copyUrl": "Copy URL", "AWS.command.apig.invokeRemoteRestApi": "Invoke in the cloud", diff --git a/packages/core/src/amazonq/commons/controllers/contentController.ts b/packages/core/src/amazonq/commons/controllers/contentController.ts index 64e1254c21a..70744417451 100644 --- a/packages/core/src/amazonq/commons/controllers/contentController.ts +++ b/packages/core/src/amazonq/commons/controllers/contentController.ts @@ -11,7 +11,7 @@ import { amazonQDiffScheme, amazonQTabSuffix } from '../../../shared/constants' import { disposeOnEditorClose } from '../../../shared/utilities/editorUtilities' import { applyChanges, - createTempFileForDiff, + createTempUrisForDiff, getIndentedCode, getSelectionFromRange, } from '../../../shared/utilities/textDocumentUtilities' @@ -19,6 +19,11 @@ import { ToolkitError, getErrorMsg } from '../../../shared/errors' import fs from '../../../shared/fs/fs' import { extractFileAndCodeSelectionFromMessage } from '../../../shared/utilities/textUtilities' import { UserWrittenCodeTracker } from '../../../codewhisperer/tracker/userWrittenCodeTracker' +import type { ViewDiff } from '../../../codewhispererChat/controllers/chat/model' +import type { TriggerEvent } from '../../../codewhispererChat/storages/triggerEvents' +import { DiffContentProvider } from './diffContentProvider' + +export type ViewDiffMessage = Pick & Partial> export class ContentProvider implements vscode.TextDocumentContentProvider { constructor(private uri: vscode.Uri) {} @@ -155,27 +160,35 @@ export class EditorContentController { * isolating them from any other modifications in the original file. * * @param message the message from Amazon Q chat + * @param scheme the URI scheme to use for the diff view */ - public async viewDiff(message: any, scheme: string = amazonQDiffScheme) { + public async viewDiff(message: ViewDiffMessage, scheme: string = amazonQDiffScheme) { const errorNotification = 'Unable to Open Diff.' - const { filePath, selection } = extractFileAndCodeSelectionFromMessage(message) + const { filePath, fileText, selection } = extractFileAndCodeSelectionFromMessage(message) try { - if (filePath && message?.code?.trim().length > 0 && selection) { - const originalFileUri = vscode.Uri.file(filePath) - const uri = await createTempFileForDiff(originalFileUri, message, selection, scheme) - + if (filePath && message?.code !== undefined && selection) { // Register content provider and show diff - const contentProvider = new ContentProvider(uri) + const contentProvider = new DiffContentProvider() const disposable = vscode.workspace.registerTextDocumentContentProvider(scheme, contentProvider) + + const [originalFileUri, modifiedFileUri] = await createTempUrisForDiff( + filePath, + fileText, + message, + selection, + scheme, + contentProvider + ) + await vscode.commands.executeCommand( 'vscode.diff', originalFileUri, - uri, + modifiedFileUri, `${path.basename(filePath)} ${amazonQTabSuffix}` ) - disposeOnEditorClose(uri, disposable) + disposeOnEditorClose(originalFileUri, disposable) } } catch (error) { void vscode.window.showInformationMessage(errorNotification) diff --git a/packages/core/src/amazonq/commons/controllers/diffContentProvider.ts b/packages/core/src/amazonq/commons/controllers/diffContentProvider.ts new file mode 100644 index 00000000000..5d2e7c2efd0 --- /dev/null +++ b/packages/core/src/amazonq/commons/controllers/diffContentProvider.ts @@ -0,0 +1,51 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import vscode from 'vscode' +import { getLogger } from '../../../shared/logger/logger' + +/** + * A TextDocumentContentProvider that can handle multiple URIs with the same scheme. + * This provider maintains a mapping of URIs to their content. + */ +export class DiffContentProvider implements vscode.TextDocumentContentProvider { + private contentMap = new Map() + private _onDidChange = new vscode.EventEmitter() + + public readonly onDidChange = this._onDidChange.event + + /** + * Register content for a specific URI + * @param uri The URI to register content for + * @param content The content to serve for this URI + */ + public registerContent(uri: vscode.Uri, content: string): void { + this.contentMap.set(uri.toString(), content) + this._onDidChange.fire(uri) + } + + /** + * Unregister a URI + * @param uri The URI to unregister + */ + public unregisterUri(uri: vscode.Uri): void { + this.contentMap.delete(uri.toString()) + } + + /** + * Provides the content for a given URI + * @param uri The URI to provide content for + * @returns The content as a string + */ + public provideTextDocumentContent(uri: vscode.Uri): string { + const content = this.contentMap.get(uri.toString()) + + if (content === undefined) { + getLogger().warn('No content registered for URI: %s', uri.toString()) + return '' + } + + return content + } +} diff --git a/packages/core/src/amazonq/commons/model.ts b/packages/core/src/amazonq/commons/model.ts index 766c5160262..3c5b228d2fc 100644 --- a/packages/core/src/amazonq/commons/model.ts +++ b/packages/core/src/amazonq/commons/model.ts @@ -3,6 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { LicenseUtil } from '../../codewhisperer/util/licenseUtil' +import { CodeReference } from '../../codewhispererChat/view/connector/connector' + // Currently importing ChatItemType in Mynah UI from the vscode side causes an error // TODO remove this once the import stops failing export type ChatItemType = @@ -13,3 +16,10 @@ export type ChatItemType = | 'answer-stream' | 'answer-part' | 'code-result' + +export const referenceLogText = (reference: CodeReference) => + `[${new Date().toLocaleString()}] Accepted recommendation from Amazon Q. Code provided with reference under ${reference.licenseName} license from repository ${reference.repository}.

` diff --git a/packages/core/src/amazonq/index.ts b/packages/core/src/amazonq/index.ts index 06af40f2c29..14c0e4a59a0 100644 --- a/packages/core/src/amazonq/index.ts +++ b/packages/core/src/amazonq/index.ts @@ -20,11 +20,6 @@ export { LspClient } from './lsp/lspClient' export * as lspClient from './lsp/lspClient' export { api } from './extApi' export { AmazonQChatViewProvider } from './webview/webView' -export { init as cwChatAppInit } from '../codewhispererChat/app' -export { init as featureDevChatAppInit } from '../amazonqFeatureDev/app' -export { init as gumbyChatAppInit } from '../amazonqGumby/app' -export { init as testChatAppInit } from '../amazonqTest/app' -export { init as docChatAppInit } from '../amazonqDoc/app' export { amazonQHelpUrl } from '../shared/constants' export * as webviewConstants from './webview/ui/texts/constants' export * as webviewTabConstants from './webview/ui/tabs/constants' @@ -40,7 +35,7 @@ export { computeDiff, } from './commons/diff' export { AuthFollowUpType, AuthMessageDataMap } from './auth/model' -export { ChatItemType } from './commons/model' +export { ChatItemType, referenceLogText } from './commons/model' export { ExtensionMessage } from '../amazonq/webview/ui/commands' export { CodeReference } from '../codewhispererChat/view/connector/connector' export { extractAuthFollowUp } from './util/authUtils' @@ -49,7 +44,10 @@ export * from './lsp/config' export * as WorkspaceLspInstaller from './lsp/workspaceInstaller' export * as secondaryAuth from '../auth/secondaryAuth' export * as authConnection from '../auth/connection' +export * as featureConfig from './webview/generators/featureConfig' +export * as messageDispatcher from './webview/messages/messageDispatcher' import { FeatureContext } from '../shared/featureConfig' +export { EditorContentController, ViewDiffMessage } from './commons/controllers/contentController' /** * main from createMynahUI is a purely browser dependency. Due to this diff --git a/packages/core/src/amazonq/indexNode.ts b/packages/core/src/amazonq/indexNode.ts new file mode 100644 index 00000000000..88a3a4bba37 --- /dev/null +++ b/packages/core/src/amazonq/indexNode.ts @@ -0,0 +1,13 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * These agents have underlying requirements on node dependencies (e.g. jsdom, admzip) + */ +export { init as cwChatAppInit } from '../codewhispererChat/app' +export { init as featureDevChatAppInit } from '../amazonqFeatureDev/app' +export { init as gumbyChatAppInit } from '../amazonqGumby/app' +export { init as testChatAppInit } from '../amazonqTest/app' +export { init as docChatAppInit } from '../amazonqDoc/app' diff --git a/packages/core/src/amazonq/lsp/lspClient.ts b/packages/core/src/amazonq/lsp/lspClient.ts index b992fef2fe3..eba89c961c4 100644 --- a/packages/core/src/amazonq/lsp/lspClient.ts +++ b/packages/core/src/amazonq/lsp/lspClient.ts @@ -8,6 +8,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ import * as vscode from 'vscode' +import { oneMB } from '../../shared/utilities/processUtils' import * as path from 'path' import * as nls from 'vscode-nls' import * as crypto from 'crypto' @@ -252,18 +253,20 @@ export async function activate(extensionContext: ExtensionContext, resourcePaths } const serverModule = resourcePaths.lsp + const memoryWarnThreshold = 800 * oneMB const serverOptions = createServerOptions({ encryptionKey: key, - executable: resourcePaths.node, + executable: [resourcePaths.node], serverModule, // TODO(jmkeyes): we always use the debug options...? execArgv: debugOptions.execArgv, + warnThresholds: { memory: memoryWarnThreshold }, }) const documentSelector = [{ scheme: 'file', language: '*' }] - await validateNodeExe(resourcePaths.node, resourcePaths.lsp, debugOptions.execArgv, logger) + await validateNodeExe([resourcePaths.node], resourcePaths.lsp, debugOptions.execArgv, logger) // Options to control the language client const clientOptions: LanguageClientOptions = { diff --git a/packages/core/src/amazonq/webview/generators/featureConfig.ts b/packages/core/src/amazonq/webview/generators/featureConfig.ts new file mode 100644 index 00000000000..8de71be5c5c --- /dev/null +++ b/packages/core/src/amazonq/webview/generators/featureConfig.ts @@ -0,0 +1,35 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { FeatureConfigProvider, FeatureContext } from '../../../shared/featureConfig' + +export async function getFeatureConfigs(): Promise { + let featureConfigs = new Map() + try { + await FeatureConfigProvider.instance.fetchFeatureConfigs() + featureConfigs = FeatureConfigProvider.getFeatureConfigs() + } catch (error) { + // eslint-disable-next-line aws-toolkits/no-console-log + console.error('Error fetching feature configs:', error) + } + + // Convert featureConfigs to a string suitable for data-features + return JSON.stringify(Array.from(featureConfigs.entries())) +} + +export function serialize(configs: string) { + let featureDataAttributes = '' + try { + // Fetch and parse featureConfigs + const featureConfigs = JSON.parse(configs) + featureDataAttributes = featureConfigs + .map((config: FeatureContext[]) => `data-feature-${config[1].name}="${config[1].variation}"`) + .join(' ') + } catch (error) { + // eslint-disable-next-line aws-toolkits/no-console-log + console.error('Error setting data-feature attribute for featureConfigs:', error) + } + return featureDataAttributes +} diff --git a/packages/core/src/amazonq/webview/generators/webViewContent.ts b/packages/core/src/amazonq/webview/generators/webViewContent.ts index 699cbc2a278..ddbee4f0e9b 100644 --- a/packages/core/src/amazonq/webview/generators/webViewContent.ts +++ b/packages/core/src/amazonq/webview/generators/webViewContent.ts @@ -6,26 +6,12 @@ import path from 'path' import { Uri, Webview } from 'vscode' import { AuthUtil } from '../../../codewhisperer/util/authUtil' -import { FeatureConfigProvider, FeatureContext } from '../../../shared/featureConfig' import globals from '../../../shared/extensionGlobals' import { isSageMaker } from '../../../shared/extensionUtilities' import { AmazonQPromptSettings } from '../../../shared/settings' +import { getFeatureConfigs, serialize } from './featureConfig' export class WebViewContentGenerator { - private async generateFeatureConfigsData(): Promise { - let featureConfigs = new Map() - try { - await FeatureConfigProvider.instance.fetchFeatureConfigs() - featureConfigs = FeatureConfigProvider.getFeatureConfigs() - } catch (error) { - // eslint-disable-next-line aws-toolkits/no-console-log - console.error('Error fetching feature configs:', error) - } - - // Convert featureConfigs to a string suitable for data-features - return JSON.stringify(Array.from(featureConfigs.entries())) - } - public async generate(extensionURI: Uri, webView: Webview): Promise { const entrypoint = process.env.WEBPACK_DEVELOPER_SERVER ? 'http: localhost' @@ -34,30 +20,21 @@ export class WebViewContentGenerator { const contentPolicy = `default-src ${entrypoint} data: blob: 'unsafe-inline'; script-src ${entrypoint} filesystem: ws: wss: 'unsafe-inline';` - let featureDataAttributes = '' - try { - // Fetch and parse featureConfigs - const featureConfigs = JSON.parse(await this.generateFeatureConfigsData()) - featureDataAttributes = featureConfigs - .map((config: FeatureContext[]) => `data-feature-${config[1].name}="${config[1].variation}"`) - .join(' ') - } catch (error) { - // eslint-disable-next-line aws-toolkits/no-console-log - console.error('Error setting data-feature attribute for featureConfigs:', error) - } + const configs = await getFeatureConfigs() + const featureDataAttributes = serialize(configs) return ` Amazon Q (Preview) - ${await this.generateJS(extensionURI, webView)} + ${await this.generateJS(extensionURI, webView, configs)} ` } - private async generateJS(extensionURI: Uri, webView: Webview): Promise { + private async generateJS(extensionURI: Uri, webView: Webview, featureConfigsString: string): Promise { const source = path.join('vue', 'src', 'amazonq', 'webview', 'ui', 'amazonq-ui.js') // Sent to dist/vue folder in webpack. const assetsPath = Uri.joinPath(extensionURI) const javascriptUri = Uri.joinPath(assetsPath, 'dist', source) @@ -77,8 +54,6 @@ export class WebViewContentGenerator { const cssEntrypointsMap = cssEntrypoints.map((item) => webView.asWebviewUri(item)) const cssLinks = cssEntrypointsMap.map((uri) => ``).join('\n') - // Fetch featureConfigs and use it within the script - const featureConfigsString = await this.generateFeatureConfigsData() const isSM = isSageMaker('SMAI') const isSMUS = isSageMaker('SMUS') diff --git a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts index a71120b353c..56d4c8503b9 100644 --- a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts +++ b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts @@ -24,93 +24,110 @@ export function dispatchWebViewMessagesToApps( webViewToAppsMessagePublishers: Map> ) { 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. - */ + handleWebviewEvent(msg, webViewToAppsMessagePublishers) + }) +} + +export function isLegacyEvent(value: string): boolean { + return ( + value === 'ui-is-ready' || + value === 'start-chat-message-telemetry' || + value === 'update-chat-message-telemetry' || + value === 'stop-chat-message-telemetry' || + value === 'open-link' || + value === 'send-telemetry' || + value === 'disclaimer-acknowledged' || + value === 'update-welcome-count' + ) +} + +export function handleWebviewEvent(msg: any, webViewToAppsMessagePublishers: Map>) { + 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.toolkit_didLoadModule.emit({ + module: qChatModuleName, + duration: performance.measure(amazonqMark.uiReady, amazonqMark.open).duration, + result: 'Succeeded', + }) + performance.clearMarks(amazonqMark.uiReady) + performance.clearMarks(amazonqMark.open) + // let cwcController know the ui is ready + webViewToAppsMessagePublishers.get('cwc')?.publish(msg) + return + } + case 'start-chat-message-telemetry': { + AmazonQChatMessageDuration.startChatMessageTelemetry(msg) + return + } + case 'update-chat-message-telemetry': { + AmazonQChatMessageDuration.updateChatMessageTelemetry(msg) + return + } + case 'stop-chat-message-telemetry': { + AmazonQChatMessageDuration.stopChatMessageTelemetry(msg) + return + } + case 'open-link': { + const { link } = msg + void openUrl(Uri.parse(link)) + return + } + case 'send-telemetry': { + if (isOpenAgentTelemetry(msg)) { telemetry.toolkit_didLoadModule.emit({ - module: qChatModuleName, - duration: performance.measure(amazonqMark.uiReady, amazonqMark.open).duration, + module: msg.module, + source: msg.trigger, result: 'Succeeded', }) - performance.clearMarks(amazonqMark.uiReady) - performance.clearMarks(amazonqMark.open) - // let cwcController know the ui is ready - webViewToAppsMessagePublishers.get('cwc')?.publish(msg) - return - } - case 'start-chat-message-telemetry': { - AmazonQChatMessageDuration.startChatMessageTelemetry(msg) - return - } - case 'update-chat-message-telemetry': { - AmazonQChatMessageDuration.updateChatMessageTelemetry(msg) - return - } - case 'stop-chat-message-telemetry': { - AmazonQChatMessageDuration.stopChatMessageTelemetry(msg) return - } - case 'open-link': { - const { link } = msg - void openUrl(Uri.parse(link)) - return - } - case 'send-telemetry': { - if (isOpenAgentTelemetry(msg)) { - telemetry.toolkit_didLoadModule.emit({ - module: msg.module, - source: msg.trigger, - result: 'Succeeded', - }) - return - } else if (isClickTelemetry(msg)) { - telemetry.ui_click.emit({ - elementId: msg.source, - result: 'Succeeded', - }) - return - } - return - } - case 'disclaimer-acknowledged': { - void AmazonQPromptSettings.instance.disablePrompt('amazonQChatDisclaimer') - return - } - case 'update-welcome-count': { - const currentLoadCount = globals.globalState.tryGet('aws.amazonq.welcomeChatShowCount', Number, 0) - void globals.globalState.tryUpdate('aws.amazonq.welcomeChatShowCount', currentLoadCount + 1) + } else if (isClickTelemetry(msg)) { + telemetry.ui_click.emit({ + elementId: msg.source, + result: 'Succeeded', + }) return } + return } - - if (msg.type === 'error') { - if (msg.event === 'toolkit_didLoadModule') { - telemetry.toolkit_didLoadModule.emit({ - module: qChatModuleName, - result: 'Failed', - reasonDesc: msg.errorMessage, - }) - } else { - telemetry.webview_error.emit({ - webviewName: qChatModuleName, - result: 'Failed', - reasonDesc: msg.errorMessage, - }) - } + case 'disclaimer-acknowledged': { + void AmazonQPromptSettings.instance.update('amazonQChatDisclaimer', true) return } - - const appMessagePublisher = webViewToAppsMessagePublishers.get(msg.tabType) - if (appMessagePublisher === undefined) { + case 'update-welcome-count': { + const currentLoadCount = globals.globalState.tryGet('aws.amazonq.welcomeChatShowCount', Number, 0) + void globals.globalState.tryUpdate('aws.amazonq.welcomeChatShowCount', currentLoadCount + 1) return } - appMessagePublisher.publish(msg) - }) + } + + if (msg.type === 'error') { + if (msg.event === 'toolkit_didLoadModule') { + telemetry.toolkit_didLoadModule.emit({ + module: qChatModuleName, + result: 'Failed', + reasonDesc: msg.errorMessage, + }) + } else { + telemetry.webview_error.emit({ + webviewName: qChatModuleName, + result: 'Failed', + reasonDesc: msg.errorMessage, + }) + } + return + } + + const appMessagePublisher = webViewToAppsMessagePublishers.get(msg.tabType) + if (appMessagePublisher === undefined) { + return + } + appMessagePublisher.publish(msg) } export function dispatchAppsMessagesToWebView(webView: Webview, appsMessageListener: MessageListener) { diff --git a/packages/core/src/amazonq/webview/ui/connectorAdapter.ts b/packages/core/src/amazonq/webview/ui/connectorAdapter.ts new file mode 100644 index 00000000000..1de1d8556c4 --- /dev/null +++ b/packages/core/src/amazonq/webview/ui/connectorAdapter.ts @@ -0,0 +1,98 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ChatPrompt, MynahUI, QuickActionCommandGroup } from '@aws/mynah-ui' +import { isTabType } from './storages/tabsStorage' +import { WebviewUIHandler } from './main' +import { FeatureContext } from '../../../shared/featureConfig' +import { TabDataGenerator } from './tabs/generator' +import { RegionProfile } from '../../../codewhisperer/models/model' +import { ChatClientAdapter, ChatEventHandler } from '@aws/chat-client' + +export class HybridChatAdapter implements ChatClientAdapter { + private uiHandler?: WebviewUIHandler + + private mynahUIRef?: { mynahUI: MynahUI } + + constructor( + private enableAgents: boolean, + private featureConfigsSerialized: [string, FeatureContext][], + private welcomeCount: number, + private disclaimerAcknowledged: boolean, + private regionProfile: RegionProfile | undefined, + private disabledCommands: string[], + private isSMUS: boolean, + private isSM: boolean, + private ideApiPostMessage: (message: any) => void + ) {} + + /** + * First we create the ui handler to get the props, then once mynah UI gets created flare will re-inject the + * mynah UI instance on the hybrid chat adapter + */ + createChatEventHandler(mynahUIRef: { mynahUI: MynahUI }): ChatEventHandler { + this.mynahUIRef = mynahUIRef + + this.uiHandler = new WebviewUIHandler({ + postMessage: this.ideApiPostMessage, + mynahUIRef: this.mynahUIRef, + enableAgents: this.enableAgents, + featureConfigsSerialized: this.featureConfigsSerialized, + welcomeCount: this.welcomeCount, + disclaimerAcknowledged: this.disclaimerAcknowledged, + regionProfile: this.regionProfile, + disabledCommands: this.disabledCommands, + isSMUS: this.isSMUS, + isSM: this.isSM, + hybridChat: true, + }) + + return this.uiHandler.mynahUIProps + } + + isSupportedTab(tabId: string): boolean { + const tabType = this.uiHandler?.tabsStorage.getTab(tabId)?.type + if (!tabType) { + return false + } + return isTabType(tabType) && tabType !== 'cwc' + } + + async handleMessageReceive(message: MessageEvent): Promise { + if (this.uiHandler) { + return this.uiHandler?.connector?.handleMessageReceive(message) + } + + // eslint-disable-next-line aws-toolkits/no-console-log + console.error('unknown message: ', message.data) + } + + isSupportedQuickAction(command: string): boolean { + return ( + command === '/dev' || + command === '/test' || + command === '/review' || + command === '/doc' || + command === '/transform' + ) + } + + handleQuickAction(prompt: ChatPrompt, tabId: string, eventId: string | undefined): void { + return this.uiHandler?.quickActionHandler?.handle(prompt, tabId, eventId) + } + + get initialQuickActions(): QuickActionCommandGroup[] { + const tabDataGenerator = new TabDataGenerator({ + isDocEnabled: this.enableAgents, + isFeatureDevEnabled: this.enableAgents, + isGumbyEnabled: this.enableAgents, + isScanEnabled: this.enableAgents, + isTestEnabled: this.enableAgents, + disabledCommands: this.disabledCommands, + commandHighlight: this.featureConfigsSerialized.find(([name]) => name === 'highlightCommand')?.[1], + }) + return tabDataGenerator.quickActionsGenerator.generateForTab('cwc') ?? [] + } +} diff --git a/packages/core/src/amazonq/webview/ui/main.ts b/packages/core/src/amazonq/webview/ui/main.ts index baf095c19cc..7d5bd48eaeb 100644 --- a/packages/core/src/amazonq/webview/ui/main.ts +++ b/packages/core/src/amazonq/webview/ui/main.ts @@ -66,6 +66,7 @@ export const createMynahUI = ( disabledCommands, isSMUS, isSM, + hybridChat: false, }) return { @@ -120,6 +121,7 @@ export class WebviewUIHandler { disabledCommands, isSMUS, isSM, + hybridChat, }: { postMessage: any mynahUIRef: { mynahUI: MynahUI | undefined } @@ -131,6 +133,7 @@ export class WebviewUIHandler { disabledCommands?: string[] isSMUS?: boolean isSM?: boolean + hybridChat?: boolean }) { this.postMessage = postMessage this.welcomeCount = welcomeCount @@ -207,6 +210,7 @@ export class WebviewUIHandler { isScanEnabled: this.isScanEnabled, isTestEnabled: this.isTestEnabled, isDocEnabled: this.isDocEnabled, + hybridChat, disabledCommands, }) @@ -642,8 +646,27 @@ export class WebviewUIHandler { }) this.mynahUIProps = { - onReady: this.connector.uiReady, + onReady: () => { + // the legacy event flow adds events listeners to the window, we want to avoid these in the lsp flow, since those + // are handled by the flare chat-client + if (hybridChat && this.connector) { + this.connector.isUIReady = true + postMessage({ + command: 'ui-is-ready', + }) + return + } + this.connector?.uiReady() + }, onTabAdd: (tabID: string) => { + if (hybridChat) { + /** + * hybrid chat doesn't support the welcome page + * tabs are already added by the quick action handler + * so theres nothing we have to do here + */ + return + } /** * If the next tab opening will cross the welcome count threshold then * update the next tabs defaults @@ -989,7 +1012,13 @@ export class WebviewUIHandler { }, } - this.mynahUIRef = { mynahUI: new MynahUI(this.mynahUIProps) } + if (!hybridChat) { + /** + * when in hybrid chat the reference gets resolved later so we + * don't need to create mynah UI + */ + this.mynahUIRef = { mynahUI: new MynahUI({ ...this.mynahUIProps, loadStyles: false }) } + } /** * Update the welcome count if we've initially shown @@ -1013,6 +1042,7 @@ export class WebviewUIHandler { isScanEnabled: this.isScanEnabled, isTestEnabled: this.isTestEnabled, isDocEnabled: this.isDocEnabled, + hybridChat, }) this.textMessageHandler = new TextMessageHandler({ mynahUIRef: this.mynahUIRef, diff --git a/packages/core/src/amazonq/webview/ui/quickActions/handler.ts b/packages/core/src/amazonq/webview/ui/quickActions/handler.ts index 85c96a1a39c..fe124d1fc0c 100644 --- a/packages/core/src/amazonq/webview/ui/quickActions/handler.ts +++ b/packages/core/src/amazonq/webview/ui/quickActions/handler.ts @@ -19,6 +19,7 @@ export interface QuickActionsHandlerProps { isScanEnabled: boolean isTestEnabled: boolean isDocEnabled: boolean + hybridChat?: boolean disabledCommands?: string[] } @@ -40,6 +41,7 @@ export class QuickActionHandler { private isScanEnabled: boolean private isTestEnabled: boolean private isDocEnabled: boolean + private isHybridChatEnabled: boolean constructor(props: QuickActionsHandlerProps) { this.mynahUIRef = props.mynahUIRef @@ -58,6 +60,7 @@ export class QuickActionHandler { this.isGumbyEnabled = props.isGumbyEnabled this.isScanEnabled = props.isScanEnabled this.isTestEnabled = props.isTestEnabled + this.isHybridChatEnabled = props.hybridChat ?? false } /** @@ -104,7 +107,7 @@ export class QuickActionHandler { } } - private handleScanCommand(tabID: string, eventId: string | undefined) { + private handleScanCommand(tabID: string | undefined, eventId: string | undefined) { if (!this.isScanEnabled || !this.mynahUI) { return } @@ -123,15 +126,17 @@ export class QuickActionHandler { return } - let affectedTabId: string | undefined = tabID - // if there is no scan tab, open a new one - const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type - if (currentTabType !== 'unknown' && currentTabType !== 'welcome') { - affectedTabId = this.mynahUI.updateStore('', { - loadingChat: true, - }) + /** + * status bar -> "full project scan is now /review" doesn't have a tab ID + * since it's called via a command so we need to manually create one + */ + if (!tabID) { + tabID = this.mynahUI.updateStore('', {}) } + // if there is no scan tab, open a new one + const affectedTabId: string | undefined = this.addTab(tabID) + if (affectedTabId === undefined) { this.mynahUI.notify({ content: uiComponentsTexts.noMoreTabsTooltip, @@ -158,7 +163,7 @@ export class QuickActionHandler { } } - private handleTestCommand(chatPrompt: ChatPrompt, tabID: string, eventId: string | undefined) { + private handleTestCommand(chatPrompt: ChatPrompt, tabID: string | undefined, eventId: string | undefined) { if (!this.isTestEnabled || !this.mynahUI) { return } @@ -172,15 +177,18 @@ export class QuickActionHandler { return } - let affectedTabId: string | undefined = tabID - // if there is no test tab, open a new one - const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type - if (currentTabType !== 'unknown' && currentTabType !== 'welcome') { - affectedTabId = this.mynahUI.updateStore('', { - loadingChat: true, - }) + /** + * right click -> generate test has no tab id + * we have to manually create one if a testgen tab + * wasn't previously created + */ + if (!tabID) { + tabID = this.mynahUI.updateStore('', {}) } + // if there is no test tab, open a new one + const affectedTabId: string | undefined = this.addTab(tabID) + if (affectedTabId === undefined) { this.mynahUI.notify({ content: uiComponentsTexts.noMoreTabsTooltip, @@ -212,12 +220,10 @@ export class QuickActionHandler { return } - let affectedTabId: string | undefined = props.tabID const realPromptText = props.chatPrompt?.escapedPrompt?.trim() ?? '' - const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type - if (currentTabType !== 'unknown' && currentTabType !== 'welcome') { - affectedTabId = this.mynahUI.updateStore('', {}) - } + + const affectedTabId = this.addTab(props.tabID) + if (affectedTabId === undefined) { this.mynahUI.notify({ content: uiComponentsTexts.noMoreTabsTooltip, @@ -305,15 +311,8 @@ export class QuickActionHandler { return } - let affectedTabId: string | undefined = tabID // if there is no gumby tab, open a new one - const currentTabType = this.tabsStorage.getTab(affectedTabId)?.type - if (currentTabType !== 'unknown' && currentTabType !== 'welcome') { - affectedTabId = this.mynahUI.updateStore('', { - loadingChat: true, - cancelButtonWhenLoading: false, - }) - } + const affectedTabId: string | undefined = this.addTab(tabID) if (affectedTabId === undefined) { this.mynahUI.notify({ @@ -343,6 +342,33 @@ export class QuickActionHandler { } } + private addTab(affectedTabId: string | undefined) { + if (!affectedTabId || !this.mynahUI) { + return + } + + const currTab = this.mynahUI.getAllTabs()[affectedTabId] + const currTabWasUsed = + (currTab.store?.chatItems?.filter((item) => item.type === ChatItemType.PROMPT).length ?? 0) > 0 + if (currTabWasUsed) { + affectedTabId = this.mynahUI.updateStore('', { + loadingChat: true, + cancelButtonWhenLoading: false, + }) + } + + if (affectedTabId && this.isHybridChatEnabled) { + this.tabsStorage.addTab({ + id: affectedTabId, + type: 'unknown', + status: 'free', + isSelected: true, + }) + } + + return affectedTabId + } + private handleClearCommand(tabID: string) { this.mynahUI?.updateStore(tabID, { chatItems: [], diff --git a/packages/core/src/amazonqDoc/session/session.ts b/packages/core/src/amazonqDoc/session/session.ts index 30d0ed4d874..8cfb5283626 100644 --- a/packages/core/src/amazonqDoc/session/session.ts +++ b/packages/core/src/amazonqDoc/session/session.ts @@ -15,7 +15,7 @@ import { TelemetryHelper } from '../../amazonq/util/telemetryHelper' import { ConversationNotStartedState } from '../../amazonqFeatureDev/session/sessionState' import { logWithConversationId } from '../../amazonqFeatureDev/userFacingText' import { ConversationIdNotFoundError, IllegalStateError } from '../../amazonqFeatureDev/errors' -import { referenceLogText } from '../../amazonqFeatureDev/constants' +import { referenceLogText } from '../../amazonq/commons/model' import { DocInteractionType, DocV2AcceptanceEvent, diff --git a/packages/core/src/amazonqFeatureDev/constants.ts b/packages/core/src/amazonqFeatureDev/constants.ts index 4bc3ca1fdb2..78cae972cc3 100644 --- a/packages/core/src/amazonqFeatureDev/constants.ts +++ b/packages/core/src/amazonqFeatureDev/constants.ts @@ -26,14 +26,6 @@ export const clientErrorMessages = [ 'The folder you chose did not contain any source files in a supported language. Choose another folder and try again.', ] -// License text that's used in codewhisperer reference log -export const referenceLogText = (reference: CodeReference) => - `[${new Date().toLocaleString()}] Accepted recommendation from Amazon Q. Code provided with reference under ${reference.licenseName} license from repository ${reference.repository}.

` - // License text that's used in the file view export const licenseText = (reference: CodeReference) => `${ diff --git a/packages/core/src/amazonqFeatureDev/session/session.ts b/packages/core/src/amazonqFeatureDev/session/session.ts index c6d4452f11f..f89db0aa9e7 100644 --- a/packages/core/src/amazonqFeatureDev/session/session.ts +++ b/packages/core/src/amazonqFeatureDev/session/session.ts @@ -15,7 +15,7 @@ import { UpdateFilesPathsParams, } from '../../amazonq/commons/types' import { ContentLengthError, ConversationIdNotFoundError, IllegalStateError } from '../errors' -import { featureDevChat, referenceLogText, featureDevScheme } from '../constants' +import { featureDevChat, featureDevScheme } from '../constants' import fs from '../../shared/fs/fs' import { FeatureDevClient } from '../client/featureDev' import { codeGenRetryLimit } from '../limits' @@ -34,6 +34,8 @@ import { FollowUpTypes } from '../../amazonq/commons/types' import { SessionConfig } from '../../amazonq/commons/session/sessionConfigFactory' import { Messenger } from '../../amazonq/commons/connector/baseMessenger' import { ContentLengthError as CommonContentLengthError } from '../../shared/errors' +import { referenceLogText } from '../../amazonq/commons/model' + export class Session { private _state?: SessionState | Omit private task: string = '' diff --git a/packages/core/src/amazonqGumby/chat/controller/controller.ts b/packages/core/src/amazonqGumby/chat/controller/controller.ts index 43e3ce51dd2..188418eb8bb 100644 --- a/packages/core/src/amazonqGumby/chat/controller/controller.ts +++ b/packages/core/src/amazonqGumby/chat/controller/controller.ts @@ -25,7 +25,6 @@ import { processSQLConversionTransformFormInput, startTransformByQ, stopTransformByQ, - validateCanCompileProject, getValidSQLConversionCandidateProjects, openHilPomFile, } from '../../../codewhisperer/commands/startTransformByQ' @@ -33,7 +32,6 @@ import { JDKVersion, TransformationCandidateProject, transformByQState } from '. import { AbsolutePathDetectedError, AlternateDependencyVersionsNotFoundError, - JavaHomeNotSetError, JobStartError, ModuleUploadError, NoJavaProjectsFoundError, @@ -59,8 +57,10 @@ import { openBuildLogFile, parseBuildFile, validateSQLMetadataFile, + validateCustomVersionsFile, } from '../../../codewhisperer/service/transformByQ/transformFileHandler' import { getAuthType } from '../../../auth/utils' +import fs from '../../../shared/fs/fs' // These events can be interactions within the chat, // or elsewhere in the IDE @@ -243,7 +243,7 @@ export class GumbyController { CodeTransformTelemetryState.instance.setSessionId() this.sessionStorage.getSession().conversationState = ConversationState.WAITING_FOR_TRANSFORMATION_OBJECTIVE - this.messenger.sendStaticTextResponse('choose-transformation-objective', message.tabID) + this.messenger.sendMessage(CodeWhispererConstants.chooseTransformationObjective, message.tabID, 'ai-prompt') this.messenger.sendChatInputEnabled(message.tabID, true) this.messenger.sendUpdatePlaceholder( message.tabID, @@ -299,7 +299,7 @@ export class GumbyController { const validProjects = await this.validateSQLConversionProjects(message) if (validProjects.length > 0) { this.sessionStorage.getSession().updateCandidateProjects(validProjects) - await this.messenger.sendSelectSQLMetadataFileMessage(message.tabID) + this.messenger.sendSelectSQLMetadataFileMessage(message.tabID) } }) .catch((err) => { @@ -383,6 +383,18 @@ export class GumbyController { case ButtonActions.SELECT_SQL_CONVERSION_METADATA_FILE: await this.processMetadataFile(message) break + case ButtonActions.SELECT_CUSTOM_DEPENDENCY_VERSION_FILE: + await this.processCustomDependencyVersionFile(message) + break + case ButtonActions.CONTINUE_TRANSFORMATION_FORM: + this.messenger.sendMessage( + CodeWhispererConstants.continueWithoutYamlMessage, + message.tabID, + 'ai-prompt' + ) + transformByQState.setCustomDependencyVersionFilePath('') + this.promptJavaHome('source', message.tabID) + break case ButtonActions.VIEW_TRANSFORMATION_HUB: await vscode.commands.executeCommand(GumbyCommands.FOCUS_TRANSFORMATION_HUB, CancelActionPositions.Chat) break @@ -403,7 +415,7 @@ export class GumbyController { await this.continueJobWithSelectedDependency(message) break case ButtonActions.CANCEL_DEPENDENCY_FORM: - this.messenger.sendUserPrompt('Cancel', message.tabID) + this.messenger.sendMessage('Cancel', message.tabID, 'prompt') await this.continueTransformationWithoutHIL(message) break case ButtonActions.OPEN_FILE: @@ -448,11 +460,27 @@ export class GumbyController { }) this.messenger.sendOneOrMultipleDiffsMessage(oneOrMultipleDiffsSelection, message.tabID) - // perform local build - await this.validateBuildWithPromptOnError(message) + this.promptJavaHome('source', message.tabID) + // TO-DO: delete line above and uncomment line below when releasing CSB + // await this.messenger.sendCustomDependencyVersionMessage(message.tabID) }) } + private promptJavaHome(type: 'source' | 'target', tabID: any) { + let jdkVersion = undefined + if (type === 'source') { + this.sessionStorage.getSession().conversationState = ConversationState.PROMPT_SOURCE_JAVA_HOME + jdkVersion = transformByQState.getSourceJDKVersion() + } else if (type === 'target') { + this.sessionStorage.getSession().conversationState = ConversationState.PROMPT_TARGET_JAVA_HOME + jdkVersion = transformByQState.getTargetJDKVersion() + } + const message = MessengerUtils.createJavaHomePrompt(jdkVersion) + this.messenger.sendMessage(message, tabID, 'ai-prompt') + this.messenger.sendChatInputEnabled(tabID, true) + this.messenger.sendUpdatePlaceholder(tabID, CodeWhispererConstants.enterJavaHomePlaceholder) + } + private async handleUserLanguageUpgradeProjectChoice(message: any) { await telemetry.codeTransform_submitSelection.run(async () => { const pathToProject: string = message.formSelectedValues['GumbyTransformLanguageUpgradeProjectForm'] @@ -521,32 +549,25 @@ export class GumbyController { }) } - private async prepareLanguageUpgradeProject(message: { pathToJavaHome: string; tabID: string }) { - if (message.pathToJavaHome) { - transformByQState.setJavaHome(message.pathToJavaHome) - getLogger().info( - `CodeTransformation: using JAVA_HOME = ${transformByQState.getJavaHome()} since source JDK does not match Maven JDK` - ) - } - - // Pre-build project locally + private async prepareLanguageUpgradeProject(tabID: string) { + // build project locally try { this.sessionStorage.getSession().conversationState = ConversationState.COMPILING - this.messenger.sendCompilationInProgress(message.tabID) + this.messenger.sendCompilationInProgress(tabID) await compileProject() } catch (err: any) { - this.messenger.sendUnrecoverableErrorResponse('could-not-compile-project', message.tabID) + this.messenger.sendUnrecoverableErrorResponse('could-not-compile-project', tabID) // reset state to allow "Start a new transformation" button to work this.sessionStorage.getSession().conversationState = ConversationState.IDLE throw err } - this.messenger.sendCompilationFinished(message.tabID) + this.messenger.sendCompilationFinished(tabID) // since compilation can potentially take a long time, double check auth const authState = AuthUtil.instance.getAuthState() if (authState !== 'connected') { - void this.messenger.sendAuthNeededExceptionMessage(authState, message.tabID) + void this.messenger.sendAuthNeededExceptionMessage(authState, tabID) this.sessionStorage.getSession().isAuthenticating = true return } @@ -554,33 +575,33 @@ export class GumbyController { // give user a non-blocking warning if build file appears to contain absolute paths await parseBuildFile() - this.messenger.sendAsyncEventProgress( - message.tabID, - true, - undefined, - GumbyNamedMessages.JOB_SUBMISSION_STATUS_MESSAGE - ) - this.messenger.sendJobSubmittedMessage(message.tabID) + this.messenger.sendAsyncEventProgress(tabID, true, undefined, GumbyNamedMessages.JOB_SUBMISSION_STATUS_MESSAGE) + this.messenger.sendJobSubmittedMessage(tabID) this.sessionStorage.getSession().conversationState = ConversationState.JOB_SUBMITTED await startTransformByQ() } - // only for Language Upgrades - private async validateBuildWithPromptOnError(message: any | undefined = undefined): Promise { - try { - // Check Java Home is set (not yet prebuilding) - await validateCanCompileProject() - } catch (err: any) { - if (err instanceof JavaHomeNotSetError) { - this.sessionStorage.getSession().conversationState = ConversationState.PROMPT_JAVA_HOME - this.messenger.sendStaticTextResponse('java-home-not-set', message.tabID) - this.messenger.sendChatInputEnabled(message.tabID, true) - this.messenger.sendUpdatePlaceholder(message.tabID, 'Enter the path to your Java installation.') - } + private async processCustomDependencyVersionFile(message: any) { + const fileUri = await vscode.window.showOpenDialog({ + canSelectMany: false, + openLabel: 'Select', + filters: { + 'YAML file': ['yaml'], // restrict user to only pick a .yaml file + }, + }) + if (!fileUri || fileUri.length === 0) { return } + const fileContents = await fs.readFileText(fileUri[0].fsPath) + const isValidFile = await validateCustomVersionsFile(fileContents) - await this.prepareLanguageUpgradeProject(message) + if (!isValidFile) { + this.messenger.sendUnrecoverableErrorResponse('invalid-custom-versions-file', message.tabID) + return + } + this.messenger.sendMessage('Received custom dependency version YAML file.', message.tabID, 'ai-prompt') + transformByQState.setCustomDependencyVersionFilePath(fileUri[0].fsPath) + this.promptJavaHome('source', message.tabID) } private async processMetadataFile(message: any) { @@ -657,19 +678,34 @@ export class GumbyController { } private async processHumanChatMessage(data: { message: string; tabID: string }) { - this.messenger.sendUserPrompt(data.message, data.tabID) + this.messenger.sendMessage(data.message, data.tabID, 'prompt') this.messenger.sendChatInputEnabled(data.tabID, false) - this.messenger.sendUpdatePlaceholder(data.tabID, 'Open a new tab to chat with Q') + this.messenger.sendUpdatePlaceholder(data.tabID, CodeWhispererConstants.openNewTabPlaceholder) const session = this.sessionStorage.getSession() switch (session.conversationState) { - case ConversationState.PROMPT_JAVA_HOME: { + case ConversationState.PROMPT_SOURCE_JAVA_HOME: { const pathToJavaHome = extractPath(data.message) if (pathToJavaHome) { - await this.prepareLanguageUpgradeProject({ - pathToJavaHome, - tabID: data.tabID, - }) + transformByQState.setSourceJavaHome(pathToJavaHome) + // if source and target JDK versions are the same, just re-use the source JAVA_HOME and start the build + if (transformByQState.getTargetJDKVersion() === transformByQState.getSourceJDKVersion()) { + transformByQState.setTargetJavaHome(pathToJavaHome) + await this.prepareLanguageUpgradeProject(data.tabID) + } else { + this.promptJavaHome('target', data.tabID) + } + } else { + this.messenger.sendUnrecoverableErrorResponse('invalid-java-home', data.tabID) + } + break + } + + case ConversationState.PROMPT_TARGET_JAVA_HOME: { + const pathToJavaHome = extractPath(data.message) + if (pathToJavaHome) { + transformByQState.setTargetJavaHome(pathToJavaHome) + await this.prepareLanguageUpgradeProject(data.tabID) // build right after we get target JDK path } else { this.messenger.sendUnrecoverableErrorResponse('invalid-java-home', data.tabID) } @@ -747,7 +783,7 @@ export class GumbyController { }) } - this.messenger.sendStaticTextResponse('end-HIL-early', message.tabID) + this.messenger.sendMessage(CodeWhispererConstants.continueWithoutHilMessage, message.tabID, 'ai-prompt') } } diff --git a/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts b/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts index 2281afff705..b12be675406 100644 --- a/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts +++ b/packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts @@ -8,6 +8,7 @@ * As much as possible, all strings used in the experience should originate here. */ +import vscode from 'vscode' import { AuthFollowUpType, AuthMessageDataMap } from '../../../../amazonq/auth/model' import { JDKVersion, TransformationCandidateProject, transformByQState } from '../../../../codewhisperer/models/model' import { AuthState } from '../../../../auth/auth2' @@ -49,6 +50,7 @@ export type UnrecoverableErrorType = | 'job-start-failed' | 'unsupported-source-db' | 'unsupported-target-db' + | 'invalid-custom-versions-file' | 'error-parsing-sct-file' | 'invalid-zip-no-sct-file' | 'invalid-from-to-jdk' @@ -412,38 +414,12 @@ export class Messenger { this.dispatcher.sendChatMessage(jobSubmittedMessage) } - public sendUserPrompt(prompt: string, tabID: string) { + public sendMessage(prompt: string, tabID: string, type: 'prompt' | 'ai-prompt') { this.dispatcher.sendChatMessage( new ChatMessage( { message: prompt, - messageType: 'prompt', - }, - tabID - ) - ) - } - - public sendStaticTextResponse(messageType: StaticTextResponseType, tabID: string) { - let message = '...' - - switch (messageType) { - case 'java-home-not-set': - message = MessengerUtils.createJavaHomePrompt() - break - case 'end-HIL-early': - message = 'I will continue transforming your code without upgrading this dependency.' - break - case 'choose-transformation-objective': - message = CodeWhispererConstants.chooseTransformationObjective - break - } - - this.dispatcher.sendChatMessage( - new ChatMessage( - { - message, - messageType: 'ai-prompt', + messageType: type, }, tabID ) @@ -482,6 +458,9 @@ export class Messenger { case 'unsupported-target-db': message = CodeWhispererConstants.invalidMetadataFileUnsupportedTargetDB break + case 'invalid-custom-versions-file': + message = CodeWhispererConstants.invalidCustomVersionsFileMessage + break case 'error-parsing-sct-file': message = CodeWhispererConstants.invalidMetadataFileErrorParsing break @@ -664,7 +643,7 @@ ${codeSnippet} this.sendInProgressMessage(tabID, message) } - public sendInProgressMessage(tabID: string, message: string, messageName?: string) { + public sendInProgressMessage(tabID: string, message: string) { this.dispatcher.sendAsyncEventProgress( new AsyncEventProgressMessage(tabID, { inProgress: true, message: undefined }) ) @@ -768,7 +747,56 @@ ${codeSnippet} ) } - public async sendSelectSQLMetadataFileMessage(tabID: string) { + public async sendCustomDependencyVersionMessage(tabID: string) { + const message = CodeWhispererConstants.chooseYamlMessage + const buttons: ChatItemButton[] = [] + + buttons.push({ + keepCardAfterClick: true, + text: 'Select .yaml file', + id: ButtonActions.SELECT_CUSTOM_DEPENDENCY_VERSION_FILE, + disabled: false, + }) + + buttons.push({ + keepCardAfterClick: false, + text: 'Continue without this', + id: ButtonActions.CONTINUE_TRANSFORMATION_FORM, + disabled: false, + }) + + this.dispatcher.sendChatMessage( + new ChatMessage( + { + message, + messageType: 'ai-prompt', + buttons, + }, + tabID + ) + ) + const sampleYAML = `name: "custom-dependency-management" +description: "Custom dependency version management for Java migration from JDK 8/11/17 to JDK 17/21" + +dependencyManagement: + dependencies: + - identifier: "com.example:library1" + targetVersion: "2.1.0" + versionProperty: "library1.version" # Optional + originType: "FIRST_PARTY" # or "THIRD_PARTY" # Optional + - identifier: "com.example:library2" + targetVersion: "3.0.0" + originType: "THIRD_PARTY" + plugins: + - identifier: "com.example.plugin" + targetVersion: "1.2.0" + versionProperty: "plugin.version" # Optional` + + const doc = await vscode.workspace.openTextDocument({ content: sampleYAML, language: 'yaml' }) + await vscode.window.showTextDocument(doc) + } + + public sendSelectSQLMetadataFileMessage(tabID: string) { const message = CodeWhispererConstants.selectSQLMetadataFileHelpMessage const buttons: ChatItemButton[] = [] diff --git a/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts b/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts index a7275ac98a3..ad1aade7c7e 100644 --- a/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts +++ b/packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts @@ -5,7 +5,7 @@ */ import * as os from 'os' -import { transformByQState, JDKVersion } from '../../../../codewhisperer/models/model' +import { JDKVersion } from '../../../../codewhisperer/models/model' import * as CodeWhispererConstants from '../../../../codewhisperer/models/constants' import DependencyVersions from '../../../models/dependencies' @@ -20,6 +20,8 @@ export enum ButtonActions { CONFIRM_SKIP_TESTS_FORM = 'gumbyTransformSkipTestsFormConfirm', CONFIRM_SELECTIVE_TRANSFORMATION_FORM = 'gumbyTransformOneOrMultipleDiffsFormConfirm', SELECT_SQL_CONVERSION_METADATA_FILE = 'gumbySQLConversionMetadataTransformFormConfirm', + SELECT_CUSTOM_DEPENDENCY_VERSION_FILE = 'gumbyCustomDependencyVersionTransformFormConfirm', + CONTINUE_TRANSFORMATION_FORM = 'gumbyTransformFormContinue', CONFIRM_DEPENDENCY_FORM = 'gumbyTransformDependencyFormConfirm', CANCEL_DEPENDENCY_FORM = 'gumbyTransformDependencyFormCancel', CONFIRM_JAVA_HOME_FORM = 'gumbyJavaHomeFormConfirm', @@ -35,14 +37,11 @@ export enum GumbyCommands { } export default class MessengerUtils { - static createJavaHomePrompt = (): string => { - let javaHomePrompt = `${ - CodeWhispererConstants.enterJavaHomeChatMessage - } ${transformByQState.getSourceJDKVersion()}. \n` + static createJavaHomePrompt = (jdkVersion: JDKVersion | undefined): string => { + let javaHomePrompt = `${CodeWhispererConstants.enterJavaHomeChatMessage} ${jdkVersion}. \n` if (os.platform() === 'win32') { javaHomePrompt += CodeWhispererConstants.windowsJavaHomeHelpChatMessage } else if (os.platform() === 'darwin') { - const jdkVersion = transformByQState.getSourceJDKVersion() if (jdkVersion === JDKVersion.JDK8) { javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(1.8)}` } else if (jdkVersion === JDKVersion.JDK11) { diff --git a/packages/core/src/amazonqGumby/chat/session/session.ts b/packages/core/src/amazonqGumby/chat/session/session.ts index b0ed125c7d8..f1a69eb60ff 100644 --- a/packages/core/src/amazonqGumby/chat/session/session.ts +++ b/packages/core/src/amazonqGumby/chat/session/session.ts @@ -7,7 +7,8 @@ import { TransformationCandidateProject } from '../../../codewhisperer/models/mo export enum ConversationState { IDLE, - PROMPT_JAVA_HOME, + PROMPT_SOURCE_JAVA_HOME, + PROMPT_TARGET_JAVA_HOME, COMPILING, JOB_SUBMITTED, WAITING_FOR_HIL_INPUT, diff --git a/packages/core/src/auth/sso/clients.ts b/packages/core/src/auth/sso/clients.ts index 01d0e031d04..e050bdc793e 100644 --- a/packages/core/src/auth/sso/clients.ts +++ b/packages/core/src/auth/sso/clients.ts @@ -258,7 +258,7 @@ function addLoggingMiddleware(client: SSOOIDCClient) { args.input as unknown as Record, 3, ['clientSecret', 'accessToken', 'refreshToken'], - '[omitted]' + { replacement: '[omitted]' } ) getLogger().debug('API request (%s %s): %O', hostname, path, input) } @@ -288,7 +288,7 @@ function addLoggingMiddleware(client: SSOOIDCClient) { result.output as unknown as Record, 3, ['clientSecret', 'accessToken', 'refreshToken'], - '[omitted]' + { replacement: '[omitted]' } ) getLogger().debug('API response (%s %s): %O', hostname, path, output) } diff --git a/packages/core/src/codewhisperer/activation.ts b/packages/core/src/codewhisperer/activation.ts index 6dab3d5cb90..6eef0fffcd3 100644 --- a/packages/core/src/codewhisperer/activation.ts +++ b/packages/core/src/codewhisperer/activation.ts @@ -95,6 +95,7 @@ import { SecurityIssueTreeViewProvider } from './service/securityIssueTreeViewPr import { setContext } from '../shared/vscode/setContext' import { syncSecurityIssueWebview } from './views/securityIssue/securityIssueWebview' import { detectCommentAboveLine } from '../shared/utilities/commentUtils' +import { notifySelectDeveloperProfile } from './region/utils' let localize: nls.LocalizeFunc @@ -104,8 +105,6 @@ export async function activate(context: ExtContext): Promise { // Import old CodeWhisperer settings into Amazon Q await CodeWhispererSettings.instance.importSettings() - const auth = AuthUtil.instance - // TODO: is this indirection useful? registerDeclaredCommands( context.extensionContext.subscriptions, @@ -156,7 +155,7 @@ export async function activate(context: ExtContext): Promise { if (configurationChangeEvent.affectsConfiguration('amazonQ.showCodeWithReferences')) { ReferenceLogViewProvider.instance.update() - if (auth.isIdcConnection()) { + if (AuthUtil.instance.isIdcConnection()) { await vscode.window .showInformationMessage( CodeWhispererConstants.ssoConfigAlertMessage, @@ -171,7 +170,7 @@ export async function activate(context: ExtContext): Promise { } if (configurationChangeEvent.affectsConfiguration('amazonQ.shareContentWithAWS')) { - if (auth.isIdcConnection()) { + if (AuthUtil.instance.isIdcConnection()) { await vscode.window .showInformationMessage( CodeWhispererConstants.ssoConfigAlertMessageShareData, @@ -341,7 +340,7 @@ export async function activate(context: ExtContext): Promise { SecurityIssueCodeActionProvider.instance ), vscode.commands.registerCommand('aws.amazonq.openEditorAtRange', openEditorAtRange), - auth.regionProfileManager.onDidChangeRegionProfile(() => { + AuthUtil.instance.regionProfileManager.onDidChangeRegionProfile(() => { // Validate user still has access to the selected customization. const selectedCustomization = getSelectedCustomization() // No need to validate base customization which has empty arn. @@ -366,23 +365,27 @@ export async function activate(context: ExtContext): Promise { // run the auth startup code with context for telemetry await telemetry.function_call.run( async () => { - if (auth.isConnectionExpired()) { - auth.showReauthenticatePrompt().catch((e) => { + if (AuthUtil.instance.isConnectionExpired()) { + AuthUtil.instance.showReauthenticatePrompt().catch((e) => { const defaulMsg = localize('AWS.generic.message.error', 'Failed to reauth:') void logAndShowError(localize, e, 'showReauthenticatePrompt', defaulMsg) }) - if (auth.isIdcConnection()) { - await auth.notifySessionConfiguration() + if (AuthUtil.instance.isIdcConnection()) { + await AuthUtil.instance.notifySessionConfiguration() } } + + if (AuthUtil.instance.regionProfileManager.requireProfileSelection()) { + await notifySelectDeveloperProfile() + } }, { emit: false, functionId: { name: 'activateCwCore' } } ) - if (auth.isIdcConnection() && auth.isConnected()) { + if (AuthUtil.instance.isIdcConnection() && AuthUtil.instance.isConnected()) { await notifyNewCustomizations() } - if (auth.isBuilderIdConnection()) { + if (AuthUtil.instance.isBuilderIdConnection()) { await CodeScansState.instance.setScansEnabled(false) } @@ -397,8 +400,8 @@ export async function activate(context: ExtContext): Promise { return ( (isScansEnabled ?? CodeScansState.instance.isScansEnabled()) && !CodeScansState.instance.isMonthlyQuotaExceeded() && - auth.isConnected() && - !auth.isBuilderIdConnection() && + AuthUtil.instance.isConnected() && + !AuthUtil.instance.isBuilderIdConnection() && editor && editor.document.uri.scheme === 'file' && securityScanLanguageContext.isLanguageSupported(editor.document.languageId) diff --git a/packages/core/src/codewhisperer/commands/startTransformByQ.ts b/packages/core/src/codewhisperer/commands/startTransformByQ.ts index 37b85be3fad..eb31839686d 100644 --- a/packages/core/src/codewhisperer/commands/startTransformByQ.ts +++ b/packages/core/src/codewhisperer/commands/startTransformByQ.ts @@ -56,7 +56,6 @@ import { submitFeedback } from '../../feedback/vue/submitFeedback' import { placeholder } from '../../shared/vscode/commands2' import { AlternateDependencyVersionsNotFoundError, - JavaHomeNotSetError, JobStartError, ModuleUploadError, PollJobError, @@ -69,8 +68,7 @@ import { getJsonValuesFromManifestFile, highlightPomIssueInProject, parseVersionsListFromPomFile, - setMaven, - writeLogs, + writeAndShowBuildLogs, } from '../service/transformByQ/transformFileHandler' import { sleep } from '../../shared/utilities/timeoutUtils' import DependencyVersions from '../../amazonqGumby/models/dependencies' @@ -111,37 +109,6 @@ export async function processSQLConversionTransformFormInput(pathToProject: stri transformByQState.setTargetJDKVersion(JDKVersion.JDK17) } -async function validateJavaHome(): Promise { - const versionData = await getVersionData() - let javaVersionUsedByMaven = versionData[1] - if (javaVersionUsedByMaven !== undefined) { - javaVersionUsedByMaven = javaVersionUsedByMaven.slice(0, 3) - if (javaVersionUsedByMaven === '1.8') { - javaVersionUsedByMaven = JDKVersion.JDK8 - } else if (javaVersionUsedByMaven === '11.') { - javaVersionUsedByMaven = JDKVersion.JDK11 - } else if (javaVersionUsedByMaven === '17.') { - javaVersionUsedByMaven = JDKVersion.JDK17 - } else if (javaVersionUsedByMaven === '21.') { - javaVersionUsedByMaven = JDKVersion.JDK21 - } - } - if (javaVersionUsedByMaven !== transformByQState.getSourceJDKVersion()) { - // means either javaVersionUsedByMaven is undefined or it does not match the project JDK - return false - } - - return true -} - -export async function validateCanCompileProject() { - await setMaven() - const javaHomeFound = await validateJavaHome() - if (!javaHomeFound) { - throw new JavaHomeNotSetError() - } -} - export async function compileProject() { try { const dependenciesFolder: FolderInfo = getDependenciesFolderInfo() @@ -150,9 +117,7 @@ export async function compileProject() { await prepareProjectDependencies(dependenciesFolder, modulePath) } catch (err) { // open build-logs.txt file to show user error logs - const logFilePath = await writeLogs() - const doc = await vscode.workspace.openTextDocument(logFilePath) - await vscode.window.showTextDocument(doc) + await writeAndShowBuildLogs(true) throw err } } @@ -300,7 +265,7 @@ export async function initiateHumanInTheLoopPrompt(jobId: string) { const profile = AuthUtil.instance.regionProfileManager.activeRegionProfile const humanInTheLoopManager = HumanInTheLoopManager.instance // 1) We need to call GetTransformationPlan to get artifactId - const transformationSteps = await getTransformationSteps(jobId, false, profile) + const transformationSteps = await getTransformationSteps(jobId, profile) const { transformationStep, progressUpdate } = findDownloadArtifactStep(transformationSteps) if (!transformationStep || !progressUpdate) { @@ -566,7 +531,7 @@ export async function pollTransformationStatusUntilPlanReady(jobId: string, prof try { const tempToolkitFolder = await makeTemporaryToolkitFolder() const tempBuildLogsDir = path.join(tempToolkitFolder, 'q-transformation-build-logs') - await downloadAndExtractResultArchive(jobId, undefined, tempBuildLogsDir, 'Logs') + await downloadAndExtractResultArchive(jobId, tempBuildLogsDir) pathToLog = path.join(tempBuildLogsDir, 'buildCommandOutput.log') transformByQState.setPreBuildLogFilePath(pathToLog) } catch (e) { @@ -788,7 +753,8 @@ export async function postTransformationJob() { } if (transformByQState.getPayloadFilePath() !== '') { - fs.rmSync(transformByQState.getPayloadFilePath(), { recursive: true, force: true }) // delete ZIP if it exists + // delete original upload ZIP at very end of transformation + fs.rmSync(transformByQState.getPayloadFilePath(), { recursive: true, force: true }) } // attempt download for user diff --git a/packages/core/src/codewhisperer/commands/types.ts b/packages/core/src/codewhisperer/commands/types.ts index e211ae76f9a..cec28829507 100644 --- a/packages/core/src/codewhisperer/commands/types.ts +++ b/packages/core/src/codewhisperer/commands/types.ts @@ -18,6 +18,8 @@ export const firstStartUpSource = ExtStartUpSources.firstStartUp export const cwEllipsesMenu = 'ellipsesMenu' /** Indicates a CodeWhisperer command was executed from the command palette */ export const commandPalette = 'commandPalette' +/** Indicates a CodeWhisperer command was executed as a result of a toast message interaction */ +export const toastMessage = 'toastMessage' /** * Indicates what caused the CodeWhisperer command to be executed, since a command can be executed from different "sources" @@ -35,3 +37,4 @@ export type CodeWhispererSource = | typeof firstStartUpSource | typeof cwEllipsesMenu | typeof commandPalette + | typeof toastMessage diff --git a/packages/core/src/codewhisperer/models/constants.ts b/packages/core/src/codewhisperer/models/constants.ts index 9d17b166cb8..2fb3dd10069 100644 --- a/packages/core/src/codewhisperer/models/constants.ts +++ b/packages/core/src/codewhisperer/models/constants.ts @@ -599,6 +599,9 @@ export const invalidMetadataFileUnsupportedSourceDB = export const invalidMetadataFileUnsupportedTargetDB = 'I can only convert SQL for migrations to Aurora PostgreSQL or Amazon RDS for PostgreSQL target databases. The provided .sct file indicates another target database for this migration.' +export const invalidCustomVersionsFileMessage = + 'Your .YAML file is not formatted correctly. Make sure that the .YAML file you upload follows the format of the sample file provided.' + export const invalidMetadataFileErrorParsing = "It looks like the .sct file you provided isn't valid. Make sure that you've uploaded the .zip file you retrieved from your schema conversion in AWS DMS." @@ -655,6 +658,17 @@ export const jobCancelledChatMessage = export const jobCancelledNotification = 'You cancelled the transformation.' +export const continueWithoutHilMessage = 'I will continue transforming your code without upgrading this dependency.' + +export const continueWithoutYamlMessage = 'Ok, I will continue without this information.' + +export const chooseYamlMessage = + 'You can optionally upload a YAML file to specify which dependency versions to upgrade to.' + +export const enterJavaHomePlaceholder = 'Enter the path to your Java installation' + +export const openNewTabPlaceholder = 'Open a new tab to chat with Q' + export const diffMessage = (multipleDiffs: boolean) => { return multipleDiffs ? 'You can review the diffs to see my proposed changes and accept or reject them. You will be able to accept changes from one diff at a time. If you reject changes in one diff, you will not be able to view or accept changes in the other diffs.' @@ -756,7 +770,7 @@ export const cleanInstallErrorChatMessage = `Sorry, I couldn\'t run the Maven cl export const cleanInstallErrorNotification = `Amazon Q could not run the Maven clean install command to build your project. For more information, see the [Amazon Q documentation](${codeTransformTroubleshootMvnFailure}).` -export const enterJavaHomeChatMessage = 'Enter the path to JDK ' +export const enterJavaHomeChatMessage = 'Enter the path to JDK' export const projectPromptChatMessage = '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.' diff --git a/packages/core/src/codewhisperer/models/model.ts b/packages/core/src/codewhisperer/models/model.ts index 99689748320..28072249371 100644 --- a/packages/core/src/codewhisperer/models/model.ts +++ b/packages/core/src/codewhisperer/models/model.ts @@ -678,12 +678,14 @@ export enum BuildSystem { Unknown = 'Unknown', } +// TO-DO: include the custom YAML file path here somewhere? export class ZipManifest { sourcesRoot: string = 'sources/' dependenciesRoot: string = 'dependencies/' buildLogs: string = 'build-logs.txt' version: string = '1.0' hilCapabilities: string[] = ['HIL_1pDependency_VersionUpgrade'] + // TO-DO: add 'CLIENT_SIDE_BUILD' here when releasing transformCapabilities: string[] = ['EXPLAINABILITY_V1'] customBuildCommand: string = 'clean test' requestedConversions?: { @@ -771,6 +773,8 @@ export class TransformByQState { private metadataPathSQL: string = '' + private customVersionPath: string = '' + private linesOfCodeSubmitted: number | undefined = undefined private planFilePath: string = '' @@ -790,11 +794,13 @@ export class TransformByQState { private jobFailureErrorChatMessage: string | undefined = undefined - private errorLog: string = '' + private buildLog: string = '' private mavenName: string = '' - private javaHome: string | undefined = undefined + private sourceJavaHome: string | undefined = undefined + + private targetJavaHome: string | undefined = undefined private chatControllers: ChatControllerEventEmitters | undefined = undefined private chatMessenger: Messenger | undefined = undefined @@ -897,6 +903,10 @@ export class TransformByQState { return this.metadataPathSQL } + public getCustomDependencyVersionFilePath() { + return this.customVersionPath + } + public getStatus() { return this.transformByQState } @@ -937,16 +947,20 @@ export class TransformByQState { return this.jobFailureErrorChatMessage } - public getErrorLog() { - return this.errorLog + public getBuildLog() { + return this.buildLog } public getMavenName() { return this.mavenName } - public getJavaHome() { - return this.javaHome + public getSourceJavaHome() { + return this.sourceJavaHome + } + + public getTargetJavaHome() { + return this.targetJavaHome } public getChatControllers() { @@ -969,8 +983,12 @@ export class TransformByQState { return this.intervalId } - public appendToErrorLog(message: string) { - this.errorLog += `${message}\n\n` + public appendToBuildLog(message: string) { + this.buildLog += `${message}\n\n` + } + + public clearBuildLog() { + this.buildLog = '' } public setToNotStarted() { @@ -1061,6 +1079,10 @@ export class TransformByQState { this.metadataPathSQL = path } + public setCustomDependencyVersionFilePath(path: string) { + this.customVersionPath = path + } + public setPlanFilePath(filePath: string) { this.planFilePath = filePath } @@ -1101,8 +1123,12 @@ export class TransformByQState { this.mavenName = mavenName } - public setJavaHome(javaHome: string) { - this.javaHome = javaHome + public setSourceJavaHome(javaHome: string) { + this.sourceJavaHome = javaHome + } + + public setTargetJavaHome(javaHome: string) { + this.targetJavaHome = javaHome } public setChatControllers(controllers: ChatControllerEventEmitters) { @@ -1144,6 +1170,7 @@ export class TransformByQState { this.jobFailureMetadata = '' this.payloadFilePath = '' this.metadataPathSQL = '' + this.customVersionPath = '' this.sourceJDKVersion = undefined this.targetJDKVersion = undefined this.sourceDB = undefined @@ -1151,7 +1178,7 @@ export class TransformByQState { this.sourceServerName = '' this.schemaOptions.clear() this.schema = '' - this.errorLog = '' + this.buildLog = '' this.customBuildCommand = '' this.intervalId = undefined this.produceMultipleDiffs = false diff --git a/packages/core/src/codewhisperer/region/regionProfileManager.ts b/packages/core/src/codewhisperer/region/regionProfileManager.ts index 3ad74f22d51..d4aa3b5abd8 100644 --- a/packages/core/src/codewhisperer/region/regionProfileManager.ts +++ b/packages/core/src/codewhisperer/region/regionProfileManager.ts @@ -22,6 +22,8 @@ import { isAwsError, ToolkitError } from '../../shared/errors' import { telemetry } from '../../shared/telemetry/telemetry' import { localize } from '../../shared/utilities/vsCodeUtils' import { IAuthProvider } from '../util/authUtil' +import { Commands } from '../../shared/vscode/commands2' +import { CachedResource } from '../../shared/utilities/resourceCache' // TODO: is there a better way to manage all endpoint strings in one place? export const defaultServiceConfig: CodeWhispererConfig = { @@ -51,7 +53,26 @@ export class RegionProfileManager { // Store the last API results (for UI propuse) so we don't need to call service again if doesn't require "latest" result private _profiles: RegionProfile[] = [] - constructor(private readonly authProvider: IAuthProvider) {} + private readonly cache = new (class extends CachedResource { + constructor(private readonly profileProvider: () => Promise) { + super( + 'aws.amazonq.regionProfiles.cache', + 60000, + { + resource: { + locked: false, + timestamp: 0, + result: undefined, + }, + }, + { timeout: 15000, interval: 1500, truthy: true } + ) + } + + override resourceProvider(): Promise { + return this.profileProvider() + } + })(this.listRegionProfile.bind(this)) get activeRegionProfile() { if (this.authProvider.isBuilderIdConnection()) { @@ -94,13 +115,21 @@ export class RegionProfileManager { return this._profiles } - async listRegionProfiles(): Promise { + constructor(private readonly authProvider: IAuthProvider) {} + + async getProfiles(): Promise { + return this.cache.getResource() + } + + async listRegionProfile(): Promise { this._profiles = [] if (!this.authProvider.isConnected() || !this.authProvider.isSsoSession()) { return [] } const availableProfiles: RegionProfile[] = [] + const failedRegions: string[] = [] + for (const [region, endpoint] of endpoints.entries()) { const client = await this.createQClient(region, endpoint) const requester = async (request: CodeWhispererUserClient.ListAvailableProfilesRequest) => @@ -125,13 +154,17 @@ export class RegionProfileManager { }) availableProfiles.push(...mappedPfs) + RegionProfileManager.logger.debug(`Found ${mappedPfs.length} profiles in region ${region}`) } catch (e) { const logMsg = isAwsError(e) ? `requestId=${e.requestId}; message=${e.message}` : (e as Error).message - RegionProfileManager.logger.error(`failed to listRegionProfiles: ${logMsg}`) - throw e + RegionProfileManager.logger.error(`Failed to list profiles for region ${region}: ${logMsg}`) + failedRegions.push(region) } + } - RegionProfileManager.logger.info(`available amazonq profiles: ${availableProfiles.length}`) + // Only throw error if all regions fail + if (failedRegions.length === endpoints.size) { + throw new Error(`Failed to list profiles for all regions: ${failedRegions.join(', ')}`) } this._profiles = availableProfiles @@ -204,6 +237,9 @@ export class RegionProfileManager { // persist to state await this.persistSelectRegionProfile() + + // Force status bar to reflect this change in state + await Commands.tryExecute('aws.amazonq.refreshStatusBar') } restoreProfileSelection = once(async () => { @@ -219,7 +255,7 @@ export class RegionProfileManager { return } // cross-validation - this.listRegionProfiles() + this.getProfiles() .then(async (profiles) => { const r = profiles.find((it) => it.arn === previousSelected.arn) if (!r) { @@ -279,7 +315,7 @@ export class RegionProfileManager { const selected = this.activeRegionProfile let profiles: RegionProfile[] = [] try { - profiles = await this.listRegionProfiles() + profiles = await this.getProfiles() } catch (e) { return [ { @@ -333,6 +369,10 @@ export class RegionProfileManager { return this.authProvider.isIdcConnection() && this.activeRegionProfile === undefined } + async clearCache() { + await this.cache.clearCache() + } + async createQClient(region: string, endpoint: string): Promise { const token = await this.authProvider.getToken() const serviceOption: ServiceOptions = { diff --git a/packages/core/src/codewhisperer/region/utils.ts b/packages/core/src/codewhisperer/region/utils.ts new file mode 100644 index 00000000000..dd988f74a30 --- /dev/null +++ b/packages/core/src/codewhisperer/region/utils.ts @@ -0,0 +1,49 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import * as nls from 'vscode-nls' +const localize = nls.loadMessageBundle() +import { AmazonQPromptSettings } from '../../shared/settings' +import { telemetry } from '../../shared/telemetry/telemetry' +import vscode from 'vscode' +import { selectRegionProfileCommand } from '../commands/basicCommands' +import { placeholder } from '../../shared/vscode/commands2' +import { toastMessage } from '../commands/types' + +/** + * Creates a toast message telling the user they need to select a Developer Profile + */ +export async function notifySelectDeveloperProfile() { + const suppressId = 'amazonQSelectDeveloperProfile' + const settings = AmazonQPromptSettings.instance + const shouldShow = settings.isPromptEnabled(suppressId) + if (!shouldShow) { + return + } + + const message = localize( + 'aws.amazonq.profile.mustSelectMessage', + 'You must select a Q Developer Profile for Amazon Q features to work.' + ) + const selectProfile = 'Select Profile' + const dontShowAgain = 'Dont Show Again' + + await telemetry.toolkit_showNotification.run(async () => { + telemetry.record({ id: 'mustSelectDeveloperProfileMessage' }) + void vscode.window.showWarningMessage(message, selectProfile, dontShowAgain).then(async (resp) => { + await telemetry.toolkit_invokeAction.run(async () => { + if (resp === selectProfile) { + // Show Profile + telemetry.record({ action: 'select' }) + void selectRegionProfileCommand.execute(placeholder, toastMessage) + } else if (resp === dontShowAgain) { + telemetry.record({ action: 'dontShowAgain' }) + await settings.disablePrompt(suppressId) + } else { + telemetry.record({ action: 'ignore' }) + } + }) + }) + }) +} diff --git a/packages/core/src/codewhisperer/service/inlineCompletionService.ts b/packages/core/src/codewhisperer/service/inlineCompletionService.ts index c552d674bae..4c3b93425be 100644 --- a/packages/core/src/codewhisperer/service/inlineCompletionService.ts +++ b/packages/core/src/codewhisperer/service/inlineCompletionService.ts @@ -167,6 +167,9 @@ export class InlineCompletionService { /** Updates the status bar to represent the latest CW state */ refreshStatusBar() { if (AuthUtil.instance.isConnected()) { + if (AuthUtil.instance.regionProfileManager.requireProfileSelection()) { + return this.setState('needsProfile') + } return this.setState('ok') } else if (AuthUtil.instance.isConnectionExpired()) { return this.setState('expired') @@ -193,6 +196,10 @@ export class InlineCompletionService { await this.statusBar.setState('notConnected') break } + case 'needsProfile': { + await this.statusBar.setState('needsProfile') + break + } } } } @@ -203,6 +210,7 @@ const states = { ok: 'ok', expired: 'expired', notConnected: 'notConnected', + needsProfile: 'needsProfile', } as const export class CodeWhispererStatusBar { @@ -245,6 +253,7 @@ export class CodeWhispererStatusBar { statusBar.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground') break } + case 'needsProfile': case 'notConnected': statusBar.text = codicon` ${getIcon('vscode-chrome-close')} ${title}` statusBar.backgroundColor = new vscode.ThemeColor('statusBarItem.errorBackground') diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts b/packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts index 97dacc1a664..476123f2d6d 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts @@ -41,10 +41,10 @@ import { calculateTotalLatency } from '../../../amazonqGumby/telemetry/codeTrans import { MetadataResult } from '../../../shared/telemetry/telemetryClient' import request from '../../../shared/request' import { JobStoppedError, ZipExceedsSizeLimitError } from '../../../amazonqGumby/errors' -import { writeLogs } from './transformFileHandler' +import { createLocalBuildUploadZip, extractOriginalProjectSources, writeAndShowBuildLogs } from './transformFileHandler' import { createCodeWhispererChatStreamingClient } from '../../../shared/clients/codewhispererChatClient' import { downloadExportResultArchive } from '../../../shared/utilities/download' -import { ExportIntent, TransformationDownloadArtifactType } from '@amzn/codewhisperer-streaming' +import { ExportContext, ExportIntent, TransformationDownloadArtifactType } from '@amzn/codewhisperer-streaming' import fs from '../../../shared/fs/fs' import { ChatSessionManager } from '../../../amazonqGumby/chat/storages/chatSession' import { encodeHTML } from '../../../shared/utilities/textUtilities' @@ -52,6 +52,9 @@ import { convertToTimeString } from '../../../shared/datetime' import { getAuthType } from '../../../auth/utils' import { UserWrittenCodeTracker } from '../../tracker/userWrittenCodeTracker' import { AuthUtil } from '../../util/authUtil' +import { DiffModel } from './transformationResultsViewProvider' +import { spawnSync } from 'child_process' // eslint-disable-line no-restricted-imports +import { isClientSideBuildEnabled } from '../../../dev/config' export function getSha256(buffer: Buffer) { const hasher = crypto.createHash('sha256') @@ -167,10 +170,10 @@ export async function resumeTransformationJob(jobId: string, userActionStatus: T transformationJobId: jobId, userActionStatus, // can be "COMPLETED" or "REJECTED" }) - if (response) { - // always store request ID, but it will only show up in a notification if an error occurs - return response.transformationStatus - } + getLogger().info( + `CodeTransformation: resumeTransformation API status code = ${response.$response.httpResponse.statusCode}` + ) + return response.transformationStatus } catch (e: any) { const errorMessage = `Resuming the job failed due to: ${(e as Error).message}` getLogger().error(`CodeTransformation: ResumeTransformation error = %O`, e) @@ -219,6 +222,8 @@ export async function uploadPayload( throw new Error(errorMessage) } + getLogger().info('CodeTransformation: created upload URL successfully') + try { await uploadArtifactToS3(payloadFileName, response, sha256, buffer) } catch (e: any) { @@ -251,7 +256,8 @@ export async function uploadPayload( */ const mavenExcludedExtensions = ['.repositories', '.sha1'] -const sourceExcludedExtensions = ['.DS_Store'] +// exclude .DS_Store (not relevant) and Maven executables (can cause permissions issues when building if user has not ran 'chmod') +const sourceExcludedExtensions = ['.DS_Store', 'mvnw', 'mvnw.cmd'] /** * Determines if the specified file path corresponds to a Maven metadata file @@ -360,7 +366,6 @@ export async function zipCode( sctFileName: metadataZip.getEntries().filter((entry) => entry.name.endsWith('.sct'))[0].name, }, } - // TO-DO: later consider making this add to path.join(zipManifest.dependenciesRoot, 'qct-sct-metadata', entry.entryName) so that it's more organized for (const entry of metadataZip.getEntries()) { zip.addFile(path.join(zipManifest.dependenciesRoot, entry.name), entry.getData()) } @@ -391,12 +396,21 @@ export async function zipCode( dependenciesCopied = true } + // TO-DO: decide where exactly to put the YAML file / what to name it + if (transformByQState.getCustomDependencyVersionFilePath() && zipManifest instanceof ZipManifest) { + zip.addLocalFile( + transformByQState.getCustomDependencyVersionFilePath(), + 'custom-upgrades', + 'dependency-versions.yaml' + ) + } + zip.addFile('manifest.json', Buffer.from(JSON.stringify(zipManifest)), 'utf-8') throwIfCancelled() // add text file with logs from mvn clean install and mvn copy-dependencies - logFilePath = await writeLogs() + logFilePath = await writeAndShowBuildLogs() // We don't add build-logs.txt file to the manifest if we are // uploading HIL artifacts if (!humanInTheLoopFlag) { @@ -633,16 +647,8 @@ export async function getTransformationPlan(jobId: string, profile: RegionProfil } } -export async function getTransformationSteps( - jobId: string, - handleThrottleFlag: boolean, - profile: RegionProfile | undefined -) { +export async function getTransformationSteps(jobId: string, profile: RegionProfile | undefined) { try { - // prevent ThrottlingException - if (handleThrottleFlag) { - await sleep(2000) - } const response = await codeWhisperer.codeWhispererClient.codeModernizerGetCodeTransformationPlan({ transformationJobId: jobId, profileArn: profile?.arn, @@ -683,6 +689,9 @@ export async function pollTransformationJob(jobId: string, validStates: string[] const errorMessage = response.transformationJob.reason if (errorMessage !== undefined) { + getLogger().error( + `CodeTransformation: GetTransformation returned transformation error reason = ${errorMessage}` + ) transformByQState.setJobFailureErrorChatMessage( `${CodeWhispererConstants.failedToCompleteJobGenericChatMessage} ${errorMessage}` ) @@ -693,6 +702,17 @@ export async function pollTransformationJob(jobId: string, validStates: string[] if (validStates.includes(status)) { break } + + // TO-DO: remove isClientSideBuildEnabled when releasing CSB + if ( + isClientSideBuildEnabled && + status === 'TRANSFORMING' && + transformByQState.getTransformationType() === TransformationType.LANGUAGE_UPGRADE + ) { + // client-side build is N/A for SQL conversions + await attemptLocalBuild() + } + /** * If we find a paused state, we need the user to take action. We will set the global * state for polling status and early exit. @@ -718,7 +738,111 @@ export async function pollTransformationJob(jobId: string, validStates: string[] return status } -export function getArtifactsFromProgressUpdate(progressUpdate?: TransformationProgressUpdate) { +async function attemptLocalBuild() { + const jobId = transformByQState.getJobId() + let artifactId + try { + artifactId = await getClientInstructionArtifactId(jobId) + getLogger().info(`CodeTransformation: found artifactId = ${artifactId}`) + } catch (e: any) { + // don't throw error so that we can try to get progress updates again in next polling cycle + getLogger().error(`CodeTransformation: failed to get client instruction artifact ID = %O`, e) + } + if (artifactId) { + const clientInstructionsPath = await downloadClientInstructions(jobId, artifactId) + getLogger().info( + `CodeTransformation: downloaded clientInstructions with diff.patch at: ${clientInstructionsPath}` + ) + await processClientInstructions(jobId, clientInstructionsPath, artifactId) + } +} + +async function getClientInstructionArtifactId(jobId: string) { + const steps = await getTransformationSteps(jobId, AuthUtil.instance.regionProfileManager.activeRegionProfile) + const progressUpdate = findDownloadArtifactProgressUpdate(steps) + + let artifactId = undefined + if (progressUpdate?.downloadArtifacts) { + artifactId = progressUpdate.downloadArtifacts[0].downloadArtifactId + } + return artifactId +} + +async function downloadClientInstructions(jobId: string, artifactId: string) { + const exportDestination = `downloadClientInstructions_${jobId}_${artifactId}` + const exportZipPath = path.join(os.tmpdir(), exportDestination) + + const exportContext: ExportContext = { + transformationExportContext: { + downloadArtifactType: TransformationDownloadArtifactType.CLIENT_INSTRUCTIONS, + downloadArtifactId: artifactId, + }, + } + + await downloadAndExtractResultArchive(jobId, exportZipPath, exportContext) + return path.join(exportZipPath, 'diff.patch') +} + +async function processClientInstructions(jobId: string, clientInstructionsPath: any, artifactId: string) { + const destinationPath = path.join(os.tmpdir(), `originalCopy_${jobId}_${artifactId}`) + await extractOriginalProjectSources(destinationPath) + getLogger().info(`CodeTransformation: copied project to ${destinationPath}`) + const diffModel = new DiffModel() + diffModel.parseDiff(clientInstructionsPath, path.join(destinationPath, 'sources'), undefined, 1, true) + // show user the diff.patch + const doc = await vscode.workspace.openTextDocument(clientInstructionsPath) + await vscode.window.showTextDocument(doc, { viewColumn: vscode.ViewColumn.One }) + await runClientSideBuild(transformByQState.getProjectCopyFilePath(), artifactId) +} + +export async function runClientSideBuild(projectCopyPath: string, clientInstructionArtifactId: string) { + const baseCommand = transformByQState.getMavenName() + const args = [] + if (transformByQState.getCustomBuildCommand() === CodeWhispererConstants.skipUnitTestsBuildCommand) { + args.push('test-compile') + } else { + args.push('test') + } + const environment = { ...process.env, JAVA_HOME: transformByQState.getTargetJavaHome() } + + const argString = args.join(' ') + const spawnResult = spawnSync(baseCommand, args, { + cwd: projectCopyPath, + shell: true, + encoding: 'utf-8', + env: environment, + }) + + const buildLogs = `Intermediate build result from running ${baseCommand} ${argString}:\n\n${spawnResult.stdout}` + transformByQState.clearBuildLog() + transformByQState.appendToBuildLog(buildLogs) + await writeAndShowBuildLogs() + + const uploadZipBaseDir = path.join( + os.tmpdir(), + `clientInstructionsResult_${transformByQState.getJobId()}_${clientInstructionArtifactId}` + ) + const uploadZipPath = await createLocalBuildUploadZip(uploadZipBaseDir, spawnResult.status, spawnResult.stdout) + + // upload build results + const uploadContext: UploadContext = { + transformationUploadContext: { + jobId: transformByQState.getJobId(), + uploadArtifactType: 'ClientBuildResult', + }, + } + getLogger().info(`CodeTransformation: uploading client build results at ${uploadZipPath} and resuming job now`) + try { + await uploadPayload(uploadZipPath, AuthUtil.instance.regionProfileManager.activeRegionProfile, uploadContext) + await resumeTransformationJob(transformByQState.getJobId(), 'COMPLETED') + } finally { + await fs.delete(projectCopyPath, { recursive: true }) + await fs.delete(uploadZipBaseDir, { recursive: true }) + getLogger().info(`CodeTransformation: Just deleted project copy and uploadZipBaseDir after client-side build`) + } +} + +export function getArtifactsFromProgressUpdate(progressUpdate: TransformationProgressUpdate) { const artifactType = progressUpdate?.downloadArtifacts?.[0]?.downloadArtifactType const artifactId = progressUpdate?.downloadArtifacts?.[0]?.downloadArtifactId return { @@ -727,6 +851,16 @@ export function getArtifactsFromProgressUpdate(progressUpdate?: TransformationPr } } +// used for client-side build +export function findDownloadArtifactProgressUpdate(transformationSteps: TransformationSteps) { + return transformationSteps + .flatMap((step) => step.progressUpdates ?? []) + .find( + (update) => update.status === 'AWAITING_CLIENT_ACTION' && update.downloadArtifacts?.[0]?.downloadArtifactId + ) +} + +// used for HIL export function findDownloadArtifactStep(transformationSteps: TransformationSteps) { for (let i = 0; i < transformationSteps.length; i++) { const progressUpdates = transformationSteps[i].progressUpdates @@ -750,21 +884,23 @@ export function findDownloadArtifactStep(transformationSteps: TransformationStep } } -export async function downloadResultArchive( - jobId: string, - downloadArtifactId: string | undefined, - pathToArchive: string, - downloadArtifactType: TransformationDownloadArtifactType -) { +export async function downloadResultArchive(jobId: string, pathToArchive: string, exportContext?: ExportContext) { const cwStreamingClient = await createCodeWhispererChatStreamingClient() try { + const args = exportContext + ? { + exportId: jobId, + exportIntent: ExportIntent.TRANSFORMATION, + exportContext: exportContext, + } + : { + exportId: jobId, + exportIntent: ExportIntent.TRANSFORMATION, + } await downloadExportResultArchive( cwStreamingClient, - { - exportId: jobId, - exportIntent: ExportIntent.TRANSFORMATION, - }, + args, pathToArchive, AuthUtil.instance.regionProfileManager.activeRegionProfile ) @@ -779,9 +915,8 @@ export async function downloadResultArchive( export async function downloadAndExtractResultArchive( jobId: string, - downloadArtifactId: string | undefined, pathToArchiveDir: string, - downloadArtifactType: TransformationDownloadArtifactType + exportContext?: ExportContext ) { const archivePathExists = await fs.existsDir(pathToArchiveDir) if (!archivePathExists) { @@ -793,9 +928,10 @@ export async function downloadAndExtractResultArchive( let downloadErrorMessage = undefined try { // Download and deserialize the zip - await downloadResultArchive(jobId, downloadArtifactId, pathToArchive, downloadArtifactType) + await downloadResultArchive(jobId, pathToArchive, exportContext) const zip = new AdmZip(pathToArchive) zip.extractAllTo(pathToArchiveDir) + getLogger().info(`CodeTransformation: downloaded result archive to: ${pathToArchiveDir}`) } catch (e) { downloadErrorMessage = (e as Error).message getLogger().error(`CodeTransformation: ExportResultArchive error = %O`, e) @@ -804,12 +940,7 @@ export async function downloadAndExtractResultArchive( } export async function downloadHilResultArchive(jobId: string, downloadArtifactId: string, pathToArchiveDir: string) { - await downloadAndExtractResultArchive( - jobId, - downloadArtifactId, - pathToArchiveDir, - TransformationDownloadArtifactType.CLIENT_INSTRUCTIONS - ) + await downloadAndExtractResultArchive(jobId, pathToArchiveDir) // manifest.json // pomFolder/pom.xml or manifest has pomFolderName path diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformFileHandler.ts b/packages/core/src/codewhisperer/service/transformByQ/transformFileHandler.ts index c2a0617c15f..fd74ca7b147 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformFileHandler.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformFileHandler.ts @@ -9,14 +9,14 @@ import * as os from 'os' import xml2js = require('xml2js') import * as CodeWhispererConstants from '../../models/constants' import { existsSync, readFileSync, writeFileSync } from 'fs' // eslint-disable-line no-restricted-imports -import { BuildSystem, DB, FolderInfo, transformByQState } from '../../models/model' +import { BuildSystem, DB, FolderInfo, TransformationType, transformByQState } from '../../models/model' import { IManifestFile } from '../../../amazonqFeatureDev/models' import fs from '../../../shared/fs/fs' import globals from '../../../shared/extensionGlobals' import { ChatSessionManager } from '../../../amazonqGumby/chat/storages/chatSession' import { AbsolutePathDetectedError } from '../../../amazonqGumby/errors' import { getLogger } from '../../../shared/logger/logger' -import { isWin } from '../../../shared/vscode/env' +import AdmZip from 'adm-zip' export function getDependenciesFolderInfo(): FolderInfo { const dependencyFolderName = `${CodeWhispererConstants.dependencyFolderName}${globals.clock.Date.now()}` @@ -27,12 +27,55 @@ export function getDependenciesFolderInfo(): FolderInfo { } } -export async function writeLogs() { +export async function writeAndShowBuildLogs(isLocalInstall: boolean = false) { const logFilePath = path.join(os.tmpdir(), 'build-logs.txt') - writeFileSync(logFilePath, transformByQState.getErrorLog()) + writeFileSync(logFilePath, transformByQState.getBuildLog()) + const doc = await vscode.workspace.openTextDocument(logFilePath) + if ( + !transformByQState.getBuildLog().includes('clean install succeeded') && + transformByQState.getTransformationType() !== TransformationType.SQL_CONVERSION + ) { + // only show the log if the build failed; show it in second column for intermediate builds only + const options = isLocalInstall ? undefined : { viewColumn: vscode.ViewColumn.Two } + await vscode.window.showTextDocument(doc, options) + } return logFilePath } +export async function createLocalBuildUploadZip(baseDir: string, exitCode: number | null, stdout: string) { + const manifestFilePath = path.join(baseDir, 'manifest.json') + const buildResultsManifest = { + capability: 'CLIENT_SIDE_BUILD', + exitCode: exitCode, + commandLogFileName: 'build-output.log', + } + const formattedManifest = JSON.stringify(buildResultsManifest) + await fs.writeFile(manifestFilePath, formattedManifest) + + const buildLogsFilePath = path.join(baseDir, 'build-output.log') + await fs.writeFile(buildLogsFilePath, stdout) + + const zip = new AdmZip() + zip.addLocalFile(buildLogsFilePath) + zip.addLocalFile(manifestFilePath) + + const zipPath = `${baseDir}.zip` + zip.writeZip(zipPath) + getLogger().info(`CodeTransformation: created local build upload zip at ${zipPath}`) + return zipPath +} + +// extract the 'sources' directory of the upload ZIP so that we can apply the diff.patch to a copy of the source code +export async function extractOriginalProjectSources(destinationPath: string) { + const zip = new AdmZip(transformByQState.getPayloadFilePath()) + const zipEntries = zip.getEntries() + for (const zipEntry of zipEntries) { + if (zipEntry.entryName.startsWith('sources')) { + zip.extractEntryTo(zipEntry, destinationPath, true, true) + } + } +} + export async function checkBuildSystem(projectPath: string) { const mavenBuildFilePath = path.join(projectPath, 'pom.xml') if (existsSync(mavenBuildFilePath)) { @@ -76,6 +119,17 @@ export async function parseBuildFile() { return undefined } +export async function validateCustomVersionsFile(fileContents: string) { + const requiredKeys = ['dependencyManagement:', 'identifier:', 'targetVersion:'] + for (const key of requiredKeys) { + if (!fileContents.includes(key)) { + getLogger().info(`CodeTransformation: .YAML file is missing required key: ${key}`) + return false + } + } + return true +} + export async function validateSQLMetadataFile(fileContents: string, message: any) { try { const sctData = await xml2js.parseStringPromise(fileContents) @@ -119,20 +173,10 @@ export async function validateSQLMetadataFile(fileContents: string, message: any return true } -export async function setMaven() { - let mavenWrapperExecutableName = isWin() ? 'mvnw.cmd' : 'mvnw' - const mavenWrapperExecutablePath = path.join(transformByQState.getProjectPath(), mavenWrapperExecutableName) - if (existsSync(mavenWrapperExecutablePath)) { - if (mavenWrapperExecutableName === 'mvnw') { - mavenWrapperExecutableName = './mvnw' // add the './' for non-Windows - } else if (mavenWrapperExecutableName === 'mvnw.cmd') { - mavenWrapperExecutableName = '.\\mvnw.cmd' // add the '.\' for Windows - } - transformByQState.setMavenName(mavenWrapperExecutableName) - } else { - transformByQState.setMavenName('mvn') - } - getLogger().info(`CodeTransformation: using Maven ${transformByQState.getMavenName()}`) +export function setMaven() { + // for now, just use regular Maven since the Maven executables can + // cause permissions issues when building if user has not ran 'chmod' + transformByQState.setMavenName('mvn') } export async function openBuildLogFile() { diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformMavenHandler.ts b/packages/core/src/codewhisperer/service/transformByQ/transformMavenHandler.ts index dacd78f6dc3..ebcbfec8970 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformMavenHandler.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformMavenHandler.ts @@ -11,31 +11,29 @@ import { spawnSync } from 'child_process' // eslint-disable-line no-restricted-i import { CodeTransformBuildCommand, telemetry } from '../../../shared/telemetry/telemetry' import { CodeTransformTelemetryState } from '../../../amazonqGumby/telemetry/codeTransformTelemetryState' import { ToolkitError } from '../../../shared/errors' -import { setMaven, writeLogs } from './transformFileHandler' +import { setMaven } from './transformFileHandler' import { throwIfCancelled } from './transformApiHandler' import { sleep } from '../../../shared/utilities/timeoutUtils' -// run 'install' with either 'mvnw.cmd', './mvnw', or 'mvn' (if wrapper exists, we use that, otherwise we use regular 'mvn') function installProjectDependencies(dependenciesFolder: FolderInfo, modulePath: string) { telemetry.codeTransform_localBuildProject.run(() => { telemetry.record({ codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId() }) - // baseCommand will be one of: '.\mvnw.cmd', './mvnw', 'mvn' + // will always be 'mvn' const baseCommand = transformByQState.getMavenName() - transformByQState.appendToErrorLog(`Running command ${baseCommand} clean install`) - - // Note: IntelliJ runs 'clean' separately from 'install'. Evaluate benefits (if any) of this. const args = [`-Dmaven.repo.local=${dependenciesFolder.path}`, 'clean', 'install', '-q'] + transformByQState.appendToBuildLog(`Running ${baseCommand} ${args.join(' ')}`) + if (transformByQState.getCustomBuildCommand() === CodeWhispererConstants.skipUnitTestsBuildCommand) { args.push('-DskipTests') } let environment = process.env - if (transformByQState.getJavaHome() !== undefined) { - environment = { ...process.env, JAVA_HOME: transformByQState.getJavaHome() } + if (transformByQState.getSourceJavaHome()) { + environment = { ...process.env, JAVA_HOME: transformByQState.getSourceJavaHome() } } const argString = args.join(' ') @@ -47,37 +45,27 @@ function installProjectDependencies(dependenciesFolder: FolderInfo, modulePath: maxBuffer: CodeWhispererConstants.maxBufferSize, }) - let mavenBuildCommand = transformByQState.getMavenName() - // slashes not allowed in telemetry - if (mavenBuildCommand === './mvnw') { - mavenBuildCommand = 'mvnw' - } else if (mavenBuildCommand === '.\\mvnw.cmd') { - mavenBuildCommand = 'mvnw.cmd' - } - + const mavenBuildCommand = transformByQState.getMavenName() telemetry.record({ codeTransformBuildCommand: mavenBuildCommand as CodeTransformBuildCommand }) if (spawnResult.status !== 0) { let errorLog = '' errorLog += spawnResult.error ? JSON.stringify(spawnResult.error) : '' errorLog += `${spawnResult.stderr}\n${spawnResult.stdout}` - transformByQState.appendToErrorLog(`${baseCommand} ${argString} failed: \n ${errorLog}`) + transformByQState.appendToBuildLog(`${baseCommand} ${argString} failed: \n ${errorLog}`) getLogger().error( - `CodeTransformation: Error in running Maven ${argString} command ${baseCommand} = ${errorLog}` + `CodeTransformation: Error in running Maven command ${baseCommand} ${argString} = ${errorLog}` ) throw new ToolkitError(`Maven ${argString} error`, { code: 'MavenExecutionError' }) } else { - transformByQState.appendToErrorLog(`${baseCommand} ${argString} succeeded`) + transformByQState.appendToBuildLog(`mvn clean install succeeded`) } }) } function copyProjectDependencies(dependenciesFolder: FolderInfo, modulePath: string) { - // baseCommand will be one of: '.\mvnw.cmd', './mvnw', 'mvn' const baseCommand = transformByQState.getMavenName() - transformByQState.appendToErrorLog(`Running command ${baseCommand} copy-dependencies`) - const args = [ 'dependency:copy-dependencies', `-DoutputDirectory=${dependenciesFolder.path}`, @@ -88,8 +76,8 @@ function copyProjectDependencies(dependenciesFolder: FolderInfo, modulePath: str ] let environment = process.env - if (transformByQState.getJavaHome() !== undefined) { - environment = { ...process.env, JAVA_HOME: transformByQState.getJavaHome() } + if (transformByQState.getSourceJavaHome()) { + environment = { ...process.env, JAVA_HOME: transformByQState.getSourceJavaHome() } } const spawnResult = spawnSync(baseCommand, args, { @@ -103,18 +91,15 @@ function copyProjectDependencies(dependenciesFolder: FolderInfo, modulePath: str let errorLog = '' errorLog += spawnResult.error ? JSON.stringify(spawnResult.error) : '' errorLog += `${spawnResult.stderr}\n${spawnResult.stdout}` - transformByQState.appendToErrorLog(`${baseCommand} copy-dependencies failed: \n ${errorLog}`) getLogger().info( - `CodeTransformation: Maven copy-dependencies command ${baseCommand} failed, but still continuing with transformation: ${errorLog}` + `CodeTransformation: Maven command ${baseCommand} ${args} failed, but still continuing with transformation: ${errorLog}` ) throw new Error('Maven copy-deps error') - } else { - transformByQState.appendToErrorLog(`${baseCommand} copy-dependencies succeeded`) } } export async function prepareProjectDependencies(dependenciesFolder: FolderInfo, rootPomPath: string) { - await setMaven() + setMaven() getLogger().info('CodeTransformation: running Maven copy-dependencies') // pause to give chat time to update await sleep(100) @@ -132,10 +117,6 @@ export async function prepareProjectDependencies(dependenciesFolder: FolderInfo, installProjectDependencies(dependenciesFolder, rootPomPath) } catch (err) { void vscode.window.showErrorMessage(CodeWhispererConstants.cleanInstallErrorNotification) - // open build-logs.txt file to show user error logs - const logFilePath = await writeLogs() - const doc = await vscode.workspace.openTextDocument(logFilePath) - await vscode.window.showTextDocument(doc) throw err } @@ -144,7 +125,7 @@ export async function prepareProjectDependencies(dependenciesFolder: FolderInfo, } export async function getVersionData() { - const baseCommand = transformByQState.getMavenName() // will be one of: 'mvnw.cmd', './mvnw', 'mvn' + const baseCommand = transformByQState.getMavenName() const projectPath = transformByQState.getProjectPath() const args = ['-v'] const spawnResult = spawnSync(baseCommand, args, { cwd: projectPath, shell: true, encoding: 'utf-8' }) @@ -174,12 +155,9 @@ export async function getVersionData() { return [localMavenVersion, localJavaVersion] } -// run maven 'versions:dependency-updates-aggregate-report' with either 'mvnw.cmd', './mvnw', or 'mvn' (if wrapper exists, we use that, otherwise we use regular 'mvn') export function runMavenDependencyUpdateCommands(dependenciesFolder: FolderInfo) { - // baseCommand will be one of: '.\mvnw.cmd', './mvnw', 'mvn' - const baseCommand = transformByQState.getMavenName() // will be one of: 'mvnw.cmd', './mvnw', 'mvn' + const baseCommand = transformByQState.getMavenName() - // Note: IntelliJ runs 'clean' separately from 'install'. Evaluate benefits (if any) of this. const args = [ 'versions:dependency-updates-aggregate-report', `-DoutputDirectory=${dependenciesFolder.path}`, @@ -188,9 +166,9 @@ export function runMavenDependencyUpdateCommands(dependenciesFolder: FolderInfo) ] let environment = process.env - // if JAVA_HOME not found or not matching project JDK, get user input for it and set here - if (transformByQState.getJavaHome() !== undefined) { - environment = { ...process.env, JAVA_HOME: transformByQState.getJavaHome() } + + if (transformByQState.getSourceJavaHome()) { + environment = { ...process.env, JAVA_HOME: transformByQState.getSourceJavaHome() } } const spawnResult = spawnSync(baseCommand, args, { diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformationHubViewProvider.ts b/packages/core/src/codewhisperer/service/transformByQ/transformationHubViewProvider.ts index 2d0585085a9..052ef53b56c 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformationHubViewProvider.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformationHubViewProvider.ts @@ -193,6 +193,8 @@ export class TransformationHubViewProvider implements vscode.WebviewViewProvider return '

' case 'COMPLETED': return '

' + case 'AWAITING_CLIENT_ACTION': + return '

' case 'FAILED': default: return '

𐔧

' @@ -326,9 +328,19 @@ export class TransformationHubViewProvider implements vscode.WebviewViewProvider jobPlanProgress['generatePlan'] === StepProgress.Succeeded && transformByQState.isRunning() ) { - const profile = AuthUtil.instance.regionProfileManager.activeRegionProfile - planSteps = await getTransformationSteps(transformByQState.getJobId(), false, profile) - transformByQState.setPlanSteps(planSteps) + try { + planSteps = await getTransformationSteps( + transformByQState.getJobId(), + AuthUtil.instance.regionProfileManager.activeRegionProfile + ) + transformByQState.setPlanSteps(planSteps) + } catch (e: any) { + // no-op; re-use current plan steps and try again in next polling cycle + getLogger().error( + `CodeTransformation: failed to get plan steps to show updates in transformation hub, continuing transformation; error = %O`, + e + ) + } } let progressHtml // for each step that has succeeded, increment activeStepId by 1 diff --git a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts index d1c6f368259..411571f0693 100644 --- a/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts +++ b/packages/core/src/codewhisperer/service/transformByQ/transformationResultsViewProvider.ts @@ -168,7 +168,8 @@ export class DiffModel { pathToDiff: string, pathToWorkspace: string, diffDescription: PatchInfo | undefined, - totalDiffPatches: number + totalDiffPatches: number, + isIntermediateBuild: boolean = false ): PatchFileNode { this.patchFileNodes = [] const diffContents = fs.readFileSync(pathToDiff, 'utf8') @@ -180,8 +181,9 @@ export class DiffModel { const changedFiles = parsePatch(diffContents) getLogger().info('CodeTransformation: parsed patch file successfully') - // path to the directory containing copy of the changed files in the transformed project - const pathToTmpSrcDir = this.copyProject(pathToWorkspace, changedFiles) + // if doing intermediate client-side build, pathToWorkspace is the path to the unzipped project's 'sources' directory (re-using upload ZIP) + // otherwise, we are at the very end of the transformation and need to copy the changed files in the project to show the diff(s) + const pathToTmpSrcDir = isIntermediateBuild ? pathToWorkspace : this.copyProject(pathToWorkspace, changedFiles) transformByQState.setProjectCopyFilePath(pathToTmpSrcDir) applyPatches(changedFiles, { diff --git a/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts b/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts index 9a4c667d7e5..1b887e587d5 100644 --- a/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts +++ b/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts @@ -21,7 +21,7 @@ import { selectRegionProfileCommand, } from '../commands/basicCommands' import { CodeWhispererCommandDeclarations } from '../commands/gettingStartedPageCommands' -import { CodeScansState, codeScanState } from '../models/model' +import { CodeScansState, codeScanState, RegionProfile } from '../models/model' import { getNewCustomizationsAvailable, getSelectedCustomization } from '../util/customizationUtil' import { cwQuickPickSource } from '../commands/types' import { AuthUtil } from '../util/authUtil' @@ -139,12 +139,16 @@ export function createSelectCustomization(): DataQuickPickItem<'selectCustomizat } as DataQuickPickItem<'selectCustomization'> } -export function createSelectRegionProfileNode(): DataQuickPickItem<'selectRegionProfile'> { - const selectedRegionProfile = AuthUtil.instance.regionProfileManager.activeRegionProfile +export function createSelectRegionProfileNode( + profile: RegionProfile | undefined +): DataQuickPickItem<'selectRegionProfile'> { + const selectedRegionProfile = profile - const label = 'Change Profile' + const label = profile ? 'Change Profile' : '(Required) Select Profile' const icon = getIcon('vscode-arrow-swap') - const description = selectedRegionProfile ? `Current profile: ${selectedRegionProfile.name}` : '' + const description = selectedRegionProfile + ? `Current profile: ${selectedRegionProfile.name}` + : 'A profile MUST be selected for features to work' return { data: 'selectRegionProfile', @@ -153,6 +157,7 @@ export function createSelectRegionProfileNode(): DataQuickPickItem<'selectRegion await selectRegionProfileCommand.execute(placeholder, cwQuickPickSource) }, description: description, + picked: profile === undefined, } } diff --git a/packages/core/src/codewhisperer/ui/statusBarMenu.ts b/packages/core/src/codewhisperer/ui/statusBarMenu.ts index ecb307d56a8..d8c05270073 100644 --- a/packages/core/src/codewhisperer/ui/statusBarMenu.ts +++ b/packages/core/src/codewhisperer/ui/statusBarMenu.ts @@ -85,7 +85,14 @@ function getAmazonQCodeWhispererNodes() { } export function getQuickPickItems(): DataQuickPickItem[] { + const isUsingEnterpriseSso = AuthUtil.instance.isIdcConnection() + const regionProfile = AuthUtil.instance.regionProfileManager.activeRegionProfile + const children = [ + // If the user has signed in but not selected a region, we strongly indicate they need to select + // a profile, otherwise features will not work. + ...(isUsingEnterpriseSso && !regionProfile ? [createSelectRegionProfileNode(undefined)] : []), + ...getAmazonQCodeWhispererNodes(), // Generic Nodes @@ -97,7 +104,7 @@ export function getQuickPickItems(): DataQuickPickItem[] { // Add settings and signout createSeparator(), createSettingsNode(), - ...(AuthUtil.instance.isIdcConnection() ? [createSelectRegionProfileNode()] : []), + ...(AuthUtil.instance.isIdcConnection() && regionProfile ? [createSelectRegionProfileNode(regionProfile)] : []), ...(AuthUtil.instance.isConnected() && !hasVendedIamCredentials() && !hasVendedCredentialsFromMetadata() ? [createSignout()] : []), diff --git a/packages/core/src/codewhisperer/util/authUtil.ts b/packages/core/src/codewhisperer/util/authUtil.ts index 629493f148a..5ff9a1c9a55 100644 --- a/packages/core/src/codewhisperer/util/authUtil.ts +++ b/packages/core/src/codewhisperer/util/authUtil.ts @@ -26,7 +26,7 @@ import { setContext } from '../../shared/vscode/setContext' import { openUrl } from '../../shared/utilities/vsCodeUtils' import { telemetry } from '../../shared/telemetry/telemetry' import { AuthStateEvent, LanguageClientAuth, LoginTypes, SsoLogin } from '../../auth/auth2' -import { builderIdStartUrl } from '../../auth/sso/constants' +import { builderIdStartUrl, internalStartUrl } from '../../auth/sso/constants' import { VSCODE_EXTENSION_ID } from '../../shared/extensions' import { RegionProfileManager } from '../region/regionProfileManager' import { AuthFormId } from '../../login/webview/vue/types' @@ -146,6 +146,10 @@ export class AuthUtil implements IAuthProvider { return Boolean(this.connection?.startUrl && this.connection?.startUrl !== builderIdStartUrl) } + isInternalAmazonUser(): boolean { + return this.isConnected() && this.connection?.startUrl === internalStartUrl + } + onDidChangeConnectionState(handler: (e: AuthStateEvent) => any) { return this.session.onDidChangeConnectionState(handler) } @@ -247,6 +251,7 @@ export class AuthUtil implements IAuthProvider { if (state === 'expired' || state === 'notConnected') { if (this.isIdcConnection()) { await this.regionProfileManager.invalidateProfile(this.regionProfileManager.activeRegionProfile?.arn) + await this.regionProfileManager.clearCache() } this.lspAuth.deleteBearerToken() } diff --git a/packages/core/src/codewhisperer/util/codewhispererSettings.ts b/packages/core/src/codewhisperer/util/codewhispererSettings.ts index c63de7aa84f..80f5d1f2a0d 100644 --- a/packages/core/src/codewhisperer/util/codewhispererSettings.ts +++ b/packages/core/src/codewhisperer/util/codewhispererSettings.ts @@ -13,6 +13,9 @@ const description = { workspaceIndexWorkerThreads: Number, workspaceIndexUseGPU: Boolean, workspaceIndexMaxSize: Number, + workspaceIndexMaxFileSize: Number, + workspaceIndexCacheDirPath: String, + workspaceIndexIgnoreFilePatterns: ArrayConstructor(String), allowFeatureDevelopmentToRunCodeAndTests: Object, ignoredSecurityIssues: ArrayConstructor(String), } @@ -55,7 +58,20 @@ export class CodeWhispererSettings extends fromExtensionManifest('amazonQ', desc public getMaxIndexSize(): number { // minimal 1MB - return Math.max(this.get('workspaceIndexMaxSize', 250), 1) + return Math.max(this.get('workspaceIndexMaxSize', 2048), 1) + } + + public getMaxIndexFileSize(): number { + // minimal 1MB + return Math.max(this.get('workspaceIndexMaxFileSize', 10), 1) + } + + public getIndexCacheDirPath(): string { + return this.get('workspaceIndexCacheDirPath', '') + } + + public getIndexIgnoreFilePatterns(): string[] { + return this.get('workspaceIndexIgnoreFilePatterns', []) } public getAutoBuildSetting(): { [key: string]: boolean } { diff --git a/packages/core/src/codewhisperer/util/customizationUtil.ts b/packages/core/src/codewhisperer/util/customizationUtil.ts index e9ec68988fd..22c6f57130f 100644 --- a/packages/core/src/codewhisperer/util/customizationUtil.ts +++ b/packages/core/src/codewhisperer/util/customizationUtil.ts @@ -133,6 +133,9 @@ export const setSelectedCustomization = async (customization: Customization, isO } vsCodeState.isFreeTierLimitReached = false await Commands.tryExecute('aws.amazonq.refreshStatusBar') + + // hack: triggers amazon q to send the customizations back to flare + await Commands.tryExecute('aws.amazonq.updateCustomizations') } export const getPersistedCustomizations = (): Customization[] => { diff --git a/packages/core/src/codewhispererChat/app.ts b/packages/core/src/codewhispererChat/app.ts index 63147002339..3916e571956 100644 --- a/packages/core/src/codewhispererChat/app.ts +++ b/packages/core/src/codewhispererChat/app.ts @@ -236,5 +236,5 @@ export function init(appContext: AmazonQAppInitContext) { appContext.registerWebViewToAppMessagePublisher(new MessagePublisher(cwChatUIInputEventEmitter), 'cwc') - registerCommands(cwChatControllerMessagePublishers) + registerCommands() } diff --git a/packages/core/src/codewhispererChat/commands/registerCommands.ts b/packages/core/src/codewhispererChat/commands/registerCommands.ts index 39d8383c867..8ec1f7ac759 100644 --- a/packages/core/src/codewhispererChat/commands/registerCommands.ts +++ b/packages/core/src/codewhispererChat/commands/registerCommands.ts @@ -6,7 +6,6 @@ import { commandPalette } from '../../codewhisperer/commands/types' import { CodeScanIssue } from '../../codewhisperer/models/model' import { Commands, VsCodeCommandArg, placeholder } from '../../shared/vscode/commands2' -import { ChatControllerMessagePublishers } from '../controllers/chat/controller' /** * Opens the Amazon Q panel, showing the correct View that should @@ -37,73 +36,11 @@ export const focusAmazonQPanelKeybinding = Commands.declare('_aws.amazonq.focusC await focusAmazonQPanel.execute(placeholder, 'keybinding') }) -const getCommandTriggerType = (data: any): EditorContextCommandTriggerType => { - // data is undefined when commands triggered from keybinding or command palette. Currently no - // way to differentiate keybinding and command palette, so both interactions are recorded as keybinding - return data === undefined ? 'keybinding' : 'contextMenu' -} - -export function registerCommands(controllerPublishers: ChatControllerMessagePublishers) { - Commands.register('aws.amazonq.explainCode', async (data) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.explainCode').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.explainCode', - triggerType: getCommandTriggerType(data), - }) - }) - }) - Commands.register('aws.amazonq.refactorCode', async (data) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.refactorCode').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.refactorCode', - triggerType: getCommandTriggerType(data), - }) - }) - }) - Commands.register('aws.amazonq.fixCode', async (data) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.fixCode').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.fixCode', - triggerType: getCommandTriggerType(data), - }) - }) - }) - Commands.register('aws.amazonq.optimizeCode', async (data) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.optimizeCode').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.optimizeCode', - triggerType: getCommandTriggerType(data), - }) - }) - }) - Commands.register('aws.amazonq.sendToPrompt', async (data) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.sendToPrompt').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.sendToPrompt', - triggerType: getCommandTriggerType(data), - }) - }) - }) - Commands.register('aws.amazonq.explainIssue', async (issue) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.explainIssue').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.explainIssue', - triggerType: 'click', - issue, - }) - }) - }) - Commands.register('aws.amazonq.generateUnitTests', async (data) => { - return focusAmazonQPanel.execute(placeholder, 'amazonq.generateUnitTests').then(() => { - controllerPublishers.processContextMenuCommand.publish({ - type: 'aws.amazonq.generateUnitTests', - triggerType: getCommandTriggerType(data), - }) - }) - }) - Commands.register('aws.amazonq.updateContextCommandItems', () => { - controllerPublishers.processContextCommandUpdateMessage.publish() - }) +export function registerCommands() { + /** + * make these no-ops, since theres still callers that need to be deprecated + */ + Commands.register('aws.amazonq.updateContextCommandItems', () => {}) } export type EditorContextBaseCommandType = diff --git a/packages/core/src/dev/config.ts b/packages/core/src/dev/config.ts index d5fa49b2426..b4df78f64b0 100644 --- a/packages/core/src/dev/config.ts +++ b/packages/core/src/dev/config.ts @@ -10,3 +10,6 @@ export const betaUrl = { amazonq: '', toolkit: '', } + +// TO-DO: remove when releasing CSB +export const isClientSideBuildEnabled = false diff --git a/packages/core/src/lambda/vue/configEditor/samInvokeComponent.vue b/packages/core/src/lambda/vue/configEditor/samInvokeComponent.vue index 6d64291cff6..e7d09c584c9 100644 --- a/packages/core/src/lambda/vue/configEditor/samInvokeComponent.vue +++ b/packages/core/src/lambda/vue/configEditor/samInvokeComponent.vue @@ -139,6 +139,10 @@ runtime in data: {{ launchConfig.lambda.runtime }} +
+ + +
@@ -195,6 +199,10 @@ For invoke the runtime defined in the template is used.

+
+ + +

@@ -229,6 +237,10 @@ runtime in data: {{ launchConfig.lambda.runtime }}
+
+ + +
diff --git a/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts b/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts index 6502accae41..375e22f4878 100644 --- a/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts +++ b/packages/core/src/lambda/vue/configEditor/samInvokeFrontend.ts @@ -48,6 +48,7 @@ interface SamInvokeVueData { showNameInput: boolean newTestEventName: string resourceData: ResourceData | undefined + useDebugger: boolean } function newLaunchConfig(existingConfig?: AwsSamDebuggerConfiguration): AwsSamDebuggerConfigurationLoose { @@ -112,6 +113,7 @@ function initData() { return { containerBuild: false, skipNewImageCheck: false, + useDebugger: true, launchConfig: newLaunchConfig(), payload: { value: '', errorMsg: '' }, apiPayload: { value: '', errorMsg: '' }, @@ -449,6 +451,7 @@ export default defineComponent({ }, } : undefined, + noDebug: !this.useDebugger, } }, clearForm() { diff --git a/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts b/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts index fd558e546d6..01a6c1279d7 100644 --- a/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts +++ b/packages/core/src/login/webview/vue/amazonq/backend_amazonq.ts @@ -211,7 +211,7 @@ export class AmazonQLoginWebview extends CommonAuthWebview { */ override async listRegionProfiles(): Promise { try { - return await AuthUtil.instance.regionProfileManager.listRegionProfiles() + return await AuthUtil.instance.regionProfileManager.getProfiles() } catch (e) { telemetry.amazonq_didSelectProfile.emit({ source: 'auth', diff --git a/packages/core/src/shared/extensionGlobals.ts b/packages/core/src/shared/extensionGlobals.ts index e0eca894d7e..6e495339de9 100644 --- a/packages/core/src/shared/extensionGlobals.ts +++ b/packages/core/src/shared/extensionGlobals.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ExtensionContext, OutputChannel } from 'vscode' +import { ExtensionContext, LogOutputChannel, OutputChannel } from 'vscode' import { LoginManager } from '../auth/deprecated/loginManager' import { AwsResourceManager } from '../dynamicResources/awsResourceManager' import { AWSClientBuilder } from './awsClientBuilder' @@ -191,7 +191,7 @@ export interface ToolkitGlobals { /** * Log messages. Use `outputChannel` for application messages. */ - logOutputChannel: OutputChannel + logOutputChannel: LogOutputChannel loginManager: LoginManager awsContextCommands: AwsContextCommands awsContext: AwsContext diff --git a/packages/core/src/shared/globalState.ts b/packages/core/src/shared/globalState.ts index 23a67667d88..036e7cfaf22 100644 --- a/packages/core/src/shared/globalState.ts +++ b/packages/core/src/shared/globalState.ts @@ -50,6 +50,7 @@ export type globalKey = | 'aws.toolkit.lsp.manifest' | 'aws.amazonq.customization.overrideV2' | 'aws.amazonq.regionProfiles' + | 'aws.amazonq.regionProfiles.cache' // Deprecated/legacy names. New keys should start with "aws.". | '#sessionCreationDates' // Legacy name from `ssoAccessTokenProvider.ts`. | 'CODECATALYST_RECONNECT' diff --git a/packages/core/src/shared/index.ts b/packages/core/src/shared/index.ts index e2d71396e5e..4cda5285f69 100644 --- a/packages/core/src/shared/index.ts +++ b/packages/core/src/shared/index.ts @@ -27,7 +27,7 @@ export { Prompter } from './ui/prompter' export { VirtualFileSystem } from './virtualFilesystem' export { VirtualMemoryFile } from './virtualMemoryFile' export { AmazonqCreateUpload, Metric } from './telemetry/telemetry' -export { getClientId, getOperatingSystem } from './telemetry/util' +export { getClientId, getOperatingSystem, getOptOutPreference } from './telemetry/util' export { extensionVersion } from './vscode/env' export { cast } from './utilities/typeConstructors' export * as workspaceUtils from './utilities/workspaceUtils' @@ -73,3 +73,4 @@ export * as processUtils from './utilities/processUtils' export * as BaseLspInstaller from './lsp/baseLspInstaller' export * as collectionUtil from './utilities/collectionUtils' export * from './datetime' +export * from './performance/marks' diff --git a/packages/core/src/shared/logger/logger.ts b/packages/core/src/shared/logger/logger.ts index 9b4bead6a37..85df7b4e1f8 100644 --- a/packages/core/src/shared/logger/logger.ts +++ b/packages/core/src/shared/logger/logger.ts @@ -18,6 +18,7 @@ export type LogTopic = | 'chat' | 'stepfunctions' | 'unknown' + | 'resourceCache' class ErrorLog { constructor( @@ -104,11 +105,6 @@ const logLevels = new Map([ export type LogLevel = 'error' | 'warn' | 'info' | 'verbose' | 'debug' export function fromVscodeLogLevel(logLevel: vscode.LogLevel): LogLevel { - if (!vscode.LogLevel) { - // vscode version <= 1.73 - return 'info' - } - switch (logLevel) { case vscode.LogLevel.Trace: case vscode.LogLevel.Debug: diff --git a/packages/core/src/shared/lsp/baseLspInstaller.ts b/packages/core/src/shared/lsp/baseLspInstaller.ts index ee71b25a4b5..27e19df6b3a 100644 --- a/packages/core/src/shared/lsp/baseLspInstaller.ts +++ b/packages/core/src/shared/lsp/baseLspInstaller.ts @@ -41,17 +41,22 @@ export abstract class BaseLspInstaller 0) { this.logger.debug(`cleaning old LSP versions: deleted ${deletedVersions.length} versions`) } @@ -71,6 +76,12 @@ export abstract class BaseLspInstaller protected abstract resourcePaths(assetDirectory?: string): T } diff --git a/packages/core/src/shared/lsp/lspResolver.ts b/packages/core/src/shared/lsp/lspResolver.ts index 90892148a9f..04527d67246 100644 --- a/packages/core/src/shared/lsp/lspResolver.ts +++ b/packages/core/src/shared/lsp/lspResolver.ts @@ -13,19 +13,30 @@ import { TargetContent, logger, LspResult, LspVersion, Manifest } from './types' import { createHash } from '../crypto' import { lspSetupStage, StageResolver, tryStageResolvers } from './utils/setupStage' import { HttpResourceFetcher } from '../resourcefetcher/httpResourceFetcher' -import { showMessageWithCancel } from '../../shared/utilities/messages' +import { showProgressWithTimeout } from '../../shared/utilities/messages' import { Timeout } from '../utilities/timeoutUtils' +import { oneMinute } from '../datetime' +import vscode from 'vscode' -// max timeout for downloading remote LSP assets progress, the lowest possible is 3000, bounded by httpResourceFetcher's waitUntil -const remoteDownloadTimeout = 5000 +// max timeout for downloading remote LSP assets. Some asserts are large (100+ MB) so this needs to be large for slow connections. +// Since the user can cancel this one we can let it run very long. +const remoteDownloadTimeout = oneMinute * 30 export class LanguageServerResolver { + private readonly downloadMessage: string + constructor( private readonly manifest: Manifest, private readonly lsName: string, private readonly versionRange: semver.Range, + /** + * Custom message to show user when downloading, if undefined it will use the default. + */ + downloadMessage?: string, private readonly _defaultDownloadFolder?: string - ) {} + ) { + this.downloadMessage = downloadMessage ?? `Updating '${this.lsName}' language server` + } /** * Downloads and sets up the Language Server, attempting different locations in order: @@ -104,7 +115,15 @@ export class LanguageServerResolver { */ private async showDownloadProgress() { const timeout = new Timeout(remoteDownloadTimeout) - await showMessageWithCancel(`Downloading '${this.lsName}' language server`, timeout) + void showProgressWithTimeout( + { + title: this.downloadMessage, + location: vscode.ProgressLocation.Notification, + cancellable: false, + }, + timeout, + 0 + ) return timeout } @@ -116,7 +135,7 @@ export class LanguageServerResolver { ): Promise { const timeout = await this.showDownloadProgress() try { - if (await this.downloadRemoteTargetContent(targetContents, latestVersion.serverVersion, timeout)) { + if (await this.downloadRemoteTargetContent(targetContents, latestVersion, timeout)) { return { location: 'remote', version: latestVersion.serverVersion, @@ -217,8 +236,8 @@ export class LanguageServerResolver { * true, if all of the contents were successfully downloaded and unzipped * false, if any of the contents failed to download or unzip */ - private async downloadRemoteTargetContent(contents: TargetContent[], version: string, timeout: Timeout) { - const downloadDirectory = this.getDownloadDirectory(version) + private async downloadRemoteTargetContent(contents: TargetContent[], lspVersion: LspVersion, timeout: Timeout) { + const downloadDirectory = this.getDownloadDirectory(lspVersion.serverVersion) if (!(await fs.existsDir(downloadDirectory))) { await fs.mkdir(downloadDirectory) @@ -254,6 +273,12 @@ export class LanguageServerResolver { const filesToDownload = await lspSetupStage('validate', async () => (await Promise.all(verifyTasks)).flat()) + // We were instructed by legal to show this message + const thirdPartyLicenses = lspVersion.thirdPartyLicenses + logger.info( + `Installing '${this.lsName}' Language Server v${lspVersion.serverVersion} to: ${downloadDirectory}${thirdPartyLicenses ? ` (Attribution notice can be found at ${thirdPartyLicenses})` : ''}` + ) + for (const file of filesToDownload) { await fs.writeFile(`${downloadDirectory}/${file.filename}`, file.data) } diff --git a/packages/core/src/shared/lsp/types.ts b/packages/core/src/shared/lsp/types.ts index 3cc96dbe681..1262d6e8fd1 100644 --- a/packages/core/src/shared/lsp/types.ts +++ b/packages/core/src/shared/lsp/types.ts @@ -72,6 +72,10 @@ export interface LspVersion { serverVersion: string isDelisted: boolean targets: Target[] + /** + * I'm not sure if this **always** exists (couldn't find it in the spec) + */ + thirdPartyLicenses?: string } export interface Manifest { diff --git a/packages/core/src/shared/lsp/utils/cleanup.ts b/packages/core/src/shared/lsp/utils/cleanup.ts index 83b58e2bb8f..3f8c27cd81d 100644 --- a/packages/core/src/shared/lsp/utils/cleanup.ts +++ b/packages/core/src/shared/lsp/utils/cleanup.ts @@ -23,7 +23,11 @@ function isDelisted(manifestVersions: LspVersion[], targetVersion: string): bool * @param downloadDirectory * @returns array of deleted versions. */ -export async function cleanLspDownloads(manifestVersions: LspVersion[], downloadDirectory: string): Promise { +export async function cleanLspDownloads( + latestInstalledVersion: string, + manifestVersions: LspVersion[], + downloadDirectory: string +): Promise { const downloadedVersions = await getDownloadedVersions(downloadDirectory) const [delistedVersions, remainingVersions] = partition(downloadedVersions, (v: string) => isDelisted(manifestVersions, v) @@ -40,6 +44,15 @@ export async function cleanLspDownloads(manifestVersions: LspVersion[], download } for (const v of sort(remainingVersions).slice(0, -2)) { + /** + * When switching between different manifests, the following edge case can occur: + * A newly downloaded version might chronologically be older than all previously downloaded versions, + * even though it's marked as the latest version in its own manifest. + * In such cases, we skip the cleanup process to preserve this version. Otherwise we will get an EPIPE error + */ + if (v === latestInstalledVersion) { + continue + } await fs.delete(path.join(downloadDirectory, v), { force: true, recursive: true }) deletedVersions.push(v) } diff --git a/packages/core/src/shared/lsp/utils/platform.ts b/packages/core/src/shared/lsp/utils/platform.ts index 5d96ef496f4..8b775433277 100644 --- a/packages/core/src/shared/lsp/utils/platform.ts +++ b/packages/core/src/shared/lsp/utils/platform.ts @@ -29,9 +29,12 @@ function getEncryptionInit(key: Buffer): string { /** * Checks that we can actually run the `node` executable and execute code with it. */ -export async function validateNodeExe(nodePath: string, lsp: string, args: string[], logger: Logger) { +export async function validateNodeExe(nodePath: string[], lsp: string, args: string[], logger: Logger) { + const bin = nodePath[0] // Check that we can start `node` by itself. - const proc = new ChildProcess(nodePath, ['-e', 'console.log("ok " + process.version)'], { logging: 'no' }) + const proc = new ChildProcess(bin, [...nodePath.slice(1), '-e', 'console.log("ok " + process.version)'], { + logging: 'no', + }) const r = await proc.run() const ok = r.exitCode === 0 && r.stdout.includes('ok') if (!ok) { @@ -41,7 +44,7 @@ export async function validateNodeExe(nodePath: string, lsp: string, args: strin } // Check that we can start `node …/lsp.js --stdio …`. - const lspProc = new ChildProcess(nodePath, [lsp, ...args], { logging: 'no' }) + const lspProc = new ChildProcess(bin, [...nodePath.slice(1), lsp, ...args], { logging: 'no' }) try { // Start asynchronously (it never stops; we need to stop it below). lspProc.run().catch((e) => logger.error('failed to run: %s', lspProc.toString(false, true))) @@ -78,18 +81,21 @@ export function createServerOptions({ executable, serverModule, execArgv, + warnThresholds, }: { encryptionKey: Buffer - executable: string + executable: string[] serverModule: string execArgv: string[] + warnThresholds?: { cpu?: number; memory?: number } }) { return async () => { - const args = [serverModule, ...execArgv] + const bin = executable[0] + const args = [...executable.slice(1), serverModule, ...execArgv] if (isDebugInstance()) { args.unshift('--inspect=6080') } - const lspProcess = new ChildProcess(executable, args) + const lspProcess = new ChildProcess(bin, args, { warnThresholds }) // this is a long running process, awaiting it will never resolve void lspProcess.run() diff --git a/packages/core/src/shared/settings-amazonq.gen.ts b/packages/core/src/shared/settings-amazonq.gen.ts index f0a3d47f989..637c5b1b12e 100644 --- a/packages/core/src/shared/settings-amazonq.gen.ts +++ b/packages/core/src/shared/settings-amazonq.gen.ts @@ -21,7 +21,9 @@ export const amazonqSettings = { "ssoCacheError": {}, "amazonQLspManifestMessage": {}, "amazonQWorkspaceLspManifestMessage": {}, - "amazonQChatDisclaimer": {} + "amazonQChatDisclaimer": {}, + "amazonQChatPairProgramming": {}, + "amazonQSelectDeveloperProfile": {} }, "amazonQ.showCodeWithReferences": {}, "amazonQ.allowFeatureDevelopmentToRunCodeAndTests": {}, @@ -31,6 +33,9 @@ export const amazonqSettings = { "amazonQ.workspaceIndexWorkerThreads": {}, "amazonQ.workspaceIndexUseGPU": {}, "amazonQ.workspaceIndexMaxSize": {}, + "amazonQ.workspaceIndexMaxFileSize": {}, + "amazonQ.workspaceIndexCacheDirPath": {}, + "amazonQ.workspaceIndexIgnoreFilePatterns": {}, "amazonQ.ignoredSecurityIssues": {} } diff --git a/packages/core/src/shared/settings-toolkit.gen.ts b/packages/core/src/shared/settings-toolkit.gen.ts index 95aaa173c2e..59a637a4870 100644 --- a/packages/core/src/shared/settings-toolkit.gen.ts +++ b/packages/core/src/shared/settings-toolkit.gen.ts @@ -42,6 +42,7 @@ export const toolkitSettings = { }, "aws.experiments": { "jsonResourceModification": {}, + "amazonqLSP": {}, "amazonqLSPInline": {}, "amazonqChatLSP": {} }, diff --git a/packages/core/src/shared/telemetry/vscodeTelemetry.json b/packages/core/src/shared/telemetry/vscodeTelemetry.json index ffd715cbed8..4a5117ee252 100644 --- a/packages/core/src/shared/telemetry/vscodeTelemetry.json +++ b/packages/core/src/shared/telemetry/vscodeTelemetry.json @@ -87,11 +87,6 @@ "type": "int", "description": "CPU used by LSP server as a percentage of all available CPUs on the system" }, - { - "name": "cwsprChatResponseErrorReason", - "type": "string", - "description": "Client error reason when processing response stream" - }, { "name": "cwsprChatInteractionTarget", "type": "string", @@ -665,56 +660,6 @@ } ] }, - { - "name": "amazonq_messageResponseError", - "description": "When an error has occured in response to a prompt", - "metadata": [ - { - "type": "cwsprChatConversationId", - "required": false - }, - { - "type": "credentialStartUrl", - "required": false - }, - { - "type": "cwsprChatTriggerInteraction" - }, - { - "type": "cwsprChatUserIntent", - "required": false - }, - { - "type": "cwsprChatHasCodeSnippet", - "required": false - }, - { - "type": "cwsprChatProgrammingLanguage", - "required": false - }, - { - "type": "cwsprChatActiveEditorTotalCharacters", - "required": false - }, - { - "type": "cwsprChatActiveEditorImportCount", - "required": false - }, - { - "type": "cwsprChatResponseCode" - }, - { - "type": "cwsprChatRequestLength" - }, - { - "type": "cwsprChatConversationType" - }, - { - "type": "cwsprChatResponseErrorReason", - "required": false - } - ] - }, { "name": "amazonq_modifyCode", "description": "% of code modified by the user after copying/inserting code from a message", diff --git a/packages/core/src/shared/utilities/collectionUtils.ts b/packages/core/src/shared/utilities/collectionUtils.ts index 9f9fe9875b9..8a428b8e8b7 100644 --- a/packages/core/src/shared/utilities/collectionUtils.ts +++ b/packages/core/src/shared/utilities/collectionUtils.ts @@ -7,6 +7,7 @@ import { isWeb } from '../extensionGlobals' import { inspect as nodeInspect } from 'util' import { AsyncCollection, toCollection } from './asyncCollection' import { SharedProp, AccumulableKeys, Coalesce, isNonNullable } from './tsUtils' +import { truncate } from './textUtilities' export function union(a: Iterable, b: Iterable): Set { const result = new Set() @@ -304,10 +305,22 @@ export function assign, U extends Partial>(data: T * @param depth * @param omitKeys Omit properties matching these names (at any depth). * @param replacement Replacement for object whose fields extend beyond `depth`, and properties matching `omitKeys`. + * @param maxStringLength truncates string values that exceed this threshold (includes values in nested arrays) */ -export function partialClone(obj: any, depth: number = 3, omitKeys: string[] = [], replacement?: any): any { +export function partialClone( + obj: any, + depth: number = 3, + omitKeys: string[] = [], + options?: { + replacement?: any + maxStringLength?: number + } +): any { // Base case: If input is not an object or has no children, return it. if (typeof obj !== 'object' || obj === null || 0 === Object.getOwnPropertyNames(obj).length) { + if (typeof obj === 'string' && options?.maxStringLength) { + return truncate(obj, options?.maxStringLength, '...') + } return obj } @@ -315,15 +328,15 @@ export function partialClone(obj: any, depth: number = 3, omitKeys: string[] = [ const clonedObj = Array.isArray(obj) ? [] : {} if (depth === 0) { - return replacement ? replacement : clonedObj + return options?.replacement ? options.replacement : clonedObj } // Recursively clone properties of the input object for (const key in obj) { if (omitKeys.includes(key)) { - ;(clonedObj as any)[key] = replacement ? replacement : Array.isArray(obj) ? [] : {} + ;(clonedObj as any)[key] = options?.replacement ? options.replacement : Array.isArray(obj) ? [] : {} } else if (Object.prototype.hasOwnProperty.call(obj, key)) { - ;(clonedObj as any)[key] = partialClone(obj[key], depth - 1, omitKeys, replacement) + ;(clonedObj as any)[key] = partialClone(obj[key], depth - 1, omitKeys, options) } } diff --git a/packages/core/src/shared/utilities/messages.ts b/packages/core/src/shared/utilities/messages.ts index fe2b08e42cf..26fd745c8d6 100644 --- a/packages/core/src/shared/utilities/messages.ts +++ b/packages/core/src/shared/utilities/messages.ts @@ -236,7 +236,7 @@ export function showOutputMessage(message: string, outputChannel: vscode.OutputC * * @see showMessageWithCancel for an example usage */ -async function showProgressWithTimeout( +export async function showProgressWithTimeout( options: vscode.ProgressOptions, timeout: Timeout, showAfterMs: number diff --git a/packages/core/src/shared/utilities/processUtils.ts b/packages/core/src/shared/utilities/processUtils.ts index 0204736f500..be44ba89bd2 100644 --- a/packages/core/src/shared/utilities/processUtils.ts +++ b/packages/core/src/shared/utilities/processUtils.ts @@ -44,6 +44,13 @@ export interface ChildProcessOptions { onStdout?: (text: string, context: RunParameterContext) => void /** Callback for intercepting text from the stderr stream. */ onStderr?: (text: string, context: RunParameterContext) => void + /** Thresholds to configure warning logs */ + warnThresholds?: { + /** Threshold for memory usage in bytes */ + memory?: number + /** Threshold for CPU usage by percentage */ + cpu?: number + } } export interface ChildProcessRunOptions extends Omit { @@ -60,8 +67,12 @@ export interface ChildProcessResult { stderr: string signal?: string } - +export const oneMB = 1024 * 1024 export const eof = Symbol('EOF') +export const defaultProcessWarnThresholds = { + memory: 100 * oneMB, + cpu: 50, +} export interface ProcessStats { memory: number @@ -69,10 +80,6 @@ export interface ProcessStats { } export class ChildProcessTracker { static readonly pollingInterval: number = 10000 // Check usage every 10 seconds - static readonly thresholds: ProcessStats = { - memory: 100 * 1024 * 1024, // 100 MB - cpu: 50, - } static readonly logger = logger.getLogger('childProcess') static readonly loggedPids = new CircularBuffer(1000) #processByPid: Map = new Map() @@ -82,6 +89,15 @@ export class ChildProcessTracker { this.#pids = new PollingSet(ChildProcessTracker.pollingInterval, () => this.monitor()) } + private getThreshold(pid: number): ProcessStats { + if (!this.#processByPid.has(pid)) { + ChildProcessTracker.logOnce(pid, `Missing process with id ${pid}, returning default threshold`) + return defaultProcessWarnThresholds + } + // Safe to assert since it exists from check above. + return this.#processByPid.get(pid)!.getWarnThresholds() + } + private cleanUp() { const terminatedProcesses = Array.from(this.#pids.values()).filter( (pid: number) => this.#processByPid.get(pid)?.stopped @@ -106,13 +122,17 @@ export class ChildProcessTracker { return } const stats = this.getUsage(pid) + const threshold = this.getThreshold(pid) if (stats) { ChildProcessTracker.logger.debug(`Process ${pid} usage: %O`, stats) - if (stats.memory > ChildProcessTracker.thresholds.memory) { - ChildProcessTracker.logOnce(pid, `Process ${pid} exceeded memory threshold: ${stats.memory}`) + if (stats.memory > threshold.memory) { + ChildProcessTracker.logOnce( + pid, + `Process ${pid} exceeded memory threshold: ${(stats.memory / oneMB).toFixed(2)} MB` + ) } - if (stats.cpu > ChildProcessTracker.thresholds.cpu) { - ChildProcessTracker.logOnce(pid, `Process ${pid} exceeded cpu threshold: ${stats.cpu}`) + if (stats.cpu > threshold.cpu) { + ChildProcessTracker.logOnce(pid, `Process ${pid} exceeded cpu threshold: ${stats.cpu}%`) } } } @@ -248,6 +268,10 @@ export class ChildProcess { return await new ChildProcess(command, args, options).run() } + public getWarnThresholds(): ProcessStats { + return { ...defaultProcessWarnThresholds, ...this.#baseOptions.warnThresholds } + } + // Inspired by 'got' /** * Creates a one-off {@link ChildProcess} class that always uses the specified options. diff --git a/packages/core/src/shared/utilities/resourceCache.ts b/packages/core/src/shared/utilities/resourceCache.ts new file mode 100644 index 00000000000..c0beee61cd6 --- /dev/null +++ b/packages/core/src/shared/utilities/resourceCache.ts @@ -0,0 +1,190 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import globals from '../extensionGlobals' +import { globalKey } from '../globalState' +import { getLogger } from '../logger/logger' +import { waitUntil } from '../utilities/timeoutUtils' + +/** + * args: + * @member result: the actual resource type callers want to use + * @member locked: readWriteLock, while the lock is acquired by one process, the other can't access to it until it's released by the previous + * @member timestamp: used for determining the resource is stale or not + */ +interface Resource { + result: V | undefined + locked: boolean + timestamp: number +} + +/** + * GlobalStates schema, which is used for vscode global states deserialization, [globals.globalState#tryGet] etc. + * The purpose of it is to allow devs to overload the resource into existing global key and no need to create a specific key for only this purpose. + */ +export interface GlobalStateSchema { + resource: Resource +} + +const logger = getLogger('resourceCache') + +function now() { + return globals.clock.Date.now() +} + +/** + * CacheResource utilizes VSCode global states API to cache resources which are expensive to get so that the result can be shared across multiple VSCode instances. + * The first VSCode instance invoking #getResource will hold a lock and make the actual network call/FS read to pull the real response. + * When the pull is done, the lock will be released and it then caches the result in the global states. Then the rest of instances can now acquire the lock 1 by 1 and read the resource from the cache. + * + * constructor: + * @param key: global state key, which is used for globals.globalState#update, #tryGet etc. + * @param expirationInMilli: cache expiration time in milli seconds + * @param defaultValue: default value for the cache if the cache doesn't pre-exist in users' FS + * @param waitUntilOption: waitUntil option for acquire lock + * + * methods: + * @method resourceProvider: implementation needs to implement this method to obtain the latest resource either via network calls or FS read + * @method getResource: obtain the resource from cache or pull the latest from the service if the cache either expires or doesn't exist + */ +export abstract class CachedResource { + constructor( + private readonly key: globalKey, + private readonly expirationInMilli: number, + private readonly defaultValue: GlobalStateSchema, + private readonly waitUntilOption: { timeout: number; interval: number; truthy: boolean } + ) {} + + abstract resourceProvider(): Promise + + async getResource(): Promise { + const cachedValue = await this.tryLoadResourceAndLock() + const resource = cachedValue?.resource + + // If cache is still fresh, return cached result, otherwise pull latest from the service + if (cachedValue && resource && resource.result) { + const duration = now() - resource.timestamp + if (duration < this.expirationInMilli) { + logger.debug( + `cache hit, duration(%sms) is less than expiration(%sms), returning cached value: %s`, + duration, + this.expirationInMilli, + this.key + ) + // release the lock + await this.releaseLock(resource, cachedValue) + return resource.result + } + + logger.debug( + `cache is stale, duration(%sms) is older than expiration(%sms), pulling latest resource: %s`, + duration, + this.expirationInMilli, + this.key + ) + } else { + logger.info(`cache miss, pulling latest resource: %s`, this.key) + } + + /** + * Possible paths here + * 1. cache doesn't exist. + * 2. cache exists but expired. + * 3. lock is held by other process and the waiting time is greater than the specified waiting time + */ + try { + // Make the real network call / FS read to pull the resource + const latest = await this.resourceProvider() + + // Update resource cache and release the lock + const r: Resource = { + locked: false, + timestamp: now(), + result: latest, + } + await this.releaseLock(r) + logger.info(`loaded latest resource and updated cache: %s`, this.key) + return latest + } catch (e) { + logger.error(`failed to load latest resource, releasing lock: %s`, this.key) + await this.releaseLock() + throw e + } + } + + // This method will lock the resource so other callers have to wait until the lock is released, otherwise will return undefined if it times out + private async tryLoadResourceAndLock(): Promise | undefined> { + const _acquireLock = async () => { + const cachedValue = this.readCacheOrDefault() + + if (!cachedValue.resource.locked) { + await this.lockResource(cachedValue) + return cachedValue + } + + return undefined + } + + const lock = await waitUntil(async () => { + const lock = await _acquireLock() + logger.debug(`trying to acquire resource cache lock: %s`, this.key) + if (lock) { + return lock + } + }, this.waitUntilOption) + + return lock + } + + async lockResource(baseCache: GlobalStateSchema): Promise { + await this.updateResourceCache({ locked: true }, baseCache) + } + + async releaseLock(): Promise + async releaseLock(resource: Partial>): Promise + async releaseLock(resource: Partial>, baseCache: GlobalStateSchema): Promise + async releaseLock(resource?: Partial>, baseCache?: GlobalStateSchema): Promise { + if (!resource) { + await this.updateResourceCache({ locked: false }, undefined) + } else if (baseCache) { + await this.updateResourceCache(resource, baseCache) + } else { + await this.updateResourceCache(resource, undefined) + } + } + + async clearCache() { + const baseCache = this.readCacheOrDefault() + await this.updateResourceCache({ result: undefined, timestamp: 0, locked: false }, baseCache) + } + + private async updateResourceCache(resource: Partial>, cache: GlobalStateSchema | undefined) { + const baseCache = cache ?? this.readCacheOrDefault() + + const toUpdate: GlobalStateSchema = { + ...baseCache, + resource: { + ...baseCache.resource, + ...resource, + }, + } + + await globals.globalState.update(this.key, toUpdate) + } + + private readCacheOrDefault(): GlobalStateSchema { + const cachedValue = globals.globalState.tryGet>(this.key, Object, { + ...this.defaultValue, + resource: { + ...this.defaultValue.resource, + locked: false, + result: undefined, + timestamp: 0, + }, + }) + + return cachedValue + } +} diff --git a/packages/core/src/shared/utilities/textDocumentUtilities.ts b/packages/core/src/shared/utilities/textDocumentUtilities.ts index 48a20a6c44b..93b22c2e560 100644 --- a/packages/core/src/shared/utilities/textDocumentUtilities.ts +++ b/packages/core/src/shared/utilities/textDocumentUtilities.ts @@ -11,6 +11,8 @@ import { getLogger } from '../logger/logger' import fs from '../fs/fs' import { ToolkitError } from '../errors' import { indent } from './textUtilities' +import { ViewDiffMessage } from '../../amazonq/commons/controllers/contentController' +import { DiffContentProvider } from '../../amazonq/commons/controllers/diffContentProvider' /** * Finds occurences of text in a document. Currently only used for highlighting cloudwatchlogs data. @@ -123,13 +125,13 @@ export async function applyChanges(doc: vscode.TextDocument, range: vscode.Range * and applying the proposed changes within the selected range. * * @param {vscode.Uri} originalFileUri - The URI of the original file. - * @param {any} message - The message object containing the proposed code changes. + * @param {ViewDiffMessage} message - The message object containing the proposed code changes. * @param {vscode.Selection} selection - The selection range in the document where the changes are applied. * @returns {Promise} - A promise that resolves to the URI of the temporary file. */ export async function createTempFileForDiff( originalFileUri: vscode.Uri, - message: any, + message: ViewDiffMessage, selection: vscode.Selection, scheme: string ): Promise { @@ -168,6 +170,53 @@ export async function createTempFileForDiff( return tempFileUri } +/** + * Creates temporary URIs for diff comparison and registers their content with a DiffContentProvider. + * This approach avoids writing to the file system by keeping content in memory. + * + * @param filePath The path of the original file (used for naming) + * @param fileText Optional content of the original file (if not provided, will be read from filePath) + * @param message The message object containing the proposed code changes + * @param selection The selection range where changes should be applied + * @param scheme The URI scheme to use + * @param diffProvider The content provider to register URIs with + * @returns A promise that resolves to a tuple of [originalUri, modifiedUri] + */ +export async function createTempUrisForDiff( + filePath: string, + fileText: string | undefined, + message: ViewDiffMessage, + selection: vscode.Selection, + scheme: string, + diffProvider: DiffContentProvider +): Promise<[vscode.Uri, vscode.Uri]> { + const originalFile = _path.parse(filePath) + const id = Date.now() + + // Create URIs with the custom scheme + const originalFileUri = vscode.Uri.parse(`${scheme}:/${originalFile.name}_original-${id}${originalFile.ext}`) + const modifiedFileUri = vscode.Uri.parse(`${scheme}:/${originalFile.name}_proposed-${id}${originalFile.ext}`) + + // Get the original content + const contentToUse = fileText ?? (await fs.readFileText(filePath)) + + // Register the original content + diffProvider.registerContent(originalFileUri, contentToUse) + + const indentedCode = getIndentedCodeFromOriginalContent(message, contentToUse, selection) + const lines = contentToUse.split('\n') + + // Create the modified content + const beforeLines = lines.slice(0, selection.start.line) + const afterLines = lines.slice(selection.end.line + 1) + const modifiedContent = [...beforeLines, indentedCode, ...afterLines].join('\n') + + // Register the modified content + diffProvider.registerContent(modifiedFileUri, modifiedContent) + + return [originalFileUri, modifiedFileUri] +} + /** * Indents the given code based on the current document's indentation at the selection start. * @@ -176,7 +225,7 @@ export async function createTempFileForDiff( * @param selection The selection range in the document. * @returns The processed code to be applied to the document. */ -export function getIndentedCode(message: any, doc: vscode.TextDocument, selection: vscode.Selection) { +export function getIndentedCode(message: ViewDiffMessage, doc: vscode.TextDocument, selection: vscode.Selection) { const indentRange = new vscode.Range(new vscode.Position(selection.start.line, 0), selection.active) let indentation = doc.getText(indentRange) @@ -187,6 +236,26 @@ export function getIndentedCode(message: any, doc: vscode.TextDocument, selectio return indent(message.code, indentation.length) } +/** + * Indents the given code based on the indentation of the original content at the selection start. + * + * @param message The message object containing the code. + * @param originalContent The original content of the document. + * @param selection The selection range in the document. + * @returns The processed code to be applied to the document. + */ +export function getIndentedCodeFromOriginalContent( + message: ViewDiffMessage, + originalContent: string, + selection: vscode.Selection +) { + const lines = originalContent.split('\n') + const selectionStartLine = lines[selection.start.line] || '' + const indentMatch = selectionStartLine.match(/^(\s*)/) + const indentation = indentMatch ? indentMatch[1] : '' + return indent(message.code, indentation.length) +} + export async function showFile(uri: vscode.Uri) { const doc = await vscode.workspace.openTextDocument(uri) await vscode.window.showTextDocument(doc, { preview: false }) diff --git a/packages/core/src/shared/utilities/textUtilities.ts b/packages/core/src/shared/utilities/textUtilities.ts index 53c2e2be32c..6bc1a4eff21 100644 --- a/packages/core/src/shared/utilities/textUtilities.ts +++ b/packages/core/src/shared/utilities/textUtilities.ts @@ -8,9 +8,10 @@ import * as crypto from 'crypto' import * as fs from 'fs' // eslint-disable-line no-restricted-imports import { default as stripAnsi } from 'strip-ansi' import { getLogger } from '../logger/logger' +import { ViewDiffMessage } from '../../amazonq/commons/controllers/contentController' /** - * Truncates string `s` if it exceeds `n` chars. + * Truncates string `s` if it has or exceeds `n` chars. * * If `n` is negative, truncates at start instead of end. * @@ -268,10 +269,11 @@ export function decodeBase64(base64Str: string): string { * @param {any} message - The message object containing the file and selection context. * @returns {Object} - An object with `filePath` and `selection` properties. */ -export function extractFileAndCodeSelectionFromMessage(message: any) { +export function extractFileAndCodeSelectionFromMessage(message: ViewDiffMessage) { const filePath = message?.context?.activeFileContext?.filePath + const fileText = message?.context?.activeFileContext?.fileText const selection = message?.context?.focusAreaContext?.selectionInsideExtendedCodeBlock as vscode.Selection - return { filePath, selection } + return { filePath, fileText, selection } } export function matchesPattern(source: string, target: string | RegExp) { diff --git a/packages/core/src/shared/vscode/commands2.ts b/packages/core/src/shared/vscode/commands2.ts index c55cd66cc7a..b40134c2afa 100644 --- a/packages/core/src/shared/vscode/commands2.ts +++ b/packages/core/src/shared/vscode/commands2.ts @@ -653,7 +653,7 @@ async function runCommand(fn: T, info: CommandInfo): Prom logger.debug( `command: running ${label} with arguments: %O`, - partialClone(args, 3, ['clientSecret', 'accessToken', 'refreshToken', 'tooltip'], '[omitted]') + partialClone(args, 3, ['clientSecret', 'accessToken', 'refreshToken', 'tooltip'], { replacement: '[omitted]' }) ) try { diff --git a/packages/core/src/test/amazonq/commons/controllers/contentController.test.ts b/packages/core/src/test/amazonq/commons/controllers/contentController.test.ts new file mode 100644 index 00000000000..003e14e4783 --- /dev/null +++ b/packages/core/src/test/amazonq/commons/controllers/contentController.test.ts @@ -0,0 +1,143 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode' +import * as sinon from 'sinon' +import assert from 'assert' +import { EditorContentController, ViewDiffMessage } from '../../../../amazonq/commons/controllers/contentController' +import * as textDocumentUtilities from '../../../../shared/utilities/textDocumentUtilities' +import * as textUtilities from '../../../../shared/utilities/textUtilities' +import { amazonQDiffScheme, amazonQTabSuffix } from '../../../../shared/constants' +import * as editorUtilities from '../../../../shared/utilities/editorUtilities' + +describe('EditorContentController', () => { + let sandbox: sinon.SinonSandbox + let controller: EditorContentController + let executeCommandStub: sinon.SinonStub + let registerTextDocumentContentProviderStub: sinon.SinonStub + let createTempUrisForDiffStub: sinon.SinonStub + let disposeOnEditorCloseStub: sinon.SinonStub + let extractParamsFromMessageStub: sinon.SinonStub + + beforeEach(() => { + sandbox = sinon.createSandbox() + controller = new EditorContentController() + + // Stub VS Code API calls + executeCommandStub = sandbox.stub(vscode.commands, 'executeCommand').resolves() + registerTextDocumentContentProviderStub = sandbox + .stub(vscode.workspace, 'registerTextDocumentContentProvider') + .returns({ dispose: () => {} }) + + // Stub utility functions + createTempUrisForDiffStub = sandbox.stub(textDocumentUtilities, 'createTempUrisForDiff') + disposeOnEditorCloseStub = sandbox.stub(editorUtilities, 'disposeOnEditorClose') + extractParamsFromMessageStub = sandbox.stub(textUtilities, 'extractFileAndCodeSelectionFromMessage') + }) + + afterEach(() => { + sandbox.restore() + }) + + describe('viewDiff', () => { + const testFilePath = '/path/to/testFile.js' + const testCode = 'new code' + const testSelection = new vscode.Selection(new vscode.Position(1, 0), new vscode.Position(2, 0)) + const testMessage: ViewDiffMessage = { + code: testCode, + } + const originalUri = vscode.Uri.parse('test-scheme:/original/testFile.js') + const modifiedUri = vscode.Uri.parse('test-scheme:/modified/testFile.js') + + beforeEach(() => { + extractParamsFromMessageStub.returns({ + filePath: testFilePath, + selection: testSelection, + }) + createTempUrisForDiffStub.resolves([originalUri, modifiedUri]) + }) + + it('should show diff view with correct URIs and title', async () => { + await controller.viewDiff(testMessage) + + // Verify content provider was registered + assert.strictEqual(registerTextDocumentContentProviderStub.calledOnce, true) + assert.strictEqual(registerTextDocumentContentProviderStub.firstCall.args[0], amazonQDiffScheme) + + // Verify createTempUrisForDiff was called with correct parameters + assert.strictEqual(createTempUrisForDiffStub.calledOnce, true) + assert.strictEqual(createTempUrisForDiffStub.firstCall.args[0], testFilePath) + assert.strictEqual(createTempUrisForDiffStub.firstCall.args[2], testMessage) + assert.strictEqual(createTempUrisForDiffStub.firstCall.args[3], testSelection) + assert.strictEqual(createTempUrisForDiffStub.firstCall.args[4], amazonQDiffScheme) + + // Verify vscode.diff command was executed with correct parameters + assert.strictEqual(executeCommandStub.calledOnce, true) + assert.strictEqual(executeCommandStub.firstCall.args[0], 'vscode.diff') + assert.strictEqual(executeCommandStub.firstCall.args[1], originalUri) + assert.strictEqual(executeCommandStub.firstCall.args[2], modifiedUri) + assert.strictEqual(executeCommandStub.firstCall.args[3], `testFile.js ${amazonQTabSuffix}`) + + // Verify disposeOnEditorClose was called + assert.strictEqual(disposeOnEditorCloseStub.calledOnce, true) + assert.strictEqual(disposeOnEditorCloseStub.firstCall.args[0], originalUri) + }) + + it('should use custom scheme when provided', async () => { + const customScheme = 'custom-scheme' + await controller.viewDiff(testMessage, customScheme) + + assert.strictEqual(registerTextDocumentContentProviderStub.firstCall.args[0], customScheme) + assert.strictEqual(createTempUrisForDiffStub.firstCall.args[4], customScheme) + }) + + it('should pass fileText to createTempUrisForDiff when available', async () => { + const testFileText = 'original file content' + extractParamsFromMessageStub.returns({ + filePath: testFilePath, + fileText: testFileText, + selection: testSelection, + }) + + await controller.viewDiff(testMessage) + + assert.strictEqual(createTempUrisForDiffStub.firstCall.args[1], testFileText) + }) + + it('should not attempt to show diff when filePath is missing', async () => { + extractParamsFromMessageStub.returns({ + filePath: undefined, + selection: testSelection, + }) + + await controller.viewDiff(testMessage) + + assert.strictEqual(registerTextDocumentContentProviderStub.called, false) + assert.strictEqual(createTempUrisForDiffStub.called, false) + assert.strictEqual(executeCommandStub.called, false) + }) + + it('should not attempt to show diff when code is missing', async () => { + await controller.viewDiff({ code: undefined as unknown as string }) + + assert.strictEqual(registerTextDocumentContentProviderStub.called, false) + assert.strictEqual(createTempUrisForDiffStub.called, false) + assert.strictEqual(executeCommandStub.called, false) + }) + + it('should not attempt to show diff when selection is missing', async () => { + extractParamsFromMessageStub.returns({ + filePath: testFilePath, + selection: undefined, + }) + + await controller.viewDiff(testMessage) + + assert.strictEqual(registerTextDocumentContentProviderStub.called, false) + assert.strictEqual(createTempUrisForDiffStub.called, false) + assert.strictEqual(executeCommandStub.called, false) + }) + }) +}) diff --git a/packages/core/src/test/codewhisperer/commands/transformByQ.test.ts b/packages/core/src/test/codewhisperer/commands/transformByQ.test.ts index 3ec69e70b04..4b478e1876e 100644 --- a/packages/core/src/test/codewhisperer/commands/transformByQ.test.ts +++ b/packages/core/src/test/codewhisperer/commands/transformByQ.test.ts @@ -41,6 +41,9 @@ import { setMaven, parseBuildFile, validateSQLMetadataFile, + createLocalBuildUploadZip, + validateCustomVersionsFile, + extractOriginalProjectSources, } from '../../../codewhisperer/service/transformByQ/transformFileHandler' import { uploadArtifactToS3 } from '../../../codewhisperer/indexNode' import request from '../../../shared/request' @@ -49,6 +52,19 @@ import * as nodefs from 'fs' // eslint-disable-line no-restricted-imports describe('transformByQ', function () { let fetchStub: sinon.SinonStub let tempDir: string + const validCustomVersionsFile = `name: "custom-dependency-management" +description: "Custom dependency version management for Java migration from JDK 8/11/17 to JDK 17/21" +dependencyManagement: + dependencies: + - identifier: "com.example:library1" + targetVersion: "2.1.0" + versionProperty: "library1.version" + originType: "FIRST_PARTY" + plugins: + - identifier: "com.example.plugin" + targetVersion: "1.2.0" + versionProperty: "plugin.version"` + const validSctFile = ` @@ -284,8 +300,55 @@ describe('transformByQ', function () { const tempFilePath = path.join(tempDir, tempFileName) await toFile('', tempFilePath) transformByQState.setProjectPath(tempDir) - await setMaven() - assert.strictEqual(transformByQState.getMavenName(), '.\\mvnw.cmd') + setMaven() + // mavenName should always be 'mvn' + assert.strictEqual(transformByQState.getMavenName(), 'mvn') + }) + + it(`WHEN local build zip created THEN zip contains all expected files and no unexpected files`, async function () { + const zipPath = await createLocalBuildUploadZip(tempDir, 0, 'sample stdout after running local build') + const zip = new AdmZip(zipPath) + const manifestEntry = zip.getEntry('manifest.json') + if (!manifestEntry) { + fail('manifest.json not found in the zip') + } + const manifestBuffer = manifestEntry.getData() + const manifestText = manifestBuffer.toString('utf8') + const manifest = JSON.parse(manifestText) + assert.strictEqual(manifest.capability, 'CLIENT_SIDE_BUILD') + assert.strictEqual(manifest.exitCode, 0) + assert.strictEqual(manifest.commandLogFileName, 'build-output.log') + assert.strictEqual(zip.getEntries().length, 2) // expecting only manifest.json and build-output.log + }) + + it('WHEN extractOriginalProjectSources THEN only source files are extracted to destination', async function () { + const tempDir = (await TestFolder.create()).path + const destinationPath = path.join(tempDir, 'originalCopy_jobId_artifactId') + await fs.mkdir(destinationPath) + + const zip = new AdmZip() + const testFiles = [ + { path: 'sources/file1.java', content: 'test content 1' }, + { path: 'sources/dir/file2.java', content: 'test content 2' }, + { path: 'dependencies/file3.jar', content: 'should not extract' }, + { path: 'manifest.json', content: '{"version": "1.0"}' }, + ] + + for (const file of testFiles) { + zip.addFile(file.path, Buffer.from(file.content)) + } + + const zipPath = path.join(tempDir, 'test.zip') + zip.writeZip(zipPath) + + transformByQState.setPayloadFilePath(zipPath) + + await extractOriginalProjectSources(destinationPath) + + const extractedFiles = getFilesRecursively(destinationPath, false) + assert.strictEqual(extractedFiles.length, 2) + assert(extractedFiles.includes(path.join(destinationPath, 'sources', 'file1.java'))) + assert(extractedFiles.includes(path.join(destinationPath, 'sources', 'dir', 'file2.java'))) }) it(`WHEN zip created THEN manifest.json contains test-compile custom build command`, async function () { @@ -453,6 +516,17 @@ describe('transformByQ', function () { assert.strictEqual(expectedWarning, warningMessage) }) + it(`WHEN validateCustomVersionsFile on fully valid .yaml file THEN passes validation`, async function () { + const isValidFile = await validateCustomVersionsFile(validCustomVersionsFile) + assert.strictEqual(isValidFile, true) + }) + + it(`WHEN validateCustomVersionsFile on invalid .yaml file THEN fails validation`, async function () { + const invalidFile = validCustomVersionsFile.replace('dependencyManagement', 'invalidKey') + const isValidFile = await validateCustomVersionsFile(invalidFile) + assert.strictEqual(isValidFile, false) + }) + it(`WHEN validateMetadataFile on fully valid .sct file THEN passes validation`, async function () { const isValidMetadata = await validateSQLMetadataFile(validSctFile, { tabID: 'abc123' }) assert.strictEqual(isValidMetadata, true) diff --git a/packages/core/src/test/shared/lsp/utils/cleanup.test.ts b/packages/core/src/test/shared/lsp/utils/cleanup.test.ts index 98f37fff28f..ec2f5a32059 100644 --- a/packages/core/src/test/shared/lsp/utils/cleanup.test.ts +++ b/packages/core/src/test/shared/lsp/utils/cleanup.test.ts @@ -41,7 +41,7 @@ describe('cleanLSPDownloads', function () { it('keeps two newest versions', async function () { await fakeInstallVersions(['1.0.0', '1.0.1', '1.1.1', '2.1.1'], installationDir.fsPath) - const deleted = await cleanLspDownloads([], installationDir.fsPath) + const deleted = await cleanLspDownloads('2.1.1', [], installationDir.fsPath) const result = (await fs.readdir(installationDir.fsPath)).map(([filename, _filetype], _index) => filename) assert.strictEqual(result.length, 2) @@ -53,6 +53,7 @@ describe('cleanLSPDownloads', function () { it('deletes delisted versions', async function () { await fakeInstallVersions(['1.0.0', '1.0.1', '1.1.1', '2.1.1'], installationDir.fsPath) const deleted = await cleanLspDownloads( + '2.1.1', [{ serverVersion: '1.1.1', isDelisted: true, targets: [] }], installationDir.fsPath ) @@ -67,6 +68,7 @@ describe('cleanLSPDownloads', function () { it('handles case where less than 2 versions are not delisted', async function () { await fakeInstallVersions(['1.0.0', '1.0.1', '1.1.1', '2.1.1'], installationDir.fsPath) const deleted = await cleanLspDownloads( + '1.0.1', [ { serverVersion: '1.1.1', isDelisted: true, targets: [] }, { serverVersion: '2.1.1', isDelisted: true, targets: [] }, @@ -83,7 +85,7 @@ describe('cleanLSPDownloads', function () { it('handles case where less than 2 versions exist', async function () { await fakeInstallVersions(['1.0.0'], installationDir.fsPath) - const deleted = await cleanLspDownloads([], installationDir.fsPath) + const deleted = await cleanLspDownloads('1.0.0', [], installationDir.fsPath) const result = (await fs.readdir(installationDir.fsPath)).map(([filename, _filetype], _index) => filename) assert.strictEqual(result.length, 1) @@ -93,6 +95,7 @@ describe('cleanLSPDownloads', function () { it('does not install delisted version when no other option exists', async function () { await fakeInstallVersions(['1.0.0'], installationDir.fsPath) const deleted = await cleanLspDownloads( + '1.0.0', [{ serverVersion: '1.0.0', isDelisted: true, targets: [] }], installationDir.fsPath ) @@ -105,6 +108,7 @@ describe('cleanLSPDownloads', function () { it('ignores invalid versions', async function () { await fakeInstallVersions(['1.0.0', '.DS_STORE'], installationDir.fsPath) const deleted = await cleanLspDownloads( + '1.0.0', [{ serverVersion: '1.0.0', isDelisted: true, targets: [] }], installationDir.fsPath ) diff --git a/packages/core/src/test/shared/utilities/collectionUtils.test.ts b/packages/core/src/test/shared/utilities/collectionUtils.test.ts index 53ddc39eff8..34aacb9f28e 100644 --- a/packages/core/src/test/shared/utilities/collectionUtils.test.ts +++ b/packages/core/src/test/shared/utilities/collectionUtils.test.ts @@ -710,8 +710,10 @@ describe('CollectionUtils', async function () { }) describe('partialClone', function () { - it('omits properties by depth', function () { - const testObj = { + let multipleTypedObj: object + + before(async function () { + multipleTypedObj = { a: 34234234234, b: '123456789', c: new Date(2023, 1, 1), @@ -724,57 +726,80 @@ describe('CollectionUtils', async function () { throw Error() }, } + }) - assert.deepStrictEqual(partialClone(testObj, 1), { - ...testObj, + it('omits properties by depth', function () { + assert.deepStrictEqual(partialClone(multipleTypedObj, 1), { + ...multipleTypedObj, d: {}, e: {}, }) - assert.deepStrictEqual(partialClone(testObj, 0, [], '[replaced]'), '[replaced]') - assert.deepStrictEqual(partialClone(testObj, 1, [], '[replaced]'), { - ...testObj, + assert.deepStrictEqual(partialClone(multipleTypedObj, 0, [], { replacement: '[replaced]' }), '[replaced]') + assert.deepStrictEqual(partialClone(multipleTypedObj, 1, [], { replacement: '[replaced]' }), { + ...multipleTypedObj, d: '[replaced]', e: '[replaced]', }) - assert.deepStrictEqual(partialClone(testObj, 3), { - ...testObj, + assert.deepStrictEqual(partialClone(multipleTypedObj, 3), { + ...multipleTypedObj, d: { d1: { d2: {} } }, }) - assert.deepStrictEqual(partialClone(testObj, 4), testObj) + assert.deepStrictEqual(partialClone(multipleTypedObj, 4), multipleTypedObj) }) it('omits properties by name', function () { - const testObj = { - a: 34234234234, - b: '123456789', - c: new Date(2023, 1, 1), - d: { d1: { d2: { d3: 'deep' } } }, + assert.deepStrictEqual(partialClone(multipleTypedObj, 2, ['c', 'e2'], { replacement: '[replaced]' }), { + ...multipleTypedObj, + c: '[replaced]', + d: { d1: '[replaced]' }, + e: { + e1: '[replaced]', + e2: '[replaced]', + }, + }) + assert.deepStrictEqual(partialClone(multipleTypedObj, 3, ['c', 'e2'], { replacement: '[replaced]' }), { + ...multipleTypedObj, + c: '[replaced]', + d: { d1: { d2: '[replaced]' } }, e: { e1: [4, 3, 7], - e2: 'loooooooooo \n nnnnnnnnnnn \n gggggggg \n string', + e2: '[replaced]', }, - f: () => { - throw Error() + }) + }) + + it('truncates properties by maxLength', function () { + const testObj = { + strValue: '1', + boolValue: true, + longString: '11111', + nestedObj: { + nestedObjAgain: { + longNestedStr: '11111', + shortNestedStr: '11', + }, + }, + nestedObj2: { + functionValue: (_: unknown) => {}, }, + nestedObj3: { + myArray: ['1', '11111', '1'], + }, + objInArray: [{ shortString: '11', longString: '11111' }], } - - assert.deepStrictEqual(partialClone(testObj, 2, ['c', 'e2'], '[omitted]'), { + assert.deepStrictEqual(partialClone(testObj, 5, [], { maxStringLength: 2 }), { ...testObj, - c: '[omitted]', - d: { d1: '[omitted]' }, - e: { - e1: '[omitted]', - e2: '[omitted]', + longString: '11...', + nestedObj: { + nestedObjAgain: { + longNestedStr: '11...', + shortNestedStr: '11', + }, }, - }) - assert.deepStrictEqual(partialClone(testObj, 3, ['c', 'e2'], '[omitted]'), { - ...testObj, - c: '[omitted]', - d: { d1: { d2: '[omitted]' } }, - e: { - e1: [4, 3, 7], - e2: '[omitted]', + nestedObj3: { + myArray: ['1', '11...', '1'], }, + objInArray: [{ shortString: '11', longString: '11...' }], }) }) }) diff --git a/packages/core/src/test/shared/utilities/processUtils.test.ts b/packages/core/src/test/shared/utilities/processUtils.test.ts index 436ac48ecc4..65817d80a56 100644 --- a/packages/core/src/test/shared/utilities/processUtils.test.ts +++ b/packages/core/src/test/shared/utilities/processUtils.test.ts @@ -10,8 +10,10 @@ import * as sinon from 'sinon' import { makeTemporaryToolkitFolder, tryRemoveFolder } from '../../../shared/filesystemUtilities' import { ChildProcess, + ChildProcessOptions, ChildProcessResult, ChildProcessTracker, + defaultProcessWarnThresholds, eof, ProcessStats, } from '../../../shared/utilities/processUtils' @@ -376,8 +378,8 @@ async function stopAndWait(runningProcess: RunningProcess): Promise { await runningProcess.result } -function startSleepProcess(timeout: number = 90): RunningProcess { - const childProcess = new ChildProcess(getSleepCmd(), [timeout.toString()]) +function startSleepProcess(options?: ChildProcessOptions, timeout: number = 90): RunningProcess { + const childProcess = new ChildProcess(getSleepCmd(), [timeout.toString()], options) const result = childProcess.run().catch(() => assert.fail('sleep command threw an error')) return { childProcess, result } } @@ -454,12 +456,12 @@ describe('ChildProcessTracker', function () { tracker.add(runningProcess.childProcess) const highCpu: ProcessStats = { - cpu: ChildProcessTracker.thresholds.cpu + 1, + cpu: defaultProcessWarnThresholds.cpu + 1, memory: 0, } const highMemory: ProcessStats = { cpu: 0, - memory: ChildProcessTracker.thresholds.memory + 1, + memory: defaultProcessWarnThresholds.memory + 1, } usageMock.returns(highCpu) @@ -480,7 +482,7 @@ describe('ChildProcessTracker', function () { tracker.add(runningProcess.childProcess) usageMock.returns({ - cpu: ChildProcessTracker.thresholds.cpu + 1, + cpu: defaultProcessWarnThresholds.cpu + 1, memory: 0, }) @@ -492,10 +494,11 @@ describe('ChildProcessTracker', function () { it('does not log for processes within threshold', async function () { const runningProcess = startSleepProcess() + tracker.add(runningProcess.childProcess) usageMock.returns({ - cpu: ChildProcessTracker.thresholds.cpu - 1, - memory: ChildProcessTracker.thresholds.memory - 1, + cpu: defaultProcessWarnThresholds.cpu - 1, + memory: defaultProcessWarnThresholds.memory - 1, }) await clock.tickAsync(ChildProcessTracker.pollingInterval) @@ -504,4 +507,51 @@ describe('ChildProcessTracker', function () { await stopAndWait(runningProcess) }) + + it('respects custom thresholds', async function () { + const largeRunningProcess = startSleepProcess({ + warnThresholds: { + cpu: defaultProcessWarnThresholds.cpu + 10, + memory: defaultProcessWarnThresholds.memory + 10, + }, + }) + tracker.add(largeRunningProcess.childProcess) + const smallRunningProcess = startSleepProcess({ + warnThresholds: { + cpu: defaultProcessWarnThresholds.cpu - 10, + memory: defaultProcessWarnThresholds.memory - 10, + }, + }) + tracker.add(smallRunningProcess.childProcess) + + usageMock.returns({ + cpu: defaultProcessWarnThresholds.cpu + 5, + memory: defaultProcessWarnThresholds.memory + 5, + }) + + await clock.tickAsync(ChildProcessTracker.pollingInterval) + assert.throws(() => assertLogsContain(largeRunningProcess.childProcess.pid().toString(), false, 'warn')) + assertLogsContain(smallRunningProcess.childProcess.pid().toString(), false, 'warn') + + await stopAndWait(largeRunningProcess) + await stopAndWait(smallRunningProcess) + }) + + it('fills custom thresholds with default', async function () { + const runningProcess = startSleepProcess({ + warnThresholds: { + cpu: defaultProcessWarnThresholds.cpu + 10, + }, + }) + tracker.add(runningProcess.childProcess) + + usageMock.returns({ + memory: defaultProcessWarnThresholds.memory + 1, + }) + + await clock.tickAsync(ChildProcessTracker.pollingInterval) + assertLogsContain(runningProcess.childProcess.pid().toString(), false, 'warn') + + await stopAndWait(runningProcess) + }) }) diff --git a/packages/core/src/test/shared/utilities/textDocumentUtilities.test.ts b/packages/core/src/test/shared/utilities/textDocumentUtilities.test.ts new file mode 100644 index 00000000000..e907e09cb41 --- /dev/null +++ b/packages/core/src/test/shared/utilities/textDocumentUtilities.test.ts @@ -0,0 +1,140 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode' +import * as sinon from 'sinon' +import assert from 'assert' +import { createTempUrisForDiff } from '../../../shared/utilities/textDocumentUtilities' +import { DiffContentProvider } from '../../../amazonq/commons/controllers/diffContentProvider' +import fs from '../../../shared/fs/fs' + +describe('textDocumentUtilities', () => { + let sandbox: sinon.SinonSandbox + + beforeEach(() => { + sandbox = sinon.createSandbox() + }) + + afterEach(() => { + sandbox.restore() + }) + + describe('createTempUrisForDiff', () => { + const testScheme = 'test-scheme' + const testFilePath = '/path/to/testFile.js' + const testFileContent = 'line 1\nline 2\nline 3\nline 4\nline 5' + const testMessage = { + code: 'new line 3', + } + const testSelection = new vscode.Selection( + new vscode.Position(2, 0), // Start at line 3 (index 2) + new vscode.Position(2, 6) // End at line 3 (index 2) + ) + + let diffProvider: DiffContentProvider + let fsReadFileTextStub: sinon.SinonStub + + beforeEach(() => { + diffProvider = new DiffContentProvider() + sandbox.stub(diffProvider, 'registerContent') + fsReadFileTextStub = sandbox.stub(fs, 'readFileText').resolves(testFileContent) + }) + + it('should create URIs with the correct scheme and file name', async () => { + const [originalUri, modifiedUri] = await createTempUrisForDiff( + testFilePath, + undefined, + testMessage, + testSelection, + testScheme, + diffProvider + ) + + assert.strictEqual(originalUri.scheme, testScheme) + assert.strictEqual(modifiedUri.scheme, testScheme) + assert.ok(originalUri.path.includes('testFile_original-')) + assert.ok(modifiedUri.path.includes('testFile_proposed-')) + }) + + it('should use provided fileText instead of reading from file when available', async () => { + const providedFileText = 'provided line 1\nprovided line 2\nprovided line 3' + + await createTempUrisForDiff( + testFilePath, + providedFileText, + testMessage, + testSelection, + testScheme, + diffProvider + ) + + // Verify fs.readFileText was not called + assert.strictEqual(fsReadFileTextStub.called, false) + + // Verify the diffProvider was called with the provided content + const registerContentCalls = (diffProvider.registerContent as sinon.SinonStub).getCalls() + assert.strictEqual(registerContentCalls.length, 2) + assert.strictEqual(registerContentCalls[0].args[1], providedFileText) + }) + + it('should read from file when fileText is not provided', async () => { + await createTempUrisForDiff(testFilePath, undefined, testMessage, testSelection, testScheme, diffProvider) + + // Verify fs.readFileText was called with the correct path + assert.strictEqual(fsReadFileTextStub.calledWith(testFilePath), true) + + // Verify the diffProvider was called with the file content + const registerContentCalls = (diffProvider.registerContent as sinon.SinonStub).getCalls() + assert.strictEqual(registerContentCalls.length, 2) + assert.strictEqual(registerContentCalls[0].args[1], testFileContent) + }) + + it('should create modified content by replacing the selected lines', async () => { + await createTempUrisForDiff( + testFilePath, + testFileContent, + testMessage, + testSelection, + testScheme, + diffProvider + ) + + // Verify the diffProvider was called with the correct modified content + const registerContentCalls = (diffProvider.registerContent as sinon.SinonStub).getCalls() + assert.strictEqual(registerContentCalls.length, 2) + + // First call is for original content + assert.strictEqual(registerContentCalls[0].args[1], testFileContent) + + // Second call is for modified content + const expectedModifiedContent = 'line 1\nline 2\nnew line 3\nline 4\nline 5' + assert.strictEqual(registerContentCalls[1].args[1], expectedModifiedContent) + }) + + it('should handle multi-line selections correctly', async () => { + // Selection spanning multiple lines (lines 2-4) + const multiLineSelection = new vscode.Selection( + new vscode.Position(1, 0), // Start at line 2 (index 1) + new vscode.Position(3, 6) // End at line 4 (index 3) + ) + + await createTempUrisForDiff( + testFilePath, + testFileContent, + testMessage, + multiLineSelection, + testScheme, + diffProvider + ) + + // Verify the diffProvider was called with the correct modified content + const registerContentCalls = (diffProvider.registerContent as sinon.SinonStub).getCalls() + + // Expected content should have lines 2-4 replaced with the new code + const expectedModifiedContent = 'line 1\nnew line 3\nline 5' + assert.strictEqual(registerContentCalls[1].args[1], expectedModifiedContent) + }) + }) +}) diff --git a/packages/core/webpack.config.js b/packages/core/webpack.config.js index 95827191571..fba19d133b2 100644 --- a/packages/core/webpack.config.js +++ b/packages/core/webpack.config.js @@ -33,6 +33,7 @@ module.exports = (env, argv) => { ...baseVueConfig.createVueEntries(), // The above `createVueEntries` path pattern match does not catch this: 'src/amazonq/webview/ui/amazonq-ui': './src/amazonq/webview/ui/main.ts', + 'src/amazonq/webview/ui/amazonq-ui-connector-adapter': './src/amazonq/webview/ui/connectorAdapter.ts', }, } diff --git a/packages/toolkit/.changes/3.56.0.json b/packages/toolkit/.changes/3.56.0.json new file mode 100644 index 00000000000..58ce02582e1 --- /dev/null +++ b/packages/toolkit/.changes/3.56.0.json @@ -0,0 +1,5 @@ +{ + "date": "2025-04-25", + "version": "3.56.0", + "entries": [] +} \ No newline at end of file diff --git a/packages/toolkit/.changes/3.57.0.json b/packages/toolkit/.changes/3.57.0.json new file mode 100644 index 00000000000..b7deaa57598 --- /dev/null +++ b/packages/toolkit/.changes/3.57.0.json @@ -0,0 +1,10 @@ +{ + "date": "2025-05-01", + "version": "3.57.0", + "entries": [ + { + "type": "Feature", + "description": "AppBuilder: unchecking the 'Attach a debugger' checkbox in local invoke webview invokes the function without a debugger" + } + ] +} \ No newline at end of file diff --git a/packages/toolkit/.changes/3.58.0.json b/packages/toolkit/.changes/3.58.0.json new file mode 100644 index 00000000000..2fdddbec911 --- /dev/null +++ b/packages/toolkit/.changes/3.58.0.json @@ -0,0 +1,5 @@ +{ + "date": "2025-05-02", + "version": "3.58.0", + "entries": [] +} \ No newline at end of file diff --git a/packages/toolkit/CHANGELOG.md b/packages/toolkit/CHANGELOG.md index ede66857244..8bceccdcf13 100644 --- a/packages/toolkit/CHANGELOG.md +++ b/packages/toolkit/CHANGELOG.md @@ -1,3 +1,15 @@ +## 3.58.0 2025-05-02 + +- Miscellaneous non-user-facing changes + +## 3.57.0 2025-05-01 + +- **Feature** AppBuilder: unchecking the 'Attach a debugger' checkbox in local invoke webview invokes the function without a debugger + +## 3.56.0 2025-04-25 + +- Miscellaneous non-user-facing changes + ## 3.55.0 2025-04-18 - Miscellaneous non-user-facing changes diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index 3d7fcdbdbbc..806a87d097b 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -2,7 +2,7 @@ "name": "aws-toolkit-vscode", "displayName": "AWS Toolkit", "description": "Including CodeCatalyst, Infrastructure Composer, and support for Lambda, S3, CloudWatch Logs, CloudFormation, and many other services.", - "version": "3.56.0-SNAPSHOT", + "version": "3.59.0-SNAPSHOT", "extensionKind": [ "workspace" ], @@ -247,13 +247,17 @@ "type": "boolean", "default": false }, + "amazonqLSP": { + "type": "boolean", + "default": true + }, "amazonqLSPInline": { "type": "boolean", "default": false }, "amazonqChatLSP": { "type": "boolean", - "default": false + "default": true } }, "additionalProperties": false