diff --git a/buildspec/release/00clonerepo.yml b/buildspec/release/00clonerepo.yml deleted file mode 100644 index 3fbf222ce9a..00000000000 --- a/buildspec/release/00clonerepo.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: 0.2 - -env: - variables: - NODE_OPTIONS: '--max-old-space-size=8192' - -phases: - install: - runtime-versions: - nodejs: 16 - - pre_build: - commands: - # Check for implicit env vars passed from the release pipeline. - - test -n "${TOOLKITS_GITHUB_REPO_OWNER}" - - test -n "${TARGET_BRANCH}" - - build: - commands: - - git clone https://github.com/${TOOLKITS_GITHUB_REPO_OWNER}/aws-toolkit-vscode.git aws-toolkit-vscode - # checkout the target branch as we want to commit to it later to update versions - - cd aws-toolkit-vscode && git checkout ${TARGET_BRANCH} - -artifacts: - base-directory: aws-toolkit-vscode - files: - - '**/*' diff --git a/buildspec/release/10changeversion.yml b/buildspec/release/10changeversion.yml deleted file mode 100644 index 2a43a5f515f..00000000000 --- a/buildspec/release/10changeversion.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: 0.2 - -env: - variables: - NODE_OPTIONS: '--max-old-space-size=8192' - -phases: - pre_build: - commands: - - aws codeartifact login --tool npm --domain "$TOOLKITS_CODEARTIFACT_DOMAIN" --domain-owner "$TOOLKITS_ACCOUNT_ID" --repository "$TOOLKITS_CODEARTIFACT_REPO" - - test -n "${TARGET_EXTENSION}" - - install: - runtime-versions: - nodejs: 16 - - build: - commands: - - | - echo "TARGET_EXTENSION=${TARGET_EXTENSION}" - echo "Removing SNAPSHOT from version string" - git config --global user.name "aws-toolkit-automation" - git config --global user.email "<>" - VERSION=$(node -e "console.log(require('./packages/${TARGET_EXTENSION}/package.json').version);" | (IFS="-"; read -r version unused && echo "$version")) - DATE=$(date) - npm version --no-git-tag-version "$VERSION" -w packages/${TARGET_EXTENSION} - # 'createRelease' uses ts-node. - # Ignore broken "postinstall" script in "src.gen/@amzn/codewhisperer-streaming/package.json". - npm install --ignore-scripts ts-node - - | - npm run createRelease -w packages/${TARGET_EXTENSION} - - | - git add packages/${TARGET_EXTENSION}/package.json - git add package-lock.json - git commit -m "Release $VERSION" - echo "tagging commit" - # e.g. amazonq/v1.0.0. Ensure this tag is up to date with 50githubrelease.yml - git tag -a "${TARGET_EXTENSION}/v${VERSION}" -m "${TARGET_EXTENSION} version $VERSION $DATE" - # cleanup - git clean -fxd - git reset HEAD --hard - -artifacts: - files: - - '**/*' diff --git a/buildspec/release/20buildrelease.yml b/buildspec/release/20buildrelease.yml deleted file mode 100644 index 8af4ef5df4f..00000000000 --- a/buildspec/release/20buildrelease.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: 0.2 - -env: - variables: - NODE_OPTIONS: '--max-old-space-size=8192' - -phases: - pre_build: - commands: - - aws codeartifact login --tool npm --domain "$TOOLKITS_CODEARTIFACT_DOMAIN" --domain-owner "$TOOLKITS_ACCOUNT_ID" --repository "$TOOLKITS_CODEARTIFACT_REPO" - - test -n "${TARGET_EXTENSION}" - install: - runtime-versions: - nodejs: 16 - - commands: - - apt-get update - - apt-get install -y libgtk-3-dev libxss1 xvfb - - apt-get install -y libnss3-dev libasound2 - - apt-get install -y libasound2-plugins - build: - commands: - - echo "TARGET_EXTENSION=${TARGET_EXTENSION}" - # --unsafe-perm is needed because we run as root - - npm ci --unsafe-perm - - npm run package -w packages/${TARGET_EXTENSION} - - cp packages/${TARGET_EXTENSION}/package.json ./package.json - - NUM_VSIX=$(ls -1q *.vsix | wc -l) - - | - if [ "$NUM_VSIX" != "1" ]; then - echo "Number of .vsix to release is not exactly 1, it is: ${NUM_VSIX}" - exit 1 - fi - -artifacts: - files: - - '*.vsix' - - package.json diff --git a/buildspec/release/30closegate.yml b/buildspec/release/30closegate.yml deleted file mode 100644 index 618613e782f..00000000000 --- a/buildspec/release/30closegate.yml +++ /dev/null @@ -1,19 +0,0 @@ -version: 0.2 - -phases: - install: - runtime-versions: - nodejs: 16 - - pre_build: - commands: - - STAGE_NAME=Release - - PIPELINE=$(echo $CODEBUILD_INITIATOR | sed -e 's/codepipeline\///') - build: - commands: - - | - aws codepipeline disable-stage-transition \ - --pipeline-name "$PIPELINE" \ - --stage-name "$STAGE_NAME" \ - --transition-type "Inbound" \ - --reason "Disabled by CloseGate (automation)" diff --git a/buildspec/release/35opengate.yml b/buildspec/release/35opengate.yml deleted file mode 100644 index 45362ac14e3..00000000000 --- a/buildspec/release/35opengate.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: 0.2 - -phases: - install: - runtime-versions: - nodejs: 16 - - pre_build: - commands: - - STAGE_NAME=SourceWithGit - - PIPELINE=$(echo $CODEBUILD_INITIATOR | sed -e 's/codepipeline\///') - build: - commands: - - | - aws codepipeline enable-stage-transition \ - --pipeline-name "$PIPELINE" \ - --stage-name "$STAGE_NAME" \ - --transition-type "Inbound" diff --git a/buildspec/release/40pushtogithub.yml b/buildspec/release/40pushtogithub.yml deleted file mode 100644 index a31f34031a3..00000000000 --- a/buildspec/release/40pushtogithub.yml +++ /dev/null @@ -1,46 +0,0 @@ -version: 0.2 - -env: - variables: - NODE_OPTIONS: '--max-old-space-size=8192' - -phases: - install: - runtime-versions: - nodejs: 16 - - pre_build: - commands: - # Check for implicit env vars passed from the release pipeline. - - test -n "${TOOLKITS_GITHUB_REPO_OWNER}" - - test -n "${GITHUB_TOKEN}" - - test -n "${TARGET_EXTENSION}" - - test -n "${TARGET_BRANCH}" - - REPO_URL="https://$GITHUB_TOKEN@github.com/${TOOLKITS_GITHUB_REPO_OWNER}/aws-toolkit-vscode.git" - - build: - commands: - - | - echo "TARGET_EXTENSION=${TARGET_EXTENSION}" - git config --global user.name "aws-toolkit-automation" - git config --global user.email "<>" - git remote add originWithCreds "$REPO_URL" - echo "Adding SNAPSHOT to next version string" - # Increase minor version - npm version --no-git-tag-version minor -w packages/${TARGET_EXTENSION} - VERSION=$(node -e "console.log(require('./packages/${TARGET_EXTENSION}/package.json').version);") - # Append -SNAPSHOT - npm version --no-git-tag-version "${VERSION}-SNAPSHOT" -w packages/${TARGET_EXTENSION} - git add packages/${TARGET_EXTENSION}/package.json - git add package-lock.json - git commit -m "Update version to snapshot version: ${VERSION}-SNAPSHOT" - - | - if [ "$STAGE" != "prod" ]; then - echo "SKIPPED (stage=${STAGE}): 'git push originWithCreds ${TARGET_BRANCH}'" - exit 0 - fi - echo "pushing to github" - git fetch originWithCreds ${TARGET_BRANCH} - git merge --no-edit -m "Merge release into ${TARGET_BRANCH}" FETCH_HEAD - git push originWithCreds --tags - git push originWithCreds ${TARGET_BRANCH} diff --git a/buildspec/release/50githubrelease.yml b/buildspec/release/50githubrelease.yml deleted file mode 100644 index df542cbee14..00000000000 --- a/buildspec/release/50githubrelease.yml +++ /dev/null @@ -1,48 +0,0 @@ -version: 0.2 - -phases: - install: - runtime-versions: - nodejs: 16 - - Commands: - # GitHub recently changed their GPG signing key for their CLI tool - # These are the updated installation instructions: - # https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt - - curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg - - chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg - - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null - - apt update - - apt install gh -y - - pre_build: - commands: - # Check for implicit env vars passed from the release pipeline. - - test -n "${TOOLKITS_GITHUB_REPO_OWNER}" - - test -n "${TARGET_EXTENSION}" - - REPO="${TOOLKITS_GITHUB_REPO_OWNER}/aws-toolkit-vscode" - - build: - commands: - - echo "TARGET_EXTENSION=${TARGET_EXTENSION}" - # pull in the build artifacts - - cp -r ${CODEBUILD_SRC_DIR_buildPipeline}/* . - - VERSION=$(node -e "console.log(require('./packages/${TARGET_EXTENSION}/package.json').version);") - - UPLOAD_TARGET=$(ls *.vsix) - - HASH_UPLOAD_TARGET=${UPLOAD_TARGET}.sha384 - - 'HASH=$(sha384sum -b $UPLOAD_TARGET | cut -d" " -f1)' - - echo "Writing hash to $HASH_UPLOAD_TARGET" - - echo $HASH > $HASH_UPLOAD_TARGET - - echo "posting $VERSION with sha384 hash $HASH to GitHub" - - PKG_DISPLAY_NAME=$(grep -m 1 displayName packages/${TARGET_EXTENSION}/package.json | grep -o '[a-zA-z][^\"]\+' | tail -n1) - - RELEASE_MESSAGE="${PKG_DISPLAY_NAME} for VS Code $VERSION" - # Only set amazonq as "latest" release. This ensures https://api.github.com/repos/aws/aws-toolkit-vscode/releases/latest - # consistently points to the amazonq artifact, instead of being "random". - - LATEST="$([ "$TARGET_EXTENSION" = amazonq ] && echo '--latest' || echo '--latest=false' )" - - | - if [ "$STAGE" = "prod" ]; then - # note: the tag arg passed here should match what is in 10changeversion.yml - gh release create "$LATEST" --repo $REPO --title "$PKG_DISPLAY_NAME $VERSION" --notes "$RELEASE_MESSAGE" -- "${TARGET_EXTENSION}/v${VERSION}" "$UPLOAD_TARGET" "$HASH_UPLOAD_TARGET" - else - echo "SKIPPED (stage=${STAGE}): 'gh release create --repo $REPO'" - fi diff --git a/buildspec/release/60publish.yml b/buildspec/release/60publish.yml deleted file mode 100644 index 0141b6e68c2..00000000000 --- a/buildspec/release/60publish.yml +++ /dev/null @@ -1,41 +0,0 @@ -# -# Publishes the release vsix to the marketplace. -# - -version: 0.2 - -phases: - install: - runtime-versions: - nodejs: 20 - commands: - - apt-get update - - apt-get install -y libsecret-1-dev - - pre_build: - commands: - # Check for implicit env vars passed from the release pipeline. - - test -n "${VS_MARKETPLACE_PAT}" - - test -n "${TARGET_EXTENSION}" - - build: - commands: - - echo "TARGET_EXTENSION=${TARGET_EXTENSION}" - # pull in the build artifacts - - cp -r ${CODEBUILD_SRC_DIR_buildPipeline}/* . - - | - UPLOAD_TARGET=$(ls *.vsix) - - | - echo "Publishing to vscode marketplace: $UPLOAD_TARGET" - if [ "$STAGE" != "prod" ]; then - echo "SKIPPED (stage=${STAGE}): 'npx vsce publish --pat xxx --packagePath ${UPLOAD_TARGET}'" - else - npx vsce publish --pat "$VS_MARKETPLACE_PAT" --packagePath "$UPLOAD_TARGET" - fi - - | - echo "Publishing to openvsx marketplace: $UPLOAD_TARGET" - if [ "$STAGE" != "prod" ]; then - echo "SKIPPED (stage=${STAGE}): 'npx --yes ovsx publish --pat xxx "${UPLOAD_TARGET}"'" - else - npx --yes ovsx publish --pat "$OVSX_PAT" "$UPLOAD_TARGET" - fi diff --git a/buildspec/release/70checkmarketplace.yml b/buildspec/release/70checkmarketplace.yml deleted file mode 100644 index 670dd2c7508..00000000000 --- a/buildspec/release/70checkmarketplace.yml +++ /dev/null @@ -1,53 +0,0 @@ -version: 0.2 - -phases: - install: - runtime-versions: - nodejs: 16 - - commands: - - apt update - - apt install -y wget gpg - - curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg - - install -o root -g root -m 644 packages.microsoft.gpg /etc/apt/trusted.gpg.d/ - - sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list' - - apt update - - apt install -y code - - pre_build: - commands: - # Check for implicit env vars passed from the release pipeline. - - test -n "${TARGET_EXTENSION}" - - build: - commands: - - VERSION=$(node -e "console.log(require('./packages/${TARGET_EXTENSION}/package.json').version);") - # get extension name, if in beta, use some hard-coded recent version - - | - if [ "${TARGET_EXTENSION}" = "amazonq" ]; then - extension_name="amazonwebservices.amazon-q-vscode" - [ "$STAGE" != "prod" ] && VERSION="1.43.0" || true - elif [ "${TARGET_EXTENSION}" = "toolkit" ]; then - extension_name="amazonwebservices.aws-toolkit-vscode" - [ "$STAGE" != "prod" ] && VERSION="3.42.0" || true - else - echo checkmarketplace: "Unknown TARGET_EXTENSION: ${TARGET_EXTENSION}" - exit 1 - fi - if [ "$STAGE" != "prod" ]; then - echo "checkmarketplace: Non-production stage detected. Installing hardcoded version '${VERSION}'." - fi - # keep installing the desired extension version until successful. Otherwise fail on codebuild timeout (1 hour). - - | - while true; do - code --uninstall-extension "${extension_name}" --no-sandbox --user-data-dir /tmp/vscode - code --install-extension "${extension_name}@${VERSION}" --no-sandbox --user-data-dir /tmp/vscode || true - cur_version=$(code --list-extensions --show-versions --no-sandbox --user-data-dir /tmp/vscode | grep ${extension_name} | cut -d'@' -f2) - if [ "${cur_version}" = "${VERSION}" ]; then - echo "checkmarketplace: Extension ${extension_name} is updated to version '${cur_version}.'" - break - else - echo "checkmarketplace: Expected extension version '${VERSION}' has not been successfully installed. Retrying..." - fi - sleep 120 # Wait for 2 minutes before retrying - done diff --git a/buildspec/release/80notify.yml b/buildspec/release/80notify.yml deleted file mode 100644 index 062895d09d0..00000000000 --- a/buildspec/release/80notify.yml +++ /dev/null @@ -1,28 +0,0 @@ -version: 0.2 - -phases: - install: - runtime-versions: - nodejs: 20 - - pre_build: - commands: - # Check for implicit env vars passed from the release pipeline. - - test -n "${NOTIFY_URL}" - - test -n "${TARGET_EXTENSION}" - - build: - commands: - - echo "TARGET_EXTENSION=${TARGET_EXTENSION}" - - export EXTENSION_NAME=$([ "$TARGET_EXTENSION" = "amazonq" ] && echo "Amazon Q" || echo "AWS Toolkit") - - export VERSION=$(node -e "console.log(require('./packages/${TARGET_EXTENSION}/package.json').version);") - - export CHANGELOG=$(cat packages/${TARGET_EXTENSION}/CHANGELOG.md | perl -ne 'BEGIN{$/="\n\n"} print if $. == 2') - - MESSAGE=$(envsubst < ./buildspec/release/notify.txt | jq -R -s '.') - - echo "Will post message - \n\n${MESSAGE}\n" - - echo "Full command - 'curl -v POST \"[NOTIFY_URL]\" -H \"Content-Type:application/json\" --data \"{\"Content\":${MESSAGE}}\"'" - - | - if [ "$STAGE" != "prod" ]; then - echo "SKIPPED (stage=${STAGE}): curl -v POST ..." - exit 0 - fi - curl -v POST "${NOTIFY_URL}" -H "Content-Type:application/json" --data "{\"Content\":${MESSAGE}}" diff --git a/buildspec/release/notify.txt b/buildspec/release/notify.txt deleted file mode 100644 index 919ee5f4be0..00000000000 --- a/buildspec/release/notify.txt +++ /dev/null @@ -1,6 +0,0 @@ -Released ${EXTENSION_NAME} v${VERSION} for VS Code - -${CHANGELOG} - -Changelog: https://github.com/aws/aws-toolkit-vscode/blob/master/packages/${TARGET_EXTENSION}/CHANGELOG.md -Release Artifact: https://github.com/aws/aws-toolkit-vscode/releases/tag/${TARGET_EXTENSION}/v${VERSION} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a40e6ab97f6..ecba925a88e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "plugins/*" ], "dependencies": { + "@aws/language-server-runtimes": "^0.2.125", "@types/node": "^22.7.5", "jaro-winkler": "^0.2.8", "vscode-nls": "^5.2.0", @@ -46,7 +47,7 @@ "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", "pretty-quick": "^4.0.0", - "ts-node": "^10.9.1", + "ts-node": "^10.9.2", "typescript": "^5.0.4", "webpack": "^5.95.0", "webpack-cli": "^5.1.4", @@ -15044,13 +15045,12 @@ } }, "node_modules/@aws/language-server-runtimes": { - "version": "0.2.119", - "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes/-/language-server-runtimes-0.2.119.tgz", - "integrity": "sha512-zHonaOBuZ9K81/EQ1hg6ieu45YK7J5M6kiFD/dpdwJwsU36Ia4rbnN2W5ZIDPryZ9Hx9WYpw72YBl+q8+6BdGQ==", - "dev": true, + "version": "0.2.125", + "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes/-/language-server-runtimes-0.2.125.tgz", + "integrity": "sha512-tjXJEagZ6rm09fcgJGu1zbFNzi0+7R1mdNFa6zCIv68c76xq5JHjc++Hne9aOgp61O6BM9uNnX3KR57v9/0E1g==", "license": "Apache-2.0", "dependencies": { - "@aws/language-server-runtimes-types": "^0.1.51", + "@aws/language-server-runtimes-types": "^0.1.56", "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.200.0", "@opentelemetry/core": "^2.0.0", @@ -15065,7 +15065,7 @@ "hpagent": "^1.2.0", "jose": "^5.9.6", "mac-ca": "^3.1.1", - "os-proxy-config": "^1.1.2", + "registry-js": "^1.16.1", "rxjs": "^7.8.2", "vscode-languageserver": "^9.0.1", "vscode-languageserver-protocol": "^3.17.5", @@ -15077,10 +15077,9 @@ } }, "node_modules/@aws/language-server-runtimes-types": { - "version": "0.1.51", - "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes-types/-/language-server-runtimes-types-0.1.51.tgz", - "integrity": "sha512-TuCA821MSRCpO/1thhHaBRpKzU/CiHM/Bvd6quJRUKwvSb8/gTG1mSBp2YoHYx4p7FUZYBko2DKDmpaB1WfvUw==", - "dev": true, + "version": "0.1.56", + "resolved": "https://registry.npmjs.org/@aws/language-server-runtimes-types/-/language-server-runtimes-types-0.1.56.tgz", + "integrity": "sha512-Md/L750JShCHUsCQUJva51Ofkn/GDBEX8PpZnWUIVqkpddDR00SLQS2smNf4UHtKNJ2fefsfks/Kqfuatjkjvg==", "license": "Apache-2.0", "dependencies": { "vscode-languageserver-textdocument": "^1.0.12", @@ -15091,7 +15090,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", - "dev": true, "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, @@ -15106,7 +15104,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", - "dev": true, "dependencies": { "@opentelemetry/core": "2.0.1", "@opentelemetry/semantic-conventions": "^1.29.0" @@ -15122,7 +15119,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.0.1.tgz", "integrity": "sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==", - "dev": true, "dependencies": { "@opentelemetry/core": "2.0.1", "@opentelemetry/resources": "2.0.1" @@ -15138,7 +15134,6 @@ "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==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -15152,7 +15147,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz", "integrity": "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.2", @@ -15169,7 +15163,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.0.tgz", "integrity": "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -15183,7 +15176,6 @@ "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==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.2.0", @@ -15198,7 +15190,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.2.0.tgz", "integrity": "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -15211,7 +15202,6 @@ "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": { "tslib": "^2.6.2" @@ -15222,7 +15212,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/ajv": { "version": "8.17.1", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -15237,7 +15226,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/jose": { "version": "5.10.0", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -15245,12 +15233,10 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/@aws/language-server-runtimes/node_modules/vscode-jsonrpc": { "version": "8.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=14.0.0" @@ -15258,7 +15244,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/vscode-languageserver": { "version": "9.0.1", - "dev": true, "license": "MIT", "dependencies": { "vscode-languageserver-protocol": "3.17.5" @@ -15269,7 +15254,6 @@ }, "node_modules/@aws/language-server-runtimes/node_modules/vscode-languageserver-protocol": { "version": "3.17.5", - "dev": true, "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", @@ -15279,8 +15263,7 @@ "node_modules/@aws/language-server-runtimes/node_modules/vscode-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", - "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", - "dev": true + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==" }, "node_modules/@aws/mynah-ui": { "version": "4.35.4", @@ -15860,7 +15843,6 @@ "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": { "node": ">=8.0.0" @@ -15870,7 +15852,6 @@ "version": "0.200.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.200.0.tgz", "integrity": "sha512-IKJBQxh91qJ+3ssRly5hYEJ8NDHu9oY/B1PXVSCWf7zytmYO9RNLB0Ox9XQ/fJ8m6gY6Q6NtBWlmXfaXt5Uc4Q==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -15883,7 +15864,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.0.tgz", "integrity": "sha512-SLX36allrcnVaPYG3R78F/UZZsBsvbc7lMCLx37LyH5MJ1KAAZ2E3mW9OAD3zGz0G8q/BtoS5VUrjzDydhD6LQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -15899,7 +15879,6 @@ "version": "0.200.0", "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.200.0.tgz", "integrity": "sha512-KfWw49htbGGp9s8N4KI8EQ9XuqKJ0VG+yVYVYFiCYSjEV32qpQ5qZ9UZBzOZ6xRb+E16SXOSCT3RkqBVSABZ+g==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.200.0", @@ -15919,7 +15898,6 @@ "version": "0.200.0", "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.200.0.tgz", "integrity": "sha512-5BiR6i8yHc9+qW7F6LqkuUnIzVNA7lt0qRxIKcKT+gq3eGUPHZ3DY29sfxI3tkvnwMgtnHDMNze5DdxW39HsAw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.0.0", @@ -15939,7 +15917,6 @@ "version": "0.200.0", "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.200.0.tgz", "integrity": "sha512-IxJgA3FD7q4V6gGq4bnmQM5nTIyMDkoGFGrBrrDjB6onEiq1pafma55V+bHvGYLWvcqbBbRfezr1GED88lacEQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.0.0", @@ -15956,7 +15933,6 @@ "version": "0.200.0", "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.200.0.tgz", "integrity": "sha512-+9YDZbYybOnv7sWzebWOeK6gKyt2XE7iarSyBFkwwnP559pEevKOUD8NyDHhRjCSp13ybh9iVXlMfcj/DwF/yw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.200.0", @@ -15978,7 +15954,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.0.tgz", "integrity": "sha512-rnZr6dML2z4IARI4zPGQV4arDikF/9OXZQzrC01dLmn0CZxU5U5OLd/m1T7YkGRj5UitjeoCtg/zorlgMQcdTg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.0.0", @@ -15995,7 +15970,6 @@ "version": "0.200.0", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.200.0.tgz", "integrity": "sha512-VZG870063NLfObmQQNtCVcdXXLzI3vOjjrRENmU37HYiPFa0ZXpXVDsTD02Nh3AT3xYJzQaWKl2X2lQ2l7TWJA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.200.0", @@ -16013,7 +15987,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.0.tgz", "integrity": "sha512-SLX36allrcnVaPYG3R78F/UZZsBsvbc7lMCLx37LyH5MJ1KAAZ2E3mW9OAD3zGz0G8q/BtoS5VUrjzDydhD6LQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -16029,7 +16002,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.0.tgz", "integrity": "sha512-rnZr6dML2z4IARI4zPGQV4arDikF/9OXZQzrC01dLmn0CZxU5U5OLd/m1T7YkGRj5UitjeoCtg/zorlgMQcdTg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.0.0", @@ -16046,7 +16018,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.0.0.tgz", "integrity": "sha512-Bvy8QDjO05umd0+j+gDeWcTaVa1/R2lDj/eOvjzpm8VQj1K1vVZJuyjThpV5/lSHyYW2JaHF2IQ7Z8twJFAhjA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.0.0", @@ -16063,7 +16034,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.0.tgz", "integrity": "sha512-qQnYdX+ZCkonM7tA5iU4fSRsVxbFGml8jbxOgipRGMFHKaXKHQ30js03rTobYjKjIfnOsZSbHKWF0/0v0OQGfw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.0.0", @@ -16081,7 +16051,6 @@ "version": "1.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.33.0.tgz", "integrity": "sha512-TIpZvE8fiEILFfTlfPnltpBaD3d9/+uQHVCyC3vfdh6WfCXKhNFzoP5RyDDIndfvZC5GrA4pyEDNyjPloJud+w==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=14" @@ -18872,14 +18841,14 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "license": "ISC" }, "node_modules/are-we-there-yet": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "deprecated": "This package is no longer supported.", - "dev": true, + "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -18889,7 +18858,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -18904,13 +18873,13 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "license": "MIT" }, "node_modules/are-we-there-yet/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -19266,7 +19235,6 @@ }, "node_modules/bl": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -19276,7 +19244,6 @@ }, "node_modules/bl/node_modules/buffer": { "version": "5.7.1", - "dev": true, "funding": [ { "type": "github", @@ -19823,7 +19790,6 @@ }, "node_modules/chownr": { "version": "1.1.4", - "dev": true, "license": "ISC" }, "node_modules/chrome-trace-event": { @@ -20019,7 +19985,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -20174,7 +20140,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true + "license": "ISC" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -20604,7 +20570,6 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -20686,7 +20651,6 @@ }, "node_modules/delegates": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/depd": { @@ -21679,7 +21643,6 @@ }, "node_modules/expand-template": { "version": "2.0.3", - "dev": true, "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" @@ -21848,7 +21811,6 @@ }, "node_modules/fast-uri": { "version": "3.0.6", - "dev": true, "funding": [ { "type": "github", @@ -22150,7 +22112,6 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/fs-extra": { @@ -22222,7 +22183,7 @@ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", "deprecated": "This package is no longer supported.", - "dev": true, + "license": "ISC", "dependencies": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -22238,7 +22199,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -22247,7 +22208,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, + "license": "MIT", "dependencies": { "number-is-nan": "^1.0.0" }, @@ -22259,7 +22220,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, + "license": "MIT", "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -22273,7 +22234,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -22350,7 +22311,6 @@ }, "node_modules/github-from-package": { "version": "0.0.0", - "dev": true, "license": "MIT" }, "node_modules/glob": { @@ -22597,7 +22557,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true + "license": "ISC" }, "node_modules/hash-base": { "version": "3.1.0", @@ -22709,7 +22669,6 @@ }, "node_modules/hpagent": { "version": "1.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=14" @@ -23059,7 +23018,6 @@ }, "node_modules/ini": { "version": "1.3.8", - "dev": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -23242,7 +23200,6 @@ }, "node_modules/is-electron": { "version": "2.2.2", - "dev": true, "license": "MIT" }, "node_modules/is-extglob": { @@ -24274,19 +24231,12 @@ }, "node_modules/mac-ca": { "version": "3.1.1", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "node-forge": "^1.3.1", "undici": "^6.16.1" } }, - "node_modules/mac-system-proxy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mac-system-proxy/-/mac-system-proxy-1.0.4.tgz", - "integrity": "sha512-IAkNLxXZrYuM99A2OhPrvUoAxohsxQciJh2D2xnD+R6vypn/AVyOYLsbZsMVCS/fEbLIe67nQ8krEAfqP12BVg==", - "dev": true - }, "node_modules/magic-string": { "version": "0.30.0", "license": "MIT", @@ -24652,7 +24602,6 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "dev": true, "license": "MIT" }, "node_modules/mocha": { @@ -24963,7 +24912,6 @@ }, "node_modules/napi-build-utils": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/natural-compare": { @@ -25063,7 +25011,6 @@ }, "node_modules/node-forge": { "version": "1.3.1", - "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -25078,7 +25025,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", "integrity": "sha512-6kM8CLXvuW5crTxsAtva2YLrRrDaiTIkIePWs9moLHqbFWT94WpNFjwS/5dfLfECg5i/lkmw3aoqVidxt23TEQ==", - "dev": true + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "3.0.3", @@ -25128,7 +25075,7 @@ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "deprecated": "This package is no longer supported.", - "dev": true, + "license": "ISC", "dependencies": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -25151,7 +25098,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -25195,7 +25142,6 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -25341,16 +25287,6 @@ "version": "0.3.0", "license": "MIT" }, - "node_modules/os-proxy-config": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/os-proxy-config/-/os-proxy-config-1.1.2.tgz", - "integrity": "sha512-sV7htE8y6NQORU0oKOUGTwQYe1gSFK3a3Z1i4h6YaqdrA9C0JIsUPQAqEkO8ejjYbRrQ+jsnks5qjtisr7042Q==", - "dev": true, - "dependencies": { - "mac-system-proxy": "^1.0.0", - "windows-system-proxy": "^1.0.0" - } - }, "node_modules/p-cancelable": { "version": "2.1.1", "license": "MIT", @@ -25642,7 +25578,6 @@ }, "node_modules/pify": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -26219,7 +26154,6 @@ }, "node_modules/rc": { "version": "1.2.8", - "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -26233,7 +26167,6 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -26483,8 +26416,8 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/registry-js/-/registry-js-1.16.1.tgz", "integrity": "sha512-pQ2kD36lh+YNtpaXm6HCCb0QZtV/zQEeKnkfEIj5FDSpF/oFts7pwizEUkWSvP8IbGb4A4a5iBhhS9eUearMmQ==", - "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "node-addon-api": "^3.2.1", "prebuild-install": "^5.3.5" @@ -26494,7 +26427,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dev": true, + "license": "MIT", "dependencies": { "mimic-response": "^2.0.0" }, @@ -26506,7 +26439,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, + "license": "Apache-2.0", "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -26518,7 +26451,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -26530,7 +26463,7 @@ "version": "2.30.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", - "dev": true, + "license": "MIT", "dependencies": { "semver": "^5.4.1" } @@ -26539,13 +26472,13 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true + "license": "MIT" }, "node_modules/registry-js/node_modules/prebuild-install": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", - "dev": true, + "license": "MIT", "dependencies": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", @@ -26574,7 +26507,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -26583,7 +26516,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", - "dev": true, + "license": "MIT", "dependencies": { "decompress-response": "^4.2.0", "once": "^1.3.1", @@ -26684,7 +26617,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -26881,7 +26813,6 @@ }, "node_modules/rxjs": { "version": "7.8.2", - "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -27193,7 +27124,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "license": "ISC" }, "node_modules/set-function-length": { "version": "1.2.2", @@ -27299,12 +27230,10 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "dev": true, "license": "ISC" }, "node_modules/simple-concat": { "version": "1.0.1", - "dev": true, "funding": [ { "type": "github", @@ -27878,7 +27807,6 @@ }, "node_modules/tar-fs": { "version": "2.1.1", - "dev": true, "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -27889,7 +27817,6 @@ }, "node_modules/tar-stream": { "version": "2.2.0", - "dev": true, "license": "MIT", "dependencies": { "bl": "^4.0.3", @@ -28325,7 +28252,6 @@ }, "node_modules/tunnel-agent": { "version": "0.6.0", - "dev": true, "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -28458,7 +28384,6 @@ }, "node_modules/undici": { "version": "6.21.2", - "dev": true, "license": "MIT", "engines": { "node": ">=18.17" @@ -29433,7 +29358,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -29460,7 +29385,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, + "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -29472,7 +29397,6 @@ }, "node_modules/win-ca": { "version": "3.5.1", - "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -29484,7 +29408,6 @@ }, "node_modules/win-ca/node_modules/make-dir": { "version": "1.3.0", - "dev": true, "license": "MIT", "dependencies": { "pify": "^3.0.0" @@ -29493,15 +29416,6 @@ "node": ">=4" } }, - "node_modules/windows-system-proxy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/windows-system-proxy/-/windows-system-proxy-1.0.0.tgz", - "integrity": "sha512-qd1WfyX9gjAqI36RHt95di2+FBr74DhvELd1EASgklCGScjwReHnWnXfUyabp/CJWl/IdnkUzG0Ub6Cv2R4KJQ==", - "dev": true, - "dependencies": { - "registry-js": "^1.15.1" - } - }, "node_modules/winston": { "version": "3.11.0", "license": "MIT", @@ -29954,7 +29868,7 @@ }, "packages/amazonq": { "name": "amazon-q-vscode", - "version": "1.90.0-SNAPSHOT", + "version": "1.91.0-SNAPSHOT", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" diff --git a/package.json b/package.json index b84e4b8c361..3769279de1c 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "webpack-merge": "^5.10.0" }, "dependencies": { + "@aws/language-server-runtimes": "^0.2.125", "@types/node": "^22.7.5", "jaro-winkler": "^0.2.8", "vscode-nls": "^5.2.0", diff --git a/packages/amazonq/.changes/1.90.0.json b/packages/amazonq/.changes/1.90.0.json new file mode 100644 index 00000000000..547528bce40 --- /dev/null +++ b/packages/amazonq/.changes/1.90.0.json @@ -0,0 +1,5 @@ +{ + "date": "2025-08-15", + "version": "1.90.0", + "entries": [] +} \ No newline at end of file diff --git a/packages/amazonq/.changes/next-release/Bug Fix-f80b74d6-d598-4d64-ae80-a7da47fecc32.json b/packages/amazonq/.changes/next-release/Bug Fix-f80b74d6-d598-4d64-ae80-a7da47fecc32.json new file mode 100644 index 00000000000..c7c24d88764 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-f80b74d6-d598-4d64-ae80-a7da47fecc32.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Enable inline completion in Jupyter Notebook" +} diff --git a/packages/amazonq/CHANGELOG.md b/packages/amazonq/CHANGELOG.md index 605eec8efe5..afc834c4037 100644 --- a/packages/amazonq/CHANGELOG.md +++ b/packages/amazonq/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.90.0 2025-08-15 + +- Miscellaneous non-user-facing changes + ## 1.89.0 2025-08-13 - Miscellaneous non-user-facing changes diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index 0ec2102a4c9..73d6b8c06b0 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 software development.", - "version": "1.90.0-SNAPSHOT", + "version": "1.91.0-SNAPSHOT", "extensionKind": [ "workspace" ], diff --git a/packages/amazonq/src/app/inline/activation.ts b/packages/amazonq/src/app/inline/activation.ts index 867ae95d9b5..13f451d5716 100644 --- a/packages/amazonq/src/app/inline/activation.ts +++ b/packages/amazonq/src/app/inline/activation.ts @@ -9,7 +9,6 @@ import { CodeWhispererConstants, isInlineCompletionEnabled, runtimeLanguageContext, - TelemetryHelper, UserWrittenCodeTracker, vsCodeState, } from 'aws-core-vscode/codewhisperer' @@ -52,11 +51,6 @@ export async function activate() { return } - if (vsCodeState.lastUserModificationTime) { - TelemetryHelper.instance.setTimeSinceLastModification( - performance.now() - vsCodeState.lastUserModificationTime - ) - } vsCodeState.lastUserModificationTime = performance.now() /** * Important: Doing this sleep(10) is to make sure diff --git a/packages/amazonq/src/app/inline/notebookUtil.ts b/packages/amazonq/src/app/inline/notebookUtil.ts new file mode 100644 index 00000000000..928de1aad33 --- /dev/null +++ b/packages/amazonq/src/app/inline/notebookUtil.ts @@ -0,0 +1,98 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode' + +import { CodeWhispererConstants, runtimeLanguageContext } from 'aws-core-vscode/codewhisperer' +import { InlineCompletionWithReferencesParams } from '@aws/language-server-runtimes/server-interface' + +function getEnclosingNotebook(document: vscode.TextDocument): vscode.NotebookDocument | undefined { + // For notebook cells, find the existing notebook with a cell that matches the current document. + return vscode.workspace.notebookDocuments.find( + (nb) => nb.notebookType === 'jupyter-notebook' && nb.getCells().some((cell) => cell.document === document) + ) +} + +export function getNotebookContext( + notebook: vscode.NotebookDocument, + document: vscode.TextDocument, + position: vscode.Position +) { + // Expand the context for a cell inside of a noteboo with whatever text fits from the preceding and subsequent cells + const allCells = notebook.getCells() + const cellIndex = allCells.findIndex((cell) => cell.document === document) + let caretLeftFileContext = '' + let caretRightFileContext = '' + + if (cellIndex >= 0 && cellIndex < allCells.length) { + // Add content from previous cells + for (let i = 0; i < cellIndex; i++) { + caretLeftFileContext += convertCellContent(allCells[i]) + '\n' + } + + // Add content from current cell up to cursor + caretLeftFileContext += allCells[cellIndex].document.getText( + new vscode.Range(new vscode.Position(0, 0), position) + ) + + // Add content from cursor to end of current cell + caretRightFileContext = allCells[cellIndex].document.getText( + new vscode.Range( + position, + allCells[cellIndex].document.positionAt(allCells[cellIndex].document.getText().length) + ) + ) + + // Add content from following cells + for (let i = cellIndex + 1; i < allCells.length; i++) { + caretRightFileContext += '\n' + convertCellContent(allCells[i]) + } + } + caretLeftFileContext = caretLeftFileContext.slice(-CodeWhispererConstants.charactersLimit) + caretRightFileContext = caretRightFileContext.slice(0, CodeWhispererConstants.charactersLimit) + return { caretLeftFileContext, caretRightFileContext } +} + +// Convert the markup cells into code with comments +export function convertCellContent(cell: vscode.NotebookCell) { + const cellText = cell.document.getText() + if (cell.kind === vscode.NotebookCellKind.Markup) { + const commentPrefix = runtimeLanguageContext.getSingleLineCommentPrefix( + runtimeLanguageContext.normalizeLanguage(cell.document.languageId) ?? cell.document.languageId + ) + if (commentPrefix === '') { + return cellText + } + return cell.document + .getText() + .split('\n') + .map((line) => `${commentPrefix}${line}`) + .join('\n') + } + return cellText +} + +export function extractFileContextInNotebooks( + document: vscode.TextDocument, + position: vscode.Position +): InlineCompletionWithReferencesParams['fileContextOverride'] | undefined { + let caretLeftFileContext = '' + let caretRightFileContext = '' + const languageName = runtimeLanguageContext.normalizeLanguage(document.languageId) ?? document.languageId + if (document.uri.scheme === 'vscode-notebook-cell') { + const notebook = getEnclosingNotebook(document) + if (notebook) { + ;({ caretLeftFileContext, caretRightFileContext } = getNotebookContext(notebook, document, position)) + return { + leftFileContent: caretLeftFileContext, + rightFileContent: caretRightFileContext, + filename: document.fileName, + fileUri: document.uri.toString(), + programmingLanguage: languageName, + } + } + } + return undefined +} diff --git a/packages/amazonq/src/app/inline/recommendationService.ts b/packages/amazonq/src/app/inline/recommendationService.ts index 55c08c820fe..5f93fdff187 100644 --- a/packages/amazonq/src/app/inline/recommendationService.ts +++ b/packages/amazonq/src/app/inline/recommendationService.ts @@ -25,6 +25,7 @@ import { DocumentEventListener } from './documentEventListener' import { getOpenFilesInWindow } from 'aws-core-vscode/utils' import { asyncCallWithTimeout } from '../../util/timeoutUtil' import { EditSuggestionState } from './editSuggestionState' +import { extractFileContextInNotebooks } from './notebookUtil' export interface GetAllRecommendationsOptions { emitTelemetry?: boolean @@ -97,6 +98,9 @@ export class RecommendationService { if (options.editsStreakToken) { request = { ...request, partialResultToken: options.editsStreakToken } } + if (document.uri.scheme === 'vscode-notebook-cell') { + request.fileContextOverride = extractFileContextInNotebooks(document, position) + } const requestStartTime = performance.now() const statusBar = CodeWhispererStatusBarManager.instance diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index bc065c8f620..679c4251c57 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import vscode, { version } from 'vscode' +import vscode from 'vscode' import * as nls from 'vscode-nls' import { LanguageClient, LanguageClientOptions, RequestType, State } from 'vscode-languageclient' import { InlineCompletionManager } from '../app/inline/completion' @@ -165,7 +165,7 @@ export async function startLanguageServer( aws: { clientInfo: { name: getClientName(), - version: version, + version: extensionVersion, extension: { name: 'AmazonQ-For-VSCode', version: extensionVersion, diff --git a/packages/amazonq/test/unit/app/inline/notebookUtil.test.ts b/packages/amazonq/test/unit/app/inline/notebookUtil.test.ts new file mode 100644 index 00000000000..697c88ef6ec --- /dev/null +++ b/packages/amazonq/test/unit/app/inline/notebookUtil.test.ts @@ -0,0 +1,87 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode' +import * as assert from 'assert' +import { createMockDocument } from 'aws-core-vscode/test' +import { convertCellContent, getNotebookContext } from '../../../../src/app/inline/notebookUtil' +import { CodeWhispererConstants } from 'aws-core-vscode/codewhisperer' + +export function createNotebookCell( + document: vscode.TextDocument = createMockDocument('def example():\n return "test"'), + kind: vscode.NotebookCellKind = vscode.NotebookCellKind.Code, + notebook: vscode.NotebookDocument = {} as any, + index: number = 0, + outputs: vscode.NotebookCellOutput[] = [], + metadata: { readonly [key: string]: any } = {}, + executionSummary?: vscode.NotebookCellExecutionSummary +): vscode.NotebookCell { + return { + document, + kind, + notebook, + index, + outputs, + metadata, + executionSummary, + } +} + +describe('Notebook Util', function () { + describe('convertCellContent', function () { + it('should return code cell content as-is', function () { + const codeCell = createNotebookCell( + createMockDocument('def example():\n return "test"'), + vscode.NotebookCellKind.Code + ) + const result = convertCellContent(codeCell) + assert.strictEqual(result, 'def example():\n return "test"') + }) + + it('should convert markdown cell content to comments for Python', function () { + const markdownCell = createNotebookCell( + createMockDocument('# Heading\nSome text'), + vscode.NotebookCellKind.Markup + ) + const result = convertCellContent(markdownCell) + assert.strictEqual(result, '# # Heading\n# Some text') + }) + }) + + describe('getNotebookContext', function () { + it('should combine context from multiple cells', function () { + const currentDoc = createMockDocument('cell2 content', 'b.ipynb') + const notebook = { + getCells: () => [ + createNotebookCell(createMockDocument('cell1 content', 'a.ipynb'), vscode.NotebookCellKind.Code), + createNotebookCell(currentDoc, vscode.NotebookCellKind.Code), + createNotebookCell(createMockDocument('cell3 content', 'c.ipynb'), vscode.NotebookCellKind.Code), + ], + } as vscode.NotebookDocument + + const position = new vscode.Position(0, 5) + + const { caretLeftFileContext, caretRightFileContext } = getNotebookContext(notebook, currentDoc, position) + + assert.strictEqual(caretLeftFileContext, 'cell1 content\ncell2') + assert.strictEqual(caretRightFileContext, ' content\ncell3 content') + }) + + it('should respect character limits', function () { + const longContent = 'a'.repeat(10000) + const notebook = { + getCells: () => [createNotebookCell(createMockDocument(longContent), vscode.NotebookCellKind.Code)], + } as vscode.NotebookDocument + + const currentDoc = createMockDocument(longContent) + const position = new vscode.Position(0, 5000) + + const { caretLeftFileContext, caretRightFileContext } = getNotebookContext(notebook, currentDoc, position) + + assert.ok(caretLeftFileContext.length <= CodeWhispererConstants.charactersLimit) + assert.ok(caretRightFileContext.length <= CodeWhispererConstants.charactersLimit) + }) + }) +}) diff --git a/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts b/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts index 9293f637935..b5d233060df 100644 --- a/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/util/telemetryHelper.test.ts @@ -4,40 +4,9 @@ */ import assert from 'assert' -import { assertTelemetryCurried, resetCodeWhispererGlobalVariables } from 'aws-core-vscode/test' -import { TelemetryHelper, Completion, session } from 'aws-core-vscode/codewhisperer' -import { - CodewhispererCompletionType, - CodewhispererSuggestionState, - CodewhispererUserDecision, -} from 'aws-core-vscode/shared' +import { TelemetryHelper, session } from 'aws-core-vscode/codewhisperer' import sinon from 'sinon' -// TODO: improve and move the following test utils to codewhisperer/testUtils.ts -function aUserDecision( - completionType: CodewhispererCompletionType, - codewhispererSuggestionIndex: number, - codewhispererSuggestionState: CodewhispererSuggestionState -): CodewhispererUserDecision { - return { - codewhispererCompletionType: completionType, - codewhispererLanguage: 'python', - codewhispererRequestId: 'aFakeRequestId', - codewhispererSessionId: 'aFakeSessionId', - codewhispererSuggestionIndex: codewhispererSuggestionIndex, - codewhispererSuggestionReferenceCount: 0, - codewhispererSuggestionState: codewhispererSuggestionState, - codewhispererTriggerType: 'OnDemand', - credentialStartUrl: 'https://www.amazon.com', - } -} - -function aCompletion(): Completion { - return { - content: 'aFakeContent', - } -} - describe('telemetryHelper', function () { describe('clientComponentLatency', function () { let sut: TelemetryHelper @@ -79,207 +48,4 @@ describe('telemetryHelper', function () { assert.ok(resetStub.calledOnce) }) }) - - describe('aggregateUserDecisionByRequest', function () { - let sut: TelemetryHelper - - beforeEach(function () { - sut = new TelemetryHelper() - }) - - it('should return Line and Accept', function () { - const decisions: CodewhispererUserDecision[] = [ - aUserDecision('Line', 0, 'Accept'), - aUserDecision('Line', 1, 'Discard'), - aUserDecision('Block', 2, 'Ignore'), - aUserDecision('Block', 3, 'Ignore'), - ] - - const actual = sut.aggregateUserDecisionByRequest(decisions, 'aFakeRequestId', 'aFakeSessionId') - assert.ok(actual) - assert.strictEqual(actual?.codewhispererCompletionType, 'Line') - assert.strictEqual(actual?.codewhispererSuggestionState, 'Accept') - }) - - it('should return Line and Reject', function () { - const decisions: CodewhispererUserDecision[] = [ - aUserDecision('Line', 0, 'Discard'), - aUserDecision('Line', 1, 'Reject'), - aUserDecision('Line', 2, 'Unseen'), - aUserDecision('Line', 3, 'Unseen'), - ] - - const actual = sut.aggregateUserDecisionByRequest(decisions, 'aFakeRequestId', 'aFakeSessionId') - assert.ok(actual) - assert.strictEqual(actual?.codewhispererCompletionType, 'Line') - assert.strictEqual(actual?.codewhispererSuggestionState, 'Reject') - }) - - it('should return Block and Accept', function () { - const decisions: CodewhispererUserDecision[] = [ - aUserDecision('Block', 0, 'Discard'), - aUserDecision('Block', 1, 'Accept'), - aUserDecision('Block', 2, 'Discard'), - aUserDecision('Block', 3, 'Ignore'), - ] - - const actual = sut.aggregateUserDecisionByRequest(decisions, 'aFakeRequestId', 'aFakeSessionId') - assert.ok(actual) - assert.strictEqual(actual?.codewhispererCompletionType, 'Block') - assert.strictEqual(actual?.codewhispererSuggestionState, 'Accept') - }) - }) - - describe('sendUserTriggerDecisionTelemetry', function () { - let sut: TelemetryHelper - - beforeEach(async function () { - await resetCodeWhispererGlobalVariables() - sut = new TelemetryHelper() - }) - - it('should return Line and Accept', function () { - sut.recordUserDecisionTelemetry( - ['aFakeRequestId', 'aFakeRequestId', 'aFakeRequestId2'], - 'aFakeSessionId', - [aCompletion(), aCompletion(), aCompletion(), aCompletion()], - 0, - 0, - new Map([ - [0, 'Line'], - [1, 'Line'], - [2, 'Block'], - [3, 'Block'], - ]) - ) - - sut.sendUserTriggerDecisionTelemetry('aFakeSessionId', aCompletion().content, 0) - const assertTelemetry = assertTelemetryCurried('codewhisperer_userTriggerDecision') - assertTelemetry({ - codewhispererSessionId: 'aFakeSessionId', - codewhispererFirstRequestId: 'aFakeRequestId', - codewhispererLanguage: 'python', - codewhispererTriggerType: 'OnDemand', - codewhispererLineNumber: 0, - codewhispererCursorOffset: 0, - codewhispererSuggestionCount: 4, - codewhispererSuggestionImportCount: 0, - codewhispererSuggestionState: 'Accept', - codewhispererCompletionType: 'Line', - codewhispererTypeaheadLength: 0, - codewhispererCharactersAccepted: aCompletion().content.length, - }) - }) - - it('should return Line and Accept 2', function () { - sut.recordUserDecisionTelemetry( - ['aFakeRequestId', 'aFakeRequestId', 'aFakeRequestId2'], - 'aFakeSessionId', - [aCompletion(), aCompletion(), aCompletion(), aCompletion()], - 3, - 0, - new Map([ - [0, 'Line'], - [1, 'Line'], - [2, 'Line'], - [3, 'Line'], - ]) - ) - - sut.sendUserTriggerDecisionTelemetry('aFakeSessionId', aCompletion().content, 0) - const assertTelemetry = assertTelemetryCurried('codewhisperer_userTriggerDecision') - assertTelemetry({ - codewhispererSessionId: 'aFakeSessionId', - codewhispererFirstRequestId: 'aFakeRequestId', - codewhispererLanguage: 'python', - codewhispererTriggerType: 'OnDemand', - codewhispererLineNumber: 0, - codewhispererCursorOffset: 0, - codewhispererSuggestionCount: 4, - codewhispererSuggestionImportCount: 0, - codewhispererSuggestionState: 'Accept', - codewhispererCompletionType: 'Line', - codewhispererTypeaheadLength: 0, - codewhispererCharactersAccepted: aCompletion().content.length, - }) - }) - - it('should return Line and Reject', function () { - sut.recordUserDecisionTelemetry( - ['aFakeRequestId', 'aFakeRequestId', 'aFakeRequestId2'], - 'aFakeSessionId', - [aCompletion(), aCompletion(), aCompletion(), aCompletion()], - -1, - 0, - new Map([ - [0, 'Line'], - [1, 'Line'], - [2, 'Line'], - [3, 'Line'], - ]) - ) - - sut.sendUserTriggerDecisionTelemetry('aFakeSessionId', '', 0) - const assertTelemetry = assertTelemetryCurried('codewhisperer_userTriggerDecision') - assertTelemetry({ - codewhispererSessionId: 'aFakeSessionId', - codewhispererFirstRequestId: 'aFakeRequestId', - codewhispererLanguage: 'python', - codewhispererTriggerType: 'OnDemand', - codewhispererLineNumber: 0, - codewhispererCursorOffset: 0, - codewhispererSuggestionCount: 4, - codewhispererSuggestionImportCount: 0, - codewhispererSuggestionState: 'Reject', - codewhispererCompletionType: 'Line', - codewhispererTypeaheadLength: 0, - codewhispererCharactersAccepted: 0, - }) - }) - }) - - describe('getSuggestionState', function () { - let telemetryHelper = new TelemetryHelper() - beforeEach(async function () { - await resetCodeWhispererGlobalVariables() - telemetryHelper = new TelemetryHelper() - }) - - it('user event is discard when recommendation state is Discarded with accept index = -1', function () { - const actual = telemetryHelper.getSuggestionState(0, -1, new Map([[0, 'Discard']])) - assert.strictEqual(actual, 'Discard') - }) - - it('user event is reject when recommendation state is Showed with accept index = -1', function () { - const actual = telemetryHelper.getSuggestionState(0, -1, new Map([[0, 'Showed']])) - assert.strictEqual(actual, 'Reject') - }) - - it('user event is Accept when recommendation state is Showed with accept index matches', function () { - const actual = telemetryHelper.getSuggestionState(0, 0, new Map([[0, 'Showed']])) - assert.strictEqual(actual, 'Accept') - }) - - it('user event is Ignore when recommendation state is Showed with accept index does not match', function () { - const actual = telemetryHelper.getSuggestionState(0, 1, new Map([[0, 'Showed']])) - assert.strictEqual(actual, 'Ignore') - }) - - it('user event is Unseen when recommendation state is not Showed, is not Unseen when recommendation is showed', function () { - const actual0 = telemetryHelper.getSuggestionState(0, 1, new Map([[1, 'Showed']])) - assert.strictEqual(actual0, 'Unseen') - const actual1 = telemetryHelper.getSuggestionState(1, 1, new Map([[1, 'Showed']])) - assert.strictEqual(actual1, 'Accept') - }) - - it('user event is Filter when recommendation state is Filter', function () { - const actual = telemetryHelper.getSuggestionState(0, 1, new Map([[0, 'Filter']])) - assert.strictEqual(actual, 'Filter') - }) - - it('user event is Empty when recommendation state is Empty', function () { - const actual = telemetryHelper.getSuggestionState(0, 1, new Map([[0, 'Empty']])) - assert.strictEqual(actual, 'Empty') - }) - }) }) diff --git a/packages/core/src/codewhisperer/util/telemetryHelper.ts b/packages/core/src/codewhisperer/util/telemetryHelper.ts index 89c04afe572..076cea19049 100644 --- a/packages/core/src/codewhisperer/util/telemetryHelper.ts +++ b/packages/core/src/codewhisperer/util/telemetryHelper.ts @@ -5,18 +5,9 @@ import globals from '../../shared/extensionGlobals' import { runtimeLanguageContext } from './runtimeLanguageContext' -import { codeWhispererClient as client, RecommendationsList } from '../client/codewhisperer' -import { LicenseUtil } from './licenseUtil' -import { - CodewhispererGettingStartedTask, - CodewhispererLanguage, - CodewhispererPreviousSuggestionState, - CodewhispererUserDecision, - CodewhispererUserTriggerDecision, - telemetry, -} from '../../shared/telemetry/telemetry' -import { CodewhispererCompletionType, CodewhispererSuggestionState } from '../../shared/telemetry/telemetry' -import { getImportCount } from './importAdderUtil' +import { codeWhispererClient as client } from '../client/codewhisperer' +import { CodewhispererGettingStartedTask, CodewhispererLanguage, telemetry } from '../../shared/telemetry/telemetry' +import { CodewhispererCompletionType } from '../../shared/telemetry/telemetry' import { CodeWhispererSettings } from './codewhispererSettings' import { getSelectedCustomization } from './customizationUtil' import { AuthUtil } from './authUtil' @@ -24,12 +15,8 @@ import { isAwsError } from '../../shared/errors' import { getLogger } from '../../shared/logger/logger' import { session } from './codeWhispererSession' import { CodeWhispererSupplementalContext } from '../models/model' -import { FeatureConfigProvider } from '../../shared/featureConfig' -import CodeWhispererUserClient, { CodeScanRemediationsEventType } from '../client/codewhispereruserclient' +import { CodeScanRemediationsEventType } from '../client/codewhispereruserclient' import { CodeAnalysisScope as CodeAnalysisScopeClientSide } from '../models/constants' -import { sleep } from '../../shared/utilities/timeoutUtils' -import { getDiagnosticsDifferences, getDiagnosticsOfCurrentFile, toIdeDiagnostics } from './diagnosticsUtil' -import { Auth } from '../../auth/auth' export class TelemetryHelper { // Some variables for client component latency @@ -45,16 +32,6 @@ export class TelemetryHelper { get firstResponseRequestId(): string { return this._firstResponseRequestId } - // variables for user trigger decision - // these will be cleared after a invocation session - private sessionDecisions: CodewhispererUserTriggerDecision[] = [] - private triggerChar?: string = undefined - private prevTriggerDecision?: CodewhispererPreviousSuggestionState - private typeAheadLength = 0 - private timeSinceLastModification = 0 - private lastTriggerDecisionTime = 0 - private classifierResult?: number = undefined - private classifierThreshold?: number = undefined // variables for tracking end to end sessions public traceId: string = 'notSet' @@ -105,434 +82,6 @@ export class TelemetryHelper { telemetry.codewhisperer_serviceInvocation.emit(event) } - public recordUserDecisionTelemetryForEmptyList( - requestIdList: string[], - sessionId: string, - paginationIndex: number, - language: CodewhispererLanguage, - supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined - ) { - const selectedCustomization = getSelectedCustomization() - const profile = AuthUtil.instance.regionProfileManager.activeRegionProfile - - telemetry.codewhisperer_userTriggerDecision.emit({ - codewhispererAutomatedTriggerType: session.autoTriggerType, - codewhispererClassifierResult: this.classifierResult, - codewhispererClassifierThreshold: this.classifierThreshold, - codewhispererCompletionType: 'Line', - codewhispererCursorOffset: session.startCursorOffset, - codewhispererCustomizationArn: selectedCustomization.arn === '' ? undefined : selectedCustomization.arn, - codewhispererFeatureEvaluations: FeatureConfigProvider.instance.getFeatureConfigsTelemetry(), - codewhispererFirstRequestId: requestIdList[0], - codewhispererGettingStartedTask: session.taskType, - codewhispererLanguage: language, - codewhispererLineNumber: session.startPos.line, - codewhispererPreviousSuggestionState: this.prevTriggerDecision, - codewhispererSessionId: sessionId, - codewhispererSuggestionCount: 0, - codewhispererSuggestionImportCount: 0, - codewhispererSuggestionState: 'Empty', - codewhispererSupplementalContextIsUtg: supplementalContextMetadata?.isUtg, - codewhispererSupplementalContextLength: supplementalContextMetadata?.contentsLength, - // eslint-disable-next-line id-length - codewhispererSupplementalContextStrategyId: supplementalContextMetadata?.strategy, - codewhispererSupplementalContextTimeout: supplementalContextMetadata?.isProcessTimeout, - codewhispererTimeSinceLastDocumentChange: this.timeSinceLastModification - ? this.timeSinceLastModification - : undefined, - codewhispererTimeSinceLastUserDecision: this.lastTriggerDecisionTime - ? performance.now() - this.lastTriggerDecisionTime - : undefined, - codewhispererTimeToFirstRecommendation: session.timeToFirstRecommendation, - codewhispererTriggerType: session.triggerType, - codewhispererTypeaheadLength: this.typeAheadLength, - credentialStartUrl: AuthUtil.instance.startUrl, - traceId: this.traceId, - }) - - client - .sendTelemetryEvent({ - telemetryEvent: { - userTriggerDecisionEvent: { - sessionId: sessionId, - requestId: requestIdList[0], - customizationArn: selectedCustomization.arn === '' ? undefined : selectedCustomization.arn, - programmingLanguage: { - languageName: runtimeLanguageContext.toRuntimeLanguage(language), - }, - completionType: 'LINE', - suggestionState: 'EMPTY', - recommendationLatencyMilliseconds: 0, - triggerToResponseLatencyMilliseconds: session.timeToFirstRecommendation, - perceivedLatencyMilliseconds: session.perceivedLatency, - timestamp: new Date(Date.now()), - suggestionReferenceCount: 0, - generatedLine: 0, - numberOfRecommendations: 0, - acceptedCharacterCount: 0, - }, - }, - profileArn: profile?.arn, - }) - .then() - .catch((error) => { - let requestId: string | undefined - if (isAwsError(error)) { - requestId = error.requestId - } - - getLogger().error(`Failed to invoke sendTelemetryEvent, requestId: ${requestId ?? ''}`) - }) - } - - /** - * This function is to record the user decision on each of the suggestion in the list of CodeWhisperer recommendations. - * @param recommendations the recommendations - * @param acceptIndex the index of the accepted suggestion in the corresponding list of CodeWhisperer response. - * If this function is not called on acceptance, then acceptIndex == -1 - * @param languageId the language ID of the current document in current active editor - * @param paginationIndex the index of pagination calls - * @param recommendationSuggestionState the key-value mapping from index to suggestion state - */ - - public recordUserDecisionTelemetry( - requestIdList: string[], - sessionId: string, - recommendations: RecommendationsList, - acceptIndex: number, - paginationIndex: number, - completionTypes: Map, - recommendationSuggestionState?: Map, - supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined - ) { - const events: CodewhispererUserDecision[] = [] - // emit user decision telemetry - for (const [i, _elem] of recommendations.entries()) { - let uniqueSuggestionReferences: string | undefined = undefined - const uniqueLicenseSet = LicenseUtil.getUniqueLicenseNames(_elem.references) - if (uniqueLicenseSet.size > 0) { - uniqueSuggestionReferences = JSON.stringify(Array.from(uniqueLicenseSet)) - } - if (_elem.content.length === 0) { - recommendationSuggestionState?.set(i, 'Empty') - } - const event: CodewhispererUserDecision = { - // TODO: maintain a list of RecommendationContexts with both recommendation and requestId in it, instead of two separate list items. - codewhispererCompletionType: this.getCompletionType(i, completionTypes), - codewhispererGettingStartedTask: session.taskType, - codewhispererLanguage: session.language, - codewhispererPaginationProgress: paginationIndex, - codewhispererRequestId: requestIdList[i], - codewhispererSessionId: sessionId ? sessionId : undefined, - codewhispererSuggestionImportCount: getImportCount(_elem), - codewhispererSuggestionIndex: i, - codewhispererSuggestionState: this.getSuggestionState(i, acceptIndex, recommendationSuggestionState), - codewhispererSuggestionReferenceCount: _elem.references ? _elem.references.length : 0, - codewhispererSuggestionReferences: uniqueSuggestionReferences, - codewhispererSupplementalContextIsUtg: supplementalContextMetadata?.isUtg, - codewhispererSupplementalContextLength: supplementalContextMetadata?.contentsLength, - codewhispererSupplementalContextTimeout: supplementalContextMetadata?.isProcessTimeout, - codewhispererTriggerType: session.triggerType, - credentialStartUrl: AuthUtil.instance.startUrl, - traceId: this.traceId, - } - events.push(event) - } - - // aggregate suggestion references count - const referenceCount = this.getAggregatedSuggestionReferenceCount(events) - - // aggregate user decision events at requestId level - const aggregatedEvent = this.aggregateUserDecisionByRequest(events, requestIdList[0], sessionId) - if (aggregatedEvent) { - this.sessionDecisions.push(aggregatedEvent) - } - - // TODO: use a ternary for this - let acceptedRecommendationContent - if (acceptIndex !== -1 && recommendations[acceptIndex] !== undefined) { - acceptedRecommendationContent = recommendations[acceptIndex].content - } else { - acceptedRecommendationContent = '' - } - - // after we have all request level user decisions, aggregate them at session level and send - this.sendUserTriggerDecisionTelemetry( - sessionId, - acceptedRecommendationContent, - referenceCount, - supplementalContextMetadata - ) - } - - public aggregateUserDecisionByRequest( - events: CodewhispererUserDecision[], - requestId: string, - sessionId: string, - supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined - ) { - // the request level user decision will contain information from both the service_invocation event - // and the user_decision events for recommendations within that request - if (!events.length) { - return - } - const aggregated: CodewhispererUserTriggerDecision = { - codewhispererAutomatedTriggerType: session.autoTriggerType, - codewhispererCompletionType: events[0].codewhispererCompletionType, - codewhispererCursorOffset: session.startCursorOffset, - codewhispererFirstRequestId: requestId, - codewhispererGettingStartedTask: session.taskType, - codewhispererLanguage: events[0].codewhispererLanguage, - codewhispererLineNumber: session.startPos.line, - codewhispererSessionId: sessionId, - codewhispererSuggestionCount: events.length, - codewhispererSuggestionImportCount: events - .map((e) => e.codewhispererSuggestionImportCount || 0) - .reduce((a, b) => a + b, 0), - codewhispererSuggestionState: this.getAggregatedSuggestionState(events), - codewhispererSupplementalContextIsUtg: supplementalContextMetadata?.isUtg, - codewhispererSupplementalContextLength: supplementalContextMetadata?.contentsLength, - codewhispererSupplementalContextTimeout: supplementalContextMetadata?.isProcessTimeout, - codewhispererTriggerType: events[0].codewhispererTriggerType, - codewhispererTypeaheadLength: 0, - credentialStartUrl: events[0].credentialStartUrl, - traceId: this.traceId, - } - return aggregated - } - - public sendUserTriggerDecisionTelemetry( - sessionId: string, - acceptedRecommendationContent: string, - referenceCount: number, - supplementalContextMetadata?: CodeWhispererSupplementalContext | undefined - ) { - // the user trigger decision will aggregate information from request level user decisions within one session - // and add additional session level insights - if (!this.sessionDecisions.length) { - return - } - - // TODO: add partial acceptance related metrics - const autoTriggerType = this.sessionDecisions[0].codewhispererAutomatedTriggerType - const language = this.sessionDecisions[0].codewhispererLanguage - const aggregatedCompletionType = this.sessionDecisions[0].codewhispererCompletionType - const aggregatedSuggestionState = this.getAggregatedSuggestionState(this.sessionDecisions) - const selectedCustomization = getSelectedCustomization() - const profile = AuthUtil.instance.regionProfileManager.activeRegionProfile - const generatedLines = - acceptedRecommendationContent.trim() === '' ? 0 : acceptedRecommendationContent.split('\n').length - const suggestionCount = this.sessionDecisions - .map((e) => e.codewhispererSuggestionCount) - .reduce((a, b) => a + b, 0) - - const aggregated: CodewhispererUserTriggerDecision = { - codewhispererAutomatedTriggerType: autoTriggerType, - codewhispererCharactersAccepted: acceptedRecommendationContent.length, - codewhispererClassifierResult: this.classifierResult, - codewhispererClassifierThreshold: this.classifierThreshold, - codewhispererCompletionType: aggregatedCompletionType, - codewhispererCursorOffset: this.sessionDecisions[0].codewhispererCursorOffset, - codewhispererCustomizationArn: selectedCustomization.arn === '' ? undefined : selectedCustomization.arn, - codewhispererFeatureEvaluations: FeatureConfigProvider.instance.getFeatureConfigsTelemetry(), - codewhispererFirstRequestId: this.sessionDecisions[0].codewhispererFirstRequestId, - codewhispererGettingStartedTask: session.taskType, - codewhispererLanguage: language, - codewhispererLineNumber: this.sessionDecisions[0].codewhispererLineNumber, - codewhispererPreviousSuggestionState: this.prevTriggerDecision, - codewhispererSessionId: this.sessionDecisions[0].codewhispererSessionId, - codewhispererSuggestionCount: suggestionCount, - codewhispererSuggestionImportCount: this.sessionDecisions - .map((e) => e.codewhispererSuggestionImportCount || 0) - .reduce((a, b) => a + b, 0), - codewhispererSuggestionState: aggregatedSuggestionState, - codewhispererSupplementalContextIsUtg: supplementalContextMetadata?.isUtg, - codewhispererSupplementalContextLength: supplementalContextMetadata?.contentsLength, - // eslint-disable-next-line id-length - codewhispererSupplementalContextStrategyId: supplementalContextMetadata?.strategy, - codewhispererSupplementalContextTimeout: supplementalContextMetadata?.isProcessTimeout, - codewhispererTimeSinceLastDocumentChange: this.timeSinceLastModification - ? this.timeSinceLastModification - : undefined, - codewhispererTimeSinceLastUserDecision: this.lastTriggerDecisionTime - ? performance.now() - this.lastTriggerDecisionTime - : undefined, - codewhispererTimeToFirstRecommendation: session.timeToFirstRecommendation, - codewhispererTriggerCharacter: autoTriggerType === 'SpecialCharacters' ? this.triggerChar : undefined, - codewhispererTriggerType: this.sessionDecisions[0].codewhispererTriggerType, - codewhispererTypeaheadLength: this.typeAheadLength, - credentialStartUrl: this.sessionDecisions[0].credentialStartUrl, - traceId: this.traceId, - } - telemetry.codewhisperer_userTriggerDecision.emit(aggregated) - this.prevTriggerDecision = this.getAggregatedSuggestionState(this.sessionDecisions) - this.lastTriggerDecisionTime = performance.now() - - // When we send a userTriggerDecision for neither Accept nor Reject, service side should not use this value - // and client side will set this value to 0.0. - let e2eLatency = session.firstSuggestionShowTime - session.invokeSuggestionStartTime - if (aggregatedSuggestionState !== 'Reject' && aggregatedSuggestionState !== 'Accept') { - e2eLatency = 0.0 - } - - const userTriggerDecisionEvent: CodeWhispererUserClient.UserTriggerDecisionEvent = { - sessionId: sessionId, - requestId: this.sessionDecisions[0].codewhispererFirstRequestId, - customizationArn: selectedCustomization.arn === '' ? undefined : selectedCustomization.arn, - programmingLanguage: { - languageName: runtimeLanguageContext.toRuntimeLanguage(this.sessionDecisions[0].codewhispererLanguage), - }, - completionType: this.getSendTelemetryCompletionType(aggregatedCompletionType), - suggestionState: this.getSendTelemetrySuggestionState(aggregatedSuggestionState), - recommendationLatencyMilliseconds: e2eLatency, - triggerToResponseLatencyMilliseconds: session.timeToFirstRecommendation, - perceivedLatencyMilliseconds: session.perceivedLatency, - timestamp: new Date(Date.now()), - suggestionReferenceCount: referenceCount, - generatedLine: generatedLines, - numberOfRecommendations: suggestionCount, - acceptedCharacterCount: acceptedRecommendationContent.length, - } - this.resetUserTriggerDecisionTelemetry() - - const sendEvent = () => - client - .sendTelemetryEvent({ - telemetryEvent: { userTriggerDecisionEvent: userTriggerDecisionEvent }, - profileArn: profile?.arn, - }) - .catch((error) => { - const requestId = isAwsError(error) ? error.requestId : undefined - getLogger().debug( - `Failed to sendTelemetryEvent to CodeWhisperer, requestId: ${requestId ?? ''}, message: ${error.message}` - ) - }) - - if (userTriggerDecisionEvent.suggestionState === 'ACCEPT' && Auth.instance.isInternalAmazonUser()) { - // wait 1 seconds for the user installed 3rd party LSP - // to update its diagnostics. - void sleep(1000).then(() => { - const diagnosticDiff = getDiagnosticsDifferences( - session.diagnosticsBeforeAccept, - getDiagnosticsOfCurrentFile() - ) - userTriggerDecisionEvent.addedIdeDiagnostics = diagnosticDiff.added.map((it) => toIdeDiagnostics(it)) - userTriggerDecisionEvent.removedIdeDiagnostics = diagnosticDiff.removed.map((it) => - toIdeDiagnostics(it) - ) - void sendEvent() - }) - } else { - void sendEvent() - } - } - - public getLastTriggerDecisionForClassifier() { - if (this.lastTriggerDecisionTime && performance.now() - this.lastTriggerDecisionTime <= 2 * 60 * 1000) { - return this.prevTriggerDecision - } - } - - public setClassifierResult(classifierResult: number) { - this.classifierResult = classifierResult - } - - public setClassifierThreshold(classifierThreshold: number) { - this.classifierThreshold = classifierThreshold - } - - public setTriggerCharForUserTriggerDecision(triggerChar: string) { - this.triggerChar = triggerChar - } - - public setTypeAheadLength(typeAheadLength: number) { - this.typeAheadLength = typeAheadLength - } - - public setTimeSinceLastModification(timeSinceLastModification: number) { - this.timeSinceLastModification = timeSinceLastModification - } - - public setTraceId(traceId: string) { - this.traceId = traceId - } - - private resetUserTriggerDecisionTelemetry() { - this.sessionDecisions = [] - this.triggerChar = '' - this.typeAheadLength = 0 - this.timeSinceLastModification = 0 - session.timeToFirstRecommendation = 0 - session.perceivedLatency = 0 - this.classifierResult = undefined - this.classifierThreshold = undefined - } - - private getSendTelemetryCompletionType(completionType: CodewhispererCompletionType) { - return completionType === 'Block' ? 'BLOCK' : 'LINE' - } - - private getAggregatedSuggestionState( - // if there is any Accept within the session, mark the session as Accept - // if there is any Reject within the session, mark the session as Reject - // if all recommendations within the session are empty, mark the session as Empty - // otherwise mark the session as Discard - events: CodewhispererUserDecision[] | CodewhispererUserTriggerDecision[] - ): CodewhispererPreviousSuggestionState { - let isEmpty = true - for (const event of events) { - if (event.codewhispererSuggestionState === 'Accept') { - return 'Accept' - } else if (event.codewhispererSuggestionState === 'Reject') { - return 'Reject' - } else if (event.codewhispererSuggestionState !== 'Empty') { - isEmpty = false - } - } - return isEmpty ? 'Empty' : 'Discard' - } - - private getSendTelemetrySuggestionState(state: CodewhispererPreviousSuggestionState) { - if (state === 'Accept') { - return 'ACCEPT' - } else if (state === 'Reject') { - return 'REJECT' - } else if (state === 'Discard') { - return 'DISCARD' - } - return 'EMPTY' - } - - private getAggregatedSuggestionReferenceCount( - events: CodewhispererUserDecision[] - // if there is reference for accepted recommendation within the session, mark the reference number - // as 1, otherwise mark the session as 0 - ) { - for (const event of events) { - if (event.codewhispererSuggestionState === 'Accept' && event.codewhispererSuggestionReferenceCount !== 0) { - return 1 - } - } - return 0 - } - - public getSuggestionState( - i: number, - acceptIndex: number, - recommendationSuggestionState?: Map - ): CodewhispererSuggestionState { - const state = recommendationSuggestionState?.get(i) - if (state && ['Empty', 'Filter', 'Discard'].includes(state)) { - return state as CodewhispererSuggestionState - } else if (recommendationSuggestionState !== undefined && recommendationSuggestionState.get(i) !== 'Showed') { - return 'Unseen' - } - if (acceptIndex === -1) { - return 'Reject' - } - return i === acceptIndex ? 'Accept' : 'Ignore' - } - public getCompletionType(i: number, completionTypes: Map) { return completionTypes.get(i) || 'Line' } diff --git a/packages/core/src/shared/utilities/index.ts b/packages/core/src/shared/utilities/index.ts index a361834406c..e86f941456d 100644 --- a/packages/core/src/shared/utilities/index.ts +++ b/packages/core/src/shared/utilities/index.ts @@ -9,3 +9,4 @@ export * from './functionUtils' export * as messageUtils from './messages' export * as CommentUtils from './commentUtils' export * from './editorUtilities' +export * from './tsUtils' diff --git a/packages/core/src/shared/utilities/proxyUtil.ts b/packages/core/src/shared/utilities/proxyUtil.ts index 06150b9fc01..fc38b3e7e0d 100644 --- a/packages/core/src/shared/utilities/proxyUtil.ts +++ b/packages/core/src/shared/utilities/proxyUtil.ts @@ -68,7 +68,7 @@ export class ProxyUtil { */ private static async setProxyEnvironmentVariables(config: ProxyConfig): Promise { // Always enable experimental proxy support for better handling of both explicit and transparent proxies - process.env.EXPERIMENTAL_HTTP_PROXY_SUPPORT = 'true' + process.env.EXPERIMENTAL_HTTP_PROXY_SUPPORT = 'false' const proxyUrl = config.proxyUrl // Set proxy environment variables