diff --git a/.config/tsaoptions.json b/.config/tsaoptions.json
new file mode 100644
index 0000000000..44c83732fa
--- /dev/null
+++ b/.config/tsaoptions.json
@@ -0,0 +1,8 @@
+{
+  "instanceUrl": "https://msazure.visualstudio.com",
+  "projectName": "One",
+  "areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell",
+  "notificationAliases": ["andschwa@microsoft.com", "slee@microsoft.com"],
+  "codebaseName": "PowerShell_vscode-powershell_20240328",
+  "tools": ["CredScan", "PoliCheck", "BinSkim"]
+}
diff --git a/.editorconfig b/.editorconfig
index 9ad197dff6..31cbf8b559 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,6 +5,7 @@ charset = utf-8
 indent_style = space
 indent_size = 4
 insert_final_newline = true
+trim_trailing_whitespace = true
 
 [*.{json,yaml,yml,code-workspace}]
 indent_size = 2
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000000..d775e01095
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,6 @@
+# Enabled on GitHub automatically
+# Enable this file in your git config:
+# git config blame.ignoreRevsFile .git-blame-ignore-revs
+
+# Prettier reformatting
+f978bae02ad48ddb5f8d4eb21512fe9b17541c5b
diff --git a/.gitattributes b/.gitattributes
index 2a922ee8df..e6caee9a0c 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,8 +3,3 @@
 
 # Set svg to binary type, as SVG is unlikely to be editted by hand. Can be treated as checked in blob
 *.svg binary
-
-# .gitattributes in project root
-# npm now seems to be insisting on LF - see https://github.com/npm/npm/issues/17161
-package.json      text eol=lf
-package-lock.json text eol=lf
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000000..d2f790a4d5
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,16 @@
+# https://help.github.com/articles/about-codeowners/
+
+# Global pattern
+* @PowerShell/extension
+
+# Developer files
+src/ @PowerShell/extension-dev
+test/ @PowerShell/extension-dev
+tools/ @PowerShell/extension-dev
+.editorconfig @PowerShell/extension-dev
+.gitattributes @PowerShell/extension-dev
+.gitignore @PowerShell/extension-dev
+extension-dev.code-workspace @PowerShell/extension-dev
+package-lock.json @PowerShell/extension-dev
+package.json @PowerShell/extension-dev
+vscode-powershell.build.ps1 @PowerShell/extension-dev
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index f4d219b7b2..d90459770a 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -1,84 +1,99 @@
 name: 🐛 Bug report
 description: Open an issue about a bug that needs fixing.
-labels: Issue-Bug
+labels: ["Issue-Bug", "Needs: Triage"]
 body:
-- type: checkboxes
-  attributes:
-    label: Prerequisites
-    options:
-    - label: I have written a descriptive issue title.
+  - type: checkboxes
+    attributes:
+      label: Prerequisites
+      options:
+        - label: I have written a descriptive issue title.
+          required: true
+        - label: I have searched all [_open and closed_ issues](https://github.com/PowerShell/vscode-powershell/issues?q=is%3Aissue) to ensure it has not already been reported.
+        - label: I have read the [troubleshooting](https://github.com/PowerShell/vscode-powershell/blob/main/docs/troubleshooting.md) guide.
+        - label: I am sure this issue is with the _extension itself_ and does not reproduce in a standalone [PowerShell](https://github.com/PowerShell/PowerShell/issues/new/choose) instance.
+        - label: I have verified that I am using the latest version of Visual Studio Code and the PowerShell extension.
+        - label: If this is a security issue, I have read the [security issue reporting guidance](https://github.com/PowerShell/vscode-powershell/blob/main/SECURITY.md).
+  - type: textarea
+    id: summary
+    attributes:
+      label: Summary
+      description: Explain the problem briefly below.
+      placeholder: I am experiencing a problem with X. I think Y should be happening but Z is actually happening.
+    validations:
       required: true
-    - label: I have searched all [issues](https://github.com/PowerShell/vscode-powershell/issues?q=is%3Aissue) to ensure it has not already been reported.
+  - type: textarea
+    id: powershell-version
+    attributes:
+      label: PowerShell Version
+      description: Paste verbatim output from `$PSVersionTable; $Host` below. **Please include `$Host`** so we know this version is from the Extension Terminal!
+      render: console
+      placeholder: |
+        PS> $PSVersionTable; $Host
+
+        Name                           Value
+        ----                           -----
+        PSVersion                      7.4.0
+        PSEdition                      Core
+        GitCommitId                    7.4.0
+        OS                             Microsoft Windows 10.0.22631
+        Platform                       Win32NT
+        PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
+        PSRemotingProtocolVersion      2.3
+        SerializationVersion           1.1.0.1
+        WSManStackVersion              3.0
+
+        Name             : Visual Studio Code Host
+        Version          : 2023.11.0
+        InstanceId       : 803ce61b-6187-4574-9c1f-827ebb11b8b6
+        UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
+        CurrentCulture   : en-US
+        CurrentUICulture : en-US
+        PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
+        DebuggerEnabled  : True
+        IsRunspacePushed : False
+        Runspace         : System.Management.Automation.Runspaces.LocalRunspace
+    validations:
       required: true
-    - label: I have read the [troubleshooting](https://github.com/PowerShell/vscode-powershell/blob/master/docs/troubleshooting.md) guide.
+  - type: textarea
+    id: vscode-version
+    attributes:
+      label: Visual Studio Code Version
+      description: Paste verbatim output from `code --version` below.
+      render: console
+      placeholder: |
+        PS> code --version
+
+        1.57.1
+        507ce72a4466fbb27b715c3722558bb15afa9f48
+        arm64
+    validations:
       required: true
-    - label: I am sure this issue is with the _extension itself_ and does not reproduce in a standalone [PowerShell](https://github.com/PowerShell/PowerShell/issues/new/choose) instance.
+  - type: textarea
+    id: extension-version
+    attributes:
+      label: Extension Version
+      description: Paste verbatim output from `code --list-extensions --show-versions | Select-String powershell` below.
+      render: console
+      placeholder: |
+        PS> code --list-extensions --show-versions | Select-String powershell
+
+        ms-vscode.powershell@2021.8.0
+    validations:
       required: true
-    - label: I have verified that I am using the latest version of Visual Studio Code and the PowerShell extension.
+  - type: textarea
+    id: steps-to-reproduce
+    attributes:
+      label: Steps to Reproduce
+      description: List of steps, sample code, failing test or link to a project that reproduces the behavior. Make sure you place a stack trace inside a code (```) block to avoid linking unrelated issues.
+    validations:
       required: true
-- type: textarea
-  attributes:
-    label: Summary
-    description: Explain the problem briefly below.
-    placeholder: I am experiencing a problem with X. I think Y should be happening but Z is actually happening.
-  validations:
-    required: true
-- type: textarea
-  attributes:
-    label: PowerShell Version
-    description: Paste verbatim output from `$PSVersionTable` below. Please double-check that this is the PowerShell version that VS Code is set to use.
-    render: console
-    placeholder: |
-      PS> $PSVersionTable
-
-      Name                           Value
-      ----                           -----
-      PSVersion                      7.1.3
-      PSEdition                      Core
-      GitCommitId                    7.1.3
-      OS                             Darwin 20.4.0 Darwin Kernel
-      Platform                       Unix
-      PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
-      PSRemotingProtocolVersion      2.3
-      SerializationVersion           1.1.0.1
-      WSManStackVersion              3.0
-  validations:
-    required: true
-- type: textarea
-  attributes:
-    label: Visual Studio Code Version
-    description: Paste verbatim output from `code --version` below.
-    render: console
-    placeholder: |
-      PS> code --version
-
-      1.57.1
-      507ce72a4466fbb27b715c3722558bb15afa9f48
-      arm64
-  validations:
-    required: true
-- type: textarea
-  attributes:
-    label: Extension Version
-    description: Paste verbatim output from `code --list-extensions --show-versions | Select-String powershell` below.
-    render: console
-    placeholder: |
-      PS> code --list-extensions --show-versions | Select-String powershell
-
-      ms-vscode.powershell@2021.8.0
-  validations:
-    required: true
-- type: textarea
-  attributes:
-    label: Steps to Reproduce
-    description: List of steps, sample code, failing test or link to a project that reproduces the behavior. Make sure you place a stack trace inside a code (```) block to avoid linking unrelated issues.
-  validations:
-    required: true
-- type: textarea
-  attributes:
-    label: Visuals
-    description: Please upload images or animations that can be used to reproduce issues in the area below. Try the [Steps Recorder](https://support.microsoft.com/en-us/windows/record-steps-to-reproduce-a-problem-46582a9b-620f-2e36-00c9-04e25d784e47) on Windows or [Screenshot](https://support.apple.com/en-us/HT208721) on macOS.
-- type: textarea
-  attributes:
-    label: Logs
-    description: Please upload logs collected by following these [instructions](https://github.com/PowerShell/vscode-powershell/blob/master/docs/troubleshooting.md#logs) in the area below. Be careful to scrub sensitive information!
+  - type: textarea
+    id: visuals
+    attributes:
+      label: Visuals
+      description: Please upload images or animations that can be used to reproduce issues in the area below. Try the [Steps Recorder](https://support.microsoft.com/en-us/windows/record-steps-to-reproduce-a-problem-46582a9b-620f-2e36-00c9-04e25d784e47) on Windows or [Screenshot](https://support.apple.com/en-us/HT208721) on macOS.
+  - type: textarea
+    id: logs
+    attributes:
+      label: Logs
+      description: Please upload logs collected by following these [instructions](https://github.com/PowerShell/vscode-powershell/blob/main/docs/troubleshooting.md#logs) in the area below. Be careful to scrub sensitive information!
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
index 81ce4a4f75..22599f9c7e 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.yml
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -1,24 +1,26 @@
 name: ✨ Feature request
 description: Open an issue about a potential new feature or improvement.
-labels: Issue-Enhancement
+labels: ["Issue-Enhancement", "Needs: Triage"]
 body:
-- type: checkboxes
-  attributes:
-    label: Prerequisites
-    options:
-    - label: I have written a descriptive issue title.
+  - type: checkboxes
+    attributes:
+      label: Prerequisites
+      options:
+        - label: I have written a descriptive issue title.
+          required: true
+        - label: I have searched all [issues](https://github.com/PowerShell/vscode-powershell/issues?q=is%3Aissue) to ensure it has not already been reported.
+          required: true
+  - type: textarea
+    id: summary
+    attributes:
+      label: Summary
+      description: Explain the feature request below.
+      placeholder: I would like to do X because it would be useful for Y and I cannot currently do it with Z.
+    validations:
       required: true
-    - label: I have searched all [issues](https://github.com/PowerShell/vscode-powershell/issues?q=is%3Aissue) to ensure it has not already been reported.
-      required: true
-- type: textarea
-  attributes:
-    label: Summary
-    description: Explain the feature request below.
-    placeholder: I would like to do X because it would be useful for Y and I cannot currently do it with Z.
-  validations:
-    required: true
-- type: textarea
-  attributes:
-    label: Proposed Design
-    description: Optionally explain any technical design below.
-    placeholder: We could accomplish this by extending X to take Y and yield Z.
+  - type: textarea
+    id: proposed-design
+    attributes:
+      label: Proposed Design
+      description: Optionally explain any technical design below.
+      placeholder: We could accomplish this by extending X to take Y and yield Z.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 0124ba47aa..0000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-version: 2
-updates:
-- package-ecosystem: npm
-  directory: "/"
-  schedule:
-    interval: daily
-    time: "05:00"
-    timezone: America/Los_Angeles
-  reviewers:
-    - "andschwa"
diff --git a/.github/release.yml b/.github/release.yml
new file mode 100644
index 0000000000..cc5a1aa807
--- /dev/null
+++ b/.github/release.yml
@@ -0,0 +1,16 @@
+changelog:
+  exclude:
+    labels:
+      - Ignore
+    authors:
+      - dependabot
+  categories:
+    - title: Enhancements & Features ✨
+      labels:
+        - Issue-Enhancement
+    - title: Squashed Bugs 🐛
+      labels:
+        - Issue-Bug
+    - title: Other Changes 🙏
+      labels:
+        - "*"
diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml
new file mode 100644
index 0000000000..c53d576379
--- /dev/null
+++ b/.github/workflows/ci-test.yml
@@ -0,0 +1,82 @@
+name: CI Tests
+permissions:
+  contents: read
+
+on:
+  push:
+    branches: [main]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [main]
+  merge_group:
+    types: [checks_requested]
+
+jobs:
+  ci:
+    name: node
+    strategy:
+      matrix:
+        os: [windows-latest, macos-latest, ubuntu-latest]
+    runs-on: ${{ matrix.os }}
+    env:
+      DOTNET_NOLOGO: true
+      DOTNET_GENERATE_ASPNET_CERTIFICATE: false
+      DISPLAY: ":99.0"
+    timeout-minutes: 10
+    steps:
+      - name: Checkout PowerShellEditorServices
+        uses: actions/checkout@v4
+        with:
+          repository: PowerShell/PowerShellEditorServices
+          path: PowerShellEditorServices
+
+      - name: Checkout vscode-powershell
+        uses: actions/checkout@v4
+        with:
+          path: vscode-powershell
+
+      - name: Validate snippets JSON file
+        shell: pwsh
+        run: $null = ConvertFrom-Json -InputObject (Get-Content -Raw -Path './snippets/PowerShell.json')
+        working-directory: vscode-powershell
+
+      - name: Install dotnet
+        uses: actions/setup-dotnet@v4
+        with:
+          cache: true
+          cache-dependency-path: PowerShellEditorServices/**/*.csproj
+          global-json-file: PowerShellEditorServices/global.json
+          config-file: PowerShellEditorServices/nuget.config
+
+      - name: Install PSResources
+        shell: pwsh
+        run: ./vscode-powershell/tools/installPSResources.ps1
+
+      - uses: actions/setup-node@v4
+        with:
+          node-version: 20
+          cache: npm
+          cache-dependency-path: vscode-powershell/package-lock.json
+
+      - name: Start X virtual framebuffer
+        if: matrix.os == 'ubuntu-latest'
+        run: /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
+
+      - name: Build, test and package
+        shell: pwsh
+        run: Invoke-Build -Configuration Release
+        working-directory: vscode-powershell
+
+      - name: Upload build artifacts
+        uses: actions/upload-artifact@v4
+        if: always()
+        with:
+          name: vscode-powershell-vsix-${{ matrix.os }}
+          path: "**/*.vsix"
+
+      - name: Upload test results
+        uses: actions/upload-artifact@v4
+        if: always()
+        with:
+          name: vscode-powershell-test-results-${{ matrix.os }}
+          path: "**/test-results.xml"
diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml
new file mode 100644
index 0000000000..8ababb3c9e
--- /dev/null
+++ b/.github/workflows/close-stale-issues.yml
@@ -0,0 +1,45 @@
+name: Issue Housekeeping
+
+permissions:
+  issues: write
+
+on:
+  schedule:
+    - cron: "0 * * * *"
+
+jobs:
+  stale-resolved-issues:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v9
+        name: Label resolved issues as needing fix verification
+        with:
+          any-of-labels: "Resolution-Answered,Resolution-Duplicate,Resolution-External,Resolution-Fixed,Resolution-Inactive"
+          stale-issue-label: "Needs: Fix Verification"
+          days-before-stale: 0
+          days-before-close: -1
+          stale-issue-message: "This issue has been labeled as resolved, please verify the provided fix (or other reason)."
+          labels-to-remove-when-stale: "Needs: Maintainer Attention,Needs: Triage"
+  stale-fixed-issues:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v9
+        name: Close issues needing fix verification after 1 week of inactivity
+        with:
+          stale-issue-label: "Needs: Fix Verification"
+          days-before-stale: -1
+          labels-to-add-when-unstale: "Needs: Maintainer Attention"
+          close-issue-reason: completed
+          close-issue-message: "This issue has been labeled as needing fix verification and has not had any activity a week. It has been closed for housekeeping purposes."
+  stale-feedback-issues:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v9
+        name: Close issues needing author feedback after 1 week of inactivity
+        with:
+          stale-issue-label: "Needs: Author Feedback"
+          days-before-stale: -1
+          labels-to-add-when-unstale: "Needs: Maintainer Attention"
+          labels-to-remove-when-unstale: "Needs: Triage"
+          close-issue-reason: completed
+          close-issue-message: "This issue has been labeled as needing feedback and has not had any activity a week. It has been closed for housekeeping purposes."
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 91c115c16f..0000000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: "CodeQL"
-
-on:
-  push:
-    branches: [ master ]
-    tags: [ v* ]
-  pull_request:
-    # The branches below must be a subset of the branches above
-    branches: [ master ]
-    paths-ignore: [ '**/*.md' ]
-  schedule:
-    - cron: '00 14 * * *' # Every morning at 7:00am PDT
-
-jobs:
-  analyze:
-    name: Analyze
-    runs-on: ubuntu-latest
-    permissions:
-      actions: read
-      contents: read
-      security-events: write
-
-    strategy:
-      fail-fast: false
-      matrix:
-        language: [ 'typescript' ]
-
-    steps:
-    - name: Checkout repository
-      uses: actions/checkout@v2
-
-    # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v1
-      with:
-        languages: ${{ matrix.language }}
-
-    - name: Autobuild
-      uses: github/codeql-action/autobuild@v1
-
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v1
diff --git a/.gitignore b/.gitignore
index 1edc71c6ff..e89c3c2740 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,13 @@
+**.js
+**.js.map
 .vscode-test/
-logs/
+*.vsix
+dist/
 modules
 modules/
 node_modules/
 out/
-sessions/
-test/.vscode/
-
+test/mocks/BinaryModule/bin/
+test/mocks/BinaryModule/obj/
 test-results.xml
-*.vsix
-*.DS_Store
+tsconfig.tsbuildinfo
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000000..0bc786ac44
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1 @@
+Andy Jordan <andy.jordan@microsoft.com> <andrew@schwartzmeyer.com>
diff --git a/.markdownlint.json b/.markdownlint.json
index e1a57605cd..7f90a5dce8 100644
--- a/.markdownlint.json
+++ b/.markdownlint.json
@@ -1,6 +1,6 @@
 {
-    "MD013": false,
-    "MD033": false,
-    "MD022": false,
-    "MD024": false
+  "MD013": false,
+  "MD033": false,
+  "MD022": false,
+  "MD024": false
 }
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000000..3a65acc502
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,7 @@
+; We generally want to save install/update commands
+save=true
+; We use a public Azure Artifacts mirror
+registry=https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/powershell/npm/registry/
+always-auth=true
+; But we don't want references to it in the lockfile
+omit-lockfile-registry-resolved=true
diff --git a/.pipelines/vscode-powershell-Official.yml b/.pipelines/vscode-powershell-Official.yml
new file mode 100644
index 0000000000..155e258706
--- /dev/null
+++ b/.pipelines/vscode-powershell-Official.yml
@@ -0,0 +1,206 @@
+#################################################################################
+#                               OneBranch Pipelines                             #
+# This pipeline was created by EasyStart from a sample located at:              #
+#   https://aka.ms/obpipelines/easystart/samples                                #
+# Documentation:  https://aka.ms/obpipelines                                    #
+# Yaml Schema:    https://aka.ms/obpipelines/yaml/schema                        #
+# Retail Tasks:   https://aka.ms/obpipelines/tasks                              #
+# Support:        https://aka.ms/onebranchsup                                   #
+#################################################################################
+
+trigger:
+  - main
+
+schedules:
+  - cron: "25 9 * * 3"
+    displayName: Weekly CodeQL
+    branches:
+      include:
+        - main
+    always: true
+
+parameters:
+  - name: debug
+    displayName: Enable debug output
+    type: boolean
+    default: false
+
+variables:
+  system.debug: ${{ parameters.debug }}
+  BuildConfiguration: Release
+  WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest
+
+resources:
+  repositories:
+    - repository: templates
+      type: git
+      name: OneBranch.Pipelines/GovernedTemplates
+      ref: refs/heads/main
+  pipelines:
+    - pipeline: PowerShellEditorServices-Official
+      source: PowerShellEditorServices-Official
+      trigger:
+        branches:
+          - main
+        stages:
+          - release
+
+extends:
+  # https://aka.ms/obpipelines/templates
+  template: v2/OneBranch.Official.CrossPlat.yml@templates
+  parameters:
+    globalSdl: # https://aka.ms/obpipelines/sdl
+      asyncSdl:
+        enabled: true
+        forStages: [build]
+    featureFlags:
+      EnableCDPxPAT: false
+      WindowsHostVersion:
+        Version: 2022
+        Network: KS3
+    release:
+      category: NonAzure
+    stages:
+      - stage: build
+        jobs:
+          - job: main
+            displayName: Build package
+            pool:
+              type: windows
+            variables:
+              ob_outputDirectory: $(Build.SourcesDirectory)/out
+              ob_sdl_codeSignValidation_excludes: -|**\*.js # Node.js JavaScript signatures are not supported
+            steps:
+              - pwsh: |
+                  $version = (Get-Content -Raw -Path package.json | ConvertFrom-Json).version
+                  Write-Output "##vso[task.setvariable variable=vsixVersion;isOutput=true]$version"
+                  $prerelease = ([semver]$version).Minor % 2 -ne 0
+                  if ($prerelease) { $version += "-preview" }
+                  Write-Output "##vso[task.setvariable variable=version;isOutput=true]$version"
+                  Write-Output "##vso[task.setvariable variable=prerelease;isOutput=true]$prerelease"
+                name: package
+                displayName: Get version from package.json
+              - task: onebranch.pipeline.version@1
+                displayName: Set OneBranch version
+                inputs:
+                  system: Custom
+                  customVersion: $(package.version)
+              - task: UseNode@1
+                displayName: Use Node 20.x
+                inputs:
+                  version: 20.x
+              - task: DownloadPipelineArtifact@2
+                displayName: Download PowerShellEditorServices
+                inputs:
+                  source: specific
+                  project: PowerShellCore
+                  definition: 2905
+                  specificBuildWithTriggering: true
+                  allowPartiallySucceededBuilds: true
+                  buildVersionToDownload: latestFromBranch
+                  branchName: refs/heads/main
+                  artifact: drop_build_main
+              - task: ExtractFiles@1
+                displayName: Extract PowerShellEditorServices
+                inputs:
+                  archiveFilePatterns: $(Pipeline.Workspace)/PowerShellEditorServices.zip
+                  destinationFolder: $(Build.SourcesDirectory)/modules
+              - pwsh: |
+                  $manifest = Test-ModuleManifest $(Build.SourcesDirectory)/modules/PowerShellEditorServices/PowerShellEditorServices.psd1
+                  Write-Host Using PowerShellEditorServices v$($manifest.Version)
+                displayName: PowerShellEditorServices version
+              - pwsh: ./tools/installPSResources.ps1 -PSRepository CFS
+                displayName: Install PSResources
+              - pwsh: Invoke-Build Test -Configuration $(BuildConfiguration)
+                displayName: Build and test
+              - task: onebranch.pipeline.signing@1
+                displayName: Sign 1st-party example PowerShell files
+                inputs:
+                  command: sign
+                  signing_profile: external_distribution
+                  search_root: $(Build.SourcesDirectory)/examples
+                  files_to_sign: "**/*.ps1;**/*.psd1;**/*.psm1"
+              - pwsh: Invoke-Build Package
+                displayName: Create package
+              - pwsh: |
+                  npx vsce generate-manifest --packagePath out/powershell-$(package.vsixVersion).vsix
+                  cp out/powershell-$(package.vsixVersion).manifest out/powershell-$(package.vsixVersion).signature.p7s
+                displayName: Generate VSIX manifest
+              - task: onebranch.pipeline.signing@1
+                displayName: Sign VSIX manifest
+                inputs:
+                  command: sign
+                  cp_code: "CP-401405-VSCodePublisherSign"
+                  search_root: $(Build.SourcesDirectory)/out
+                  files_to_sign: "*.signature.p7s"
+      - stage: release
+        dependsOn: build
+        condition: eq(variables['Build.Reason'], 'Manual')
+        variables:
+          ob_release_environment: Production
+          version: $[ stageDependencies.build.main.outputs['package.version'] ]
+          vsixVersion: $[ stageDependencies.build.main.outputs['package.vsixVersion'] ]
+          prerelease: $[ stageDependencies.build.main.outputs['package.prerelease'] ]
+        jobs:
+          - job: github
+            displayName: Publish draft to GitHub
+            pool:
+              type: release
+            templateContext:
+              inputs:
+                - input: pipelineArtifact
+                  artifactName: drop_build_main
+            steps:
+              - task: GitHubRelease@1
+                displayName: Create GitHub release
+                inputs:
+                  gitHubConnection: GitHub
+                  repositoryName: PowerShell/vscode-powershell
+                  target: main
+                  assets: |
+                    $(Pipeline.Workspace)/powershell-$(vsixVersion).vsix
+                    $(Pipeline.Workspace)/powershell-$(vsixVersion).manifest
+                    $(Pipeline.Workspace)/powershell-$(vsixVersion).signature.p7s
+                  tagSource: userSpecifiedTag
+                  tag: v$(version)
+                  isDraft: true
+                  isPreRelease: $(prerelease)
+                  addChangeLog: false
+                  releaseNotesSource: inline
+                  releaseNotesInline: "<!-- TODO: Generate release notes on GitHub! -->"
+          - job: validation
+            displayName: Manual validation
+            pool:
+              type: server
+            timeoutInMinutes: 1440
+            steps:
+              - task: ManualValidation@0
+                displayName: Wait 24 hours for validation
+                inputs:
+                  notifyUsers: $(Build.RequestedForEmail)
+                  instructions: Please validate the release and then publish it!
+          - job: vscode
+            dependsOn: validation
+            displayName: Publish to VS Code Marketplace
+            pool:
+              type: release
+            templateContext:
+              inputs:
+                - input: pipelineArtifact
+                  artifactName: drop_build_main
+              workflow: vsce
+              vsce:
+                serviceConnection: vscode-marketplace
+                vsixPath: "$(Pipeline.Workspace)/powershell-$(vsixVersion).vsix"
+                signaturePath: "$(Pipeline.Workspace)/powershell-$(vsixVersion).signature.p7s"
+                manifestPath: "$(Pipeline.Workspace)/powershell-$(vsixVersion).manifest"
+                preRelease: $(prerelease)
+                useCustomVSCE: true
+                feed:
+                  organization: mscodehub
+                  project: PowerShellCore
+                  feedName: PowerShellCore_PublicPackages
+            steps:
+              - pwsh: |
+                  Write-Host Publishing: $(vsixVersion), pre-release: $(prerelease)
+                displayName: No-op step to satisfy pipeline requirements
diff --git a/.poshchan/settings.json b/.poshchan/settings.json
deleted file mode 100644
index 383cedb7b0..0000000000
--- a/.poshchan/settings.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "version": "0.1",
-  "azdevops": {
-    "build_targets": {
-      "ci": "vscode-powershell-ci"
-    },
-    "authorized_users": [
-      "adityapatwardhan",
-      "anmenaga",
-      "bergmeister",
-      "daxian-dbw",
-      "JamesWTruher",
-      "PaulHigin",
-      "rjmholt",
-      "rkeithhill",
-      "SeeminglyScience",
-      "SteveL-MSFT",
-      "TravisEz13",
-      "TylerLeonhardt"
-    ]
-  },
-  "failures": {
-    "authorized_users": [
-      "adityapatwardhan",
-      "anmenaga",
-      "bergmeister",
-      "daxian-dbw",
-      "glennsarti",
-      "JamesWTruher",
-      "PaulHigin",
-      "rjmholt",
-      "rkeithhill",
-      "SeeminglyScience",
-      "SteveL-MSFT",
-      "TravisEz13",
-      "TylerLeonhardt"
-    ]
-  },
-  "reminders": {
-    "authorized_users": "*"
-  }
-}
\ No newline at end of file
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000000..3772289cad
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,3 @@
+dist/
+modules/
+out/
diff --git a/.vscode-test.mjs b/.vscode-test.mjs
new file mode 100644
index 0000000000..7b14da081f
--- /dev/null
+++ b/.vscode-test.mjs
@@ -0,0 +1,21 @@
+import { defineConfig } from "@vscode/test-cli";
+import { existsSync } from "fs";
+
+export default defineConfig({
+    files: "test/**/*.test.ts",
+    // It may break CI but we'll know sooner rather than later
+    version: "insiders",
+    launchArgs: [
+        // Other extensions are unnecessary while testing
+        "--disable-extensions",
+        // Undocumented but valid option to use a temporary profile for testing
+        "--profile-temp",
+    ],
+    workspaceFolder: `test/${existsSync("C:\\powershell-7\\pwsh.exe") ? "OneBranch" : "TestEnvironment"}.code-workspace`,
+    mocha: {
+        ui: "bdd", // describe, it, etc.
+        require: ["esbuild-register"], // transpile TypeScript on-the-fly
+        slow: 2 * 1000, // 2 seconds for slow test
+        timeout: 2 * 60 * 1000, // 2 minutes to allow for debugging
+    },
+});
diff --git a/.vscodeignore b/.vscodeignore
index d04733defc..a056db7fb7 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -1,27 +1,10 @@
-.github/
-.poshchan/
-.vscode/
-.vscode-test/
-.vsts-ci/
-logs/
-node_modules/
-out/
-scripts/
-sessions/
-src/
-test/
-tools/
-
-!out/main.js
-
-.editorconfig
-.gitattributes
-.gitignore
-.markdownlint.json
-.vscodeignore
-build.ps1
-extension-dev.code-workspace
-*.vsix
-tsconfig.json
-tslint.json
-vscode-powershell.build.ps1
+**
+!*.md
+!*.txt
+!dist/extension.js
+!docs/
+!examples/
+!media/
+!modules/
+!snippets/
+!themes/
diff --git a/.vsts-ci/azure-pipelines-ci.yml b/.vsts-ci/azure-pipelines-ci.yml
deleted file mode 100644
index 5611ae8543..0000000000
--- a/.vsts-ci/azure-pipelines-ci.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr)
-
-variables:
-  # Don't download unneeded packages
-  - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
-    value: 'true'
-  # Improve performance by not sending telemetry
-  - name: DOTNET_CLI_TELEMETRY_OPTOUT
-    value: 'true'
-
-trigger:
-  branches:
-    include:
-      - master
-
-resources:
-  repositories:
-  - repository: PowerShellEditorServices
-    type: github
-    endpoint: GitHub
-    name: PowerShell/PowerShellEditorServices
-    ref: master
-
-jobs:
-- job: PS51_Win2019
-  displayName: PowerShell 5.1 - Windows Server 2019
-  pool:
-    vmImage: windows-2019
-  steps:
-  - template: templates/ci-general.yml
-    parameters:
-      pwsh: false
-
-- job: PS7_Win2019
-  displayName: PowerShell 7 - Windows Server 2019
-  pool:
-    vmImage: windows-2019
-  steps:
-  - template: templates/ci-general.yml
-
-- job: PS7_macOS
-  displayName: PowerShell 7 - macOS 10.15
-  pool:
-    vmImage: macOS-10.15
-  steps:
-  - template: templates/ci-general.yml
-
-- job: PS7_Ubuntu
-  displayName: PowerShell 7 - Ubuntu 20.04
-  pool:
-    vmImage: ubuntu-20.04
-  steps:
-  - template: templates/ci-general.yml
diff --git a/.vsts-ci/azure-pipelines-release.yml b/.vsts-ci/azure-pipelines-release.yml
deleted file mode 100644
index f1d7b90b86..0000000000
--- a/.vsts-ci/azure-pipelines-release.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-name: Release-$(Build.SourceBranchName)-$(Date:yyyyMMdd)$(Rev:.rr)
-
-variables:
-  # Don't download unneeded packages
-  - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
-    value: 'true'
-  # Improve performance by not sending telemetry
-  - name: DOTNET_CLI_TELEMETRY_OPTOUT
-    value: 'true'
-
-trigger: none
-
-resources:
-  repositories:
-  - repository: ComplianceRepo
-    type: github
-    endpoint: GitHub
-    name: PowerShell/Compliance
-
-  - repository: PowerShellEditorServices
-    type: git
-    name: PowerShellEditorServices
-    ref: release
-
-  pipelines:
-  - pipeline: PowerShellEditorServices
-    source: PowerShellEditorServices
-    trigger:
-      branches:
-      - release
-
-stages:
-- stage: Build
-  displayName: Build the release
-  jobs:
-  - job: Build
-    pool:
-      name: 1ES
-      demands: ImageOverride -equals PSMMS2019-Secure
-    steps:
-    - template: templates/ci-general.yml
-      parameters:
-        usePipelineArtifact: true
-
-- stage: Sign
-  displayName: Sign the release
-  jobs:
-  - job: Sign
-    pool:
-      name: 1ES
-      demands: ImageOverride -equals PSMMS2019-Secure
-    variables:
-    - group: ESRP
-    steps:
-    - template: templates/release-general.yml
-
-- stage: PublishGitHub
-  displayName: Publish the draft release
-  jobs:
-  - deployment: Publish
-    environment: vscode-powershell-github
-    pool:
-      name: 1ES
-      demands: ImageOverride -equals PSMMSUbuntu20.04-Secure
-    variables:
-    - group: Publish
-    strategy:
-      runOnce:
-        deploy:
-          steps:
-          - template: templates/publish-github.yml
-
-- stage: PublishMarkets
-  displayName: Publish to marketplace and gallery
-  jobs:
-  - deployment: Publish
-    environment: vscode-powershell-markets
-    pool:
-      name: 1ES
-      demands: ImageOverride -equals PSMMSUbuntu20.04-Secure
-    variables:
-    - group: Publish
-    strategy:
-      runOnce:
-        deploy:
-          steps:
-          - template: templates/publish-markets.yml
diff --git a/.vsts-ci/misc-analysis.yml b/.vsts-ci/misc-analysis.yml
deleted file mode 100644
index 388993c01c..0000000000
--- a/.vsts-ci/misc-analysis.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr)
-
-trigger:
-  branches:
-    include:
-    - master
-
-pr:
-- master
-
-resources:
-  repositories:
-  - repository: ComplianceRepo
-    type: github
-    endpoint: GitHub
-    name: PowerShell/compliance
-
-jobs:
-- job: Compliance
-  pool:
-    vmImage: windows-latest
-  steps:
-  - checkout: self
-  - checkout: ComplianceRepo
-  - template: ci-compliance.yml@ComplianceRepo
-# NOTE: This enables our project to work with Visual Studio's Rich Navigation:
-# https://visualstudio.microsoft.com/services/rich-code-navigation/
-- job: RichCodeNav
-  pool:
-    vmImage: windows-latest
-  steps:
-  # TODO: Move to GitHub Action
-  - task: RichCodeNavIndexer@0
-    continueOnError: true
-    inputs:
-      serviceConnection: rich-nav
-      nugetServiceConnection: rich-nav-nuget
-      githubServiceConnection: PowerShell
-      languages: typescript,csharp
-      serviceEndpoint: https://prod.richnav.vsengsaas.visualstudio.com
diff --git a/.vsts-ci/templates/ci-general.yml b/.vsts-ci/templates/ci-general.yml
deleted file mode 100644
index d4a042048c..0000000000
--- a/.vsts-ci/templates/ci-general.yml
+++ /dev/null
@@ -1,86 +0,0 @@
-parameters:
-  - name: pwsh
-    type: boolean
-    default: true
-  - name: usePipelineArtifact
-    type: boolean
-    default: false
-
-steps:
-- task: PowerShell@2
-  displayName: PowerShell version
-  inputs:
-    targetType: inline
-    script: $PSVersionTable
-    pwsh: ${{ parameters.pwsh }}
-
-- checkout: self
-
-# NOTE: We either checkout the Git repo for PowerShellEditorServices, or we
-# download a pre-built artifact from the triggering pipeline and extract it to
-# the modules folder. In this way we do not accidentally build a release of the
-# server from this pipeline.
-- checkout: PowerShellEditorServices
-  condition: not(${{ parameters.usePipelineArtifact }})
-
-- task: DownloadPipelineArtifact@2
-  condition: ${{ parameters.usePipelineArtifact }}
-  displayName: Download PowerShellEditorServices
-  inputs:
-    source: specific
-    project: PowerShellEditorServices
-    pipeline: 36
-    preferTriggeringPipeline: true
-    allowPartiallySucceededBuilds: true
-    artifact: PowerShellEditorServices
-
-- task: ExtractFiles@1
-  condition: ${{ parameters.usePipelineArtifact }}
-  displayName: Extract PowerShellEditorServices module
-  inputs:
-    archiveFilePatterns: $(Pipeline.Workspace)/PowerShellEditorServices.zip
-    destinationFolder: $(Build.SourcesDirectory)/vscode-powershell/modules
-
-- task: UseDotNet@2
-  condition: not(${{ parameters.usePipelineArtifact }})
-  displayName: Install .NET 6.0.x SDK
-  inputs:
-    packageType: sdk
-    version: 6.0.x
-    performMultiLevelLookup: true
-
-- task: UseDotNet@2
-  condition: not(${{ parameters.usePipelineArtifact }})
-  displayName: Install .NET 3.1.x runtime
-  inputs:
-    packageType: runtime
-    version: 3.1.x
-    performMultiLevelLookup: true
-
-- task: PowerShell@2
-  displayName: Build and test
-  inputs:
-    targetType: inline
-    script: |
-      Get-Module -ListAvailable Pester
-      Install-Module InvokeBuild -Scope CurrentUser -Force
-      Install-Module platyPS -Scope CurrentUser -Force
-      Invoke-Build -Configuration Release
-      Write-Host "##vso[task.setvariable variable=vsixPath]$(Resolve-Path powershell-*.vsix)"
-    workingDirectory: $(Build.SourcesDirectory)/vscode-powershell
-    pwsh: ${{ parameters.pwsh }}
-
-- publish: $(vsixPath)
-  artifact: vscode-powershell-vsix-$(System.JobId)
-  displayName: Publish extension artifact
-
-- publish: $(Build.SourcesDirectory)/vscode-powershell/scripts/Install-VSCode.ps1
-  artifact: vscode-powershell-unsigned-script-$(System.JobId)
-  displayName: Publish unsigned script artifact
-
-- task: PublishTestResults@2
-  displayName: Publish test results
-  inputs:
-    testRunner: JUnit
-    testResultsFiles: '**/test-results.xml'
-  condition: succeededOrFailed()
diff --git a/.vsts-ci/templates/credscan.yml b/.vsts-ci/templates/credscan.yml
deleted file mode 100644
index eb711c8e0f..0000000000
--- a/.vsts-ci/templates/credscan.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-parameters:
-  pool: 'Hosted VS2017'
-  jobName: 'credscan'
-  displayName: Secret Scan
-
-jobs:
-- job: ${{ parameters.jobName }}
-  pool:
-    name: ${{ parameters.pool }}
-
-  displayName: ${{ parameters.displayName }}
-
-  steps:
-  - powershell:  Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))"
-    displayName: Set Build Name for Non-PR
-    condition: ne(variables['Build.Reason'], 'PullRequest')
-
-  - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
-    displayName: 'Scan for secrets'
-    inputs:
-      debugMode: false
-
-  - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
-    displayName: 'Publish Secret Scan Logs to Build Artifacts'
-    continueOnError: true
-
-  - task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1
-    displayName: 'Check for failures'
-    inputs:
-      CredScan: true
-      ToolLogsNotFoundAction: Error
diff --git a/.vsts-ci/templates/publish-github.yml b/.vsts-ci/templates/publish-github.yml
deleted file mode 100644
index c2c17feeda..0000000000
--- a/.vsts-ci/templates/publish-github.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-steps:
-- checkout: self
-
-- download: current
-  artifact: vscode-powershell
-  displayName: Download signed artifacts
-
-- pwsh: |
-    $(Build.SourcesDirectory)/tools/setupReleaseTools.ps1 -Token $(GitHubToken)
-    New-DraftRelease -RepositoryName vscode-powershell -Assets $(Pipeline.Workspace)/vscode-powershell/powershell-*.vsix,$(Pipeline.Workspace)/vscode-powershell/Install-VSCode.ps1
-  displayName: Drafting a GitHub Release
diff --git a/.vsts-ci/templates/publish-markets.yml b/.vsts-ci/templates/publish-markets.yml
deleted file mode 100644
index e7d278754b..0000000000
--- a/.vsts-ci/templates/publish-markets.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-steps:
-- checkout: self
-
-- download: current
-  artifact: vscode-powershell
-  displayName: Download signed artifacts
-
-- pwsh: |
-    npm ci --loglevel=error
-    npm run publish -- --packagePath $(Pipeline.Workspace)/vscode-powershell/powershell-*.vsix --pat $(VsceToken)
-  displayName: Publishing VSIX to VS Code Marketplace
-
-# NOTE: We rarely update this script, so we can ignore errors from the gallery
-# caused by us trying to re-publish an updated script.
-- pwsh: |
-    Publish-Script -Path $(Pipeline.Workspace)/vscode-powershell/Install-VSCode.ps1 -NuGetApiKey $(GalleryToken)
-  displayName: Publishing Install-VSCode.ps1 to PowerShell Gallery
-  continueOnError: true
diff --git a/.vsts-ci/templates/release-general.yml b/.vsts-ci/templates/release-general.yml
deleted file mode 100644
index 65c71e47c6..0000000000
--- a/.vsts-ci/templates/release-general.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-steps:
-- download: current
-  displayName: Download pipeline artifacts
-
-- checkout: ComplianceRepo
-
-- template: EsrpSign.yml@ComplianceRepo
-  parameters:
-    buildOutputPath: $(Pipeline.Workspace)/vscode-powershell-unsigned-script-*
-    signOutputPath: $(Pipeline.Workspace)/signed
-    alwaysCopy: true
-    certificateId: CP-230012 # Authenticode certificate
-    shouldSign: true # We always want to sign
-    # NOTE: Code AKA *.vsix files are not signed
-    pattern: Install-VSCode.ps1
-
-# NOTE: Because the scan template doesn't copy (unlike the sign template), we do
-# it ourselves so that we can publish one finished artifact.
-- pwsh: Copy-Item -Path $(Pipeline.Workspace)/vscode-powershell-vsix-*/*.vsix -Destination $(Pipeline.Workspace)/signed -Verbose
-  displayName: Copy extension to signed folder
-
-- template: EsrpScan.yml@ComplianceRepo
-  parameters:
-    scanPath: $(Pipeline.Workspace)/signed
-    pattern: powershell-*.vsix
-
-- checkout: self
-
-- template: Sbom.yml@ComplianceRepo
-  parameters:
-    BuildDropPath: $(Pipeline.Workspace)/signed
-    Build_Repository_Uri: https://github.com/PowerShell/vscode-powershell.git
-    packageName: vscode-powershell
-    packageVersion: $(System.JobId)
-    sourceScanPath: $(Build.SourcesDirectory)/vscode-powershell
-
-- template: script-module-compliance.yml@ComplianceRepo
-  parameters:
-    # component-governance
-    sourceScanPath: $(Build.SourcesDirectory)/vscode-powershell
-    # credscan
-    suppressionsFile: $(Build.SourcesDirectory)/vscode-powershell/tools/credScan/suppress.json
-    # TermCheck AKA PoliCheck
-    targetArgument: $(Build.SourcesDirectory)/vscode-powershell
-    optionsUEPATH: $(Build.SourcesDirectory)/vscode-powershell/tools/terms/UserExclusions.xml
-    optionsRulesDBPath: ''
-    optionsFTPath: $(Build.SourcesDirectory)/vscode-powershell/tools/terms/FileTypeSet.xml
-    # tsa-upload
-    codeBaseName: PowerShell_PowerShellEditorServices_20210201
-    # We don't use any Windows APIs directly, so we don't need API scan
-    APIScan: false
-
-- publish: $(Pipeline.Workspace)/signed
-  artifact: vscode-powershell
-  displayName: Publish signed artifacts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc815c4488..35e51191bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,1603 @@
 # PowerShell Extension Release History
 
+## v2025.2.0
+### Monday, June 30, 2025
+
+With PowerShell Editor Services [v4.3.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.3.0)!
+
+New stable release!
+
+See more details at the GitHub Release for [v2025.2.0](https://github.com/PowerShell/vscode-powershell/releases/tag/v2025.2.0).
+
+## v2025.3.1-preview
+### Wednesday, June 25, 2025
+
+With PowerShell Editor Services [v4.3.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.3.0)!
+
+PowerShell installed via `brew` now found!
+
+See more details at the GitHub Release for [v2025.3.1-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2025.3.1-preview).
+
+## v2025.3.0-preview
+### Tuesday, March 18, 2025
+
+With PowerShell Editor Services [v4.3.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.3.0)!
+
+Now with [PSScriptAnalyzer v1.2.4](https://github.com/PowerShell/PSScriptAnalyzer/releases/tag/1.24.0)
+and [PSReadLine v2.4.1-beta1](https://github.com/PowerShell/PSReadLine/releases/tag/v2.4.1-beta1).
+
+See more details at the GitHub Release for [v2025.3.0-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2025.3.0-preview).
+
+## v2025.0.0
+### Tuesday, January 21, 2025
+
+With PowerShell Editor Services [v4.2.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.2.0)!
+
+New Year Update!
+
+PowerShell 7.4+ and Windows PowerShell 5.1 (on a best-effort basis)
+are now solely supported as 7.3 LTS and 7.2 are past end-of-support.
+
+A major bug due to a Global Assembly Cache conflict with Serilog
+when using Windows PowerShell has been resolved by removing the
+troublesome dependency. This also came with a wonderful logging
+overhaul for both the server and client. Thanks Justin!
+
+Dependencies and VS Code engine have been updated. Snippets fixed.
+Extension settings are now categorized. Additional PowerShell
+executable path verification fixed.
+
+See more details at the GitHub Release for [v2025.0.0](https://github.com/PowerShell/vscode-powershell/releases/tag/v2025.0.0).
+
+## v2025.1.0-preview
+### Thursday, January 16, 2025
+
+With PowerShell Editor Services [v4.2.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.2.0)!
+
+VS Code engine update and snippet fix
+
+See more details at the GitHub Release for [v2025.1.0-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2025.1.0-preview).
+
+## v2024.5.2-preview
+### Wednesday, December 04, 2024
+
+With PowerShell Editor Services [v4.1.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.1.0)!
+
+Bug fixes and build improvements.
+
+See more details at the GitHub Release for [v2024.5.2-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.5.2-preview).
+
+## v2024.5.1-preview
+### Monday, November 18, 2024
+
+With PowerShell Editor Services [v4.0.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v4.0.0)!
+
+Drop support for PowerShell <7.4 and logging overhaul
+
+PowerShell 7.2 LTS and 7.3 are now past end-of-support and are now unsupported.
+This is an incompatible API change so we're bumping the major version
+of PowerShell Editor Services.
+Please update to PowerShell 7.4 LTS going forward.
+
+This release contains a logging overhaul which purposely removes our
+dependency on Serilog and should lead to improved stability with
+PowerShell 5.1 (by avoiding a major GAC assembly conflict).
+
+See more details at the GitHub Release for [v2024.5.1-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.5.1-preview).
+
+## v2024.4.0
+### Monday, November 04, 2024
+
+With PowerShell Editor Services [v3.21.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v3.21.0)!
+
+Call-operator support and various bug fixes.
+
+See more details at the GitHub Release for [v2024.4.0](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.4.0).
+
+## v2024.5.0-preview
+### Wednesday, October 30, 2024
+
+With PowerShell Editor Services [v3.21.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v3.21.0)!
+
+Call-operator support and various bug fixes.
+
+See more details at the GitHub Release for [v2024.5.0-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.5.0-preview).
+
+## v2024.2.2
+### Friday, May 03, 2024
+
+With PowerShell Editor Services [v3.20.1](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v3.20.1)!
+
+Update third-party notices.
+
+See more details at the GitHub Release for [v2024.2.2](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.2.2).
+
+## v2024.2.1
+### Tuesday, April 16, 2024
+
+With PowerShell Editor Services [v3.20.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v3.20.0)!
+
+Hotfix for incorrect signing certificate, sorry about that!
+
+Also removed Plaster integration as we were unable to correctly sign it since we no longer own it.
+
+See more details at the GitHub Release for [v2024.2.1](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.2.1).
+
+## v2024.2.0
+### Monday, April 08, 2024
+
+With PowerShell Editor Services [v3.19.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v3.19.0)!
+
+New stable release!
+
+This release comes with PSReadLine v2.4.0-beta0 and PSScriptAnalyzer v1.22.0.
+
+It includes an overhauled support for Terminal Shell Integration,
+so it always supports VS Code's latest features!
+
+The codebase was cleaned up by the removal of several deprecated features.
+Multiple bugs were fixed in the shutdown process,
+default debugger configurations and IntelliSense.
+A setting was added to allow the exclusion of the execution policy CLI argument at startup,
+so that users in restricted environments are better able to launch the extension.
+
+This release went through three pre-releases.
+Thank you so much to all our beta testers and users for your contributions.
+
+See more details at the GitHub Release for [v2024.2.0](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.2.0).
+
+## v2024.3.2-preview
+### Wednesday, April 03, 2024
+
+With PowerShell Editor Services [v3.19.0](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v3.19.0)!
+
+Overhauled Terminal Shell Integration!
+
+See more details at the GitHub Release for [v2024.3.2-preview](https://github.com/PowerShell/vscode-powershell/releases/tag/v2024.3.2-preview).
+
+## v2024.3.1-preview
+### Tuesday, March 5, 2024
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🙏 [vscode-powershell #4932](https://github.com/PowerShell/vscode-powershell/pull/4934) - Don't make the Command Explorer visible by default.
+- ✨ 💭 [vscode-powershell #4933](https://github.com/PowerShell/vscode-powershell/pull/4933) - Fix how we pass the log directory to Editor Services.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.18.0
+
+- ✨ 📟 [PowerShellEditorServices #2148](https://github.com/PowerShell/PowerShellEditorServices/pull/2148) - Update to PSReadLine v2.4.0-beta0.
+- ✨ 📟 [PowerShellEditorServices #2141](https://github.com/PowerShell/PowerShellEditorServices/pull/2141) - Update to PSScriptAnalyzer v1.22.0.
+- ✨ 👷 [PowerShellEditorServices #2138](https://github.com/PowerShell/PowerShellEditorServices/pull/2138) - Fixed sln file. (Thanks @dkattan!)
+- #️⃣ 🙏 [PowerShellEditorServices #2137](https://github.com/PowerShell/PowerShellEditorServices/pull/2137) - Fixed TextReader disposal. (Thanks @dkattan!)
+- 🐛#️⃣ 🙏 [PowerShellEditorServices #2135](https://github.com/PowerShell/PowerShellEditorServices/pull/2135) - Fix PowerShell 7.2 E2E unit test for last change.
+- ✨ 🛫 [PowerShellEditorServices #1855](https://github.com/PowerShell/PowerShellEditorServices/pull/2129) - Add sane defaults to `Start-EditorServices`.
+- ✨#️⃣ 🙏 [PowerShellEditorServices #2122](https://github.com/PowerShell/PowerShellEditorServices/pull/2122) - Add `UseNullPSHostUI` config so apps hosting PSES can disable it. (Thanks @dkattan!)
+- 🐛 🧠 [PowerShellEditorServices #2115](https://github.com/PowerShell/PowerShellEditorServices/pull/2115) - Added null check to `GetCompletionsAsync`. (Thanks @dkattan!)
+
+## v2024.3.0-preview
+### Thursday, January 25, 2024
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🚂 [vscode-powershell #4902](https://github.com/PowerShell/vscode-powershell/pull/4902) - Enable the native vscode-languageclient tracing option. (Thanks @JustinGrote!)
+- 🐛 📟 [vscode-powershell #4900](https://github.com/PowerShell/vscode-powershell/pull/4900) - Fix `PowerShellProcess.dipose()` to fire the `onExited` event idempotently.
+- ✨ 🚂 [vscode-powershell #4892](https://github.com/PowerShell/vscode-powershell/pull/4893) - Remove deprecated features.
+- 🐛 🔍 [vscode-powershell #4843](https://github.com/PowerShell/vscode-powershell/pull/4888) - Fix up debugger configuration resolvers .
+- ✨ 🔧 [vscode-powershell #3034](https://github.com/PowerShell/vscode-powershell/pull/4883) - Add developer setting to disable `-ExecutionPolicy Bypass` flags.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.17.0
+
+- ✨ 🚂 [PowerShellEditorServices #2132](https://github.com/PowerShell/PowerShellEditorServices/pull/2132) - Remove `PowerShellEditorServices.VSCode` module / `ContentViews` feature.
+- 🐛 🔍 [PowerShellEditorServices #2130](https://github.com/PowerShell/PowerShellEditorServices/pull/2130) - Fix up debugger attach handlers.
+
+## v2024.0.0
+### Wednesday, January 10, 2024
+
+Happy New Year! This stable release includes a bunch if improvements to the LSP server,
+PowerShell Editor Services and comes with a major upgrade to our testing system. Please
+see the below changelog! Going forward we plan to release on a quarterly basis. Thanks for
+being such fantastic users!
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4865](https://github.com/PowerShell/vscode-powershell/pull/4865) - Update CI to install .NET SDK 8.0.
+- ✨ 👷 [vscode-powershell #4860](https://github.com/PowerShell/vscode-powershell/pull/4860) - Bump VS Code engine.
+- #️⃣ 🙏 [vscode-powershell #4833](https://github.com/PowerShell/vscode-powershell/pull/4833) - Setup ``actions/stale`` for issue management.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.14.0-v3.16.0
+
+- 🐛 📟 [vscode-powershell #4854](https://github.com/PowerShell/PowerShellEditorServices/pull/2125) - Update shell integration script to fix command decorations.
+- ✨ 🚨 [PowerShellEditorServices #2124](https://github.com/PowerShell/PowerShellEditorServices/pull/2124) - Test end-to-end with PowerShell Daily.
+- ✨ 👷 [PowerShellEditorServices #2114](https://github.com/PowerShell/PowerShellEditorServices/pull/2114) - Add PowerShell 7.4 SDK and `net8.0` framework.
+- ✨ 🚨 [PowerShellEditorServices #2110](https://github.com/PowerShell/PowerShellEditorServices/pull/2110) - Switch to GitHub Actions for all CI.
+- 🐛 🔍 [vscode-powershell #4816](https://github.com/PowerShell/PowerShellEditorServices/pull/2097) - When the built-in `$null` was watched its value was incorrect.
+- 🐛 🚂 [vscode-powershell #4814](https://github.com/PowerShell/PowerShellEditorServices/pull/2096) - Allow `WorkspacePaths` to be empty if we're not in a workspace.
+- 🐛 📟 [vscode-powershell #4788](https://github.com/PowerShell/PowerShellEditorServices/pull/2091) - Run `SetInitialWorkingDirectoryAsync` before `LoadProfiles`.
+- 🐛 🙏 [vscode-powershell #4784](https://github.com/PowerShell/PowerShellEditorServices/pull/2090) - Ignore `didOpen` notifications for `git` schemed documents from VS Code.
+- 🐛 🙏 [PowerShellEditorServices #2084](https://github.com/PowerShell/PowerShellEditorServices/pull/2084) - Add `SortDocumentSymbols` to make the outline hierarchical (again).
+
+## v2024.1.0-preview
+### Wednesday, January 03, 2024
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4865](https://github.com/PowerShell/vscode-powershell/pull/4865) - Update CI to install .NET SDK 8.0.
+- ✨ 👷 [vscode-powershell #4860](https://github.com/PowerShell/vscode-powershell/pull/4860) - Bump VS Code engine.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.16.0
+
+- 🐛 📟 [vscode-powershell #4854](https://github.com/PowerShell/PowerShellEditorServices/pull/2125) - Update shell integration script to fix command decorations.
+- ✨ 🚨 [PowerShellEditorServices #2124](https://github.com/PowerShell/PowerShellEditorServices/pull/2124) - Test end-to-end with PowerShell Daily.
+- ✨ 👷 [PowerShellEditorServices #2114](https://github.com/PowerShell/PowerShellEditorServices/pull/2114) - Add PowerShell 7.4 SDK and `net8.0` framework.
+- ✨ 🚨 [PowerShellEditorServices #2110](https://github.com/PowerShell/PowerShellEditorServices/pull/2110) - Switch to GitHub Actions for all CI.
+
+## v2023.11.1-preview
+### Thursday, December 07, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4833](https://github.com/PowerShell/vscode-powershell/pull/4833) - Setup ``actions/stale`` for issue management.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.15.0
+
+- 🐛 🔍 [vscode-powershell #4816](https://github.com/PowerShell/PowerShellEditorServices/pull/2097) - When the built-in `$null` was watched its value was incorrect.
+- 🐛 🚂 [vscode-powershell #4814](https://github.com/PowerShell/PowerShellEditorServices/pull/2096) - Allow `WorkspacePaths` to be empty if we're not in a workspace.
+
+## v2023.11.0-preview
+### Tuesday, November 07, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.14.0
+
+- 🐛 📟 [vscode-powershell #4788](https://github.com/PowerShell/PowerShellEditorServices/pull/2091) - Run `SetInitialWorkingDirectoryAsync` before `LoadProfiles`.
+- 🐛 🙏 [vscode-powershell #4784](https://github.com/PowerShell/PowerShellEditorServices/pull/2090) - Ignore `didOpen` notifications for `git` schemed documents from VS Code.
+- 🐛 🙏 [PowerShellEditorServices #2084](https://github.com/PowerShell/PowerShellEditorServices/pull/2084) - Add `SortDocumentSymbols` to make the outline hierarchical (again).
+
+## v2023.8.0
+### Wednesday, October 11, 2023
+
+This one took a while! As always, these changes were available in the pre-release channel
+which went through six versions to get us to today's release.
+
+The `cwd` setting now supports `~` for home directory, relative paths, and named workspace
+folders. The `additionalPowerShellExes` setting also now supports `~`, checks for missing
+extensions if necessary, and both settings smartly strip surrounding quotes from the
+user-supplied value. These two settings are now far more user-friendly.
+
+Thanks to efforts across the team, we are shipping the extension with the latest and
+greatest PSReadLine, `v2.3.4`!
+
+The extension commands AKA `$psEditor` API was reworked and no longer mangles path casing.
+It also now exposes the `CloseFile` and `SaveFile` methods, and supports multi-root
+workspaces.
+
+A new setting `integratedConsole.startLocation` was added to control the Extension
+Terminal's starting position. Thanks @krishankanumuri!
+
+To wrap things up, another crash when `$ErrorActionPreference = "stop"` was resolved. A
+race condition for the language status item's name and icon was fixed. Our telemetry went
+down after a package upgrade which required a cross-team effort to resolve (it's now also
+cleaned up to send just what we're using). The DSC breakpoints capability now works as
+intended without causing module load errors or emitting "sticky" progress information. A
+bug when the log level was set to `None` broke the server was fixed. Our server's major
+dependency, OmniSharp's `csharp-language-server-protocol`, was updated to v0.19.9 which
+means we can now use the current LSP spec v3.17. We had to work with the project to
+resolve a serialization regression. Finally, a lot of various build improvements were
+made.
+
+Please note the change in our versioning schema: the middle version number no longer
+corresponds to the month, but is simply incremented. Even versions are stable, and odd
+versions are pre-release, with the latter purposefully being versioned higher than the
+former in order to keep both channels available in the Visual Studio Code marketplace.
+
+Thanks to all the many community contributors whose efforts make releases such as these
+possible!
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🙏 [vscode-powershell #4780](https://github.com/PowerShell/vscode-powershell/pull/4780) - Stop hiding Activity Bar in ISE Mode.
+- #️⃣ 🙏 [vscode-powershell #4762](https://github.com/PowerShell/vscode-powershell/pull/4763) - Downgrade `vscode-languageclient` to v8.1.0.
+- ✨ 📖 [vscode-powershell #4739](https://github.com/PowerShell/vscode-powershell/pull/4739) - Add official support policy document.
+- ⚡️ 💭 [vscode-powershell #4734](https://github.com/PowerShell/vscode-powershell/pull/4734) - Remove unused telemetry.
+- ✨ 📖 [vscode-powershell #4729](https://github.com/PowerShell/vscode-powershell/pull/4729) - Add note about installing ESLint globally for VS Code extension.
+- #️⃣ 🙏 [vscode-powershell #4711](https://github.com/PowerShell/vscode-powershell/pull/4711) - Update extension telemetry dependency.
+- ✨ 👷 [vscode-powershell #4707](https://github.com/PowerShell/vscode-powershell/pull/4707) - Move `--sourcemap` to scripts instead of `Invoke-Build`. (Thanks @JustinGrote!)
+- #️⃣ 🙏 [vscode-powershell #4702](https://github.com/PowerShell/vscode-powershell/pull/4704) - Use a `CustomRequest` to disconnect the dotnet debugger from attach sessions. (Thanks @JustinGrote!)
+- 🐛 🙏 [vscode-powershell #2960](https://github.com/PowerShell/vscode-powershell/pull/4703) - Respect file path casing in extension commands.
+- 🐛 📺 [vscode-powershell #4696](https://github.com/PowerShell/vscode-powershell/pull/4696) - Fix race condition with displaying PowerShell name on icon.
+- 🐛 🔧 [vscode-powershell #4557](https://github.com/PowerShell/vscode-powershell/pull/4687) - Support `~`, `./` and named workspace folders in `cwd`.
+- ✨ 🔧 [vscode-powershell #4686](https://github.com/PowerShell/vscode-powershell/pull/4686) - Enhance `additionalPowerShellExes` setting.
+- #️⃣ 🙏 [vscode-powershell #4684](https://github.com/PowerShell/vscode-powershell/pull/4684) - Remove LinkEditorServices comment in development.md. (Thanks @fflaten!)
+- #️⃣ 🙏 [vscode-powershell #4676](https://github.com/PowerShell/vscode-powershell/pull/4676) - Move ESLint Dependabot group to npm. (Thanks @fflaten!)
+- #️⃣ 🙏 [vscode-powershell #4667](https://github.com/PowerShell/vscode-powershell/pull/4667) - Bump ESLint packages to v6.
+- #️⃣ 🙏 [vscode-powershell #4661](https://github.com/PowerShell/vscode-powershell/pull/4661) - Update readme.
+- 🐛 👷 [vscode-powershell #4651](https://github.com/PowerShell/vscode-powershell/pull/4651) - Fix unit test for Windows running on arm64.
+- ✨ 👷 [vscode-powershell #4641](https://github.com/PowerShell/vscode-powershell/pull/4641) - Update VS Code engine to 1.79.0.
+- ✨ 🔧 [vscode-powershell #4181](https://github.com/PowerShell/vscode-powershell/pull/4639) - Add `startLocation` setting for Extension Terminal. (Thanks @krishankanumuri!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.13.0
+
+- ✨ 📟 [PowerShellEditorServices #2087](https://github.com/PowerShell/PowerShellEditorServices/pull/2087) - Upgrade bundled PSReadLine module to v2.3.4.
+- 🐛 🔍 [PowerShellEditorServices #2081](https://github.com/PowerShell/PowerShellEditorServices/pull/2081) - Silence progress output of `Get-DscResource` (take two).
+- 🐛 🚂 [PowerShellEditorServices #2083](https://github.com/PowerShell/PowerShellEditorServices/pull/2083) - Upgrade OmniSharp to v0.19.9.
+- ✨ 📟 [PowerShellEditorServices #2080](https://github.com/PowerShell/PowerShellEditorServices/pull/2080) - Bump to new PSReadLine stable release v2.3.3.
+- 🐛 🔍 [PowerShellEditorServices #2068](https://github.com/PowerShell/PowerShellEditorServices/pull/2068) - Wrap import of DSC module with `ProgressPreference = SilentlyContinue`.
+- 🐛 💭 [vscode-powershell #4735](https://github.com/PowerShell/PowerShellEditorServices/pull/2066) - Add `None` to `PsesLogLevel` enum.
+- ⚡️ 💭 [PowerShellEditorServices #2065](https://github.com/PowerShell/PowerShellEditorServices/pull/2065) - Remove unused telemetry.
+- 🐛 🔍 [vscode-powershell #3904](https://github.com/PowerShell/PowerShellEditorServices/pull/2064) - Fix debugging script blocks that aren't in files.
+- 🐛 🚂 [vscode-powershell #3971](https://github.com/PowerShell/PowerShellEditorServices/pull/2062) - Import `PSDesiredStateConfiguration` by name.
+- 🐛 🔍 [PowerShellEditorServices #2037](https://github.com/PowerShell/PowerShellEditorServices/pull/2058) - Ignore not finding DSC module.
+- ✨ 🚨 [vscode-powershell #3484](https://github.com/PowerShell/PowerShellEditorServices/pull/2055) - Move `ConstrainedLanguageMode` tests to separate task.
+- ✨ 📟 [PowerShellEditorServices #2054](https://github.com/PowerShell/PowerShellEditorServices/pull/2054) - Update PSReadLine to `v2.3.2-beta2`.
+- ✨ 🙏 [PowerShellEditorServices #2053](https://github.com/PowerShell/PowerShellEditorServices/pull/2053) - Fix up extension API.
+- 🐛 📟 [PowerShellEditorServices #2050](https://github.com/PowerShell/PowerShellEditorServices/pull/2052) - Fix shell integration for PowerShell 5.1 with strict mode.
+- ✨ 📟 [PowerShellEditorServices #2046](https://github.com/PowerShell/PowerShellEditorServices/pull/2046) - Bump PSReadLine to beta for extension preview.
+
+## v2023.9.5-preview
+### Tuesday, October 10, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🙏 [vscode-powershell #4780](https://github.com/PowerShell/vscode-powershell/pull/4780) - Stop hiding Activity Bar in ISE Mode.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.13.0
+
+- ✨ 📟 [PowerShellEditorServices #2087](https://github.com/PowerShell/PowerShellEditorServices/pull/2087) - Upgrade bundled PSReadLine module to v2.3.4.
+
+## v2023.9.4-preview
+### Friday, September 29, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4762](https://github.com/PowerShell/vscode-powershell/pull/4763) - Downgrade `vscode-languageclient` to v8.1.0.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.12.0
+
+Just updating the client above.
+
+## v2023.9.3-preview
+### Thursday, September 28, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📖 [vscode-powershell #4739](https://github.com/PowerShell/vscode-powershell/pull/4739) - Add official support policy document.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.12.0
+
+- 🐛 🔍 [PowerShellEditorServices #2081](https://github.com/PowerShell/PowerShellEditorServices/pull/2081) - Silence progress output of `Get-DscResource` (take two).
+- 🐛 🚂 [PowerShellEditorServices #2083](https://github.com/PowerShell/PowerShellEditorServices/pull/2083) - Upgrade OmniSharp to v0.19.9.
+- ✨ 📟 [PowerShellEditorServices #2080](https://github.com/PowerShell/PowerShellEditorServices/pull/2080) - Bump to new PSReadLine stable release v2.3.3.
+- 🐛 🔍 [PowerShellEditorServices #2068](https://github.com/PowerShell/PowerShellEditorServices/pull/2068) - Wrap import of DSC module with `ProgressPreference = SilentlyContinue`.
+
+## v2023.9.2-preview
+### Wednesday, September 13, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ⚡️ 💭 [vscode-powershell #4734](https://github.com/PowerShell/vscode-powershell/pull/4734) - Remove unused telemetry.
+- ✨ 📖 [vscode-powershell #4729](https://github.com/PowerShell/vscode-powershell/pull/4729) - Add note about installing ESLint globally for VS Code extension.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.11.0
+
+- 🐛 💭 [vscode-powershell #4735](https://github.com/PowerShell/PowerShellEditorServices/pull/2066) - Add `None` to `PsesLogLevel` enum.
+- ⚡️ 💭 [PowerShellEditorServices #2065](https://github.com/PowerShell/PowerShellEditorServices/pull/2065) - Remove unused telemetry.
+- 🐛 🔍 [vscode-powershell #3904](https://github.com/PowerShell/PowerShellEditorServices/pull/2064) - Fix debugging script blocks that aren't in files.
+- 🐛 🚂 [vscode-powershell #3971](https://github.com/PowerShell/PowerShellEditorServices/pull/2062) - Import `PSDesiredStateConfiguration` by name.
+
+## v2023.9.1-preview
+### Friday, August 25, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4711](https://github.com/PowerShell/vscode-powershell/pull/4711) - Update extension telemetry dependency.
+- ✨ 👷 [vscode-powershell #4707](https://github.com/PowerShell/vscode-powershell/pull/4707) - Move `--sourcemap` to scripts instead of `Invoke-Build`. (Thanks @JustinGrote!)
+- #️⃣ 🙏 [vscode-powershell #4702](https://github.com/PowerShell/vscode-powershell/pull/4704) - Use a CustomRequest to disconnect the dotnet debugger from attach sessions.. (Thanks @JustinGrote!)
+- 🐛 🙏 [vscode-powershell #2960](https://github.com/PowerShell/vscode-powershell/pull/4703) - Respect file path casing in extension commands.
+- 🐛 📺 [vscode-powershell #4696](https://github.com/PowerShell/vscode-powershell/pull/4696) - Fix race condition with displaying PowerShell name on icon.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.10.0
+
+- 🐛 🔍 [PowerShellEditorServices #2037](https://github.com/PowerShell/PowerShellEditorServices/pull/2058) - Ignore not finding DSC module.
+- ✨ 🚨 [vscode-powershell #3484](https://github.com/PowerShell/PowerShellEditorServices/pull/2055) - Move `ConstrainedLanguageMode` tests to separate task.
+- ✨ 📟 [PowerShellEditorServices #2054](https://github.com/PowerShell/PowerShellEditorServices/pull/2054) - Update PSReadLine to `v2.3.2-beta2`.
+- ✨ 🙏 [PowerShellEditorServices #2053](https://github.com/PowerShell/PowerShellEditorServices/pull/2053) - Fix up extension API.
+- 🐛 📟 [PowerShellEditorServices #2050](https://github.com/PowerShell/PowerShellEditorServices/pull/2052) - Fix shell integration for PowerShell 5.1 with strict mode.
+
+## v2023.9.0-preview
+### Wednesday, August 09, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🔧 [vscode-powershell #4557](https://github.com/PowerShell/vscode-powershell/pull/4687) - Support `~`, `./` and named workspace folders in `cwd`.
+- ✨ 🔧 [vscode-powershell #4686](https://github.com/PowerShell/vscode-powershell/pull/4686) - Enhance `additionalPowerShellExes` setting.
+- #️⃣ 🙏 [vscode-powershell #4684](https://github.com/PowerShell/vscode-powershell/pull/4684) - Remove LinkEditorServices comment in development.md. (Thanks @fflaten!)
+- #️⃣ 🙏 [vscode-powershell #4676](https://github.com/PowerShell/vscode-powershell/pull/4676) - Move ESLint Dependabot group to npm. (Thanks @fflaten!)
+- #️⃣ 🙏 [vscode-powershell #4667](https://github.com/PowerShell/vscode-powershell/pull/4667) - Bump ESLint packages to v6.
+- #️⃣ 🙏 [vscode-powershell #4661](https://github.com/PowerShell/vscode-powershell/pull/4661) - Update readme.
+- 🐛 👷 [vscode-powershell #4651](https://github.com/PowerShell/vscode-powershell/pull/4651) - Fix unit test for Windows running on arm64.
+- ✨ 👷 [vscode-powershell #4641](https://github.com/PowerShell/vscode-powershell/pull/4641) - Update VS Code engine to 1.79.0.
+- ✨ 🔧 [vscode-powershell #4181](https://github.com/PowerShell/vscode-powershell/pull/4639) - Add `startLocation` setting for Extension Terminal. (Thanks @krishankanumuri!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.9.0
+
+- ✨ 📟 [PowerShellEditorServices #2046](https://github.com/PowerShell/PowerShellEditorServices/pull/2046) - Bump PSReadLine to beta for extension preview.
+
+## v2023.6.0
+### Tuesday, June 06, 2023
+
+This release focused on fixing the "disappearing output" bug present in PowerShell 5.1,
+where an old bug with the `Out-Default` cmdlet's `TranscribeOnly` flag could cause the
+Extension Terminal to stop displaying output. While the root cause in the cmdlet is fixed
+upstream, that fix is only in PowerShell Core, and not backported to Windows PowerShell.
+We were able to workaround the bug with a very careful use of reflection to reset the
+flag's value at the appropriate times (see the three takes it took to get this right).
+
+We also refactored the client's startup logic so that it should be impossible to create a
+ghost Extension Terminal, and the error handling and logging was given a thorough cleanup.
+Finally, two noisy bugs were fixed: when completions are canceled the useless error
+message is no longer produced, and when the DSC module is only loaded in one attempt
+instead of repeatedly.
+
+Please enjoy these bugfixes! We sure enjoy making the extension more stable.
+
+Don't forget to catch Andy's talk, "PowerShell Extension for VS Code Deep Dive" at
+[PSConfEU](https://psconf.eu) on Thursday, 22 June 2023!
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4599](https://github.com/PowerShell/vscode-powershell/pull/4599) - Make `sessionManager.start()` idempotent.
+- 🐛 🛫 [vscode-powershell #4584](https://github.com/PowerShell/vscode-powershell/pull/4584) - Robustify startup, error handling, and logging.
+- 🐛 📺 [vscode-powershell #4553](https://github.com/PowerShell/vscode-powershell/pull/4570) - Remove the MSI install logic (it's unreliable).
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.7
+
+- 🐛 📟 [PowerShellEditorServices #2031](https://github.com/PowerShell/PowerShellEditorServices/pull/2031) - Fix the `TranscribeOnly` bug (take three).
+- 🐛 💭 [vscode-powershell #4582](https://github.com/PowerShell/PowerShellEditorServices/pull/2028) - Ignore cancellation of completion requests.
+- 🐛 📟 [vscode-powershell #3991](https://github.com/PowerShell/PowerShellEditorServices/pull/2026) - Fix the `TranscribeOnly` bug (take two).
+- 🐛 📟 [vscode-powershell #3991](https://github.com/PowerShell/PowerShellEditorServices/pull/2023) - Fix disappearing output in PowerShell 5.1.
+- 🐛 🔍 [PowerShellEditorServices #2020](https://github.com/PowerShell/PowerShellEditorServices/pull/2020) - Fix repeated failure to load DSC module.
+
+## v2023.5.4-preview
+### Tuesday, May 30, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+No changes, just pulling in PSES.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.7
+
+- 🐛 📟 [PowerShellEditorServices #2031](https://github.com/PowerShell/PowerShellEditorServices/pull/2031) - Fix the `TranscribeOnly` bug (take three).
+
+## v2023.5.3-preview
+### Wednesday, May 24, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4599](https://github.com/PowerShell/vscode-powershell/pull/4599) - Make `sessionManager.start()` idempotent.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.6
+
+No changes.
+
+## v2023.5.2-preview
+### Tuesday, May 23, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🛫 [vscode-powershell #4584](https://github.com/PowerShell/vscode-powershell/pull/4584) - Robustify startup, error handling, and logging.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.6
+
+- 🐛 💭 [vscode-powershell #4582](https://github.com/PowerShell/PowerShellEditorServices/pull/2028) - Ignore cancellation of completion requests.
+- 🐛 📟 [vscode-powershell #3991](https://github.com/PowerShell/PowerShellEditorServices/pull/2026) - Fix the `TranscribeOnly` bug (take two).
+
+## v2023.5.1-preview
+### Friday, May 12, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 📺 [vscode-powershell #4553](https://github.com/PowerShell/vscode-powershell/pull/4570) - Remove the MSI install logic (it's unreliable).
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.5
+
+- 🐛 📟 [vscode-powershell #3991](https://github.com/PowerShell/PowerShellEditorServices/pull/2023) - Fix disappearing output in PowerShell 5.1.
+- 🐛 🔍 [PowerShellEditorServices #2020](https://github.com/PowerShell/PowerShellEditorServices/pull/2020) - Fix repeated failure to load DSC module.
+
+## v2023.5.0
+### Wednesday, May 03, 2023
+
+This release focused on include Justin Grote's new "attach .NET debugger" debug
+configuration for binary PowerShell modules, and on handling start-up failures more
+gracefully. If the start-up fails because the configured PowerShell is out-of-date,
+instead of a confusing "undefined" error message we now detect the problem, inform the
+user with a pop-up message of it, and offer to open the installation and/or update
+instructions.
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🙏 [vscode-powershell #4549](https://github.com/PowerShell/vscode-powershell/pull/4549) - Update readme and troubleshooting docs.
+- ✨ 🙏 [vscode-powershell #4548](https://github.com/PowerShell/vscode-powershell/pull/4548) - Use named debug configurations instead of duplicating them.
+- 🐛 🚨 [vscode-powershell #4547](https://github.com/PowerShell/vscode-powershell/pull/4547) - Fix flaky test.
+- 🐛 🛫 [vscode-powershell #4543](https://github.com/PowerShell/vscode-powershell/pull/4543) - Update startup logic to handle session failure reasons.
+- #️⃣ 🙏 [vscode-powershell #4534](https://github.com/PowerShell/vscode-powershell/pull/4534) - Add ESBuild Problem Matcher Extension. (Thanks @JustinGrote!)
+- 🐛 🙏 [vscode-powershell #4521](https://github.com/PowerShell/vscode-powershell/pull/4532) - Handle end-of-support PowerShell with error message.
+- ✨ 👷 [vscode-powershell #4518](https://github.com/PowerShell/vscode-powershell/pull/4518) - Enable Mocha Test Explorer Integration. (Thanks @JustinGrote!)
+- 🐛 🔍 [vscode-powershell #4517](https://github.com/PowerShell/vscode-powershell/pull/4517) - Fix `attachDotnetDebugger` with custom config. (Thanks @fflaten!)
+- 🐛 🔍 [vscode-powershell #4516](https://github.com/PowerShell/vscode-powershell/pull/4516) - Add new debug configurations to `package.json`. (Thanks @JustinGrote!)
+- #️⃣ 🔍 [vscode-powershell #4511](https://github.com/PowerShell/vscode-powershell/pull/4511) - Add additional debug configuration templates for Pester and binary modules. (Thanks @JustinGrote!)
+- #️⃣ 🔍🙏 [vscode-powershell #4510](https://github.com/PowerShell/vscode-powershell/pull/4510) - Improve extension authoring experience with new Build Tasks and Launch Configs. (Thanks @JustinGrote!)
+- ✨ 👷 [vscode-powershell #4502](https://github.com/PowerShell/vscode-powershell/pull/4503) - Enable VS Code unit tests in Linux CI.
+- ✨ 🙏 [vscode-powershell #4498](https://github.com/PowerShell/vscode-powershell/pull/4500) - Enable ESLint `explicit-function-return-type`.
+- ✨ 🔍 [vscode-powershell #3903](https://github.com/PowerShell/vscode-powershell/pull/3903) - Add `attachDotnetDebugger` debug option. (Thanks @JustinGrote!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.4
+
+- 🐛 🛫 [vscode-powershell #4509](https://github.com/PowerShell/PowerShellEditorServices/pull/2018) - Set session failure with reason when applicable.
+- ✨ 📖 [PowerShellEditorServices #2016](https://github.com/PowerShell/PowerShellEditorServices/pull/2016) - Add guide to configure Neovim. (Thanks @csc027!)
+
+## v2023.4.1-preview
+### Tuesday, April 25, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🛫 [vscode-powershell #4543](https://github.com/PowerShell/vscode-powershell/pull/4543) - Update startup logic to handle session failure reasons.
+- #️⃣ 🙏 [vscode-powershell #4534](https://github.com/PowerShell/vscode-powershell/pull/4534) - Add ESBuild Problem Matcher Extension. (Thanks @JustinGrote!)
+- 🐛 🙏 [vscode-powershell #4521](https://github.com/PowerShell/vscode-powershell/pull/4532) - Handle end-of-support PowerShell with error message.
+- ✨ 👷 [vscode-powershell #4518](https://github.com/PowerShell/vscode-powershell/pull/4518) - Enable Mocha Test Explorer Integration. (Thanks @JustinGrote!)
+- 🐛 🔍 [vscode-powershell #4517](https://github.com/PowerShell/vscode-powershell/pull/4517) - Fix `attachDotnetDebugger` with custom config. (Thanks @fflaten!)
+- 🐛 🔍 [vscode-powershell #4516](https://github.com/PowerShell/vscode-powershell/pull/4516) - Add new debug configurations to `package.json`. (Thanks @JustinGrote!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.4
+
+- 🐛 🛫 [vscode-powershell #4509](https://github.com/PowerShell/PowerShellEditorServices/pull/2018) - Set session failure with reason when applicable.
+- ✨ 📖 [PowerShellEditorServices #2016](https://github.com/PowerShell/PowerShellEditorServices/pull/2016) - Add guide to configure Neovim. (Thanks @csc027!)
+
+## v2023.4.0-preview
+### Wednesday, April 12, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🔍 [vscode-powershell #4511](https://github.com/PowerShell/vscode-powershell/pull/4511) - Add additional debug configuration templates for Pester and binary modules. (Thanks @JustinGrote!)
+- #️⃣ 🔍🙏 [vscode-powershell #4510](https://github.com/PowerShell/vscode-powershell/pull/4510) - Improve extension authoring experience with new Build Tasks and Launch Configs. (Thanks @JustinGrote!)
+- ✨ 👷 [vscode-powershell #4502](https://github.com/PowerShell/vscode-powershell/pull/4503) - Enable VS Code unit tests in Linux CI.
+- ✨ 🙏 [vscode-powershell #4498](https://github.com/PowerShell/vscode-powershell/pull/4500) - Enable ESLint `explicit-function-return-type`.
+- ✨ 🔍 [vscode-powershell #3903](https://github.com/PowerShell/vscode-powershell/pull/3903) - Add `attachDotnetDebugger` debug option. (Thanks @JustinGrote!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.3
+
+- No update.
+
+## v2023.3.3
+### Thursday, March 30, 2023
+
+This is primarily a bug-fix focused release, and we want to say thanks to all our loyal
+preview extension users! The "PowerShell Preview" extension has now been officially
+deprecated, with "preview" releases now available via the "pre-release" option on the
+stable "PowerShell" extension in the marketplace. While you should be migrated
+automatically, feel free to just uninstall the preview and install the now one-and-only
+extension, but please keep testing our pre-releases! This change makes it much simpler to
+use, as you no longer have to switch between two different extensions and instead can use
+VS Code's marketplace to install your choice of version!
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 👷 [vscode-powershell #4481](https://github.com/PowerShell/vscode-powershell/pull/4481) - Remove problematic `[RepoNames]` PowerShell class.
+- ✨ 👷 [vscode-powershell #4464](https://github.com/PowerShell/vscode-powershell/pull/4464) - Remove `preview` label from marketplace.
+- ✨ 👷 [vscode-powershell #3716](https://github.com/PowerShell/vscode-powershell/pull/4462) - Adopt the pre-release extension feature.
+- 🐛 ✂️ [vscode-powershell #4455](https://github.com/PowerShell/vscode-powershell/pull/4455) - Fix up "Calculated Property" snippet. (Thanks @DougDyreng!)
+- 🐛 📺 [vscode-powershell #4453](https://github.com/PowerShell/vscode-powershell/pull/4454) - Fix `GenerateBugReport` command to pre-fill template.
+- ✨ 🙏 [vscode-powershell #4425](https://github.com/PowerShell/vscode-powershell/pull/4425) - Hide last line in folded ranges for ISE Mode. (Thanks @fflaten!)
+- #️⃣ 🙏 [vscode-powershell #4417](https://github.com/PowerShell/vscode-powershell/pull/4417) - Fix up dependencies.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.3
+
+- Documentation update and CI fix.
+- 🐛 🙏 [vscode-powershell #4443](https://github.com/PowerShell/PowerShellEditorServices/pull/2006) - Fix declaration detection for variables with type constraints.
+- ✨ 🙏 [vscode-powershell #3604](https://github.com/PowerShell/PowerShellEditorServices/pull/2003) - Add document symbols for `#region`.
+- ✨ 🙏 [PowerShellEditorServices #2000](https://github.com/PowerShell/PowerShellEditorServices/pull/2000) - Code clean-up and fixing end-to-end tests.
+- 🐛 🐢 [PowerShellEditorServices #1998](https://github.com/PowerShell/PowerShellEditorServices/pull/1998) - Support module-qualified calls for Pester keywords. (Thanks @fflaten!)
+- 🐛 🙏 [vscode-powershell #3192](https://github.com/PowerShell/PowerShellEditorServices/pull/1997) - Fix New-EditorFile adding content in current file. (Thanks @fflaten!)
+
+## v2023.3.2-preview
+### Monday, March 27, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 👷 [vscode-powershell #4481](https://github.com/PowerShell/vscode-powershell/pull/4481) - Remove problematic `[RepoNames]` PowerShell class.
+- ✨ 👷 [vscode-powershell #4464](https://github.com/PowerShell/vscode-powershell/pull/4464) - Remove `preview` label from marketplace.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.3
+
+- Documentation update and CI fix.
+
+## v2023.3.1-preview
+### Wednesday, March 15, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 👷 [vscode-powershell #3716](https://github.com/PowerShell/vscode-powershell/pull/4462) - Adopt the pre-release extension feature.
+- 🐛 ✂️ [vscode-powershell #4455](https://github.com/PowerShell/vscode-powershell/pull/4455) - Fix up "Calculated Property" snippet. (Thanks @DougDyreng!)
+- 🐛 📺 [vscode-powershell #4453](https://github.com/PowerShell/vscode-powershell/pull/4454) - Fix `GenerateBugReport` command to pre-fill template.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.2
+
+No changes.
+
+## v2023.3.0-preview
+### Thursday, March 09, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🙏 [vscode-powershell #4425](https://github.com/PowerShell/vscode-powershell/pull/4425) - Hide last line in folded ranges for ISE Mode. (Thanks @fflaten!)
+- #️⃣ 🙏 [vscode-powershell #4417](https://github.com/PowerShell/vscode-powershell/pull/4417) - Fix up dependencies.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.2
+
+- 🐛 🙏 [vscode-powershell #4443](https://github.com/PowerShell/PowerShellEditorServices/pull/2006) - Fix declaration detection for variables with type constraints.
+- ✨ 🙏 [vscode-powershell #3604](https://github.com/PowerShell/PowerShellEditorServices/pull/2003) - Add document symbols for `#region`.
+- ✨ 🙏 [PowerShellEditorServices #2000](https://github.com/PowerShell/PowerShellEditorServices/pull/2000) - Code clean-up and fixing end-to-end tests.
+- 🐛 🐢 [PowerShellEditorServices #1998](https://github.com/PowerShell/PowerShellEditorServices/pull/1998) - Support module-qualified calls for Pester keywords. (Thanks @fflaten!)
+- 🐛 🙏 [vscode-powershell #3192](https://github.com/PowerShell/PowerShellEditorServices/pull/1997) - Fix New-EditorFile adding content in current file. (Thanks @fflaten!)
+
+## v2023.2.1
+### Thursday, February 23, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+Primarily an update to v3.8 of PowerShell Editor Services, as previewed over February.
+Includes a massive enhancement to extension's symbol support, nearly completing the
+[Consistent References][] project, with the final work in an upcoming preview. Enjoy!
+
+[Consistent References]: https://github.com/PowerShell/vscode-powershell/projects/13
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.1
+
+- ✨ 📁 [vscode-powershell #2112](https://github.com/PowerShell/PowerShellEditorServices/pull/1995) - Add `WorkspaceFolders` and use it when enumerating files.
+- ✨ 🙏 [vscode-powershell #1481](https://github.com/PowerShell/PowerShellEditorServices/pull/1993) - Count `${Function:My-Function}` as a function reference.
+- 🐛 🙏 [vscode-powershell #1089](https://github.com/PowerShell/PowerShellEditorServices/pull/1990) - Strip scope from function references.
+- 🐛 🙏 [PowerShellEditorServices #1989](https://github.com/PowerShell/PowerShellEditorServices/pull/1989) - Keep only first assignment as declaration.
+- ✨ 🐢 [PowerShellEditorServices #1988](https://github.com/PowerShell/PowerShellEditorServices/pull/1988) - Support Run/Debug tests in PSKoans-files. (Thanks @fflaten!)
+
+In the PR below we rewrote all the symbol logic. Classes (and their properties and
+methods) are now proper symbols. Instead of a dozen similar-yet-different Abstract Symbol
+Tree (AST) PowerShell script visitors handling different parts of each symbol-related
+request, we have a single visitor that builds a cached dictionary of symbols for each
+file. This was a massive simplification of the code that also leads to huge performance
+improvements across all the symbol related features:
+
+- [Go to Symbol in Workspace](https://code.visualstudio.com/Docs/editor/editingevolved#_open-symbol-by-name)
+- [Go to Symbol in Editor](https://code.visualstudio.com/Docs/editor/editingevolved#_go-to-symbol)
+- [Go to Definition](https://code.visualstudio.com/Docs/editor/editingevolved#_go-to-definition)
+- [Go to References / CodeLens](https://code.visualstudio.com/Docs/editor/editingevolved#_reference-information)
+- [Outline view](https://code.visualstudio.com/docs/getstarted/userinterface#_outline-view)
+
+Please try it out and give us feedback! There's plenty of room for more improvement, and
+this will be much easier going forward.
+
+- ✨ 🙏 [PowerShellEditorServices #1984](https://github.com/PowerShell/PowerShellEditorServices/pull/1984) - Integrating class symbol support.
+
+## v2023.2.1-preview
+### Monday, February 13, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+Includes the updates from PowerShell Editor Services below:
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.1
+
+- ✨ 📁 [vscode-powershell #2112](https://github.com/PowerShell/PowerShellEditorServices/pull/1995) - Add `WorkspaceFolders` and use it when enumerating files.
+- ✨ 🙏 [vscode-powershell #1481](https://github.com/PowerShell/PowerShellEditorServices/pull/1993) - Count `${Function:My-Function}` as a function reference.
+- 🐛 🙏 [vscode-powershell #1089](https://github.com/PowerShell/PowerShellEditorServices/pull/1990) - Strip scope from function references.
+- 🐛 🙏 [PowerShellEditorServices #1989](https://github.com/PowerShell/PowerShellEditorServices/pull/1989) - Keep only first assignment as declaration.
+- ✨ 🐢 [PowerShellEditorServices #1988](https://github.com/PowerShell/PowerShellEditorServices/pull/1988) - Support Run/Debug tests in PSKoans-files. (Thanks @fflaten!)
+
+## v2023.2.0-preview
+### Thursday, February 02, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+This preview includes all the work outlined below for enhanced symbol support.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.8.0
+
+In the PR below we rewrote all the symbol logic. Classes (and their properties and
+methods) are now proper symbols. Instead of a dozen similar-yet-different Abstract Symbol
+Tree (AST) PowerShell script visitors handling different parts of each symbol-related
+request, we have a single visitor that builds a cached dictionary of symbols for each
+file. This was a massive simplification of the code that also leads to huge performance
+improvements across all the symbol related features:
+
+- [Go to Symbol in Workspace](https://code.visualstudio.com/Docs/editor/editingevolved#_open-symbol-by-name)
+- [Go to Symbol in Editor](https://code.visualstudio.com/Docs/editor/editingevolved#_go-to-symbol)
+- [Go to Definition](https://code.visualstudio.com/Docs/editor/editingevolved#_go-to-definition)
+- [Go to References / CodeLens](https://code.visualstudio.com/Docs/editor/editingevolved#_reference-information)
+- [Outline view](https://code.visualstudio.com/docs/getstarted/userinterface#_outline-view)
+
+Please try it out and give us feedback! There's plenty of room for more improvement, and
+this will be much easier going forward.
+
+- ✨ 🙏 [PowerShellEditorServices #1984](https://github.com/PowerShell/PowerShellEditorServices/pull/1984) - Integrating class symbol support.
+
+## v2023.1.0
+### Wednesday, January 18, 2023
+
+First stable release for the new year, includes a multitude of fixes for the debugger!
+Expanding variables with properties that are inaccessible no longer causes a short-circuit
+preventing the rest of the properties from being expanded, variable values whose expansion
+results in PowerShell code being executed now works as expected, and in general all the
+correct properties are now present. We look forward to adding the ability to view static
+and private fields in a future update.
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 👷 [vscode-powershell #4357](https://github.com/PowerShell/vscode-powershell/pull/4357) - Fix `@vscode/vsce` dependency after its rename.
+- 🐛 ✂️ [vscode-powershell #4346](https://github.com/PowerShell/vscode-powershell/pull/4347) - Fix class snippet (unnecessary space between `<` and `#`). (Thanks @ALiwoto!)
+- 🐛 🛫 [vscode-powershell #4329](https://github.com/PowerShell/vscode-powershell/pull/4331) - Automatically find "PowerShell Daily" at its common path.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.7.3
+
+- 🐛 🚂 [vscode-powershell #4343](https://github.com/PowerShell/PowerShellEditorServices/pull/1982) - Update VS Code shell integration script.
+- ✨ 🙏 [PowerShellEditorServices #1981](https://github.com/PowerShell/PowerShellEditorServices/pull/1981) - Make `Set-ScriptExtent` not slow.
+- 🐛 🙏 [PowerShellEditorServices #1959](https://github.com/PowerShell/PowerShellEditorServices/pull/1980) - Use an empty array instead of `null`.
+- 🐛 🔍 [vscode-powershell #4174](https://github.com/PowerShell/PowerShellEditorServices/pull/1975) - Fix several bugs in the debugger.
+- #️⃣ 🙏 [PowerShellEditorServices #1973](https://github.com/PowerShell/PowerShellEditorServices/pull/1973) - Update `Microsoft.PowerShell.SDK` with workaround.
+
+## v2023.1.0-preview
+### Wednesday, January 04, 2023
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 👷 [vscode-powershell #4357](https://github.com/PowerShell/vscode-powershell/pull/4357) - Fix `@vscode/vsce` dependency after its rename.
+- 🐛 ✂️ [vscode-powershell #4346](https://github.com/PowerShell/vscode-powershell/pull/4347) - Fix class snippet (unnecessary space between `<` and `#`). (Thanks @ALiwoto!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.7.3
+
+- 🐛 🚂 [vscode-powershell #4343](https://github.com/PowerShell/PowerShellEditorServices/pull/1982) - Update VS Code shell integration script.
+- ✨ 🙏 [PowerShellEditorServices #1981](https://github.com/PowerShell/PowerShellEditorServices/pull/1981) - Make `Set-ScriptExtent` not slow.
+- 🐛 🙏 [PowerShellEditorServices #1959](https://github.com/PowerShell/PowerShellEditorServices/pull/1980) - Use an empty array instead of `null`.
+
+## v2022.12.2-preview
+### Tuesday, December 20, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🛫 [vscode-powershell #4329](https://github.com/PowerShell/vscode-powershell/pull/4331) - Automatically find "PowerShell Daily" at its common path.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.7.2
+
+- 🐛 🔍 [vscode-powershell #4174](https://github.com/PowerShell/PowerShellEditorServices/pull/1975) - Fix several bugs in the debugger.
+- #️⃣ 🙏 [PowerShellEditorServices #1973](https://github.com/PowerShell/PowerShellEditorServices/pull/1973) - Update `Microsoft.PowerShell.SDK` with workaround.
+
+## v2022.12.1
+### Thursday, December 15, 2022
+
+This release brings a variety of bugfixes and feature improvements, including everyone's
+favorite: [VS Code Terminal Shell Integration][shell-integration] in the PowerShell
+Extension Terminal! We overhauled the PowerShell update notification feature, with support
+for more platforms and architectures. Also checkout the revamped settings descriptions in
+VS Code, complete with formatting and hyperlinks.
+
+[shell-integration]: https://code.visualstudio.com/docs/terminal/shell-integration
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🔧 [vscode-powershell #4315](https://github.com/PowerShell/vscode-powershell/pull/4320) - Enhance (and correct) our settings' descriptions using markdown.
+- 🐛 ✂️ [vscode-powershell #3964](https://github.com/PowerShell/vscode-powershell/pull/4311) - Fix `try-catch` snippet (missing a `$`).
+- 🐛 🔧 [vscode-powershell #4308](https://github.com/PowerShell/vscode-powershell/pull/4308) - Restore original settings after disabling ISE mode.
+- ✨ 🚂 [vscode-powershell #4301](https://github.com/PowerShell/vscode-powershell/pull/4307) - Bump engine to 1.67.0 and update panel graphics.
+- ✨ 🛫 [vscode-powershell #3226](https://github.com/PowerShell/vscode-powershell/pull/4306) - Rewrite `UpdatePowerShell` feature.
+- 🐛 🛫 [vscode-powershell #3435](https://github.com/PowerShell/vscode-powershell/pull/4298) - Skip auto-update on unsupported Windows architectures.
+- 🐛 🔧 [vscode-powershell #4297](https://github.com/PowerShell/vscode-powershell/pull/4297) - Fix small bug with `powerShellDefaultVersion` warning.
+- ✨ 🔧 [vscode-powershell #4129](https://github.com/PowerShell/vscode-powershell/pull/4295) - Show warning if `powerShellDefaultVersion` is set but not found.
+- ✨ 📁 [vscode-powershell #2153](https://github.com/PowerShell/vscode-powershell/pull/3796) - Fully support multi-root workspaces.
+- 🐛 💭 [vscode-powershell #4202](https://github.com/PowerShell/vscode-powershell/pull/4276) - Make `Logger.WriteLine` thread-safe and fix bug with UNC paths.
+- ✨ 📟 [vscode-powershell #4271](https://github.com/PowerShell/vscode-powershell/pull/4271) - Send shell integration setting to server.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.7.1
+
+- 🐛 🚂 [vscode-powershell #4212](https://github.com/PowerShell/PowerShellEditorServices/pull/1970) - Fix `ShowHelpHandler` by running with `RequiresForeground`.
+- ✨ 👷 [PowerShellEditorServices #1879](https://github.com/PowerShell/PowerShellEditorServices/pull/1967) - Drop support for end-of-life PowerShell 7.0.
+- ✨ 🛫 [PowerShellEditorServices #1965](https://github.com/PowerShell/PowerShellEditorServices/pull/1965) - Send `GitCommitId` over `GetVersionHandler`.
+- 🐛 🛫 [PowerShellEditorServices #1964](https://github.com/PowerShell/PowerShellEditorServices/pull/1964) - Remove unnecessary `PowerShellProcessArchitecture`.
+- 🐛 🚂 [PowerShellEditorServices #1953](https://github.com/PowerShell/PowerShellEditorServices/pull/1953) - Fix `IsExternalInit` bug, re-enable tests, and update OmniSharp to v0.19.7.
+- 🐛 🙏 [PowerShellEditorServices #1962](https://github.com/PowerShell/PowerShellEditorServices/pull/1962) - Revert manual pin of Newtonsoft.Json.
+- 🐛 📟 [vscode-powershell #4279](https://github.com/PowerShell/PowerShellEditorServices/pull/1961) - Replace backtick-e with `$([char]0x1b)`.
+- ✨ 📟 [vscode-powershell #3901](https://github.com/PowerShell/PowerShellEditorServices/pull/1958) - Enable VS Code's shell integration.
+- 🐛 🔍 [vscode-powershell #4269](https://github.com/PowerShell/PowerShellEditorServices/pull/1957) - Escape single quotes when launching a script by path.
+- ✨ 🚨 [PowerShellEditorServices #1955](https://github.com/PowerShell/PowerShellEditorServices/pull/1955) - Add PowerShell 7.3 to test matrix.
+
+## v2022.12.1-preview
+### Monday, December 12, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🔧 [vscode-powershell #4315](https://github.com/PowerShell/vscode-powershell/pull/4320) - Enhance (and correct) our settings' descriptions using markdown.
+- 🐛 ✂️ [vscode-powershell #3964](https://github.com/PowerShell/vscode-powershell/pull/4311) - Fix `try-catch` snippet (missing a `$`).
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.7.1
+
+- 🐛 🚂 [vscode-powershell #4212](https://github.com/PowerShell/PowerShellEditorServices/pull/1970) - Fix `ShowHelpHandler` by running with `RequiresForeground`.
+
+## v2022.12.0-preview
+### Tuesday, December 06, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🔧 [vscode-powershell #4308](https://github.com/PowerShell/vscode-powershell/pull/4308) - Restore original settings after disabling ISE mode.
+- ✨ 🚂 [vscode-powershell #4301](https://github.com/PowerShell/vscode-powershell/pull/4307) - Bump engine to 1.67.0 and update panel graphics.
+- ✨ 🛫 [vscode-powershell #3226](https://github.com/PowerShell/vscode-powershell/pull/4306) - Rewrite `UpdatePowerShell` feature.
+- 🐛 🛫 [vscode-powershell #3435](https://github.com/PowerShell/vscode-powershell/pull/4298) - Skip auto-update on unsupported Windows architectures.
+- 🐛 🔧 [vscode-powershell #4297](https://github.com/PowerShell/vscode-powershell/pull/4297) - Fix small bug with `powerShellDefaultVersion` warning.
+- ✨ 🔧 [vscode-powershell #4129](https://github.com/PowerShell/vscode-powershell/pull/4295) - Show warning if `powerShellDefaultVersion` is set but not found.
+- ✨ 📁 [vscode-powershell #2153](https://github.com/PowerShell/vscode-powershell/pull/3796) - Fully support multi-root workspaces.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.7.0
+
+- ✨ 👷 [PowerShellEditorServices #1879](https://github.com/PowerShell/PowerShellEditorServices/pull/1967) - Drop support for end-of-life PowerShell 7.0.
+- ✨ 🛫 [PowerShellEditorServices #1965](https://github.com/PowerShell/PowerShellEditorServices/pull/1965) - Send `GitCommitId` over `GetVersionHandler`.
+- 🐛 🛫 [PowerShellEditorServices #1964](https://github.com/PowerShell/PowerShellEditorServices/pull/1964) - Remove unnecessary `PowerShellProcessArchitecture`.
+- 🐛 🚂 [PowerShellEditorServices #1953](https://github.com/PowerShell/PowerShellEditorServices/pull/1953) - Fix `IsExternalInit` bug, re-enable tests, and update OmniSharp to v0.19.7.
+
+## v2022.11.2-preview
+### Tuesday, November 29, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+Just dependency updates.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.6.3
+
+- 🐛 🙏 [PowerShellEditorServices #1962](https://github.com/PowerShell/PowerShellEditorServices/pull/1962) - Revert manual pin of Newtonsoft.Json.
+- 🐛 📟 [vscode-powershell #4279](https://github.com/PowerShell/PowerShellEditorServices/pull/1961) - Replace backtick-e with `$([char]0x1b)`.
+
+## v2022.11.1-preview
+### Monday, November 21, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 💭 [vscode-powershell #4202](https://github.com/PowerShell/vscode-powershell/pull/4276) - Make `Logger.WriteLine` thread-safe and fix bug with UNC paths.
+- ✨ 📟 [vscode-powershell #4271](https://github.com/PowerShell/vscode-powershell/pull/4271) - Send shell integration setting to server.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.6.2
+
+- ✨ 📟 [vscode-powershell #3901](https://github.com/PowerShell/PowerShellEditorServices/pull/1958) - Enable VS Code's shell integration.
+- 🐛 🔍 [vscode-powershell #4269](https://github.com/PowerShell/PowerShellEditorServices/pull/1957) - Escape single quotes when launching a script by path.
+- ✨ 🚨 [PowerShellEditorServices #1955](https://github.com/PowerShell/PowerShellEditorServices/pull/1955) - Add PowerShell 7.3 to test matrix.
+
+## v2022.11.0
+### Wednesday, November 16, 2022
+
+The November release represents a renewed focus on the client, that is, the TypeScript
+extension for Visual Studio Code. We've paid back a significant amount of technical debt
+by enabling both the TypeScript compiler's and ESLint linter's strict checks, helping us
+ensure we are writing correct code. We've increased the client's logging, made the
+walkthrough's installation instructions cross-platform, added a warning popup when custom
+configured additional PowerShell executables aren't found, and fixed a couple debugger
+configuration edge cases.
+
+A regression for the `OnIdle` handler was fixed in the server, complete with regression
+tests covering the registration and triggering of idle events registered both in a profile
+and during a session. A workaround was implemented for a completion bug in PowerShell that
+was causing the LSP session to disconnect when used with third-party clients. When
+executing scripts, the path is now escaped with single quotes instead of double quotes,
+addressing the edge case where a path contains a dollar sign, and is now inline with
+PowerShell's semantics.
+
+The build is now correctly published in release mode which should be more performant and
+won't allow the user to accidentally enable the "wait for debugger" scenario (which can
+appear as a hang, though it is a correctly working feature that is now hidden behind more
+developer settings). Additionally, checks were added to both the server and client build
+pipelines to assert that the bits are in release mode before packaging, as it was
+unfortunately the act of running the tests that erroneously and silently overwrote release
+bits with debug bits.
+
+Finally, a long-standing bug that often prevented the server from starting with Windows
+PowerShell was resolved. Known to users as the `DryIoc` error (which was a misleading
+stacktrace that commonly popped up), we tracked down a broken dependency of OmniSharp that
+when present and loaded into the GAC caused a type resolution error. While it took a year
+for us to find the root cause, the fix was a single line dependency update for OmniSharp,
+and then some work to incorporate the OmniSharp update into the server.
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🚂 [vscode-powershell #3561](https://github.com/PowerShell/vscode-powershell/pull/4206) - Enable `strict` TypeScript mode .
+- 🐛 🔍 [vscode-powershell #4201](https://github.com/PowerShell/vscode-powershell/pull/4203) - Fix automatic focus to temporary debug terminal (if it exists).
+- 🐛 🚂 [vscode-powershell #4213](https://github.com/PowerShell/vscode-powershell/pull/4228) - Remove `FindModule.ts` since its long since been deprecated.
+- 🐛 🔍 [vscode-powershell #4223](https://github.com/PowerShell/vscode-powershell/pull/4227) - Only check a script's extension if a script file was given.
+- ✨ 👷 [vscode-powershell #4220](https://github.com/PowerShell/vscode-powershell/pull/4220) - Add assertion to build that PSES bits are built in release configuration.
+- ✨ 🚂 [vscode-powershell #3561](https://github.com/PowerShell/vscode-powershell/pull/4206) - Enable `strict` TypeScript mode .
+- 🐛 🔍 [vscode-powershell #4201](https://github.com/PowerShell/vscode-powershell/pull/4203) - Fix automatic focus to temporary debug terminal (if it exists).
+- ✨ 👷 [vscode-powershell #2882](https://github.com/PowerShell/vscode-powershell/pull/3331) - Replace TSLint with ESLint.
+- ✨ 💭 [vscode-powershell #4242](https://github.com/PowerShell/vscode-powershell/pull/4242) - Show warning when additional PowerShell is not found.
+- 🐛 🛫 [vscode-powershell #4241](https://github.com/PowerShell/vscode-powershell/pull/4241) - Guard `-WaitForDebugger` flag client-side too.
+- ✨ 💭 [vscode-powershell #4240](https://github.com/PowerShell/vscode-powershell/pull/4240) - Capture more logs.
+- ✨ 💭 [vscode-powershell #4235](https://github.com/PowerShell/vscode-powershell/pull/4235) - Refactor `settings.ts`.
+- 🐛 📺 [vscode-powershell #4149](https://github.com/PowerShell/vscode-powershell/pull/4233) - Add cross-platform installation to walkthrough.
+- 🐛 🔍 [vscode-powershell #4231](https://github.com/PowerShell/vscode-powershell/pull/4231) - Check script extension for current file only.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.6.1
+
+- 🐛 🚂 [vscode-powershell #4219](https://github.com/PowerShell/PowerShellEditorServices/pull/1936) - Fix regression around `OnIdle` handler.
+- 🐛 🧠 [PowerShellEditorServices #1926](https://github.com/PowerShell/PowerShellEditorServices/pull/1935) - Catch exceptions within completion handler.
+- 🐛 👷 [vscode-powershell #4218](https://github.com/PowerShell/PowerShellEditorServices/pull/1933) - Fix release build.
+- ✨ 📖 [PowerShellEditorServices #1932](https://github.com/PowerShell/PowerShellEditorServices/pull/1932) - Add example of starting PSES in a script to readme. (Thanks @smartguy1196!)
+- #️⃣ 🙏 [PowerShellEditorServices #1931](https://github.com/PowerShell/PowerShellEditorServices/pull/1931) - Fix broken links in readme. (Thanks @smartguy1196!)
+- #️⃣ 🙏 [PowerShellEditorServices #1947](https://github.com/PowerShell/PowerShellEditorServices/pull/1947) - Manually update `Newtonsoft.Json`.
+- 🐛 🚂 [vscode-powershell #4175](https://github.com/PowerShell/PowerShellEditorServices/pull/1946) - Bump OmniSharp to `v0.19.6`.
+- 🐛 🔍 [vscode-powershell #4238](https://github.com/PowerShell/PowerShellEditorServices/pull/1940) - Wrap script paths with single instead of double quotes.
+
+## v2022.11.0-preview
+### Thursday, November 03, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 💭 [vscode-powershell #4242](https://github.com/PowerShell/vscode-powershell/pull/4242) - Show warning when additional PowerShell is not found.
+- 🐛 🛫 [vscode-powershell #4241](https://github.com/PowerShell/vscode-powershell/pull/4241) - Guard `-WaitForDebugger` flag client-side too.
+- ✨ 💭 [vscode-powershell #4240](https://github.com/PowerShell/vscode-powershell/pull/4240) - Capture more logs.
+- ✨ 💭 [vscode-powershell #4235](https://github.com/PowerShell/vscode-powershell/pull/4235) - Refactor `settings.ts`.
+- 🐛 📺 [vscode-powershell #4149](https://github.com/PowerShell/vscode-powershell/pull/4233) - Add cross-platform installation to walkthrough.
+- 🐛 🔍 [vscode-powershell #4231](https://github.com/PowerShell/vscode-powershell/pull/4231) - Check script extension for current file only.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.6.1
+
+- #️⃣ 🙏 [PowerShellEditorServices #1947](https://github.com/PowerShell/PowerShellEditorServices/pull/1947) - Manually update `Newtonsoft.Json`.
+- 🐛 🚂 [vscode-powershell #4175](https://github.com/PowerShell/PowerShellEditorServices/pull/1946) - Bump OmniSharp to `v0.19.6`.
+- 🐛 🔍 [vscode-powershell #4238](https://github.com/PowerShell/PowerShellEditorServices/pull/1940) - Wrap script paths with single instead of double quotes.
+
+## v2022.10.2-preview
+### Tuesday, October 25, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🚂 [vscode-powershell #4213](https://github.com/PowerShell/vscode-powershell/pull/4228) - Remove `FindModule.ts` since its long since been deprecated.
+- 🐛 🔍 [vscode-powershell #4223](https://github.com/PowerShell/vscode-powershell/pull/4227) - Only check a script's extension if a script file was given.
+- ✨ 👷 [vscode-powershell #4220](https://github.com/PowerShell/vscode-powershell/pull/4220) - Add assertion to build that PSES bits are built in release configuration.
+- ✨ 🚂 [vscode-powershell #3561](https://github.com/PowerShell/vscode-powershell/pull/4206) - Enable `strict` TypeScript mode .
+- 🐛 🔍 [vscode-powershell #4201](https://github.com/PowerShell/vscode-powershell/pull/4203) - Fix automatic focus to temporary debug terminal (if it exists).
+- ✨ 👷 [vscode-powershell #2882](https://github.com/PowerShell/vscode-powershell/pull/3331) - Replace TSLint with ESLint.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.6.0
+
+- 🐛 🚂 [vscode-powershell #4219](https://github.com/PowerShell/PowerShellEditorServices/pull/1936) - Fix regression around `OnIdle` handler.
+- 🐛 🧠 [PowerShellEditorServices #1926](https://github.com/PowerShell/PowerShellEditorServices/pull/1935) - Catch exceptions within completion handler.
+- 🐛 👷 [vscode-powershell #4218](https://github.com/PowerShell/PowerShellEditorServices/pull/1933) - Fix release build.
+- ✨ 📖 [PowerShellEditorServices #1932](https://github.com/PowerShell/PowerShellEditorServices/pull/1932) - Add example of starting PSES in a script to readme. (Thanks @smartguy1196!)
+- #️⃣ 🙏 [PowerShellEditorServices #1931](https://github.com/PowerShell/PowerShellEditorServices/pull/1931) - Fix broken links in readme. (Thanks @smartguy1196!)
+
+## v2022.10.0
+### Thursday, October 20, 2022
+
+This October stable release incorporates a number of bugfixes throughout September and
+early October, though is not based on the latest preview, v2022.10.1-preview, as the
+refactors involved in enabling TypeScript's strict type checking and ESLint's strict
+linting will need more testing. However, based on the success of the PowerShell Script
+Analyzer's [v1.21.0][pssa-v1.21] release we wanted to get this to you sooner!
+
+Highlighted bugfixes include: supporting events registered to PowerShell's `OnIdle`
+handler so that Azure cmdlets such as `Az.Tools.Predictor` now work, a lock around the
+client's `start()` so the extension terminal cannot accidentally be spawned multiple
+times, and making the default debug configurations not override your current working
+directory (by unsetting `cwd` on all of them).
+
+In addition to fixing bugs, we also reintroduced a fan-favorite feature: the PowerShell
+Language Status Icon will visually indicate if the execution pipeline is busy. For
+example, a long-running task in the PowerShell Extension Terminal or a launched editor
+command will show a spinner!
+
+Finally, I wanted to call out work by Patrick to significantly improve the performance of
+reference finding (which powers the reference code lenses), so large workspaces can now be
+used more easily. If these performance improvements are still not enough for a particular
+workspace, we also introduced two new settings to fine-tune the feature:
+
+- `powershell.analyzeOpenDocumentsOnly` when enabled will only search for references within open documents
+- `powershell.enableReferencesCodeLens` can be used to disable reference finding without having to turn off other code lenses
+
+[pssa-v1.21]: https://github.com/PowerShell/PSScriptAnalyzer/releases/tag/1.21.0
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🔍 [vscode-powershell #4201](https://github.com/PowerShell/vscode-powershell/pull/4203) - Fix automatic focus to temporary debug terminal (if it exists).
+- 🐛 ✂️ [vscode-powershell #4195](https://github.com/PowerShell/vscode-powershell/pull/4195) - Fix Function Help snippet. (Thanks @okhoel!)
+- ✨ 📺 [vscode-powershell #4193](https://github.com/PowerShell/vscode-powershell/pull/4193) - Handle busy notification for all PowerShell tasks.
+- ✨ ‍🕵️ [vscode-powershell #4164](https://github.com/PowerShell/vscode-powershell/pull/4164) - Enable new PSScriptAnalyzer option `avoidSemicolonsAsLineTerminators`. (Thanks @bergmeister!)
+- ✨ 📺 [vscode-powershell #3954](https://github.com/PowerShell/vscode-powershell/pull/4187) - Re-implement indicator when running registered editor commands.
+- 🐛 🔍 [vscode-powershell #4185](https://github.com/PowerShell/vscode-powershell/pull/4186) - Only check a script's extension if a script was given.
+- 🐛 🔍 [vscode-powershell #4082](https://github.com/PowerShell/vscode-powershell/pull/4172) - Refactor the debug launch configuration resolvers.
+- 🐛 📁 [vscode-powershell #4163](https://github.com/PowerShell/vscode-powershell/pull/4171) - Fix incorrect docstring for `powershell.cwd`.
+- #️⃣ 🙏 [vscode-powershell #4170](https://github.com/PowerShell/vscode-powershell/pull/4170) - Add setting to only analyze open documents for references.
+- 🐛 🛫 [vscode-powershell #4160](https://github.com/PowerShell/vscode-powershell/pull/4161) - Lock `SessionManager.start()` so only one session is started.
+- ✨ 🔧 [vscode-powershell #4139](https://github.com/PowerShell/vscode-powershell/pull/4139) - Add setting to control the references code lens.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.4
+
+- ✨ 🚂 [PowerShellEditorServices #1928](https://github.com/PowerShell/PowerShellEditorServices/pull/1928) - Generalize the execution busy status to all PowerShell tasks.
+- ✨ ‍🕵️ [PowerShellEditorServices #1916](https://github.com/PowerShell/PowerShellEditorServices/pull/1916) - Upgrade PSScriptAnalyzer to 1.21.0. (Thanks @bergmeister!)
+- ✨ 🙏 [PowerShellEditorServices #1924](https://github.com/PowerShell/PowerShellEditorServices/pull/1924) - Re-implement indicator when running registered editor commands.
+- 🐛 🛫 [vscode-powershell #4048](https://github.com/PowerShell/PowerShellEditorServices/pull/1918) - Created a nested PowerShell for the top-level loop.
+- #️⃣ 🙏 [PowerShellEditorServices #1917](https://github.com/PowerShell/PowerShellEditorServices/pull/1917) - Overhaul workspace search for symbol references.
+- ✨ 🚨 [PowerShellEditorServices #1914](https://github.com/PowerShell/PowerShellEditorServices/pull/1914) - Add regression tests for F5 and F8 saving to history.
+- ✨ 🙏 [PowerShellEditorServices #1900](https://github.com/PowerShell/PowerShellEditorServices/pull/1900) - Add setting to control references code lens.
+
+## v2022.10.1-preview
+### Monday, October 17, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🚂 [vscode-powershell #3561](https://github.com/PowerShell/vscode-powershell/pull/4206) - Enable `strict` TypeScript mode .
+- 🐛 🔍 [vscode-powershell #4201](https://github.com/PowerShell/vscode-powershell/pull/4203) - Fix automatic focus to temporary debug terminal (if it exists).
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.4
+
+No changes.
+
+## v2022.10.0-preview
+### Friday, October 07, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 ✂️ [vscode-powershell #4195](https://github.com/PowerShell/vscode-powershell/pull/4195) - Fix Function Help snippet. (Thanks @okhoel!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.4
+
+No changes.
+
+## v2022.9.2-preview
+### Friday, September 30, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #4193](https://github.com/PowerShell/vscode-powershell/pull/4193) - Handle busy notification for all PowerShell tasks.
+- ✨ ‍🕵️ [vscode-powershell #4164](https://github.com/PowerShell/vscode-powershell/pull/4164) - Enable new PSScriptAnalyzer option `avoidSemicolonsAsLineTerminators`. (Thanks @bergmeister!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.4
+
+- ✨ 🚂 [PowerShellEditorServices #1928](https://github.com/PowerShell/PowerShellEditorServices/pull/1928) - Generalize the execution busy status to all PowerShell tasks.
+- ✨ ‍🕵️ [PowerShellEditorServices #1916](https://github.com/PowerShell/PowerShellEditorServices/pull/1916) - Upgrade PSScriptAnalyzer to 1.21.0. (Thanks @bergmeister!)
+
+## v2022.9.1-preview
+### Wednesday, September 28, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #3954](https://github.com/PowerShell/vscode-powershell/pull/4187) - Re-implement indicator when running registered editor commands.
+- 🐛 🔍 [vscode-powershell #4185](https://github.com/PowerShell/vscode-powershell/pull/4186) - Only check a script's extension if a script was given.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.3
+
+- ✨ 🙏 [PowerShellEditorServices #1924](https://github.com/PowerShell/PowerShellEditorServices/pull/1924) - Re-implement indicator when running registered editor commands.
+
+## v2022.9.0-preview
+### Tuesday, September 27, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🔍 [vscode-powershell #4082](https://github.com/PowerShell/vscode-powershell/pull/4172) - Refactor the debug launch configuration resolvers.
+- 🐛 📁 [vscode-powershell #4163](https://github.com/PowerShell/vscode-powershell/pull/4171) - Fix incorrect docstring for `powershell.cwd`.
+- #️⃣ 🙏 [vscode-powershell #4170](https://github.com/PowerShell/vscode-powershell/pull/4170) - Add setting to only analyze open documents for references.
+- 🐛 🛫 [vscode-powershell #4160](https://github.com/PowerShell/vscode-powershell/pull/4161) - Lock `SessionManager.start()` so only one session is started.
+- ✨ 🔧 [vscode-powershell #4139](https://github.com/PowerShell/vscode-powershell/pull/4139) - Add setting to control the references code lens.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.2
+
+- 🐛 🛫 [vscode-powershell #4048](https://github.com/PowerShell/PowerShellEditorServices/pull/1918) - Created a nested PowerShell for the top-level loop.
+- #️⃣ 🙏 [PowerShellEditorServices #1917](https://github.com/PowerShell/PowerShellEditorServices/pull/1917) - Overhaul workspace search for symbol references.
+- ✨ 🚨 [PowerShellEditorServices #1914](https://github.com/PowerShell/PowerShellEditorServices/pull/1914) - Add regression tests for F5 and F8 saving to history.
+- ✨ 🙏 [PowerShellEditorServices #1900](https://github.com/PowerShell/PowerShellEditorServices/pull/1900) - Add setting to control references code lens.
+
+## v2022.8.5
+### Tuesday, August 30, 2022
+
+This release incorporates all the changes since v2022.7.2, first tested across six
+previews. Thanks for using PowerShell in VS Code!
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🔧 [vscode-powershell #4151](https://github.com/PowerShell/vscode-powershell/pull/4152) - Add `integratedConsole.startInBackground` to completely hide the terminal.
+- ✨ 📖 [vscode-powershell #4080](https://github.com/PowerShell/vscode-powershell/pull/4147) - Create a walkthrough experience for PowerShell. (Thanks @S-Hakim!)
+- #️⃣ 🚂🙏 [vscode-powershell #4141](https://github.com/PowerShell/vscode-powershell/pull/4141) - Improve language client library close action message.
+- 🐛 🛫 [vscode-powershell #4136](https://github.com/PowerShell/vscode-powershell/pull/4140) - Handle edge case where user closes `cwd` picker.
+- ✨ 🙏 [vscode-powershell #4117](https://github.com/PowerShell/vscode-powershell/pull/4117) - Add `ToggleISEMode` command with tests.
+- 🐛 🛫 [vscode-powershell #4128](https://github.com/PowerShell/vscode-powershell/pull/4131) - Update `vscode-languageclient` and refactor (a lot of TLC).
+- ✨ 📺 [vscode-powershell #3266](https://github.com/PowerShell/vscode-powershell/pull/4125) - Fix debugger to start language client when necessary.
+- 🐛 🛫 [vscode-powershell #4111](https://github.com/PowerShell/vscode-powershell/pull/4121) - Use `vscode.workspace.fs` and suppress startup banner for `dotnet` installs of PowerShell.
+- 🐛 ✂️ [vscode-powershell #4120](https://github.com/PowerShell/vscode-powershell/pull/4120) - Remove extraneous `)` from the do-while snippet. (Thanks @ncook-hxgn!)
+- ✨ 📺 [vscode-powershell #4100](https://github.com/PowerShell/vscode-powershell/pull/4105) - Remove popup when extension updates.
+- 🐛 📁 [vscode-powershell #4102](https://github.com/PowerShell/vscode-powershell/pull/4104) - Fix edge case for workspaces defined with zero folders.
+- 🐛 📁 [vscode-powershell #4098](https://github.com/PowerShell/vscode-powershell/pull/4099) - Fix `checkIfDirectoryExists()` so `validateCwdSetting()` works.
+- ✨ 📟 [vscode-powershell #2523](https://github.com/PowerShell/vscode-powershell/pull/4096) - Don't hide extension terminal entirely.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.1
+
+- 🐛 ‍🕵️ [PowerShellEditorServices #1906](https://github.com/PowerShell/PowerShellEditorServices/pull/1907) - Remove `null` markers to avoid `NullReferenceException`.
+- 🐛 📁 [PowerShellEditorServices #1901](https://github.com/PowerShell/PowerShellEditorServices/pull/1902) - Fix file close in workspace service for Linux. (Thanks @fflaten!)
+- ✨ 🐢 [PowerShellEditorServices #1892](https://github.com/PowerShell/PowerShellEditorServices/pull/1899) - Add symbols for Pester setup and teardown blocks. (Thanks @fflaten!)
+- 🐛 🔍 [PowerShellEditorServices #1897](https://github.com/PowerShell/PowerShellEditorServices/pull/1898) - Add artificial stack frame to represent contexts without one.
+- 🐛 🔍 [PowerShellEditorServices #1894](https://github.com/PowerShell/PowerShellEditorServices/pull/1894) - Fix stepping while watch expressions or interactive pipeline is running.
+- ✨ 🐢 [PowerShellEditorServices #1891](https://github.com/PowerShell/PowerShellEditorServices/pull/1893) - Fix whitespace in Pester symbol and add test. (Thanks @fflaten!)
+- 🐛 🙏 [PowerShellEditorServices #1887](https://github.com/PowerShell/PowerShellEditorServices/pull/1890) - Fix symbol highlight when hovering function name. (Thanks @fflaten!)
+- ✨ 🚨 [PowerShellEditorServices #1874](https://github.com/PowerShell/PowerShellEditorServices/pull/1874) - Add end-to-end integration test with Vim.
+- 🐛 ‍🕵️ [vscode-powershell #4112](https://github.com/PowerShell/PowerShellEditorServices/pull/1873) - Fix (and test) regression with PSScriptAnalyzer default rules.
+- ✨ 🚨 [PowerShellEditorServices #1872](https://github.com/PowerShell/PowerShellEditorServices/pull/1872) - Add regression tests for parse error DiagnosticMarkers. (Thanks @fflaten!)
+- ✨ 🚨 [PowerShellEditorServices #1870](https://github.com/PowerShell/PowerShellEditorServices/pull/1870) - Add `DoesNotDuplicateScriptMarkersAsync` regression test.
+- 🐛 ‍🕵️ [PowerShellEditorServices #1869](https://github.com/PowerShell/PowerShellEditorServices/pull/1869) - Fix duplicate DiagnosticMarkers when reopening a file. (Thanks @fflaten!)
+- ✨ 🚨 [PowerShellEditorServices #1867](https://github.com/PowerShell/PowerShellEditorServices/pull/1867) - Add regression test for when `prompt` is undefined.
+- 🐛 🛫 [vscode-powershell #4073](https://github.com/PowerShell/PowerShellEditorServices/pull/1866) - Fix bug where error in `prompt` function crashed REPL.
+- #️⃣ 🙏 [vscode-powershell #2697](https://github.com/PowerShell/PowerShellEditorServices/pull/1864) - Use `HostInfo.BundledModulePath` to find PSScriptAnalyzer.
+
+## v2022.8.5-preview
+### Thursday, August 25, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🔧 [vscode-powershell #4151](https://github.com/PowerShell/vscode-powershell/pull/4152) - Add `integratedConsole.startInBackground` to completely hide the terminal.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.1
+
+- 🐛 ‍🕵️ [PowerShellEditorServices #1906](https://github.com/PowerShell/PowerShellEditorServices/pull/1907) - Remove `null` markers to avoid `NullReferenceException`.
+
+## v2022.8.4-preview
+### Friday, August 19, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📖 [vscode-powershell #4080](https://github.com/PowerShell/vscode-powershell/pull/4147) - Create a walkthrough experience for PowerShell. (Thanks @S-Hakim!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.0
+
+No update.
+
+## v2022.8.3-preview
+### Thursday, August 18, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- #️⃣ 🚂🙏 [vscode-powershell #4141](https://github.com/PowerShell/vscode-powershell/pull/4141) - Improve language client library close action message.
+- 🐛 🛫 [vscode-powershell #4136](https://github.com/PowerShell/vscode-powershell/pull/4140) - Handle edge case where user closes `cwd` picker.
+- ✨ 🙏 [vscode-powershell #4117](https://github.com/PowerShell/vscode-powershell/pull/4117) - Add `ToggleISEMode` command with tests.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.5.0
+
+- 🐛 📁 [PowerShellEditorServices #1901](https://github.com/PowerShell/PowerShellEditorServices/pull/1902) - Fix file close in workspace service for Linux. (Thanks @fflaten!)
+- ✨ 🐢 [PowerShellEditorServices #1892](https://github.com/PowerShell/PowerShellEditorServices/pull/1899) - Add symbols for Pester setup and teardown blocks. (Thanks @fflaten!)
+- 🐛 🔍 [PowerShellEditorServices #1897](https://github.com/PowerShell/PowerShellEditorServices/pull/1898) - Add artificial stack frame to represent contexts without one.
+- 🐛 🔍 [PowerShellEditorServices #1894](https://github.com/PowerShell/PowerShellEditorServices/pull/1894) - Fix stepping while watch expressions or interactive pipeline is running.
+- ✨ 🐢 [PowerShellEditorServices #1891](https://github.com/PowerShell/PowerShellEditorServices/pull/1893) - Fix whitespace in Pester symbol and add test. (Thanks @fflaten!)
+- 🐛 🙏 [PowerShellEditorServices #1887](https://github.com/PowerShell/PowerShellEditorServices/pull/1890) - Fix symbol highlight when hovering function name. (Thanks @fflaten!)
+
+## v2022.8.2-preview
+### Friday, August 12, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🛫 [vscode-powershell #4128](https://github.com/PowerShell/vscode-powershell/pull/4131) - Update `vscode-languageclient` and refactor (a lot of TLC).
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.4.10
+
+- Just dependency updates.
+
+## v2022.8.1-preview
+### Thursday, August 11, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #3266](https://github.com/PowerShell/vscode-powershell/pull/4125) - Fix debugger to start language client when necessary.
+- 🐛 🛫 [vscode-powershell #4111](https://github.com/PowerShell/vscode-powershell/pull/4121) - Use `vscode.workspace.fs` and suppress startup banner for `dotnet` installs of PowerShell.
+- 🐛 ✂️ [vscode-powershell #4120](https://github.com/PowerShell/vscode-powershell/pull/4120) - Remove extraneous `)` from the do-while snippet. (Thanks @ncook-hxgn!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.4.9
+
+- ✨ 🚨 [PowerShellEditorServices #1874](https://github.com/PowerShell/PowerShellEditorServices/pull/1874) - Add end-to-end integration test with Vim.
+- 🐛 ‍🕵️ [vscode-powershell #4112](https://github.com/PowerShell/PowerShellEditorServices/pull/1873) - Fix (and test) regression with PSScriptAnalyzer default rules.
+- ✨ 🚨 [PowerShellEditorServices #1872](https://github.com/PowerShell/PowerShellEditorServices/pull/1872) - Add regression tests for parse error DiagnosticMarkers. (Thanks @fflaten!)
+- ✨ 🚨 [PowerShellEditorServices #1870](https://github.com/PowerShell/PowerShellEditorServices/pull/1870) - Add `DoesNotDuplicateScriptMarkersAsync` regression test.
+- 🐛 ‍🕵️ [PowerShellEditorServices #1869](https://github.com/PowerShell/PowerShellEditorServices/pull/1869) - Fix duplicate DiagnosticMarkers when reopening a file. (Thanks @fflaten!)
+
+## v2022.8.0-preview
+### Wednesday, August 03, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #4100](https://github.com/PowerShell/vscode-powershell/pull/4105) - Remove popup when extension updates.
+- 🐛 📁 [vscode-powershell #4102](https://github.com/PowerShell/vscode-powershell/pull/4104) - Fix edge case for workspaces defined with zero folders.
+- 🐛 📁 [vscode-powershell #4098](https://github.com/PowerShell/vscode-powershell/pull/4099) - Fix `checkIfDirectoryExists()` so `validateCwdSetting()` works.
+- ✨ 📟 [vscode-powershell #2523](https://github.com/PowerShell/vscode-powershell/pull/4096) - Don't hide extension terminal entirely.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.4.8
+
+- ✨ 🚨 [PowerShellEditorServices #1867](https://github.com/PowerShell/PowerShellEditorServices/pull/1867) - Add regression test for when `prompt` is undefined.
+- 🐛 🛫 [vscode-powershell #4073](https://github.com/PowerShell/PowerShellEditorServices/pull/1866) - Fix bug where error in `prompt` function crashed REPL.
+- #️⃣ 🙏 [vscode-powershell #2697](https://github.com/PowerShell/PowerShellEditorServices/pull/1864) - Use `HostInfo.BundledModulePath` to find PSScriptAnalyzer.
+
+## v2022.7.2
+### Friday, July 29, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 💭 [vscode-powershell #4093](https://github.com/PowerShell/vscode-powershell/pull/4093) - Change `storageUri` to `globalStorageUri` for log and session files.
+- ✨ 📟 [vscode-powershell #4053](https://github.com/PowerShell/vscode-powershell/pull/4090) - Rename "Integrated Console" to "Extension Terminal".
+- ✨ 🚨 [vscode-powershell #4089](https://github.com/PowerShell/vscode-powershell/pull/4089) - Update and extend CI matrix.
+- ✨ 🚂 [vscode-powershell #4088](https://github.com/PowerShell/vscode-powershell/pull/4088) - Use `context.storageUri` for session file (and refactor).
+- ✨ 🔧 [vscode-powershell #4067](https://github.com/PowerShell/vscode-powershell/pull/4071) - Use `context.storageUri` for logs and support `None` level.
+- ✨ 🔧 [vscode-powershell #4064](https://github.com/PowerShell/vscode-powershell/pull/4064) - Add multi-root choice experience to `powershell.cwd`.
+- ✨ 📺 [vscode-powershell #4063](https://github.com/PowerShell/vscode-powershell/pull/4063) - Change configuration title to just `PowerShell`.
+- ✨ 📖 [vscode-powershell #4062](https://github.com/PowerShell/vscode-powershell/pull/4062) - Add note about accidentally disabling completions.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.4.7
+
+- ✨ 🚨 [PowerShellEditorServices #1861](https://github.com/PowerShell/PowerShellEditorServices/pull/1861) - Add `DebuggerBreaksInUntitledScript` unit test.
+- ✨ 📟 [PowerShellEditorServices #1860](https://github.com/PowerShell/PowerShellEditorServices/pull/1860) - Rename "Integrated Console" to "Extension Terminal".
+- ✨ 🚨 [PowerShellEditorServices #1859](https://github.com/PowerShell/PowerShellEditorServices/pull/1859) - Update and extend CI matrix.
+- ✨ 🚨 [PowerShellEditorServices #1858](https://github.com/PowerShell/PowerShellEditorServices/pull/1858) - Add regression test for debugging script with dot-source operator.
+- ✨ 🚨 [PowerShellEditorServices #1857](https://github.com/PowerShell/PowerShellEditorServices/pull/1857) - Add regression test for `$PSDebugContext` in `prompt` function.
+- 🐛 🛫 [PowerShellEditorServices #1849](https://github.com/PowerShell/PowerShellEditorServices/pull/1851) - Add `Directory.Exists()` check to `SetInitialWorkingDirectoryAsync()`.
+- ✨ 🚨 [PowerShellEditorServices #1850](https://github.com/PowerShell/PowerShellEditorServices/pull/1850) - Catch `OperationCanceledException` in both command loops.
+- ✨ 🚨 [PowerShellEditorServices #1793](https://github.com/PowerShell/PowerShellEditorServices/pull/1848) - Improve CI stability.
+- ✨ 🚨 [PowerShellEditorServices #1846](https://github.com/PowerShell/PowerShellEditorServices/pull/1846) - Add end-to-end Pester unit test.
+
+## v2022.7.2-preview
+### Tuesday, July 26, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 💭 [vscode-powershell #4093](https://github.com/PowerShell/vscode-powershell/pull/4093) - Change `storageUri` to `globalStorageUri` for log and session files.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices) v3.4.7
+
+No changes.
+
+## v2022.7.1-preview
+### Monday, July 25, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📟 [vscode-powershell #4053](https://github.com/PowerShell/vscode-powershell/pull/4090) - Rename "Integrated Console" to "Extension Terminal".
+- ✨ 🚨 [vscode-powershell #4089](https://github.com/PowerShell/vscode-powershell/pull/4089) - Update and extend CI matrix.
+- ✨ 🚂 [vscode-powershell #4088](https://github.com/PowerShell/vscode-powershell/pull/4088) - Use `context.storageUri` for session file (and refactor).
+- ✨ 🔧 [vscode-powershell #4067](https://github.com/PowerShell/vscode-powershell/pull/4071) - Use `context.storageUri` for logs and support `None` level.
+- ✨ 🔧 [vscode-powershell #4064](https://github.com/PowerShell/vscode-powershell/pull/4064) - Add multi-root choice experience to `powershell.cwd`.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 🚨 [PowerShellEditorServices #1861](https://github.com/PowerShell/PowerShellEditorServices/pull/1861) - Add `DebuggerBreaksInUntitledScript` unit test.
+- ✨ 📟 [PowerShellEditorServices #1860](https://github.com/PowerShell/PowerShellEditorServices/pull/1860) - Rename "Integrated Console" to "Extension Terminal".
+- ✨ 🚨 [PowerShellEditorServices #1859](https://github.com/PowerShell/PowerShellEditorServices/pull/1859) - Update and extend CI matrix.
+- ✨ 🚨 [PowerShellEditorServices #1858](https://github.com/PowerShell/PowerShellEditorServices/pull/1858) - Add regression test for debugging script with dot-source operator.
+- ✨ 🚨 [PowerShellEditorServices #1857](https://github.com/PowerShell/PowerShellEditorServices/pull/1857) - Add regression test for `$PSDebugContext` in `prompt` function.
+
+## v2022.7.0-preview
+### Monday, July 11, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #4063](https://github.com/PowerShell/vscode-powershell/pull/4063) - Change configuration title to just `PowerShell`.
+- ✨ 📖 [vscode-powershell #4062](https://github.com/PowerShell/vscode-powershell/pull/4062) - Add note about accidentally disabling completions.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🛫 [PowerShellEditorServices #1849](https://github.com/PowerShell/PowerShellEditorServices/pull/1851) - Add `Directory.Exists()` check to `SetInitialWorkingDirectoryAsync()`.
+- ✨ 🚨 [PowerShellEditorServices #1850](https://github.com/PowerShell/PowerShellEditorServices/pull/1850) - Catch `OperationCanceledException` in both command loops.
+- ✨ 🚨 [PowerShellEditorServices #1793](https://github.com/PowerShell/PowerShellEditorServices/pull/1848) - Improve CI stability.
+- ✨ 🚨 [PowerShellEditorServices #1846](https://github.com/PowerShell/PowerShellEditorServices/pull/1846) - Add end-to-end Pester unit test.
+
+## v2022.6.3
+### Wednesday, June 30, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📖 [vscode-powershell #4046](https://github.com/PowerShell/vscode-powershell/pull/4046) - Update tooling and READMEs for branch rename.
+- ✨ 🔧 [vscode-powershell #4033](https://github.com/PowerShell/vscode-powershell/pull/4034) - Mark unused `useX86Host` setting as deprecated.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 🙏 [PowerShellEditorServices #1844](https://github.com/PowerShell/PowerShellEditorServices/pull/1845) - Update PSReadLine to v2.2.6.
+- ✨ 📖 [PowerShellEditorServices #1843](https://github.com/PowerShell/PowerShellEditorServices/pull/1843) - Find/replace of `master` to `main` for branch rename.
+- 🐛 📟 [vscode-powershell #3683](https://github.com/PowerShell/PowerShellEditorServices/pull/1841) - Add command to PSReadLine history before cancellation.
+- 🐛 🔍 [PowerShellEditorServices #1839](https://github.com/PowerShell/PowerShellEditorServices/pull/1839) - Fix logic checking for untitled or raw scripts.
+- 🐛 🔍 [PowerShellEditorServices #1838](https://github.com/PowerShell/PowerShellEditorServices/pull/1838) - Don't use `RunContinuationsAsynchronously` for our `TaskCompletionSource`.
+- 🐛 📟 [vscode-powershell #4021](https://github.com/PowerShell/PowerShellEditorServices/pull/1836) - Fix piping to native commands for Windows PowerShell.
+- ✨ 📖 [PowerShellEditorServices #1831](https://github.com/PowerShell/PowerShellEditorServices/pull/1833) - Add readme about `ReadKey` workarounds.
+- ✨ 🚨 [PowerShellEditorServices #1832](https://github.com/PowerShell/PowerShellEditorServices/pull/1832) - Improve `$PROFILE` variable and profile loading test.
+- ✨ 🚨 [PowerShellEditorServices #1830](https://github.com/PowerShell/PowerShellEditorServices/pull/1830) - Add regression test for untitled scripts in Windows PowerShell.
+- ✨ 🚨 [PowerShellEditorServices #1828](https://github.com/PowerShell/PowerShellEditorServices/pull/1828) - Add regression test for accidentally allowing removal of `$psEditor`.
+
+## v2022.6.3-preview
+### Wednesday, June 29, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📖 [vscode-powershell #4046](https://github.com/PowerShell/vscode-powershell/pull/4046) - Update tooling and READMEs for branch rename.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 🙏 [PowerShellEditorServices #1844](https://github.com/PowerShell/PowerShellEditorServices/pull/1845) - Update PSReadLine to v2.2.6.
+- ✨ 📖 [PowerShellEditorServices #1843](https://github.com/PowerShell/PowerShellEditorServices/pull/1843) - Find/replace of `master` to `main` for branch rename.
+- 🐛 📟 [vscode-powershell #3683](https://github.com/PowerShell/PowerShellEditorServices/pull/1841) - Add command to PSReadLine history before cancellation.
+
+## v2022.6.2-preview
+### Wednesday, June 22, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 🔧 [vscode-powershell #4033](https://github.com/PowerShell/vscode-powershell/pull/4034) - Mark unused `useX86Host` setting as deprecated.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🔍 [PowerShellEditorServices #1839](https://github.com/PowerShell/PowerShellEditorServices/pull/1839) - Fix logic checking for untitled or raw scripts.
+- 🐛 🔍 [PowerShellEditorServices #1838](https://github.com/PowerShell/PowerShellEditorServices/pull/1838) - Don't use `RunContinuationsAsynchronously` for our `TaskCompletionSource`.
+- 🐛 📟 [vscode-powershell #4021](https://github.com/PowerShell/PowerShellEditorServices/pull/1836) - Fix piping to native commands for Windows PowerShell.
+- ✨ 📖 [PowerShellEditorServices #1831](https://github.com/PowerShell/PowerShellEditorServices/pull/1833) - Add readme about `ReadKey` workarounds.
+- ✨ 🚨 [PowerShellEditorServices #1832](https://github.com/PowerShell/PowerShellEditorServices/pull/1832) - Improve `$PROFILE` variable and profile loading test.
+- ✨ 🚨 [PowerShellEditorServices #1830](https://github.com/PowerShell/PowerShellEditorServices/pull/1830) - Add regression test for untitled scripts in Windows PowerShell.
+- ✨ 🚨 [PowerShellEditorServices #1828](https://github.com/PowerShell/PowerShellEditorServices/pull/1828) - Add regression test for accidentally allowing removal of `$psEditor`.
+
+## v2022.6.1
+### Tuesday, June 21, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+New stable release with all changes below since `v2022.5.1`:
+
+- 🐛 📖 [vscode-powershell #4018](https://github.com/PowerShell/vscode-powershell/pull/4018) - Fix outdated link to security guidelines. (Thanks @rklec!)
+- 🐛 👷 [vscode-powershell #3993](https://github.com/PowerShell/vscode-powershell/pull/3993) - Revert modifications caused by Code's test run.
+- 🐛 🚂 [vscode-powershell #3992](https://github.com/PowerShell/vscode-powershell/pull/3992) - Fix how we check extension mode.
+- 🐛 🛫 [vscode-powershell #3986](https://github.com/PowerShell/vscode-powershell/pull/3986) - Pass `EnableProfileLoading` and `InitialWorkingDirectory` as `initializationOptions`.
+- ✨ 📺 [vscode-powershell #3976](https://github.com/PowerShell/vscode-powershell/pull/3976) - Add warning about intellisense to PSIC terminate dialog. (Thanks @JustinGrote!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+Includes `v3.4.3` with all changes below since `v3.3.5`:
+
+- ✨ 📟 [PowerShellEditorServices #1823](https://github.com/PowerShell/PowerShellEditorServices/pull/1823) - Utilize the `AddToHistory` delegate from PSRL proxy.
+- ✨ 🛫 [PowerShellEditorServices #1821](https://github.com/PowerShell/PowerShellEditorServices/pull/1821) - Add regression test for no defined profiles.
+- ✨ 👷 [PowerShellEditorServices #1820](https://github.com/PowerShell/PowerShellEditorServices/pull/1820) - Add Emacs regression tests for PSES.
+- 🐛 🧠 [PowerShellEditorServices #1819](https://github.com/PowerShell/PowerShellEditorServices/pull/1819) - Remove bad UX of commit characters for paths.
+- 🐛 🔍 [PowerShellEditorServices #1818](https://github.com/PowerShell/PowerShellEditorServices/pull/1818) - Exit debugger stop early if cause is PSE.
+- ✨ 👷 [PowerShellEditorServices #1817](https://github.com/PowerShell/PowerShellEditorServices/pull/1817) - Fix build script to support Windows on Arm64.
+- 🐛 🔍 [PowerShellEditorServices #1815](https://github.com/PowerShell/PowerShellEditorServices/pull/1815) - Set `IsDebuggingRemoteRunspace` sooner for attach.
+- 🐛 🙏 [PowerShellEditorServices #1814](https://github.com/PowerShell/PowerShellEditorServices/pull/1814) - Fix error when piping `IFilePosition` to `ConvertTo-ScriptExtent`.
+- ✨ 🧠 [PowerShellEditorServices #1809](https://github.com/PowerShell/PowerShellEditorServices/pull/1809) - Additional IntelliSense fixes and ToolTip overhaul.
+- 🐛 🛫 [PowerShellEditorServices #1807](https://github.com/PowerShell/PowerShellEditorServices/pull/1807) - Fix startup bug when zero profiles are present.
+- 🐛 🔍 [vscode-powershell #3965](https://github.com/PowerShell/PowerShellEditorServices/pull/1804) - Wrap untitled script with newlines.
+- 🐛 🔍 [vscode-powershell #3980](https://github.com/PowerShell/PowerShellEditorServices/pull/1803) - Fix execution of debug prompt commands.
+- 🐛 📟 [PowerShellEditorServices #1802](https://github.com/PowerShell/PowerShellEditorServices/pull/1802) - Set `EnableProfileLoading` default to `true`.
+- 🐛 🙏 [PowerShellEditorServices #1695](https://github.com/PowerShell/PowerShellEditorServices/pull/1801) - Re-enable stdio clients by fixing initialization sequence.
+- ✨ 🧠 [PowerShellEditorServices #1799](https://github.com/PowerShell/PowerShellEditorServices/pull/1799) - Fix a lot of IntelliSense issues.
+- #️⃣ 🙏 [vscode-powershell #3962](https://github.com/PowerShell/PowerShellEditorServices/pull/1797) - Increase stack size for PowerShell 5. (Thanks @nohwnd!)
+
+## v2022.6.1-preview
+### Monday, June 13, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 📖 [vscode-powershell #4018](https://github.com/PowerShell/vscode-powershell/pull/4018) - Fix outdated link to security guidelines. (Thanks @rklec!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 📟 [PowerShellEditorServices #1823](https://github.com/PowerShell/PowerShellEditorServices/pull/1823) - Utilize the `AddToHistory` delegate from PSRL proxy.
+- ✨ 🛫 [PowerShellEditorServices #1821](https://github.com/PowerShell/PowerShellEditorServices/pull/1821) - Add regression test for no defined profiles.
+- ✨ 👷 [PowerShellEditorServices #1820](https://github.com/PowerShell/PowerShellEditorServices/pull/1820) - Add Emacs regression tests for PSES.
+- 🐛 🧠 [PowerShellEditorServices #1819](https://github.com/PowerShell/PowerShellEditorServices/pull/1819) - Remove bad UX of commit characters for paths.
+- 🐛 🔍 [PowerShellEditorServices #1818](https://github.com/PowerShell/PowerShellEditorServices/pull/1818) - Exit debugger stop early if cause is PSE.
+- ✨ 👷 [PowerShellEditorServices #1817](https://github.com/PowerShell/PowerShellEditorServices/pull/1817) - Fix build script to support Windows on Arm64.
+- 🐛 🔍 [PowerShellEditorServices #1815](https://github.com/PowerShell/PowerShellEditorServices/pull/1815) - Set `IsDebuggingRemoteRunspace` sooner for attach.
+- 🐛 🙏 [PowerShellEditorServices #1814](https://github.com/PowerShell/PowerShellEditorServices/pull/1814) - Fix error when piping `IFilePosition` to `ConvertTo-ScriptExtent`.
+
+## v2022.5.5-preview
+### Friday, May 20, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+No changes.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 🧠 [PowerShellEditorServices #1809](https://github.com/PowerShell/PowerShellEditorServices/pull/1809) - Additional IntelliSense fixes and ToolTip overhaul.
+
+## v2022.5.4-preview
+### Thursday, May 19, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+No changes.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🛫 [PowerShellEditorServices #1807](https://github.com/PowerShell/PowerShellEditorServices/pull/1807) - Fix startup bug when zero profiles are present.
+
+## v2022.5.3-preview
+### Thursday, May 19, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 👷 [vscode-powershell #3993](https://github.com/PowerShell/vscode-powershell/pull/3993) - Revert modifications caused by Code's test run.
+- 🐛 🚂 [vscode-powershell #3992](https://github.com/PowerShell/vscode-powershell/pull/3992) - Fix how we check extension mode.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+No changes.
+
+## v2022.5.2-preview
+### Tuesday, May 17, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🛫 [vscode-powershell #3986](https://github.com/PowerShell/vscode-powershell/pull/3986) - Pass `EnableProfileLoading` and `InitialWorkingDirectory` as `initializationOptions`.
+- ✨ 📺 [vscode-powershell #3976](https://github.com/PowerShell/vscode-powershell/pull/3976) - Add warning about intellisense to PSIC terminate dialog. (Thanks @JustinGrote!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🔍 [vscode-powershell #3965](https://github.com/PowerShell/PowerShellEditorServices/pull/1804) - Wrap untitled script with newlines.
+- 🐛 🔍 [vscode-powershell #3980](https://github.com/PowerShell/PowerShellEditorServices/pull/1803) - Fix execution of debug prompt commands.
+- 🐛 📟 [PowerShellEditorServices #1802](https://github.com/PowerShell/PowerShellEditorServices/pull/1802) - Set `EnableProfileLoading` default to `true`.
+- 🐛 🙏 [PowerShellEditorServices #1695](https://github.com/PowerShell/PowerShellEditorServices/pull/1801) - Re-enable stdio clients by fixing initialization sequence.
+- ✨ 🧠 [PowerShellEditorServices #1799](https://github.com/PowerShell/PowerShellEditorServices/pull/1799) - Fix a lot of IntelliSense issues.
+- #️⃣ 🙏 [vscode-powershell #3962](https://github.com/PowerShell/PowerShellEditorServices/pull/1797) - Increase stack size for PowerShell 5. (Thanks @nohwnd!)
+
+## v2022.5.1
+### Friday, May 06, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🔍 [vscode-powershell #3950](https://github.com/PowerShell/vscode-powershell/pull/3951) - Handle `sendKeyPress` events for temporary integrated consoles.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🔍 [vscode-powershell #3950](https://github.com/PowerShell/PowerShellEditorServices/pull/1791) - Send `sendKeyPress` event across DAP for temporary integrated consoles.
+
+## v2022.5.0
+### Tuesday, May 03, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+Welcome to the new and improved PowerShell for Visual Studio Code!
+
+This update represents a complete overhaul of the core PowerShell engine of PowerShell
+Editor Services, intending to create a more reliable and stable user experience. This
+release represents nearly two years' work, tracked in PSES
+[#1295](https://github.com/PowerShell/PowerShellEditorServices/issues/1295) and
+implemented in PSES
+[#1459](https://github.com/PowerShell/PowerShellEditorServices/pull/1459). It is our
+response to many issues opened by users over the last several years.
+
+Thank you to all of the community members who opened issues which helped motivate this
+major update.
+
+These major updates have also been tested over the last 6 months, in 13 releases of our
+[PowerShell Preview extension for Visual Studio
+Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.powershell). A
+huge thank you to all of the community members who have tested these changes to the
+extension and have worked with us to polish the extension before releasing it through our
+stable channel.
+
+Please see our
+[blog](https://devblogs.microsoft.com/powershell/major-update-to-the-powershell-extension-for-visual-studio-code)
+for more details!
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 🙏 [PowerShellEditorServices #1787](https://github.com/PowerShell/PowerShellEditorServices/pull/1787) - Bump PSReadLine to `v2.2.5`.
+
+## v2022.5.0-preview
+### Monday, May 02, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+Fourth Release Candidate! Thanks for finding bugs and helping us squash them!
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 📟 [PowerShellEditorServices #1785](https://github.com/PowerShell/PowerShellEditorServices/pull/1785) - Add `IHostUISupportsMultipleChoiceSelection` implementation.
+- 🐛 🔍 [PowerShellEditorServices #1784](https://github.com/PowerShell/PowerShellEditorServices/pull/1784) - Do not exit from `DebuggerStop` unless resuming.
+
+## v2022.4.3-preview
+### Thursday, April 28, 2022
+
+Third Release Candidate. Our recent debugger and `ReadKey` overhauls revealed some other
+bugs that needed squashing! Please test this thoroughly. We're gaining confidence!
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🙏 [vscode-powershell #3939](https://github.com/PowerShell/vscode-powershell/pull/3939) - Send `p` instead of `\0` for `sendKeyPress`.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🛫 [PowerShellEditorServices #1782](https://github.com/PowerShell/PowerShellEditorServices/pull/1782) - Fix ordering of startup tasks so `psEditor` is defined before profiles are loaded.
+- 🐛 📟 [PowerShellEditorServices #1781](https://github.com/PowerShell/PowerShellEditorServices/pull/1781) - Bring back `WriteWithPrompt()`.
+- 🐛 📟 [vscode-powershell #3937](https://github.com/PowerShell/PowerShellEditorServices/pull/1779) - Update to latest PSReadLine beta (with fix for race condition).
+- 🐛 🔍 [PowerShellEditorServices #1778](https://github.com/PowerShell/PowerShellEditorServices/pull/1778) - Fix extra prompting and manual debugger commands.
+- ✨ 🚂 [PowerShellEditorServices #1777](https://github.com/PowerShell/PowerShellEditorServices/pull/1777) - Consolidate `InterruptCurrentForeground` and `MustRunInForeground`.
+- ✨ 🚂 [PowerShellEditorServices #1776](https://github.com/PowerShell/PowerShellEditorServices/pull/1776) - Don't cancel on disposal of `CancellationScope`.
+
+## v2022.4.2-preview
+### Wednesday, April 20, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+Just including updates to PowerShell Editor Services. This is the second Release
+Candidate! Please give it a thorough test.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 👷 [PowerShellEditorServices #1761](https://github.com/PowerShell/PowerShellEditorServices/pull/1766) - Bump `net461` to `net462` due to upcoming end of support.
+- 🐛 💎 [vscode-powershell #3928](https://github.com/PowerShell/PowerShellEditorServices/pull/1764) - Fix formatting handlers and PSScriptAnalyzer loading.
+- 🐛 🔍 [PowerShellEditorServices #1762](https://github.com/PowerShell/PowerShellEditorServices/pull/1762) - Fix prompt spam and general debugger reliability improvements.
+- ✨ 🙏 [PowerShellEditorServices #1479](https://github.com/PowerShell/PowerShellEditorServices/pull/1759) - Enable IDE0005 (unneccessary using statements) as error.
+- 🐛 🙏 [PowerShellEditorServices #1754](https://github.com/PowerShell/PowerShellEditorServices/pull/1758) - With a fix in PSReadLine, we don't have to return a "null" key press.
+
+## v2022.4.1-preview
+### Monday, April 18, 2022
+
+This is our first Release Candidate. We've merged a set of major fixes to the debugger so
+that attaching to remote processes / runspaces now works again. While the extension is not
+perfect (yet), we believe at this point the preview far exceeds the stable extension in
+terms of usability and stability, and it is time to roll this out. Please give this a
+thorough testing, as we hope to roll it into the stable extension next week.
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #3919](https://github.com/PowerShell/vscode-powershell/pull/3919) - Improve Settings Editor experience in a few places. (Thanks @TylerLeonhardt!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- #️⃣ 🙏 [PowerShellEditorServices #1757](https://github.com/PowerShell/PowerShellEditorServices/pull/1757) - Enable code analysis and formatting as errors on build.
+- ✨ 🚂 [PowerShellEditorServices #1755](https://github.com/PowerShell/PowerShellEditorServices/pull/1755) - Apply automatic fixes (manually).
+- 🐛 🔍 [PowerShellEditorServices #1736](https://github.com/PowerShell/PowerShellEditorServices/pull/1752) - Fix attach to process debugging.
+
+## v2022.4.0-preview
+### Tuesday, April 12, 2022
+
+We delayed moving the preview branch to stable in order to fix issues surrounding our
+`ReadKey` / `ReadLine` logic. This preview contains a new minor release of PowerShell
+Editor Services with an entire rewrite of that logic, utilizing what we hope is a much
+better workaround for the underlying issue in .NET's `Console.ReadKey`. Please give this
+release a thorough testing, especially in the console with PSReadLine.
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 🙏 [vscode-powershell #3911](https://github.com/PowerShell/vscode-powershell/pull/3911) - Add `sendKeyPress` notification used to "cancel" `Console.ReadKey`.
+- 🐛 ✂️ [vscode-powershell #3276](https://github.com/PowerShell/vscode-powershell/pull/3900) - Fix snippet prefixes (especially `#region`).
+- ✨ 📺 [vscode-powershell #3897](https://github.com/PowerShell/vscode-powershell/pull/3897) - Add PowerShell icon to Integrated Console.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- 🐛 🙏 [PowerShellEditorServices #1751](https://github.com/PowerShell/PowerShellEditorServices/pull/1751) - Re-workaround uncancellable `Console.ReadKey`.
+- 🐛 ‍🕵️ [PowerShellEditorServices #1749](https://github.com/PowerShell/PowerShellEditorServices/pull/1749) - Correctly map `SuggestedCorrection` to `MarkerCorrection`. (Thanks @bergmeister!)
+
+## v2022.3.1-preview
+### Thursday, March 24, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- 🐛 📺 [vscode-powershell #3878](https://github.com/PowerShell/vscode-powershell/pull/3883) - Add several more commands to activation events.
+- 🐛 📖 [vscode-powershell #3857](https://github.com/PowerShell/vscode-powershell/pull/3879) - Update troubleshooting guide etc.
+- 🐛 📺 [vscode-powershell #3874](https://github.com/PowerShell/vscode-powershell/pull/3877) - Add PowerShell version to language status item.
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- #️⃣ 🙏 [PowerShellEditorServices #1746](https://github.com/PowerShell/PowerShellEditorServices/pull/1746) - Replace `_consoleHostUI` with `_underlyingHostUI`.
+
+## v2022.3.0-preview
+### Thursday, March 10, 2022
+
+#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)
+
+- ✨ 📺 [vscode-powershell #2499](https://github.com/PowerShell/vscode-powershell/pull/3869) - Use Code's new Language Status API.
+- ✨ 📺 [vscode-powershell #3866](https://github.com/PowerShell/vscode-powershell/pull/3866) - Fix title of PowerShell Command Explorer pane.
+- ✨ 📺 [vscode-powershell #3865](https://github.com/PowerShell/vscode-powershell/pull/3865) - Replace custom graphics with updated Codicons.
+- ✨ 🔧 [vscode-powershell #3858](https://github.com/PowerShell/vscode-powershell/pull/3859) - Deprecate `promptToUpdatePackageManagement`.
+- 🐛 📟 [vscode-powershell #3360](https://github.com/PowerShell/vscode-powershell/pull/3854) - Use new `isTransient` API to prevent duplicate integrated consoles.
+- 🐛 🔍 [vscode-powershell #3259](https://github.com/PowerShell/vscode-powershell/pull/3852) - Fix Pester `Test/Debug` code lenses to now change directory.
+- ✨ ✂️ [vscode-powershell #3839](https://github.com/PowerShell/vscode-powershell/pull/3839) - Modernize built-in snippets. (Thanks @JustinGrote!)
+
+#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
+
+- ✨ 🧠 [vscode-powershell #3364](https://github.com/PowerShell/PowerShellEditorServices/pull/1738) - Improve completion logic (more icons!).
+- 🐛 🛫 [PowerShellEditorServices #1576](https://github.com/PowerShell/PowerShellEditorServices/pull/1735) - Remove `PackageManagement` module update prompt.
+- 🐛 📟 [PowerShellEditorServices #1734](https://github.com/PowerShell/PowerShellEditorServices/pull/1734) - Finish redirection of `$Host.PrivateData`.
+- 🐛 📟 [PowerShellEditorServices #1639](https://github.com/PowerShell/PowerShellEditorServices/pull/1732) - Redirect `PSHost.Notify*Application` methods.
+
 ## v2022.2.2-preview
 ### Thursday, February 24, 2022
 
@@ -93,7 +1691,7 @@ are updating the stable extension to bring some bug fixes forward. Please try ou
 [PowerShell Preview extension][] for the latest and hopefully greatest experience, and
 help us squash those bugs!
 
-[PowerShell Preview extension]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell-Preview
+[PowerShell Preview extension]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.powershell
 
 #### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
 
@@ -1011,7 +2609,7 @@ for features to come out in the following stable release.
 
 You may also notice that the history of the changelog has changed.
 For a full list of changes between this release and the previous stable release,
-see [here](https://github.com/PowerShell/vscode-powershell/blob/master/docs/preview_to_stable_changelog.md).
+see [here](https://github.com/PowerShell/vscode-powershell/blob/main/docs/preview_to_stable_changelog.md).
 You can find the changelog from the old stable fork
 [here](https://github.com/PowerShell/vscode-powershell/blob/legacy/1.x/CHANGELOG.md).
 
@@ -1604,8 +3202,8 @@ As stated above, this version of the PowerShell extension only works with Window
 #### [vscode-PowerShell](https://github.com/PowerShell/vscode-PowerShell)
 
 - [vscode-PowerShell #1632](https://github.com/PowerShell/vscode-powershell/pull/1632) -
-  Started [a document for ISE-like configuration of VSCode](https://github.com/PowerShell/vscode-powershell/blob/master/docs/ise_compatibility.md).
-  Please help us build it out by [contirbuting an edit](https://github.com/PowerShell/vscode-powershell/edit/master/docs/ise_compatibility.md).
+  Started [a document for ISE-like configuration of VSCode](https://github.com/PowerShell/vscode-powershell/blob/main/docs/ise_compatibility.md).
+  Please help us build it out by [contirbuting an edit](https://github.com/PowerShell/vscode-powershell/edit/main/docs/ise_compatibility.md).
 
 #### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)
 
@@ -1646,7 +3244,7 @@ As stated above, this version of the PowerShell extension only works with Window
   Add <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>J</kbd> (<kbd>Cmd</kbd>+<kbd>Alt</kbd>+<kbd>J</kbd> on macOS)
   keybinding to open up list of available snippets
 - [vscode-PowerShell #1597](https://github.com/PowerShell/vscode-powershell/pull/1597) -
-  Make `Install-VSCode.ps1` work on macOS and Linux. Get the script [here](https://github.com/PowerShell/vscode-powershell/blob/master/scripts/Install-VSCode.ps1)
+  Make `Install-VSCode.ps1` work on macOS and Linux. Get the script [here](https://github.com/PowerShell/vscode-powershell/blob/main/scripts/Install-VSCode.ps1)
 - [vscode-PowerShell #1580](https://github.com/PowerShell/vscode-powershell/pull/1580) -
   `New-EditorFile` works on non-PowerShell untitled files
 - [vscode-PowerShell #1557](https://github.com/PowerShell/vscode-powershell/pull/1557) -
@@ -2336,14 +3934,14 @@ Thanks to new PowerShell Editor Services co-maintainer [Patrick Meinecke](https:
 we've gained a new set of useful commands for interacting with the $psEditor APIs
 within the Integrated Console:
 
-- [Find-Ast](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/Find-Ast.md)
-- [Get-Token](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/Get-Token.md)
-- [ConvertFrom-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/ConvertFrom-ScriptExtent.md)
-- [ConvertTo-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/ConvertTo-ScriptExtent.md)
-- [Set-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/Set-ScriptExtent.md)
-- [Join-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/Join-ScriptExtent.md)
-- [Test-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/Test-ScriptExtent.md)
-- [Import-EditorCommand](https://github.com/PowerShell/PowerShellEditorServices/blob/master/module/docs/Import-EditorCommand.md)
+- [Find-Ast](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/Find-Ast.md)
+- [Get-Token](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/Get-Token.md)
+- [ConvertFrom-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/ConvertFrom-ScriptExtent.md)
+- [ConvertTo-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/ConvertTo-ScriptExtent.md)
+- [Set-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/Set-ScriptExtent.md)
+- [Join-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/Join-ScriptExtent.md)
+- [Test-ScriptExtent](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/Test-ScriptExtent.md)
+- [Import-EditorCommand](https://github.com/PowerShell/PowerShellEditorServices/blob/main/module/docs/Import-EditorCommand.md)
 
 This should also resolve the issues some people were seeing when we tried
 to load the unsigned temporary script containing `Register-EditorCommand`
@@ -3198,7 +4796,7 @@ for more details on how it can be used and how you can create your own templates
 The PowerShell extension now uses any "suggested corrections" which are returned with
 a rule violation in your script file to provide a "quick fix" option for the affected
 section of code.  For example, when the `PSAvoidUsingCmdletAliases` rule finds the use
-of a non-whitelisted alias, you will see a light bulb icon that gives the option to
+of a non-allowlisted alias, you will see a light bulb icon that gives the option to
 change to the full name (right click or <kbd>Ctrl+.</kbd> on the marker):
 
 ![Screenshot of PSScriptAnalyzer quick fix](https://cloud.githubusercontent.com/assets/79405/21247558/05887e86-c2e5-11e6-9c67-e4558a7e2dba.png)
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index dddfa22df2..686e5e7a09 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,8 +1,10 @@
-# Code of Conduct
+# Microsoft Open Source Code of Conduct
 
-This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code].
-For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments.
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
 
-[conduct-code]: http://opensource.microsoft.com/codeofconduct/
-[conduct-FAQ]: http://opensource.microsoft.com/codeofconduct/faq/
-[conduct-email]: mailto:opencode@microsoft.com
+Resources:
+
+- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
+- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
+- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
+- Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support)
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000000..193280892b
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,5 @@
+<Project>
+  <PropertyGroup>
+    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
+  </PropertyGroup>
+</Project>
diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 0000000000..38021b41e3
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,5 @@
+<Project>
+  <ItemGroup>
+    <PackageVersion Include="PowerShellStandard.Library" Version="5.1.1" />
+  </ItemGroup>
+</Project>
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000000..0b3f68dbc3
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,814 @@
+NOTICES AND INFORMATION
+Do Not Translate or Localize
+
+This software incorporates material from third parties.
+Microsoft makes certain open source code available at https://3rdpartysource.microsoft.com,
+or you may send a check or money order for US $5.00, including the product name,
+the open source component name, platform, and version number, to:
+
+Source Code Compliance Team
+Microsoft Corporation
+One Microsoft Way
+Redmond, WA 98052
+USA
+
+Notwithstanding any other terms, you may reverse engineer this software to the extent
+required to debug changes to any libraries licensed under the GNU Lesser General Public License.
+
+---------------------------------------------------------
+
+webidl-conversions 3.0.1 - BSD-2-Clause
+https://github.com/jsdom/webidl-conversions#readme
+
+Copyright (c) 2014, Domenic Denicola
+
+# The BSD 2-Clause License
+
+Copyright (c) 2014, Domenic Denicola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+lru-cache 6.0.0 - ISC
+https://github.com/isaacs/node-lru-cache#readme
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+minimatch 5.1.6 - ISC
+https://github.com/isaacs/minimatch#readme
+
+Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors
+
+The ISC License
+
+Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+semver 7.6.0 - ISC
+https://github.com/npm/node-semver#readme
+
+Copyright Isaac Z. Schlueter
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+yallist 4.0.0 - ISC
+https://github.com/isaacs/yallist#readme
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/1ds-core-js 4.1.2 - MIT
+https://github.com/microsoft/ApplicationInsights-JS#readme
+
+copyright Microsoft 2018
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/1ds-post-js 4.1.2 - MIT
+https://github.com/microsoft/ApplicationInsights-JS#readme
+
+copyright Microsoft 2018
+copyright Microsoft 2020
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+copyright Microsoft 2018-2020
+copyright Microsoft 2022 Simple
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/applicationinsights-channel-js 3.1.2 - MIT
+https://github.com/microsoft/ApplicationInsights-JS#readme
+
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/applicationinsights-common 3.1.2 - MIT
+https://github.com/microsoft/ApplicationInsights-JS#readme
+
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/applicationinsights-core-js 3.1.2 - MIT
+https://github.com/microsoft/ApplicationInsights-JS#readme
+
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/applicationinsights-shims 3.0.1 - MIT
+https://github.com/microsoft/ApplicationInsights-JS/tree/main/tools/shims
+
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/applicationinsights-web-basic 3.1.2 - MIT
+https://github.com/microsoft/ApplicationInsights-JS#readme
+
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@microsoft/dynamicproto-js 2.0.3 - MIT
+https://github.com/microsoft/DynamicProto-JS#readme
+
+Copyright (c) 2022 Nevware21
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft and contributors
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@nevware21/ts-async 0.5.0 - MIT
+https://github.com/nevware21/ts-async
+
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) NevWare21 and contributors
+
+MIT License
+
+Copyright (c) 2022 Nevware21
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@nevware21/ts-utils 0.11.1 - MIT
+https://github.com/nevware21/ts-utils
+
+Copyright (c) 2022 NevWare21
+Copyright (c) 2022 Nevware21
+Copyright (c) 2023 Nevware21
+Copyright (c) 2024 Nevware21
+Copyright (c) NevWare21 and contributors
+
+MIT License
+
+Copyright (c) 2022 NevWare21
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+@vscode/extension-telemetry 0.9.6 - MIT
+https://github.com/Microsoft/vscode-extension-telemetry#readme
+
+Copyright (c) Microsoft Corporation
+
+vscode-extension-telemetry
+
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+balanced-match 1.0.2 - MIT
+https://github.com/juliangruber/balanced-match
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+brace-expansion 2.0.1 - MIT
+https://github.com/juliangruber/brace-expansion
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+MIT License
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+node-fetch 2.7.0 - MIT
+https://github.com/bitinn/node-fetch
+
+Copyright (c) 2016 David Frank
+
+The MIT License (MIT)
+
+Copyright (c) 2016 David Frank
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+tr46 0.0.3 - MIT
+https://github.com/Sebmaster/tr46.js#readme
+
+
+MIT License
+
+Copyright (c) Sebastian Mayr
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+untildify 4.0.0 - MIT
+https://github.com/sindresorhus/untildify#readme
+
+(c) Sindre Sorhus (https://sindresorhus.com)
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+uuid 9.0.1 - MIT
+https://github.com/uuidjs/uuid#readme
+
+Copyright 2011, Sebastian Tschan https://blueimp.net
+Copyright (c) 2010-2020 Robert Kieffer and other contributors
+Copyright (c) Paul Johnston 1999 - 2009 Other contributors Greg Holt, Andrew Kepert, Ydnar, Lostinet
+
+The MIT License (MIT)
+
+Copyright (c) 2010-2020 Robert Kieffer and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+vscode-jsonrpc 8.2.0 - MIT
+https://github.com/Microsoft/vscode-languageserver-node#readme
+
+Copyright (c) Microsoft Corporation
+
+Copyright (c) Microsoft Corporation
+
+All rights reserved.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+vscode-languageclient 9.0.1 - MIT
+https://github.com/Microsoft/vscode-languageserver-node#readme
+
+Copyright (c) Microsoft Corporation
+
+Copyright (c) Microsoft Corporation
+
+All rights reserved.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+vscode-languageserver-protocol 3.17.5 - MIT
+https://github.com/Microsoft/vscode-languageserver-node#readme
+
+Copyright (c) Microsoft Corporation
+Copyright (c) TypeFox, Microsoft and others
+
+Copyright (c) Microsoft Corporation
+
+All rights reserved.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+vscode-languageserver-types 3.17.5 - MIT
+https://github.com/Microsoft/vscode-languageserver-node#readme
+
+Copyright (c) Microsoft Corporation
+
+Copyright (c) Microsoft Corporation
+
+All rights reserved.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+whatwg-url 5.0.0 - MIT
+https://github.com/jsdom/whatwg-url#readme
+
+(c) extraPathPercentEncodeSet.has
+Copyright (c) 2015-2016 Sebastian Mayr
+
+The MIT License (MIT)
+
+Copyright (c) 2015–2016 Sebastian Mayr
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+---------------------------------------------------------
diff --git a/README.md b/README.md
index 7d6600c782..70f7df3726 100644
--- a/README.md
+++ b/README.md
@@ -1,158 +1,133 @@
-# PowerShell Language Support for Visual Studio Code
+# PowerShell for Visual Studio Code
 
-[![Build Status](https://dev.azure.com/powershell/vscode-powershell/_apis/build/status/PowerShell.vscode-powershell?branchName=master)](https://dev.azure.com/powershell/vscode-powershell/_build/latest?definitionId=51&branchName=master)
-[![Version](https://vsmarketplacebadge.apphb.com/version/ms-vscode.PowerShell.svg)](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
-[![Installs](https://vsmarketplacebadge.apphb.com/installs-short/ms-vscode.PowerShell.svg)](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
-[![Discord](https://img.shields.io/discord/180528040881815552.svg?label=%23vscode&logo=discord&logoColor=white)](https://aka.ms/powershell-vscode-discord)
-[![Join the chat at https://gitter.im/PowerShell/vscode-powershell](https://badges.gitter.im/PowerShell/vscode-powershell.svg)](https://gitter.im/PowerShell/vscode-powershell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![CI Tests](https://github.com/PowerShell/vscode-powershell/actions/workflows/ci-test.yml/badge.svg)](https://github.com/PowerShell/vscode-powershell/actions/workflows/ci-test.yml)
+[![Version](https://img.shields.io/visual-studio-marketplace/v/ms-vscode.PowerShell)](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
+[![Installs](https://img.shields.io/visual-studio-marketplace/i/ms-vscode.PowerShell)](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
+[![Join the chat on Discord](https://img.shields.io/discord/180528040881815552.svg?label=%23vscode&logo=discord&logoColor=white)](https://aka.ms/powershell-vscode-discord)
 
-This extension provides rich PowerShell language support for [Visual Studio Code](https://github.com/Microsoft/vscode) (VS Code).
+This extension provides rich [PowerShell][] language support for [Visual Studio Code][] (VS Code).
 Now you can write and debug PowerShell scripts using the excellent IDE-like interface
-that Visual Studio Code provides.
-
-This extension is powered by the PowerShell language server,
-[PowerShell Editor Services](https://github.com/PowerShell/PowerShellEditorServices).
-This leverages the
-[Language Server Protocol](https://microsoft.github.io/language-server-protocol/)
-where `PowerShellEditorServices` is the server and `vscode-powershell` is the client.
-
-Also included in this extension is the PowerShell ISE theme for Visual Studio Code. It is
-not activated by default, but after installing this extension either click "Set Color
-Theme" or use the [theme picker](https://code.visualstudio.com/docs/getstarted/themes) and
-select "PowerShell ISE" for a fun and familiar experience.
+that VS Code provides.
+
+This repository, `vscode-powershell`, is the [Language Server Protocol][] client for VS
+Code and [`PowerShellEditorServices`][] is the server (also used by other editors, such as
+Emacs and Vim).
+
+[PowerShell]: https://github.com/PowerShell/PowerShell
+[Visual Studio Code]: https://github.com/Microsoft/vscode
+[`PowerShellEditorServices`]: https://github.com/PowerShell/PowerShellEditorServices
+[Language Server Protocol]: https://microsoft.github.io/language-server-protocol/
+
+## Available Features
+
+- [Syntax highlighting][]
+- Advanced built-in [code snippets][]
+- [IntelliSense][] for cmdlets and more
+- [Problems][] reported by [PowerShell Script Analyzer][]
+- [Go to Definition][] of cmdlets, variables, classes and more
+- [Find References][] of cmdlets, variables, classes and more
+- Document and Workspace [Symbol Navigation][]
+- Symbol-based [Outline View][]
+- Run selected PowerShell code in current terminal using <kbd>F8</kbd>
+- Launch online help for the symbol under the cursor using <kbd>Ctrl+F1</kbd>
+- PowerShell [Debugger][] integration
+- An Extension Terminal that can interact with the debugger (try `Set-PSBreakpoint`!)
+- PowerShell ISE theme findable in the [theme picker][]
+- Also try ISE Mode with the **Toggle ISE Mode** command
+
+Bundled with the extension is the PowerShell ISE theme. It is not activated by default,
+but after installing this extension either click **Set Color Theme** or use the [theme
+picker][] and select **PowerShell ISE**.
+
+[Syntax highlighting]: https://github.com/PowerShell/EditorSyntax
+[code snippets]: https://code.visualstudio.com/docs/editor/userdefinedsnippets
+[IntelliSense]: https://code.visualstudio.com/docs/editor/intellisense
+[Problems]: https://code.visualstudio.com/docs/getstarted/tips-and-tricks#_errors-and-warnings
+[PowerShell Script Analyzer]: http://github.com/PowerShell/PSScriptAnalyzer
+[Go to Definition]: https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition
+[Find References]: https://code.visualstudio.com/docs/editor/editingevolved#_reference-information
+[Symbol Navigation]: https://code.visualstudio.com/docs/editor/editingevolved#_open-symbol-by-name
+[Outline View]: https://code.visualstudio.com/docs/getstarted/userinterface#_outline-view
+[Debugger]: https://learn.microsoft.com/powershell/scripting/dev-cross-plat/vscode/using-vscode#debugging-with-visual-studio-code
+[theme picker]: https://code.visualstudio.com/docs/getstarted/themes
 
 ## Platform Support
 
-The extension _should_ work anywhere VS Code itself and PowerShell Core 7 or higher is
-[supported][]. For Windows PowerShell, only version 5.1 is supported. Please note that
-PowerShell Core 6 is end-of-life and so not supported. Our test matrix includes the
-following:
-
-- **Windows Server 2019** with Windows PowerShell 5.1 and PowerShell Core 7.1.5
-- **macOS 10.15** with PowerShell Core 7.1.5
-- **Ubuntu 20.04** with PowerShell Core 7.1.5
-
-[supported]: https://docs.microsoft.com/en-us/powershell/scripting/powershell-support-lifecycle?view=powershell-7.1#supported-platforms
-
-Read the [installation instructions](https://docs.microsoft.com/en-us/powershell/scripting/components/vscode/using-vscode)
-to get more details on how to use the extension on these platforms.
-
-**Read the [troubleshooting guide](./docs/troubleshooting.md) for answers to common questions.**
-
-## Features
-
-- Syntax highlighting
-- Code snippets
-- IntelliSense for cmdlets and more
-- Rule-based analysis provided by [PowerShell Script Analyzer](http://github.com/PowerShell/PSScriptAnalyzer)
-- Go to Definition of cmdlets and variables
-- Find References of cmdlets and variables
-- Document and workspace symbol discovery
-- Run selected selection of PowerShell code using <kbd>F8</kbd>
-- Launch online help for the symbol under the cursor using <kbd>Ctrl</kbd>+<kbd>F1</kbd>
-- Local script debugging
-- Integrated console support
-- PowerShell ISE color theme
-
-## Installing the Extension
-
-You can install the official release of the PowerShell extension by following the steps
-in the [Visual Studio Code documentation](https://code.visualstudio.com/docs/editor/extension-gallery).
-In the Extensions pane, search for "PowerShell" extension and install it there. You will
-get notified automatically about any future extension updates!
-
-You can also install a VSIX package from our [Releases page](https://github.com/PowerShell/vscode-powershell/releases) by following the
-[Install from a VSIX](https://code.visualstudio.com/docs/editor/extension-gallery#_install-from-a-vsix)
-instructions. The easiest way is through the command line:
-
-```powershell
-code --install-extension powershell-<version>.vsix
-```
+The extension should work everywhere [Visual Studio Code](https://code.visualstudio.com/docs/supporting/requirements) is supported using [PowerShell 7+ currently supported versions][].
 
-> NOTE: If you are using VS Code Insiders, the command will be `code-insiders`.
+> [!IMPORTANT]
+> For Windows PowerShell, only version 5.1 is supported and only on a best-effort basis. [.NET Framework 4.8][dotnet-framework] or higher is required.
 
-### Script-based Installation
+> [!IMPORTANT]
+> [Visual Studio Code for the Web](https://code.visualstudio.com/docs/editor/vscode-web) is only supported for limited functionality such as basic syntax highlighting, as the PowerShell engine cannot run in this environment currently.
 
-If you're on Windows 7 or greater with the [PowerShellGet](https://msdn.microsoft.com/powershell/gallery/readme)
-module installed, you can easily install both Visual Studio Code and the PowerShell
-extension by running the following command:
+[VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview) Environments, including [Github Codespaces](https://github.com/features/codespaces) and [VS Code Server](https://code.visualstudio.com/docs/remote/vscode-server) are supported.
 
-```powershell
-Install-Script Install-VSCode -Scope CurrentUser; Install-VSCode.ps1
-```
+We actively test the following configurations [in Github Actions on every commit](https://github.com/PowerShell/vscode-powershell/actions/workflows/ci-test.yml):
+- **Windows Server 2022** with Windows PowerShell 5.1 and PowerShell 7+
+- **macOS 14.7** with PowerShell 7+
+- **Ubuntu 24.04** with PowerShell 7+
 
-You will need to accept the prompts that appear if this is your first time running
-the `Install-Script` command.
+On Windows, we also test with and without Constrained Language Mode enabled.
 
-**Alternatively** you can download and execute the script directly from the web
-without the use of `Install-Script`.  However we **highly recommend** that you
-[read the script](https://raw.githubusercontent.com/PowerShell/vscode-powershell/master/scripts/Install-VSCode.ps1)
-first before running it in this way!
-
-```powershell
-iex (iwr https://raw.githubusercontent.com/PowerShell/vscode-powershell/master/scripts/Install-VSCode.ps1)
-```
-
-## Reporting Problems
+Read the [installation instructions][]
+to get more details on how to use the extension on these platforms.
 
-If you experience any problems with the PowerShell Extension, see
-[the troubleshooting docs](./docs/troubleshooting.md) for information
-on diagnosing and reporting issues.
+[PowerShell 7+ currently supported versions]: https://docs.microsoft.com/en-us/powershell/scripting/powershell-support-lifecycle
+[installation instructions]: https://docs.microsoft.com/en-us/powershell/scripting/components/vscode/using-vscode
+[dotnet-framework]: https://dotnet.microsoft.com/en-us/download/dotnet-framework
 
-## Security Note
+## Installing the Extension
 
-For any security issues, please see [here](./docs/troubleshooting.md#note-on-security).
+The PowerShell extension can be installed from the Visual Studio Code Marketplace by
+clicking the [**Install Button**][]. You can also install the PowerShell extension from
+within VS Code by opening the **Extensions** view with keyboard shortcut
+<kbd>Ctrl+Shift+X</kbd>, typing PowerShell, and selecting the extension.
 
-## Example Scripts
+We would encourage you to try the _pre-release_ version whenever possible. When a
+_Pre-Release_ is available, it can be installed from the marketplace using the
+**Switch to Pre-Release Version** button. You can switch back to the stable version of the
+extension by using the **Switch to Release Version** button that will appear. You can also
+downgrade to other versions of the extension using the arrow next to the **Uninstall**
+button and choosing **Install Another Version**.
 
-There are some example scripts in the extension's `examples` folder that you can
-use to discover PowerShell editing and debugging functionality.  Please
-check out the included [README.md](examples/README.md) file to learn more about
-how to use them.
+[**Install Button**]: vscode:extension/ms-vscode.PowerShell
 
-This folder can be found at the following path:
+## Getting Help
 
-```powershell
-$HOME/.vscode[-insiders]/extensions/ms-vscode.powershell[-preview]-<version>/examples
-```
+Please our [support](SUPPORT.md) document.
 
-To open/view the extension's examples in Visual Studio Code, run the following from your
-PowerShell session:
+## Code of Conduct
 
-```powershell
-code (Get-ChildItem $HOME/.vscode/extensions/ms-vscode.powershell-*/examples)[-1]
-```
+Please see our [Code of Conduct](CODE_OF_CONDUCT.md) before participating in this project.
 
 ## Contributing to the Code
 
 Check out the [development documentation](docs/development.md) for more details
 on how to contribute to this extension!
 
+## Security Note
+
+For any security issues, please see [here](SECURITY.md).
+
 ## Maintainers
 
-- Rob Holt - [@rjmholt](https://github.com/rjmholt)
+### Current
+
+- Andy Jordan - [@andyleejordan](https://github.com/andyleejordan)
 - Patrick Meinecke - [@SeeminglyScience](https://github.com/SeeminglyScience)
-- Andy Schwartzmeyer - [@andschwa](https://github.com/andschwa)
 - Sydney Smith - [@SydneyhSmith](https://github.com/SydneyhSmith)
+- Justin Grote - [@JustinGrote](https://github.com/JustinGrote)
 
 ### Emeriti
 
 - Keith Hill - [@rkeithhill](https://github.com/rkeithhill)
+- Rob Holt - [@rjmholt](https://github.com/rjmholt)
 - Tyler Leonhardt - [@TylerLeonhardt](https://github.com/TylerLeonhardt)
 - David Wilson - [@daviwil](https://github.com/daviwil)
 
 ## License
 
-This extension is [licensed under the MIT License](LICENSE.txt).  Please see the
-[third-party notices](Third%20Party%20Notices.txt) file for details on the third-party
+This extension is [licensed under the MIT License](LICENSE.txt). Please see the
+[third-party notices](NOTICE.txt) file for details on the third-party
 binaries that we include with releases of this project.
-
-## [Code of Conduct][conduct-md]
-
-This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code].
-For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments.
-
-[conduct-code]: http://opensource.microsoft.com/codeofconduct/
-[conduct-FAQ]: http://opensource.microsoft.com/codeofconduct/faq/
-[conduct-email]: mailto:opencode@microsoft.com
-[conduct-md]: https://github.com/PowerShell/vscode-powershell/blob/master/CODE_OF_CONDUCT.md
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000000..f941d308b1
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,41 @@
+<!-- BEGIN MICROSOFT SECURITY.MD V0.0.9 BLOCK -->
+
+## Security
+
+Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin) and [PowerShell](https://github.com/PowerShell).
+
+If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below.
+
+## Reporting Security Issues
+
+**Please do not report security vulnerabilities through public GitHub issues.**
+
+Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report).
+
+If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).
+
+You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 
+
+Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
+
+  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
+  * Full paths of source file(s) related to the manifestation of the issue
+  * The location of the affected source code (tag/branch/commit or direct URL)
+  * Any special configuration required to reproduce the issue
+  * Step-by-step instructions to reproduce the issue
+  * Proof-of-concept or exploit code (if possible)
+  * Impact of the issue, including how an attacker might exploit the issue
+
+This information will help us triage your report more quickly.
+
+If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs.
+
+## Preferred Languages
+
+We prefer all communications to be in English.
+
+## Policy
+
+Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd).
+
+<!-- END MICROSOFT SECURITY.MD BLOCK -->
diff --git a/SUPPORT.md b/SUPPORT.md
new file mode 100644
index 0000000000..973f76643f
--- /dev/null
+++ b/SUPPORT.md
@@ -0,0 +1,18 @@
+# Support
+
+## How to file issues and get help
+
+If you experience any problems with the PowerShell Extension, see the
+[troubleshooting docs](docs/troubleshooting.md) for common issues.
+
+If you find a bug, please [open an issue][] so we can fix it.
+
+Don't forget to check out the official guide on
+[Using VS Code for PowerShell Development][].
+
+[Using VS Code for PowerShell Development]: https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/using-vscode
+[open an issue]: https://github.com/PowerShell/vscode-powershell/issues/new/choose
+
+## Microsoft Support Policy
+
+Support for this project is limited to the resources listed above.
diff --git a/Third Party Notices.txt b/Third Party Notices.txt
deleted file mode 100644
index 1a2e50bcd2..0000000000
--- a/Third Party Notices.txt	
+++ /dev/null
@@ -1,16 +0,0 @@
-This file is based on or incorporates material from the projects listed below (Third Party IP). The original copyright notice and the license under which Microsoft received such Third Party IP, are set forth below. Such licenses and notices are provided for informational purposes only. Microsoft licenses the Third Party IP to you under the licensing terms for the Microsoft product. Microsoft reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
-
----
-
-Json.NET
-
-Copyright (c) 2007 James Newton-King
- Provided for Informational Purposes Only
-
-MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/build.ps1 b/build.ps1
index e5ee197fba..ddf9f1c019 100644
--- a/build.ps1
+++ b/build.ps1
@@ -103,7 +103,7 @@ if ($Bootstrap) {
     } else {
         $missingTools | ForEach-Object {$string += "* $_`n"}
         $string += "`nAll instructions for installing these tools can be found on VSCode PowerShell's Github:`n" `
-            + "https://github.com/PowerShell/vscode-powershell/blob/master/docs/development.md"
+            + "https://github.com/PowerShell/vscode-powershell/blob/main/docs/development.md"
     }
     Write-Host "`n$string`n"
 } elseif(hasMissingTools) {
diff --git a/docs/azure_data_studio/README_FOR_MARKETPLACE.md b/docs/azure_data_studio/README_FOR_MARKETPLACE.md
index 87f89c527c..7ecea003f9 100644
--- a/docs/azure_data_studio/README_FOR_MARKETPLACE.md
+++ b/docs/azure_data_studio/README_FOR_MARKETPLACE.md
@@ -1,14 +1,14 @@
-# PowerShell Language Support for Azure Data Studio
+# PowerShell  for Azure Data Studio
 
-[![Build Status](https://dev.azure.com/powershell/vscode-powershell/_apis/build/status/PowerShell.vscode-powershell?branchName=master)](https://dev.azure.com/powershell/vscode-powershell/_build/latest?definitionId=51&branchName=master)
+[![Build Status](https://dev.azure.com/powershell/vscode-powershell/_apis/build/status/PowerShell.vscode-powershell?branchName=main)](https://dev.azure.com/powershell/vscode-powershell/_build/latest?definitionId=51&branchName=main)
 [![Version](https://vsmarketplacebadge.apphb.com/version/ms-vscode.PowerShell.svg)](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
 [![Installs](https://vsmarketplacebadge.apphb.com/installs-short/ms-vscode.PowerShell.svg)](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell)
-[![Discord](https://img.shields.io/discord/180528040881815552.svg?label=%23vscode&logo=discord&logoColor=white)](https://aka.ms/powershell-vscode-discord)
-[![Join the chat at https://gitter.im/PowerShell/vscode-powershell](https://badges.gitter.im/PowerShell/vscode-powershell.svg)](https://gitter.im/PowerShell/vscode-powershell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![Join the chat on Discord](https://img.shields.io/discord/180528040881815552.svg?label=%23vscode&logo=discord&logoColor=white)](https://aka.ms/powershell-vscode-discord)
+[![Join the chat on Gitter](https://badges.gitter.im/PowerShell/vscode-powershell.svg)](https://gitter.im/PowerShell/vscode-powershell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 
 This extension provides rich PowerShell language support for [Azure Data Studio](https://github.com/Microsoft/azuredatastudio) (ADS).
 Now you can write and run PowerShell scripts using the excellent IDE-like interface
-that Azure Data Studio provides.
+that ADS provides.
 
 This extension is powered by the PowerShell language server,
 [PowerShell Editor Services](https://github.com/PowerShell/PowerShellEditorServices).
@@ -23,14 +23,15 @@ select "PowerShell ISE" for a fun and familiar experience.
 
 ## Platform Support
 
-The extension _should_ work anywhere ADS itself and PowerShell Core 7 or higher is
+The extension _should_ work anywhere ADS itself and PowerShell Core 7.2 or higher is
 [supported][]. For Windows PowerShell, only version 5.1 is supported. Please note that
 PowerShell Core 6 is end-of-life and so not supported. Our test matrix includes the
 following:
 
-- **Windows Server 2019** with Windows PowerShell 5.1 and PowerShell Core 7.1.5
-- **macOS 10.15** with PowerShell Core 7.1.5
-- **Ubuntu 20.04** with PowerShell Core 7.1.5
+- **Windows Server 2022** with Windows PowerShell 5.1 and PowerShell Core 7.2.7
+- **Windows Server 2019** with Windows PowerShell 5.1 and PowerShell Core 7.2.7
+- **macOS 11** with PowerShell Core 7.2.7
+- **Ubuntu 20.04** with PowerShell Core 7.2.7
 
 [supported]: https://docs.microsoft.com/en-us/powershell/scripting/powershell-support-lifecycle?view=powershell-7.1#supported-platforms
 
@@ -51,7 +52,7 @@ to get more details on how to use the extension on these platforms.
 - Run selected selection of PowerShell code using <kbd>F8</kbd>
 - Launch online help for the symbol under the cursor using <kbd>Ctrl</kbd>+<kbd>F1</kbd>
 - Local script debugging
-- Integrated console support
+- Extension Terminal support
 - PowerShell ISE color theme
 
 ## Installing the Extension
@@ -61,7 +62,7 @@ in the [Azure Data Studio documentation](https://docs.microsoft.com/en-us/sql/az
 In the Extensions pane, search for "PowerShell" extension and install it there.  You will
 get notified automatically about any future extension updates!
 
-You can also install a VSIX package from our [Releases page](https://github.com/PowerShell/vscode-powershell/releases) by following the
+You can also install a VSIX package from our [releases page](https://github.com/PowerShell/vscode-powershell/releases) by following the
 [Install from a VSIX](https://code.visualstudio.com/docs/editor/extension-gallery#_install-from-a-vsix)
 instructions. The easiest way is through the command line:
 
@@ -69,9 +70,15 @@ instructions. The easiest way is through the command line:
 azuredatastudio --install-extension powershell-<version>.vsix
 ```
 
+## Reporting Problems
+
+If you experience any problems with the PowerShell Extension, see
+[the troubleshooting docs](./docs/troubleshooting.md) for information
+on diagnosing and reporting issues.
+
 ## Security Note
 
-For any security issues, please see [here](./docs/troubleshooting.md#note-on-security).
+For any security issues, please see [here](./SECURITY.md).
 
 ## Example Scripts
 
@@ -138,7 +145,7 @@ Name                 Status           Size     Space  Recovery Compat. Owner
                                             Available  Model     Level
 ----                 ------           ---- ---------- -------- ------- -----
 AdventureWorks2017   Normal      336.00 MB   57.01 MB Simple       140 sa
-master               Normal        6.00 MB  368.00 KB Simple       140 sa
+main               Normal        6.00 MB  368.00 KB Simple       140 sa
 model                Normal       16.00 MB    5.53 MB Full         140 sa
 msdb                 Normal       48.44 MB    1.70 MB Simple       140 sa
 PBIRS                Normal      144.00 MB   55.95 MB Full         140 sa
@@ -173,14 +180,14 @@ on how to contribute to this extension!
 
 ## Maintainers
 
-- Rob Holt - [@rjmholt](https://github.com/rjmholt)
 - Patrick Meinecke - [@SeeminglyScience](https://github.com/SeeminglyScience)
-- Andy Schwartzmeyer - [@andschwa](https://github.com/andschwa)
+- Andy Jordan - [@andschwa](https://github.com/andschwa)
 - Sydney Smith - [@SydneyhSmith](https://github.com/SydneyhSmith)
 
 ### Emeriti
 
 - Keith Hill - [@rkeithhill](https://github.com/rkeithhill)
+- Rob Holt - [@rjmholt](https://github.com/rjmholt)
 - Tyler Leonhardt - [@TylerLeonhardt](https://github.com/TylerLeonhardt)
 - David Wilson - [@daviwil](https://github.com/daviwil)
 
@@ -198,4 +205,4 @@ For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [open
 [conduct-code]: http://opensource.microsoft.com/codeofconduct/
 [conduct-FAQ]: http://opensource.microsoft.com/codeofconduct/faq/
 [conduct-email]: mailto:opencode@microsoft.com
-[conduct-md]: https://github.com/PowerShell/vscode-powershell/blob/master/CODE_OF_CONDUCT.md
+[conduct-md]: https://github.com/PowerShell/vscode-powershell/blob/main/CODE_OF_CONDUCT.md
diff --git a/docs/community_snippets.md b/docs/community_snippets.md
index 7d8816d09b..39ac2195a1 100644
--- a/docs/community_snippets.md
+++ b/docs/community_snippets.md
@@ -2,7 +2,7 @@
 
 > A curated list of awesome vscode snippets for PowerShell.
 
-*Inspired by the [awesome](https://github.com/sindresorhus/awesome) lists, focusing on PowerShell snippets in VSCode*
+_Inspired by the [awesome](https://github.com/sindresorhus/awesome) lists, focusing on PowerShell snippets in VSCode_
 
 [![Awesome](https://awesome.re/badge.svg)](https://awesome.re)
 
@@ -18,25 +18,28 @@ _To contribute, check out our [guide here](#contributing)._
 
 | Snippet name | Description |
 | --------- | ---------|
-| [AssertMock](#assert-mock) | _Creates assert mock Pester test_ |
+| [AssertMock](#assertmock) | _Creates assert mock Pester test_ |
 | [AWSRegionDynamicParameter](#awsregiondynamicparameter) | _Creates a dynamic parameter of current AWS regions by @jbruett_ |
 | [DataTable](#datatable) | _Creates a DataTable_ |
 | [DateTimeWriteVerbose](#datetimewriteverbose) | _Write-Verbose with the time and date pre-pended to your message by @ThmsRynr_ |
+| [DSC](#dsc) | __DSC snippets previously bundled in extension__ |
+| [Examples](#examples) | __Examples previously bundled in extension__ |
 | [Error-Terminating](#error-terminating) | _Create a full terminating error by @omniomi_ |
 | [Exchange Online Connection](#exchange-online-connection) | _Create a connection to Exchange Online by @vmsilvamolina_ |
 | [HTML header](#html-header) | _Add HTML header with the style tag by @vmsilvamolina_ |
 | [MaxColumnLengthinDataTable](#maxcolumnlengthindatatable) | _Gets the max length of string columns in datatables_ |
 | [New Azure Resource Group](#new-azure-resource-group) | _Create an Azure Resource group by @vmsilvamolina_ |
 | [Parameter-Credential](#parameter-credential) | _Add a standard credential parameter to your function by @omniomi_ |
+| [Pester](#pester) | __Pester snippets previously bundled in extension__ |
 | [PesterTestForMandatoryParameter](#pestertestformandatoryparameter) | _Create Pester test for a mandatory parameter_ |
 | [PesterTestForParameter](#pestertestforparameter) | _Create Pester test for parameter_ |
 | [Send-MailMessage](#send-mailmessage) | _Send an mail message with the most common parameters by @fullenw1_ |
 
 ## Snippets
 
-### Assert Mock
+### AssertMock
 
-Creates Assert Mock for Pester Tests y @SQLDBAWithABeard
+Creates Assert Mock for Pester Tests by @SQLDBAWithABeard.
 
 #### Snippet
 
@@ -57,7 +60,7 @@ Creates Assert Mock for Pester Tests y @SQLDBAWithABeard
 
 ### AWSRegionDynamicParameter
 
-Creates a dynamic parameter of the current AWS regions.  Includes parameter validation.
+Creates a dynamic parameter of the current AWS regions. Includes parameter validation.
 
 #### Snippet
 
@@ -139,6 +142,408 @@ Quickly add a `Write-Verbose` with the current date and time inserted before the
 }
 ```
 
+### DSC
+
+DSC snippets migrated from the extension.
+
+```json
+{
+  "DSC Ensure Enum": {
+    "prefix": "DSC Ensure enum",
+    "description": "DSC Ensure enum definition snippet",
+    "body": [
+      "enum Ensure {",
+      "\tAbsent",
+      "\tPresent",
+      "}",
+      "$0"
+    ]
+  },
+  "DSC Resource Provider (class-based)": {
+    "prefix": "DSC resource provider (class-based)",
+    "description": "Class-based DSC resource provider snippet",
+    "body": [
+      "[DscResource()]",
+      "class ${ResourceName:NameOfResource} {",
+      "\t[DscProperty(Key)]",
+      "\t[string] $${PropertyName:KeyName}",
+      "\t",
+      "\t# Gets the resource's current state.",
+      "\t[${ResourceName:NameOfResource}] Get() {",
+      "\t\t${0:$TM_SELECTED_TEXT}",
+      "\t\treturn \\$this",
+      "\t}",
+      "\t",
+      "\t# Sets the desired state of the resource.",
+      "\t[void] Set() {",
+      "\t\t",
+      "\t}",
+      "\t",
+      "\t# Tests if the resource is in the desired state.",
+      "\t[bool] Test() {",
+      "\t\t",
+      "\t}",
+      "}"
+    ]
+  },
+  "DSC Resource Provider (function-based)": {
+    "prefix": "DSC resource provider (function-based)",
+    "description": "Function-based DSC resource provider snippet",
+    "body": [
+      "function Get-TargetResource {",
+      "\tparam (",
+      "\t)",
+      "\t",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}",
+      "function Set-TargetResource {",
+      "\tparam (",
+      "\t)",
+      "\t",
+      "}",
+      "function Test-TargetResource {",
+      "\tparam (",
+      "\t)",
+      "\t",
+      "}"
+    ]
+  },
+}
+```
+
+### Examples
+
+Example snippets migrated from the extension.
+
+```json
+{
+  "Example-Class": {
+    "prefix": "ex-class",
+    "description": "Example: class snippet with a constructor, property and a method",
+    "body": [
+      "class ${1:MyClass} {",
+      "\t# Property: Holds name",
+      "\t[String] \\$Name",
+      "",
+      "\t# Constructor: Creates a new MyClass object, with the specified name",
+      "\t${1:MyClass}([String] \\$NewName) {",
+      "\t\t# Set name for ${1:MyClass}",
+      "\t\t\\$this.Name = \\$NewName",
+      "\t}",
+      "",
+      "\t# Method: Method that changes \\$Name to the default name",
+      "\t[void] ChangeNameToDefault() {",
+      "\t\t\\$this.Name = \"DefaultName\"",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-Cmdlet": {
+    "prefix": "ex-cmdlet",
+    "description": "Example: script cmdlet snippet with all attributes and inline help fields",
+    "body": [
+      "<#",
+      ".SYNOPSIS",
+      "\tShort description",
+      ".DESCRIPTION",
+      "\tLong description",
+      ".EXAMPLE",
+      "\tExample of how to use this cmdlet",
+      ".EXAMPLE",
+      "\tAnother example of how to use this cmdlet",
+      ".INPUTS",
+      "\tInputs to this cmdlet (if any)",
+      ".OUTPUTS",
+      "\tOutput from this cmdlet (if any)",
+      ".NOTES",
+      "\tGeneral notes",
+      ".COMPONENT",
+      "\tThe component this cmdlet belongs to",
+      ".ROLE",
+      "\tThe role this cmdlet belongs to",
+      ".FUNCTIONALITY",
+      "\tThe functionality that best describes this cmdlet",
+      "#>",
+      "function ${name:Verb-Noun} {",
+      "\t[CmdletBinding(DefaultParameterSetName='Parameter Set 1',",
+      "\t               SupportsShouldProcess=\\$true,",
+      "\t               PositionalBinding=\\$false,",
+      "\t               HelpUri = 'http://www.microsoft.com/',",
+      "\t               ConfirmImpact='Medium')]",
+      "\t[Alias()]",
+      "\t[OutputType([String])]",
+      "\tParam (",
+      "\t\t# Param1 help description",
+      "\t\t[Parameter(Mandatory=\\$true,",
+      "\t\t           Position=0,",
+      "\t\t           ValueFromPipeline=\\$true,",
+      "\t\t           ValueFromPipelineByPropertyName=\\$true,",
+      "\t\t           ValueFromRemainingArguments=\\$false, ",
+      "\t\t           ParameterSetName='Parameter Set 1')]",
+      "\t\t[ValidateNotNull()]",
+      "\t\t[ValidateNotNullOrEmpty()]",
+      "\t\t[ValidateCount(0,5)]",
+      "\t\t[ValidateSet(\"sun\", \"moon\", \"earth\")]",
+      "\t\t[Alias(\"p1\")] ",
+      "\t\t\\$Param1,",
+      "\t\t",
+      "\t\t# Param2 help description",
+      "\t\t[Parameter(ParameterSetName='Parameter Set 1')]",
+      "\t\t[AllowNull()]",
+      "\t\t[AllowEmptyCollection()]",
+      "\t\t[AllowEmptyString()]",
+      "\t\t[ValidateScript({\\$true})]",
+      "\t\t[ValidateRange(0,5)]",
+      "\t\t[int]",
+      "\t\t\\$Param2,",
+      "\t\t",
+      "\t\t# Param3 help description",
+      "\t\t[Parameter(ParameterSetName='Another Parameter Set')]",
+      "\t\t[ValidatePattern(\"[a-z]*\")]",
+      "\t\t[ValidateLength(0,15)]",
+      "\t\t[String]",
+      "\t\t\\$Param3",
+      "\t)",
+      "\t",
+      "\tbegin {",
+      "\t}",
+      "\t",
+      "\tprocess {",
+      "\t\tif (\\$pscmdlet.ShouldProcess(\"Target\", \"Operation\")) {",
+      "\t\t\t$0",
+      "\t\t}",
+      "\t}",
+      "\t",
+      "\tend {",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-DSC Configuration": {
+    "prefix": "ex-DSC config",
+    "description": "Example: DSC configuration snippet that uses built-in resource providers",
+    "body": [
+      "configuration Name {",
+      "\t# One can evaluate expressions to get the node list",
+      "\t# E.g: \\$AllNodes.Where(\"Role -eq Web\").NodeName",
+      "\tnode (\"Node1\",\"Node2\",\"Node3\")",
+      "\t{",
+      "\t\t# Call Resource Provider",
+      "\t\t# E.g: WindowsFeature, File",
+      "\t\tWindowsFeature FriendlyName",
+      "\t\t{",
+      "\t\t\tEnsure = \"Present\"",
+      "\t\t\tName = \"Feature Name\"",
+      "\t\t}",
+      "",
+      "\t\tFile FriendlyName",
+      "\t\t{",
+      "\t\t\tEnsure = \"Present\"",
+      "\t\t\tSourcePath = \\$SourcePath",
+      "\t\t\tDestinationPath = \\$DestinationPath",
+      "\t\t\tType = \"Directory\"",
+      "\t\t\tDependsOn = \"[WindowsFeature]FriendlyName\"",
+      "\t\t}",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-DSC Resource Provider (class-based)": {
+    "prefix": "ex-DSC resource provider (class-based)",
+    "description": "Example: class-based DSC resource provider snippet",
+    "body": [
+      "# Defines the values for the resource's Ensure property.",
+      "enum Ensure {",
+      "\t# The resource must be absent.",
+      "\tAbsent",
+      "\t# The resource must be present.",
+      "\tPresent",
+      "}",
+      "",
+      "# [DscResource()] indicates the class is a DSC resource.",
+      "[DscResource()]",
+      "class NameOfResource {",
+      "\t# A DSC resource must define at least one key property.",
+      "\t[DscProperty(Key)]",
+      "\t[string] \\$P1",
+      "\t",
+      "\t# Mandatory indicates the property is required and DSC will guarantee it is set.",
+      "\t[DscProperty(Mandatory)]",
+      "\t[Ensure] \\$P2",
+      "\t",
+      "\t# NotConfigurable properties return additional information about the state of the resource.",
+      "\t# For example, a Get() method might return the date a resource was last modified.",
+      "\t# NOTE: These properties are only used by the Get() method and cannot be set in configuration.",
+      "\t[DscProperty(NotConfigurable)]",
+      "\t[Nullable[datetime]] \\$P3",
+      "\t",
+      "\t[DscProperty()]",
+      "\t[ValidateSet(\"val1\", \"val2\")]",
+      "\t[string] \\$P4",
+      "\t",
+      "\t# Gets the resource's current state.",
+      "\t[NameOfResource] Get() {",
+      "\t\t# NotConfigurable properties are set in the Get method.",
+      "\t\t\\$this.P3 = something",
+      "\t\t# Return this instance or construct a new instance.",
+      "\t\treturn \\$this",
+      "\t}",
+      "\t",
+      "\t# Sets the desired state of the resource.",
+      "\t[void] Set() {",
+      "\t}",
+      "\t",
+      "\t# Tests if the resource is in the desired state.",
+      "\t[bool] Test() {",
+      "\t\t return \\$true",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-DSC Resource Provider (function based)": {
+    "prefix": "ex-DSC resource provider (function based)",
+    "description": "Example: function-based DSC resource provider snippet",
+    "body": [
+      "function Get-TargetResource {",
+      "\t# TODO: Add parameters here",
+      "\t# Make sure to use the same parameters for",
+      "\t# Get-TargetResource, Set-TargetResource, and Test-TargetResource",
+      "\tparam (",
+      "\t)",
+      "}",
+      "function Set-TargetResource {",
+      "\t# TODO: Add parameters here",
+      "\t# Make sure to use the same parameters for",
+      "\t# Get-TargetResource, Set-TargetResource, and Test-TargetResource",
+      "\tparam (",
+      "\t)",
+      "}",
+      "function Test-TargetResource {",
+      "\t# TODO: Add parameters here",
+      "\t# Make sure to use the same parameters for",
+      "\t# Get-TargetResource, Set-TargetResource, and Test-TargetResource",
+      "\tparam (",
+      "\t)",
+      "}"
+    ]
+  },
+  "Example-Path Processing for No Wildcards Allowed": {
+    "prefix": "ex-path processing for no wildcards allowed",
+    "description": "Example: processing non-wildcard paths that must exist (for use in process block). See parameter-path snippets.",
+    "body": [
+      "# Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=\\$true)]",
+      "\\$paths = @()",
+      "foreach (\\$aPath in \\$Path) {",
+      "\tif (!(Test-Path -LiteralPath \\$aPath)) {",
+      "\t\t\\$ex = New-Object System.Management.Automation.ItemNotFoundException \"Cannot find path '\\$aPath' because it does not exist.\"",
+      "\t\t\\$category = [System.Management.Automation.ErrorCategory]::ObjectNotFound",
+      "\t\t\\$errRecord = New-Object System.Management.Automation.ErrorRecord \\$ex,'PathNotFound',\\$category,\\$aPath",
+      "\t\t\\$psCmdlet.WriteError(\\$errRecord)",
+      "\t\tcontinue",
+      "\t}",
+      "",
+      "\t# Resolve any relative paths",
+      "\t\\$paths += \\$psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\\$aPath)",
+      "}",
+      "",
+      "foreach (\\$aPath in \\$paths) {",
+      "\tif (\\$pscmdlet.ShouldProcess(\\$aPath, 'Operation')) {",
+      "\t\t# Process each path",
+      "\t\t$0",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-Path Processing for Non-Existing Paths": {
+    "prefix": "ex-path processing for non-existing paths",
+    "description": "Example: processing non-existing paths typically used in New-* commands (for use in process block). See parameter-path snippet.",
+    "body": [
+      "# Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=\\$true)]",
+      "\\$paths = @()",
+      "foreach (\\$aPath in \\$Path) {",
+      "\t# Resolve any relative paths",
+      "\t\\$paths += \\$psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\\$aPath)",
+      "}",
+      "",
+      "foreach (\\$aPath in \\$paths) {",
+      "\tif (\\$pscmdlet.ShouldProcess(\\$aPath, 'Operation')) {",
+      "\t\t# Process each path",
+      "\t\t$0",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-Path Processing for Wildcards Allowed": {
+    "prefix": "ex-path processing for wildcards allowed",
+    "description": "Example: processing wildcard paths that must exist (for use in process block). See parameter-path-wildcards and parameter-literalpath snippets.",
+    "body": [
+      "# Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=\\$true, DefaultParameterSetName='Path')]",
+      "\\$paths = @()",
+      "if (\\$psCmdlet.ParameterSetName -eq 'Path') {",
+      "\tforeach (\\$aPath in \\$Path) {",
+      "\t\tif (!(Test-Path -Path \\$aPath)) {",
+      "\t\t\t\\$ex = New-Object System.Management.Automation.ItemNotFoundException \"Cannot find path '\\$aPath' because it does not exist.\"",
+      "\t\t\t\\$category = [System.Management.Automation.ErrorCategory]::ObjectNotFound",
+      "\t\t\t\\$errRecord = New-Object System.Management.Automation.ErrorRecord \\$ex,'PathNotFound',\\$category,\\$aPath",
+      "\t\t\t\\$psCmdlet.WriteError(\\$errRecord)",
+      "\t\t\tcontinue",
+      "\t\t}",
+      "\t",
+      "\t\t# Resolve any wildcards that might be in the path",
+      "\t\t\\$provider = \\$null",
+      "\t\t\\$paths += \\$psCmdlet.SessionState.Path.GetResolvedProviderPathFromPSPath(\\$aPath, [ref]\\$provider)",
+      "\t}",
+      "}",
+      "else {",
+      "\tforeach (\\$aPath in \\$LiteralPath) {",
+      "\t\tif (!(Test-Path -LiteralPath \\$aPath)) {",
+      "\t\t\t\\$ex = New-Object System.Management.Automation.ItemNotFoundException \"Cannot find path '\\$aPath' because it does not exist.\"",
+      "\t\t\t\\$category = [System.Management.Automation.ErrorCategory]::ObjectNotFound",
+      "\t\t\t\\$errRecord = New-Object System.Management.Automation.ErrorRecord \\$ex,'PathNotFound',\\$category,\\$aPath",
+      "\t\t\t\\$psCmdlet.WriteError(\\$errRecord)",
+      "\t\t\tcontinue",
+      "\t\t}",
+      "\t",
+      "\t\t# Resolve any relative paths",
+      "\t\t\\$paths += \\$psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\\$aPath)",
+      "\t}",
+      "}",
+      "",
+      "foreach (\\$aPath in \\$paths) {",
+      "\tif (\\$pscmdlet.ShouldProcess(\\$aPath, 'Operation')) {",
+      "\t\t# Process each path",
+      "\t\t$0",
+      "\t}",
+      "}"
+    ]
+  },
+  "Example-Splatting": {
+    "prefix": "ex-splat",
+    "description": "Example: PowerShell splatting technique snippet",
+    "body": [
+      "\\$Params = @{",
+      "\tModule = '*'",
+      "\tVerb = 'Get'",
+      "}",
+      "Get-Command @Params"
+    ]
+  },
+  "Example-Switch": {
+    "prefix": "ex-switch",
+    "description": "Example: switch statement snippet",
+    "body": [
+      "switch (${variable:\\$x})",
+      "{",
+      "\t'${val:value1}' { $1 }",
+      "\t{\\$_ -in 'A','B','C'} {}",
+      "\t'value3' {}",
+      "\tDefault {}",
+      "}"
+    ]
+  },
+}
+```
+
 ### Error-Terminating
 
 Quickly add a fully defined error record and throw. by @omniomi
@@ -162,7 +567,7 @@ Quickly add a fully defined error record and throw. by @omniomi
 
 ### Exchange Online Connection
 
-Connect to Exchange Online, by @vmsilvamolina
+Connect to Exchange Online, by @vmsilvamolina.
 
 #### Snippet
 
@@ -212,7 +617,7 @@ Add HTML header to a variable with the style tag (for css).
 
 ### MaxColumnLengthinDataTable
 
-Takes a datatable object and iterates through it to get the max length of the string columns - useful for data loads into a SQL Server table with fixed column widths by @SQLDBAWithABeard
+Takes a datatable object and iterates through it to get the max length of the string columns - useful for data loads into a SQL Server table with fixed column widths by @SQLDBAWithABeard.
 
 #### Snippet
 
@@ -254,7 +659,7 @@ Create a Resource Group on Azure, by @vmsilvamolina.
 
 ### Parameter-Credential
 
-Add a `-Credential` parameter that supports a PSCredential object in a variable, `-Credential (Get-Credential)`, or `-Credential Username` (will prompt). Includes an empty PSCredential object as the default value but this is the first tabstop so pressing backspace after inserting the snippet removes it. by @omniomi
+Add a `-Credential` parameter that supports a PSCredential object in a variable, `-Credential (Get-Credential)`, or `-Credential Username` (will prompt). Includes an empty PSCredential object as the default value but this is the first tabstop so pressing backspace after inserting the snippet removes it, by @omniomi.
 
 #### Snippet
 
@@ -273,9 +678,69 @@ Add a `-Credential` parameter that supports a PSCredential object in a variable,
 }
 ```
 
+### Pester
+
+Pester snippets migrated from the extension.
+
+```json
+{
+  "PesterContext": {
+    "prefix": "Context-Pester",
+    "description": "Pester - Context block",
+    "body": [
+      "Context \"${1:ContextName}\" {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}"
+    ]
+  },
+  "PesterContextIt": {
+    "prefix": "Context-It-Pester",
+    "description": "Pester - Context block with nested It block",
+    "body": [
+      "Context \"${1:ContextName}\" {",
+      "\tIt \"${2:ItName}\" {",
+      "\t\t${3:${TM_SELECTED_TEXT:Assertion}}",
+      "\t}$0",
+      "}"
+    ]
+  },
+  "PesterDescribeBlock": {
+    "prefix": "Describe-Pester",
+    "description": "Pester Describe block",
+    "body": [
+      "Describe \"${1:DescribeName}\" {",
+      "\t${0:TM_SELECTED_TEXT}",
+      "}"
+    ]
+  },
+  "PesterDescribeContextIt": {
+    "prefix": "Describe-Context-It-Pester",
+    "description": "Pester Describe block with nested Context & It blocks",
+    "body": [
+      "Describe \"${1:DescribeName}\" {",
+      "\tContext \"${2:ContextName}\" {",
+      "\t\tIt \"${3:ItName}\" {",
+      "\t\t\t${4:${TM_SELECTED_TEXT:Assertion}}",
+      "\t\t}$0",
+      "\t}",
+      "}"
+    ]
+  },
+  "PesterIt": {
+    "prefix": "It-Pester",
+    "description": "Pester - It block",
+    "body": [
+      "It \"${1:ItName}\" {",
+      "\t${2:${TM_SELECTED_TEXT:Assertion}}",
+      "}$0"
+    ]
+  }
+}
+```
+
 ### PesterTestForMandatoryParameter
 
-Quickly create a Pester Test for existence of a mandatory parameter by @SQLDBAWithABeard
+Quickly create a Pester Test for existence of a mandatory parameter by @SQLDBAWithABeard.
 
 #### Snippet
 
@@ -293,7 +758,7 @@ Quickly create a Pester Test for existence of a mandatory parameter by @SQLDBAWi
 
 ### PesterTestForParameter
 
-Quickly create a Pester Test for existence of a parameter by @SQLDBAWithABeard
+Quickly create a Pester Test for existence of a parameter by @SQLDBAWithABeard.
 
 #### Snippet
 
@@ -316,36 +781,37 @@ Add the Send-MailMessage cmdlet with the most common parameters in a hashtable f
 #### Snippet
 
 ```json
-"ex-Send-MailMessage": { 
-	"prefix": "ex-Send-MailMessage", 
-	"body": [ 
-		"$$Params = @{", 
-		"    'SmtpServer'  = 'smtp.mycompany.com'", 
-		"    'Port'        = 25", 
-		"    'Priority'    = 'Normal'", 
-		"    'From'        = 'sender@mycompany.com'", 
-		"    'To'          = 'mainrecipient@mycompany.com'", 
-		"    'Cc'          = 'copyrecipient@mycompany.com'", 
-		"    'Bcc'         = 'hiddenrecipient@mycompany.com'", 
-		"    'Subject'     = 'Mail title'", 
-		"    'Body'        = 'This is the content of my mail'", 
-		"    'BodyAsHtml'  = $$false", 
-		"    'Attachments' = 'c:\\MyFile.txt'", 
-		"}", 
-		"Send-MailMessage @Params" 
-	], 
-	"description": "Send a mail message" 
+"ex-Send-MailMessage": {
+	"prefix": "ex-Send-MailMessage",
+	"body": [
+		"$$Params = @{",
+		"    'SmtpServer'  = 'smtp.mycompany.com'",
+		"    'Port'        = 25",
+		"    'Priority'    = 'Normal'",
+		"    'From'        = 'sender@mycompany.com'",
+		"    'To'          = 'mainrecipient@mycompany.com'",
+		"    'Cc'          = 'copyrecipient@mycompany.com'",
+		"    'Bcc'         = 'hiddenrecipient@mycompany.com'",
+		"    'Subject'     = 'Mail title'",
+		"    'Body'        = 'This is the content of my mail'",
+		"    'BodyAsHtml'  = $$false",
+		"    'Attachments' = 'c:\\MyFile.txt'",
+		"}",
+		"Send-MailMessage @Params"
+	],
+	"description": "Send a mail message"
 }
 ```
 
 ## Contributing
 
 To optimize snippet usability and discoverability for end users we will only ship snippets in the extension which we believe meet the following requirements:
+
 - Must be broadly applicable to most PowerShell extension users
-- Must be substantially different from existing snippets or intellisense 
+- Must be substantially different from existing snippets or intellisense
 - Must not violate any intellectual property rights
 
-If your snippet does not meet these requirements but would still be useful to customers we will include it in our list of [Awesome Community Snippets](https://github.com/PowerShell/vscode-powershell/blob/master/docs/community_snippets.md). Additionally, snippet creators can publish snippet libraries as standalone extensions in the [VSCode Marketplace](https://code.visualstudio.com/api/working-with-extensions/publishing-extension). 
+If your snippet does not meet these requirements but would still be useful to customers we will include it in our list of [Awesome Community Snippets](https://github.com/PowerShell/vscode-powershell/blob/main/docs/community_snippets.md). Additionally, snippet creators can publish snippet libraries as standalone extensions in the [VSCode Marketplace](https://code.visualstudio.com/api/working-with-extensions/publishing-extension).
 
 If you'd like a snippet to be considered for addition to the list, [open a pull request](https://opensource.guide/how-to-contribute/#opening-a-pull-request) with the following changes:
 
diff --git a/docs/development.md b/docs/development.md
index 109fc3909d..3caac3bb01 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -2,35 +2,53 @@
 
 ## Development Setup
 
-You'll need to clone two repositories and set up your development environment
-to before you can proceed.
+1. [Fork and clone][fork] the [vscode-powershell repository](https://github.com/PowerShell/vscode-powershell).
 
-1. [Fork and clone][fork] the [vscode-powershell repository](https://github.com/PowerShell/vscode-powershell)
-
-2. [Fork and clone][fork] the [PowerShell Editor Services (PSES) repository](https://github.com/PowerShell/PowerShellEditorServices)
+1. [Fork and clone][fork] the [PowerShell Editor Services (PSES) repository](https://github.com/PowerShell/PowerShellEditorServices).
    > The `vscode-powershell` folder and the `PowerShellEditorServices` folder should be next to each other on the file
    > system. Code in `vscode-powershell` looks for PSES at `../PowerShellEditorServices` if you're building locally so
    > PSES must be in that location.
 
-3. Follow the [development instructions](https://github.com/PowerShell/PowerShellEditorServices#development) for
+1. Follow the [development instructions](https://github.com/PowerShell/PowerShellEditorServices#development) for
    PowerShell Editor Services. **You will need to complete this step before proceeding**.
 
-4. Install the latest [Visual Studio Code Insiders release](https://code.visualstudio.com/insiders)
-   > You can also use the [standard Visual Studio Code release](https://code.visualstudio.com/). Both will work, but
-   > using VSCode Insiders means the extension can be developed ready for new features and changes in the next VSCode
-   > release.
+1. Install [Node.js](https://nodejs.org/en/) 18.x or higher.
+
+1. Install [Visual Studio Code](https://code.visualstudio.com).
+   Open the multi-root workspace file in this repo, `extension-dev.code-workspace`.
+   > This has a set of recommended extensions to install and provides tasks.
+   > The ESLint formatter will require you to install ESLint globally, using `npm install -g eslint`.
+   > Otherwise VS Code will erroneously complain that it isn't able to use it to format TypeScript files.
 
-5. Install [Node.js](https://nodejs.org/en/) 10.x or higher.
+1. (optional) Set `git config blame.ignoreRevsFile .git-blame-ignore-revs` to ignore formatting-related commits.
 
 [fork]: https://help.github.com/articles/fork-a-repo/
 
+## Tracking Upstream Dependencies
+
+As a VS Code extension, we first rely on the `engine` field of `package.json` to
+state the lowest version of VS Code we support.
+
+When our `engine` field is updated the development dependency `@types/vscode`
+must be updated to match. Note that it uses `~` (not `^`) so as to accept new
+patches with `npm update` but not new minor versions. Then we check that version
+of VS Code's own `package.json` file for their [`electron`][] dependency. The
+major version of [Electron][] will tell us which [Node.js][] is included, which
+dictates which version of Node.js the extension is eventually run with. This
+lets us finally update our `@types/node` development dependency to match, our
+developer machines if necessary, the CI and OneBranch pipeline tasks, and the
+`.tsconfig` file. Note that the version of `@types/node` will not necessarily
+exactly match the version of Node.js, but the major version should.
+
+[`electron`]: https://github.com/microsoft/vscode/blob/138f619c86f1199955d53b4166bef66ef252935c/package.json#L156
+[Electron]: https://releases.electronjs.org/release/v32.2.6
+[Node.js]: https://nodejs.org/en/download/package-manager
+
 ### Building the Code
 
 #### From Visual Studio Code
 
-> Press <kbd>Ctrl</kbd>+<kbd>P</kbd> and type `task build`
-
-This will compile the TypeScript files in the project to JavaScript files.
+Press <kbd>Ctrl+P</kbd> and type `task build`. Explore the other provided tasks for helpful commands.
 
 #### From a PowerShell prompt
 
@@ -38,48 +56,68 @@ This will compile the TypeScript files in the project to JavaScript files.
 Invoke-Build Build
 ```
 
-As a developer, you may want to use `Invoke-Build LinkEditorServices` to setup a symbolic
-link to its modules instead of copying the files. This will mean the built extension will
-always have the latest version of your PowerShell Editor Services build, but this cannot
-be used to package the extension into a VSIX. So it is a manual step.
+Explore the `vscode-powershell.build.ps1` file for other build targets.
 
 ### Launching the extension
+First, ensure you have completed a build as instructed above, as the launch templates do not check some prerequisites for performance reasons.
 
-#### From Visual Studio Code
+To debug the extension use one of the provided `Launch Extension` debug configurations.
+1. `Launch Extension`: Launches the debugger using your personal profile settings.
+2. `Temp Profile`: Launches VS Code with a temp profile that resets on every launch. Useful for "out of the box" environment testing.
+3. `Isolated Profile`: Launches the debugger with a persistent debug profile specific to the extension, so you can preserve some settings or test certain prerequisites.
 
-> To debug the extension, press <kbd>F5</kbd>.  To run the extension without debugging, press
-> <kbd>Ctrl</kbd>+<kbd>F5</kbd> or <kbd>Cmd</kbd>+<kbd>F5</kbd> on macOS.
+All three templates use pre-launch tasks to build the code, and support automatic restart of the extension host on changes to the Extension source code. [Hot Reload](https://devblogs.microsoft.com/dotnet/introducing-net-hot-reload/) is also enabled for PowerShell Editor Services.
 
-#### From a command prompt
+> [!WARNING]
+> There is a current limitation that, if you restart the extension/extension host or it is restarted due to a extension code change, the editor services attachment will be disconnected due to the PSES terminal being terminated, and you will either need to restart the debug session completely, or do a manual build of PSES and run the `Attach to Editor Services` debug launch manually.
 
-```cmd
-code --extensionDevelopmentPath="c:\path\to\vscode-powershell" .
-```
+Try the `powershell.developer.editorServicesWaitForDebugger` setting to ensure that you are fully attached before the extension startup process continues.
 
 ## Contributing Snippets
 
 For more information on contributing snippets please read our
-[snippet requirements](https://github.com/PowerShell/vscode-powershell/blob/master/docs/community_snippets.md#contributing).
+[snippet requirements](https://github.com/PowerShell/vscode-powershell/blob/main/docs/community_snippets.md#contributing).
 
 ## Creating a Release
 
 These are the current steps for creating a release for both the editor services
-and the extension. ADO access is restricted to Microsoft employees and is used
-to sign and validate the produced binaries before publishing on behalf of
-Microsoft. The comments are manual steps.
+and the extension. Azure DevOps access is restricted to Microsoft employees and
+is used to sign and validate the produced binaries before publishing on behalf
+of Microsoft. Assume `origin` is GitHub and `ado` is Azure DevOps.
 
 ```powershell
-Import-Module ./tools/ReleaseTools.psm1
-New-Release -PsesVersion <version> -VsceVersion <version>
+cd ./PowerShellEditorServices
+git checkout -B release
+./tools/updateVersion.ps1 -Version "4.0.0" -Changes "Major release!"
 # Amend changelog as necessary
-# Push release branches to ADO
-# Permit both pipelines to draft GitHub releases
-# Download and test assets
-# Check telemetry for stability before releasing
-# Publish draft releases and merge (don't squash!) branches
-# Permit vscode-extension pipeline to publish to marketplace
+git push --force-with-lease origin
+# Open, approve, and merge PR on GitHub
+cd ../vscode-powershell
+git checkout -B release
+./tools/updateVersion.ps1 -Version "2024.4.0" -Changes "Major release!"
+# Amend changelog as necessary
+git push --force-with-lease origin
+# Open, approve, and merge PR on GitHub
+cd ../PowerShellEditorServices
+git checkout main
+git pull
+git push ado HEAD:release
+cd ../vscode-powershell
+git checkout main
+git pull
+git push ado HEAD:release
+# Download and test assets from draft GitHub Releases
+# Publish releases, ensuring tag is at release commit in `main`
+# Permit pipeline to publish to marketplace
 ```
 
+If rolling from pre-release to release, do not change the version of PowerShell
+Editor Services between a pre-release and the subsequent release! We only
+need to release the extension.
+
+The Azure DevOps pipelines have to build off a PR merged to `main` for _reasons_,
+hence that repo is a superset including all our commits plus signed PR merge commits.
+
 ### Versioning
 
 For both our repositories we use Git tags in the form `vX.Y.Z` to mark the releases in the
@@ -92,44 +130,56 @@ mark any specific release, that is the point of the tags.
 For PowerShellEditor Services, we simply follow semantic versioning, e.g.
 `vX.Y.Z`. We do not release previews frequently because this dependency is not
 generally used directly: it's a library consumed by other projects which
-themselves use preview releases for beta testing.
-
-For the VS Code PowerShell Extension, our version follows `vYYYY.M.X`, that is:
-current year, current month, and patch version (not day). This is not semantic
-versioning because of issues with how the VS Code marketplace and extension
-hosting API itself uses our version number. This scheme _does not_ mean we
-release on a chronological schedule: we release based on completed work. If the
-month has changed over since the last release, the patch version resets to 0.
-Each subsequent release that month increments the patch version.
-
-Before releasing a "stable" release we should almost always first release a
-"preview" of the same code. The exception to this is "hotfix" releases where we
-need to push _only_ bug fixes out as soon as possible, and these should be built
-off the last release's codebase (found from the Git tag). The preview release is
-uploaded separately to the marketplace as the "PowerShell Preview" extension. It
-should not significantly diverge from the stable release ("PowerShell"
-extension), but is used for public beta testing. The preview version should
-match the upcoming stable version, but with `-preview` appended.  When multiple
-previews are needed, the patch version is incremented, and the last preview's
-version is used for the stable release. (So the stable version may jump a few
-patch versions in between releases.)
-
-For example, the date is May 7, 2022. The last release was in April, and its
-version was `v2022.4.3`. Some significant work has been completed and we want to
-release the extension. First we create a preview release with version
-`v2022.5.0-preview` (the patch reset to 0 because the month changed, and
-`-preview` was appended). After publishing, some issues were identified and we
-decided we needed a second preview release. Its version is `v2022.5.1-preview`.
-User feedback indicates that preview is working well, so to create a stable
-release we use the same code (but with an updated changelog etc.) and use
-version `v2022.5.1`, the _first_ stable release for May (as `v2022.5.0` was
-skipped due to those identified issues in the preview). All of these releases
-may consume the same or different version of PowerShell Editor Services, say
-`v3.2.4`. It may update between preview versions or stable versions (but should
-not change between a preview and its associated stable release, as they should
-use the same code which includes dependencies).
-
-### Pending Improvements
-
-* `Update-Changelog` should verify the version is in the correct format
-* `Update-Changelog` could be faster by not downloading _every_ PR
+themselves use pre-releases for beta testing.
+
+For the VS Code PowerShell Extension, our version follows `vYYYY.X.Z`, that is: current
+year, minor version, and patch version. This is not semantic versioning because of issues
+with how the VS Code marketplace and extension hosting API itself uses our version number.
+We do not release on a chronological schedule: we release based on completed work. For
+historical reasons we are stuck with the major version being year.
+
+Before releasing a stable version (a _release_) we should almost always first release a
+preview of the same code, which is a _pre-release_. The exception to this is hotfix
+releases where we need to push _only_ bug fixes out as soon as possible, and these should
+be built off the last release's codebase (found from the Git tag). The pre-release is
+uploaded to the marketplace using the `--pre-release` flag given to `vsce` (the CLI tool
+used to do so). The previous separate "PowerShell Preview" extension has been deprecated
+in favor of using the marketplace's support for [pre-releases][] on the one-and-only
+extension.
+
+Because the marketplace does not actually understand Semantic Versioning pre-release tags
+(the `-preview` suffix), the patch numbers need to increment continuously, but we append
+`-preview` to _our_ version in the changelog and Git tags. When multiple pre-releases are
+needed, the patch version is incremented (again because the marketplace ignores the
+pre-release tag, we can't do `-alpha`, `-beta` etc.). The `preview` field in
+the extension's manifest (the `package.json` file) is _always_ `false`, even for
+pre-releases, because the marketplace takes the information from the latest release
+inclusive of pre-releases, hence it was causing the one-and-only extension to look like it
+was in preview. This is also why the icon no longer changes to the PowerShell Preview icon
+for pre-releases. When they support pre-releases better (ideally that means supporting the
+pre-release tags in full) we can revisit this.
+
+Furthermore, for releases, the minor version must be _even_ (like 0, 2, etc.) and for
+pre-releases it must be _odd_ (like 1, 3, etc.), and an upcoming release's version must be
+`n-1` of the pre-release which previews it. That is, release `v2024.0.0` is previewed in
+the pre-release `v2024.1.0-preview`. This scheme is designed such that the "newest" (by version)
+release is always a pre-release, so that the VS Code marketplace _always_ shows a
+pre-release option. When we previously did this the other way around (incrementing the
+release as `n+1` to the pre-release), every time we released, the pre-release option
+(dropdown) in the marketplace would unfortunately disappear.
+
+[pre-releases]: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions
+
+For example, the date is August 23, 2023. The last release was in June, and its version
+was `v2023.6.0`. Some significant work has been completed and we want to release the
+extension, so the next release will be `v2023.8.0` (the minor version is `n+2` because it
+must remain even, it only coincidentally matches the month). That means first we create a
+pre-release with version `v2023.9.0-preview` (the minor version is `n+1` of the upcoming
+release, and `-preview` was appended). After publishing, some issues were identified and
+we decided we needed a second pre-release. Its version is `v2023.9.1-preview`. User
+feedback hopefully indicates that the pre-release is working well, so to create a release
+we will use the same code (but with an updated changelog etc.) and use version
+`v2023.8.0`, the _next_ release since `v2023.6.0`. The version of PowerShell Editor
+Services may update between pre-releases or releases, but must not change between a
+pre-release and its subsequent release, as they should use the same code (which includes
+dependencies).
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 25b5ea6a82..4c2b6195dd 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -1,7 +1,27 @@
 # Troubleshooting PowerShell Extension Issues
 
 This document contains troubleshooting steps for commonly reported issues when using the
-[PowerShell Extension] for Visual Studio Code.
+[PowerShell Extension][] for Visual Studio Code.
+
+## How do I change the PowerShell version?
+
+Starting VS Code 1.65, extensions now use the [language status item API][] instead of
+manually adding a button to the status bar. That means the PowerShell icon button in the
+status bar now exists under the language status menu, which looks like: `{}`. You can then
+pin the icon back to the status bar by hovering over that menu and clicking the pin
+button. The PowerShell icon will show you the current session's version, and clicking it
+will let you change to another session. The language status icon will only appear when the
+active editor's language mode is PowerShell.
+
+### Using Windows PowerShell 5.1
+
+While we _highly encourage_ the use of [PowerShell 7.4 LTS][], if you must use Windows
+PowerShell 5.1 we attempt to support it on a best-effort basis. Unfortunately, being two
+major versions behind and in maintenance mode, Windows PowerShell is missing many of the
+bug fixes and APIs we use to make the extension experience great. So please, if you can,
+use PowerShell Core. That said, when using Windows PowerShell on older versions of the
+Windows operating system, if the extension is failing to start (e.g. [#2571][]), try
+installing [WMF 5.1][] and [.NET Framework 4.8][dotnet-framework].
 
 ## How do I debug my PowerShell script?
 
@@ -13,64 +33,63 @@ Scripting Guys blog posts (thanks community!):
 
 ## Script analysis is reporting false errors
 
-Script analysis is provided by the [PSScriptAnalyzer] project on GitHub. If the warning
+Script analysis is provided by the [PSScriptAnalyzer][] project on GitHub. If the warning
 message starts with `[PSScriptAnalyzer]` or if you are getting faulty script diagnostics
-(red and green squiggly lines under PowerShell in scripts) please [open an issue there].
+(red and green squiggly lines under PowerShell in scripts) please [open an issue there][].
 
-## Double-click isn't selecting the whole variable
+## Completions aren't appearing
 
-Visual Studio Code provides a default set of word separators, that is,
-characters that split words and so affect double-click selections. The editor's
-defaults include both `-` and `$`. In [v2021.5.1] we started providing a default
-value for PowerShell files that excludes these two symbols. The intention of
-this change was to increase predictability, as double-clicking PowerShell
-symbols would now select the same portion that the extension highlights as well
-as align with collected user feedback.
+First, please ensure that the extension itself has properly started. Do this by opening
+the PowerShell Extension Terminal and checking the value of the variable `$psEditor`,
+it should return a version and other fields. If it does not, you're probably in a
+different "PowerShell" terminal in VS Code, and not the PowerShell Extension Terminal.
+So please open a bug about your extension failing to start instead.
 
-Different users have a variety of different preferences around these word
-selection settings and you can easily configure your own [word separators] in
-Visual Studio Code's settings.
+If the extension _is_ started and the Extension Terminal functional, completions should appear! Please
+double-check that your `editor.suggest.showFunctions` VS Code setting is `true`, as
+setting it to `false` _will_ disable completions (from all extensions). You may also want
+to check other related settings under "Text Editor -> Suggestions" in VS Code.
 
-We exclude `-` by default because unlike programming languages that use
-`CamelCase` or `snake_case`, PowerShell uses a `Verb-Noun` style where dashes
-are part of many symbol names (like underscores in other languages). So by
-excluding it we configure Visual Studio Code to treat `Verb-Noun` as one
-symbol/word, which matches what the extension semantically highlights when the
-cursor is placed within it.
+## Double-click isn't selecting the whole variable
 
-We briefly excluded `$` by default too because PowerShell uses it as a prefix
-for variable substition, and many users were already excluding it. However, we
-could not find a strong consensus [#3378], so we reverted this exclusion.
+VS Code provides a default set of word separators, that is, characters that split words
+and so affect double-click selections. The editor's defaults include `-`, however we
+exclude `-` for PowerShell documents because unlike programming languages that use
+`CamelCase` or `snake_case`, PowerShell uses a `Verb-Noun` style where dashes are part of
+many symbol names (like underscores in other languages). So by excluding it we configure
+VS Code to treat `Verb-Noun` as one symbol/word, which matches what the extension
+semantically highlights when the cursor is placed within it.
 
-To set the word separator behavior to separate words in PowerShell on `-` and
-`$` add the following entry to the Visual Studio Code's `settings.json`:
+Users may also wish to set VS Code's integrated terminal's word separators (a separate
+setting) to exclude `-` to mirror the behavior in the terminal. This will apply to _all_
+terminals, not just PowerShell terminals.
 
 ```json
-"[powershell]": {
-    "editor.wordSeparators": "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?"
-}
+"terminal.integrated.wordSeparators": " ()[]{}',\"`─"
 ```
 
-This will cause `-` and `$` to register as word boundaries, meaning for example
-that double-clicking on a letter in `$MyVariable` will not select the `$` and on
-the `G` in `Get-Process` will only select `Get` rather than the verb and noun.
+Different users have a variety of different preferences around these word selection
+settings and you can easily configure your own [word separators][] in VS Code's settings.
 
-Users may also wish to set Visual Studio Code's integrated terminal's word separators (a
-separate setting) to exclude `-` to mirror the behavior in the terminal. This will apply
-to _all_ terminals, not just PowerShell terminals.
+To revert this behavior, add the following entry to the VS Code's `settings.json`:
 
 ```json
-"terminal.integrated.wordSeparators": " ()[]{}',\"`─"
+"[powershell]": {
+    "editor.wordSeparators": "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?"
+}
 ```
 
+This will cause `-` to register as a word boundary, meaning for example on the `G` in
+`Get-Process` will only select `Get` rather than the verb and noun `Get-Process`.
+
 ## Problems with syntax highlighting
 
-PowerShell syntax highlighting is performed in combintation by the [PowerShell Extension]
-(semantic highlighting) and [Editor Syntax]. Syntax highlighting for VS Code, Atom,
-SublimeText and even GitHub is provided by the [Editor Syntax] repository on GitHub.
+PowerShell syntax highlighting is performed in combination by the [PowerShell Extension][]
+(semantic highlighting) and [Editor Syntax][]. Syntax highlighting for VS Code, Atom,
+SublimeText and even GitHub is provided by the [Editor Syntax][] repository on GitHub.
 
-We introducted [Semantic Highlighting] in [v2021.2.2], a feature that applies tokenized
-colors at a layer above [Editor Syntax]. However, after [community feedback][#3221] and
+We introduced [Semantic Highlighting][] in [v2021.2.2][], a feature that applies tokenized
+colors at a layer above [Editor Syntax][]. However, after [community feedback][#3221] and
 multiple bug reports (including colors changing unexpectedly and [randomly][#3295]), we
 have decided to disable it by default.
 
@@ -78,136 +97,151 @@ To enable semantic highlighting and use this "experimental" feature, set:
 
 ```json
 "[powershell]": {
-    "editor.semanticHighlighting.enabled": false
+    "editor.semanticHighlighting.enabled": true
 }
 ```
 
-If you enable it, you can customize the colors used for the various tokens. See [#3221]
+If you enable it, you can customize the colors used for the various tokens. See [#3221][]
 for more info and to leave suggestions.
 
 If it is disabled and your issue remains, then please open those syntax highlighting
-issues there in [Editor Syntax].
+issues there in [Editor Syntax][].
 
 ## Windows aren't appearing
 
-Due to an [issue](https://github.com/Microsoft/vscode/issues/42356) in Electron, windows
-spawned by Visual Studio Code (such as those for `Get-Credential`, `Connect-MsolService`,
-`Connect-AzAccount`, `Connect-AzureAd`, etc.) do not appear above Visual Studio Code.
+Due to a known issue in [Electron][], windows spawned by VS Code (such as those for
+`Get-Credential`, `Connect-MsolService`, `Connect-AzAccount`, `Connect-AzureAd`, etc.) do
+not appear above VS Code. Use <kbd>Alt</kbd>+<kbd>Tab</kbd> on Windows or
+<kbd>Cmd</kbd>+<kbd>Tab</kbd> on macOS to switch to the other window.
 
 ## Visual Studio Code is not working like the ISE
 
-The PowerShell extension does not aim to perfectly recreate
-the experience of the PowerShell ISE.
-However, we do want to support compatibility whenever possible
-to do so without breaking existing functionality.
+The [PowerShell Extension][] does not aim to perfectly recreate the experience of the
+PowerShell ISE. However, we do want to support compatibility whenever possible to do so
+without breaking existing functionality.
 
-Please see [the ISE compatibility doc](https://docs.microsoft.com/powershell/scripting/components/vscode/how-to-replicate-the-ise-experience-in-vscode)
-for ways to configure VSCode to be closer to the ISE.
+Please see the [ISE compatibility doc][] for ways to increase VS Code's similarity.
 
-Bear in mind that many of the UI/UX aspects of VSCode are driven by
-VSCode itself and can't be changed by the extension.
-The VSCode maintainers are quite reasonable though,
+Bear in mind that many of the UI/UX aspects of VS Code are driven by VS Code itself and
+can't be changed by the extension. The VS Code maintainers are quite reasonable though,
 and you can ask for new features [in their repository](https://github.com/Microsoft/vscode).
 
 ## Known issues in the extension
 
-- If you are running the Preview version "PowerShell Preview" side-by-side with the stable version "PowerShell"
-  you will experience performance and debug issues.
-  This is expected until VSCode offers extension channels - [vscode#15756](https://github.com/Microsoft/vscode/issues/15756)
-  - You MUST [DISABLE](https://code.visualstudio.com/docs/editor/extension-gallery#_disable-an-extension) one of them for the best performance.
-    Docs on how to disable an extension can be found [here](https://code.visualstudio.com/docs/editor/extension-gallery#_disable-an-extension)
-- "The Language Service could not be started" but it does start with the x86 version of PowerShell
-  - Do you use Avecto/BeyondSoft?
-    We've received reports that Avecto, BeyondSoft
-    and other privilege management software
-    dramatically slow down the start up of Windows PowerShell x64.
-    Please give the privilege management software feedback.
-    For some,
-    [updating to the latest version has fixed the issue](https://github.com/PowerShell/vscode-powershell/issues/2526#issuecomment-638329157).
-- IntelliSense is slow
-  - This is a known issue that we've been chipping away at. There doesn't seem
-    to be any one performance drain, but we've been trying to incrementally
-    improve performance bit-by-bit everywhere. Currently we are focusing on [this issue](https://github.com/PowerShell/PowerShellEditorServices/issues/1295).
-- Variable renaming doesn't work properly - [#261]
-  - PowerShell's usage of [dynamic scope] rather than [lexical scope]
-    makes it [formally undecidable] to statically rename variables correctly
-    (the only way to know for sure which `$x`s refer to the same variable is to
-    run the PowerShell script).
+* "CorruptZip: end of central directory record signature not found" when installing the
+  extension, [#4474][].
+
+  * Unfortunately it appears that a common corporate VPN with a firewall by Palo Alto is
+    disrupting the download of the extension binary from the VS Code marketplace. Please
+    reach out to your network administrators about this.
+
+* "The Language Service could not be started" but it does start with the x86 version of
+  PowerShell.
+
+  * Do you use Avecto / BeyondSoft? We've received reports that Avecto, BeyondSoft and
+    other privilege management software dramatically slow down the start up of Windows
+    PowerShell x64. Please give the privilege management software feedback.
+
+* `Write-Output` is broken in Windows PowerShell 5.1, [#3991][].
+
+  * We seem to have recently narrowed this down! If `Start-Transcript` has been called
+    within the Extension Terminal, say in your PowerShell profile, this will eventually
+    cause output to no longer appear. Please try removing the call to `Start-Transcript`
+    and restarting the extension. We are investigating a fix.
+
+* Variable renaming doesn't work as expected, [#261][].
+
+  * PowerShell's usage of [dynamic scope][] rather than [lexical scope][] makes it
+    [formally undecidable][] to statically rename variables correctly (the only way to
+    know for sure which `$x`s refer to the same variable is to run the PowerShell script).
     However, like with many features, we attempt a best effort.
-- "Go to Definition" doesn't work through module imports - [#499]
-  - Again this is a best-effort task.
-- Completions don't cycle when <kbd>Tab</kbd> is pressed like in the ISE - [#25]
-  - [Use the tab comletion settings in VSCode](https://docs.microsoft.com/en-us/powershell/scripting/components/vscode/how-to-replicate-the-ise-experience-in-vscode?view=powershell-6#tab-completion)
-- My command that opens a dialog does nothing - [#410 (comment)]
-  - Check that the dialog hasn't opened behind VSCode. This is a known
-    [VSCode issue].
-- PowerShell classes don't have proper reference/symbol support - [#3]
-  - One of the blockers for this was that we still supported Windows PowerShell v3 and v4. However, we don't support v3 and v4 anymore so we can do this work but it's not on the roadmap at this time.
-- Document formatting takes a long time - [#984]
-  - Document formatting is provided by [PSScriptAnalyzer], but there
-    may be opportunities to improve our integration with it in the
-    [PowerShell Extension] too.
-- PSReadLine throws an error ever so often - [#3701](https://github.com/PowerShell/vscode-powershell/issues/3701)
-  - This is a known issue due to the PowerShell eventing framework running registered
+
+* `$PSScriptRoot` is not populated when running a code block (via F8), [#633][].
+
+  * This is by design. The value of `$PSScriptRoot` is only populated by PowerShell when
+    the caller is a script. Since <kbd>F8</kbd> or "Run Selection" is essentially
+    copy-pasting the selection into the terminal, it's behavior is the same as if you the
+    user pasted it. That is, it's a block of code and not a script file, and therefore
+    there is no relevant context to populate `$PSScriptRoot`.
+
+* Completions don't cycle when <kbd>Tab</kbd> is pressed like in the ISE, [#25][].
+
+  * Use the tab completion settings recommended in the [ISE compatibility doc][].
+
+* My command that opens a dialog does nothing, [#410 (comment)][].
+
+  * Check that the dialog hasn't opened behind VS Code. This is a known issue in
+    [Electron][], the framework used by VS Code.
+
+* Document formatting takes a long time, [#984][].
+
+  * Document formatting is provided by [PSScriptAnalyzer][], but there may be
+    opportunities to improve our integration with it in the extension too.
+
+* PSReadLine throws an error ever so often, [#3701][].
+
+  * This is a known issue due to the PowerShell eventing framework running registered
     `OnIdle` events outside of PowerShell Editor Service's dedicated PowerShell execution
     pipeline. Until we can disable event registration, you will need to avoid registering
     events in the first place.
-  - A known work around includes unregistering from this event.
-    `Get-EventSubscriber -Force -SourceIdentifier PowerShell.OnIdle -EA 0 | Unregister-Event -Force`
-    can be run manually (or added to your profile) to avoid this bug.
-  * Related issues: [PowerShell Editor Services #1591](https://github.com/PowerShell/PowerShellEditorServices/issues/1591),
+
+  * A known work around includes unregistering from this event. `Get-EventSubscriber
+    -Force -SourceIdentifier PowerShell.OnIdle -EA 0 | Unregister-Event -Force` can be run
+    manually (or added to your profile) to avoid this bug.
+
+  * Also see: [PowerShell Editor Services #1591](https://github.com/PowerShell/PowerShellEditorServices/issues/1591),
     [PSReadLine #3091](https://github.com/PowerShell/PSReadLine/issues/3091),
-    [Azure PowerShell #16585](https://github.com/Azure/azure-powershell/issues/16586)
+    and [Azure PowerShell #16585](https://github.com/Azure/azure-powershell/issues/16586).
 
 ## Reporting an issue
 
-If you experience a problem with the [PowerShell Extension]:
+If you experience a problem with the PowerShell Extension:
+
+1. Search through [existing issues][] on GitHub.
+
+   In some circumstances, an issue may already be closed due to a fix being merged but not
+   yet released - so be sure to quickly check closed issues as well.
+
+2. Most features are provided by the client-agnostic [PowerShell Editor Services][]
+   backend project that the extension leverages, so it's also worth a [look there][].
 
-1. Search through [existing issues] on GitHub.
-   In some circumstances, an issue may already be closed due to
-   a fix being merged but not yet released - so be sure to quickly
-   check closed issues as well.
-2. Most features are provided by the client-agnostic [PowerShell Editor Services]
-   backend project that the extension leverages, so it's also worth a
-   [look there].
-3. If you don't see the issue you're experiencing, please [open a new issue].
+3. If you don't see the issue you're experiencing, please [open a new issue][].
 
 ## Opening a new issue
 
-If you experience an issue with the [PowerShell Extension] and can't find
-an existing issue for it, [open an issue on us on GitHub].
+If you experience an issue with the PowerShell Extension and can't find an existing issue
+for it, [open a new issue][].
 
-You can also open an issue directly from VSCode by entering the
-[Command Palette] with <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>
-(<kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> on macOS) and running the
-`PowerShell: Upload Bug Report to GitHub` command.
+You can also open an issue directly from VS Code by entering the [Command Palette][] with
+<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>
+(<kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> on macOS) and running the `PowerShell:
+Upload Bug Report to GitHub` command.
 
 When opening an issue, keep in mind:
 
-- The fastest way to fixing a bug is reproducing it, and reproducing it
-  is easier with [more information].
-- The issue templates are designed to help you provide all the information
-  needed to solve your issue
-- As Free and Open Source Software, the [PowerShell Extension] thrives on
-  the contributions of community members &mdash; if you're interested in
-  [tackling an issue], we always accept contributions and will help you
-  at every step.
+* The fastest way to fixing a bug is reproducing it, and reproducing it
+  is easier with [more information][].
+
+* The issue templates are designed to help you provide all the information needed to solve
+  your issue, please fill out the entire questionnaire.
+
+* As Open Source Software the [PowerShell Extension][] thrives on the contributions of
+  community members! If you're interested in [tackling an issue][], we love accepting
+  contributions and will help you at every step.
 
 ## Reproducing the issue
 
-To fix the issue, we need to be able to reproduce it.
-To do that, we need:
+To fix the issue, we need to be able to reproduce it. To do that, we need:
 
-- A small/minimal script or sequence of user steps that result in the problem occurring.
-- A description of the behavior you are expecting.
-- A description of the actual behavior that occurs.
+* A small/minimal script or sequence of user steps that result in the problem occurring.
+* A description of the behavior you are expecting.
+* A description of the actual behavior that occurs.
 
-In some cases, a GIF of the issue occuring is also very helpful.
+In some cases, a GIF of the issue occurring is also very helpful.
 
-When you open a new issue,
-the GitHub issue template will have sections
-to guide you through providing all of this information
-as well as environment information discussed below.
+When you [open a new issue][], the GitHub issue template will have sections to guide you
+through providing all of this information as well as environment information discussed
+below.
 
 ## Providing information about your environment
 
@@ -215,150 +249,115 @@ For solving most issues, the following information is important to provide:
 
 ### Logs
 
-Logs provide context for what was happening when the issue occurred.
-**Note: You should skim through your logs for any sensitive information you would not like to share online**
+Logs provide context for what was happening when the issue occurred. **You should browse
+your logs for any sensitive information you would not like to share online!**
 
-- Before sending through logs, try and reproduce the issue with
-  **log level set to Diagnostic**. You can set this
-  in the [VSCode Settings] (<kbd>Ctrl</kbd>+<kbd>,</kbd>) with:
+* Before sending through logs, try and reproduce the issue with **log level set to
+  Trace**. You can set this in the [VS Code Settings][]
+  (<kbd>Ctrl</kbd>+<kbd>,</kbd>) with:
 
   ```json
-  "powershell.developer.editorServicesLogLevel": "Diagnostic"
+  "powershell.developer.editorServicesLogLevel": "Trace"
   ```
 
-  After you have captured the issue with the log level turned up,
-  you may want to return it (since verbose logging can use disk space):
+* After you have captured the issue with the log level turned up, you may want to return
+  it (since verbose logging can use disk space):
 
   ```json
   "powershell.developer.editorServicesLogLevel": "Normal"
   ```
 
-  Logs are located at
+* Logs are located at:
+  * Unix: `~/.config/Code/User/globalStorage/ms-vscode.powershell/logs`.
+  * Windows: `%APPDATA%\Code\User\globalStorage\ms-vscode.powershell\logs`
 
-  ```powershell
-  $HOME/.vscode[-insiders]/extensions/ms-vscode.powershell-<version>/logs/
-  ```
+* In VS Code you can open and read the logs directly from the [Command Palette][]
+  (<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>) with `PowerShell: Open PowerShell Extension Logs Folder`.
 
-  or if you're using the preview version of the extension
+  > NOTE: Don't forget to also attach the [Language Server Protocol payload
+  > logs](#provide-language-server-protocol-payload-logs)!
 
-  ```powershell
-  $HOME/.vscode[-insiders]/extensions/ms-vscode.powershell-preview-<version>/logs/
-  ```
-
-  For example:
-
-  ```powershell
-  $HOME/vscode/extensions/ms-vscode.powershell-2019.5.1/logs
-  ```
+* You can attach your logs to an issue by zipping them and dragging and dropping them onto
+  your open issue description in the browser.
 
-- In VSCode you can open and read the logs directly from the [Command Palette]
-  (<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>)
-  with `PowerShell: Open PowerShell Extension Logs Folder`.
-
-> NOTE: Don't forget to also attach the [Language Server Protocol payload logs](#provide-language-server-protocol-payload-logs)!
-
-- You can attach your logs to an issue by zipping them and drag/dropping
-  them onto your open issue description in the browser.
-
-- If you prefer to share your logs privately, you can send them to
-  vscode-powershell@microsoft.com. Please still open an issue though
-  so we can track the work &mdash; other users may have the same issue.
+* If you prefer to share your logs privately, you can send them to
+  <vscode-powershell@microsoft.com>. **Please still open an issue though so we can track
+  the work, and reference it in your email.**
 
 #### Provide Language Server Protocol payload logs
 
-The PowerShell extension works mostly from sending and receiving messages from [PowerShell Editor Services](httos://github.com/PowerShell/PowerShellEditorServices).
-In some cases, getting to the bottom of a bug will require looking at the payloads of these messages. To do this:
+A lot of the features of the PowerShell extension actually come from Visual Studio Code directly interacting with the [PowerShell Editor Services](https://github.com/PowerShell/PowerShellEditorServices) process via a [Language Server Protocol client](https://code.visualstudio.com/api/language-extensions/language-server-extension-guide#logging-support-for-language-server).
+In some cases, getting to the bottom of a bug will require looking at the payloads of
+these messages. To enable viewing these messages:
 
-- Add the following setting to your settings file:
+* Add the following setting to your settings file:
 
   ```json
-  "powershell editor services.trace.server":"verbose"
+  "powershell.trace.server":"verbose"
   ```
 
-> NOTE: While VSCode will not recognize and highlight it, it is a valid option and enables tracer logs on the server.
-
-- Restart Visual Studio Code and reproduce the issue.
+* Restart VS Code and reproduce the issue.
 
-- Go into the "Output" panel (<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>U</kbd> or <kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>U</kbd>).
+* Go into the "Output" panel (<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>U</kbd> or
+  <kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>U</kbd>).
 
-- In the drop down on the right, select "PowerShell Editor Services".
+* In the drop down on the right, select "PowerShell Editor Services Client".
 
-- Copy the entire contents of the Output panel and paste it into the GitHub issue in the browser.
-At this point, you may delete the setting if you want.
+* Copy the entire contents of the Output panel and paste it into the GitHub issue in the
+  browser. At this point, you may delete the setting if you want.
 
-- Again, if you prefer to share your logs privately, you can send them to
-  vscode-powershell@microsoft.com. Please still open an issue though
-  so we can track the work &mdash; other users may have the same issue.
+* Again, if you prefer to share your logs privately, you can send them to
+  <vscode-powershell@microsoft.com>. **Please still open an issue though so we can track
+  the work, and reference it in your email.**
 
 ### Visual Studio Code version
 
-[Your VSCode version] can be obtained from the Integrated Console
-or PowerShell like this:
+[Your VS Code version][] can be obtained from the Extension Terminal or any terminal:
 
-```shell
-code -v
+```powershell
+code --version
 ```
 
-If you are using VSCode Insiders, use this command:
-
-```shell
-code-insiders -v
-```
+If you are using VS Code Insiders, substitute `code-insiders` for `code`.
 
 You should get an output like:
 
 ```text
-1.27.0
-493869ee8e8a846b0855873886fc79d480d342de
-x64
+1.57.1
+507ce72a4466fbb27b715c3722558bb15afa9f48
+arm64
 ```
 
-If VSCode is not on your path, you will get a message like
+If VS Code is not on your path, you will get a message like:
 
 ```text
 code: The term 'code' is not recognized as the name of a cmdlet, ...
 ```
 
-in this case, use the file menu in VSCode and choose `Help`>`About`
-(or `Code`>`About Visual Studio Code` on macOS) to get version information.
+In this case, use the file menu in VS Code and choose `Help` > `About` (or `Code` > `About
+Visual Studio Code` on macOS) to get version information.
 
 ### PowerShell extension version
 
-[Your installed PowerShell Extension version] can similarly be found with:
+[Your installed PowerShell Extension version][] can similarly be found with:
 
-```shell
-code --list-extensions --show-versions
-```
-
-With VSCode Insiders:
-
-```shell
-code-insiders --list-extensions --show-versions
+```powershell
+code --list-extensions --show-versions | Select-String powershell
 ```
 
 You should get an output like:
 
 ```text
-DavidAnson.vscode-markdownlint@0.20.0
-eamodio.gitlens@8.5.6
-EditorConfig.EditorConfig@0.12.4
-jchannon.csharpextensions@1.3.0
-k--kato.docomment@0.1.2
-ms-vscode.cpptools@0.18.1
-ms-dotnettools.csharp@1.12.13
-ms-vscode.PowerShell@2.0.0
-twxs.cmake@0.0.17
-vscodevim.vim@0.16.5
+ms-vscode.powershell@2021.8.0
 ```
 
-If VSCode isn't on your path use the [Command Palette]
-(<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>) to enter
-`Extensions: Show Installed Extensions` and list your extensions.
+If VS Code isn't on your path, use the [Command Palette][]
+(<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>) to run `Extensions: Show Installed
+Extensions` and list your extensions.
 
 ### Editor Services version
 
-To get the [PowerShell Editor Services] version, in the Integrated
-Console, enter:
+To get the [PowerShell Editor Services][] version, in the Extension Terminal, enter:
 
 ```powershell
 > $psEditor.EditorServicesVersion
@@ -369,18 +368,20 @@ Major  Minor  Build  Revision
 
 ### PowerShell version table
 
-You can get [your PowerShell version table] from the Integrated Console:
+You can get [your PowerShell version table][] from the Extension Terminal through the
+variable `$PSVersionTable`:
 
 ```powershell
-> $PSVersionTable
+PS> $PSVersionTable
+
 Name                           Value
 ----                           -----
-PSVersion                      6.1.0
+PSVersion                      7.1.3
 PSEdition                      Core
-GitCommitId                    6.1.0
-OS                             Microsoft Windows 10.0.18242
-Platform                       Win32NT
-PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
+GitCommitId                    7.1.3
+OS                             Darwin 20.4.0 Darwin Kernel
+Platform                       Unix
+PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
 PSRemotingProtocolVersion      2.3
 SerializationVersion           1.1.0.1
 WSManStackVersion              3.0
@@ -388,20 +389,9 @@ WSManStackVersion              3.0
 
 ### Operating system information
 
-- Windows - all needed information should already be in the `$PSVersionTable`
-- macOS
-  - Your macOS version (e.g. High Sierra 10.13.6)
-- Linux
-  - `uname -a`
-  - Your distro and version (usually `lsb_release -a` is the best here)
-
-### Note on security
-
-If you believe there is a security vulnerability in the [PowerShell Extension]
-(or in [PowerShell Editor Services]), it **must** be reported directly to
-secure@microsoft.com to allow for [Coordinated Vulnerability Disclosure].
-**Only** open an issue if secure@microsoft.com has confirmed that filing
-an issue on GitHub is appropriate.
+* Windows: all needed information should already be in the `$PSVersionTable`.
+* macOS: your macOS version (e.g. High Sierra 10.13.6).
+* Linux: Use `uname -a` and and `lsb_release -a`.
 
 [Editor Syntax]: https://github.com/PowerShell/EditorSyntax
 [PowerShell Editor Services]: https://github.com/PowerShell/PowerShellEditorServices
@@ -409,41 +399,37 @@ an issue on GitHub is appropriate.
 [PSScriptAnalyzer]: https://github.com/PowerShell/PSScriptAnalyzer
 
 [Command Palette]: https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette
-[Coordinated Vulnerability Disclosure]: https://technet.microsoft.com/security/dn467923
-[custom host]: https://docs.microsoft.com/en-us/powershell/developer/hosting/custom-host-samples
 [dynamic scope]: http://ig2600.blogspot.com/2010/01/powershell-is-dynamically-scoped-and.html
+[Electron]: https://github.com/Microsoft/vscode/issues/42356
 [existing issues]: https://github.com/PowerShell/vscode-powershell/issues
 [formally undecidable]: https://en.wikipedia.org/wiki/Undecidable_problem
+[ISE compatibility doc]: https://docs.microsoft.com/powershell/scripting/components/vscode/how-to-replicate-the-ise-experience-in-vscode
+[language status item API]: https://code.visualstudio.com/updates/v1_65#_language-status-items
 [lexical scope]: https://stackoverflow.com/questions/1047454/what-is-lexical-scope
 [look there]: https://github.com/PowerShell/PowerShellEditorServices/issues
 [more information]: #providing-information-about-your-environment
-[open an issue]: https://github.com/PowerShell/vscode-powershell/issues/new/choose
-[open a new issue]: #opening-a-new-issue
+[open a new issue]: https://github.com/PowerShell/vscode-powershell/issues/new/choose
 [open an issue there]: https://github.com/PowerShell/PSScriptAnalyzer/issues/new/choose
-[open an issue on us on GitHub]: https://github.com/PowerShell/vscode-powershell/issues/new/choose
-[Reporting Problems]: ../README.md#reporting-problems
+[PowerShell 7.4 LTS]: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4
 [semantic highlighting]: https://code.visualstudio.com/api/language-extensions/semantic-highlight-guide
 [tackling an issue]: ./development.md
 [v2021.2.2]: https://github.com/PowerShell/vscode-powershell/releases/tag/v2021.2.2
-[v2021.5.1]: https://github.com/PowerShell/vscode-powershell/releases/tag/v2021.5.1
-[VSCode issue]: https://github.com/Microsoft/vscode/issues/42356
-[VSCode Settings]: https://code.visualstudio.com/docs/getstarted/settings
-[will break this compatibility]: https://github.com/PowerShell/vscode-powershell/issues/1310
+[VS Code Settings]: https://code.visualstudio.com/docs/getstarted/settings
+[WMF 5.1]: https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/setup/install-configure
+[dotnet-framework]: https://dotnet.microsoft.com/en-us/download/dotnet-framework
 [word separators]: https://stackoverflow.com/questions/31632351/visual-studio-code-customizing-word-separators
 [Your installed PowerShell Extension version]: https://code.visualstudio.com/docs/editor/extension-gallery#_list-installed-extensions
 [your PowerShell version table]: http://www.powertheshell.com/topic/learnpowershell/firststeps/psversion/
-[Your VSCode version]: https://code.visualstudio.com/docs/supporting/FAQ#_how-do-i-find-the-vs-code-version
+[Your VS Code version]: https://code.visualstudio.com/docs/supporting/FAQ#_how-do-i-find-the-vs-code-version
 
-[#3]: https://github.com/PowerShell/vscode-powershell/issues/3
 [#25]: https://github.com/PowerShell/vscode-powershell/issues/25
-[#140]: https://github.com/PowerShell/vscode-powershell/issues/140
+[#4474]: https://github.com/PowerShell/vscode-powershell/issues/4474
+[#3991]: https://github.com/PowerShell/vscode-powershell/issues/3991
 [#261]: https://github.com/PowerShell/vscode-powershell/issues/261
 [#410 (comment)]: https://github.com/PowerShell/vscode-powershell/issues/410#issuecomment-397531817
-[#499]: https://github.com/PowerShell/vscode-powershell/issues/499
-[#535]: https://github.com/PowerShell/vscode-powershell/issues/535
-[#550]: https://github.com/PowerShell/vscode-powershell/issues/550
-[#647]: https://github.com/PowerShell/vscode-powershell/issues/647
 [#984]: https://github.com/PowerShell/vscode-powershell/issues/984
+[#2571]: https://github.com/PowerShell/vscode-powershell/issues/2572
 [#3221]: https://github.com/PowerShell/vscode-powershell/issues/3221#issuecomment-810563456
 [#3295]: https://github.com/PowerShell/vscode-powershell/issues/3295
-[#3378]: https://github.com/PowerShell/vscode-powershell/issues/3378
+[#3701]: https://github.com/PowerShell/vscode-powershell/issues/3701
+[#633]: https://github.com/PowerShell/vscode-powershell/issues/633
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000000..9ad447020d
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,50 @@
+import eslint from "@eslint/js";
+import eslintConfigPrettier from "eslint-config-prettier/flat";
+import tseslint from "typescript-eslint";
+
+export default tseslint.config(
+    eslint.configs.recommended,
+    tseslint.configs.strictTypeChecked,
+    tseslint.configs.stylisticTypeChecked,
+    eslintConfigPrettier,
+    {
+        languageOptions: {
+            parserOptions: {
+                projectService: true,
+                tsconfigRootDir: import.meta.dirname,
+            },
+        },
+        rules: {
+            "@typescript-eslint/explicit-function-return-type": "error",
+            "@typescript-eslint/no-empty-object-type": "off",
+            "@typescript-eslint/no-floating-promises": [
+                "error",
+                {
+                    ignoreVoid: true,
+                },
+            ],
+            "@typescript-eslint/no-non-null-assertion": "off",
+            "@typescript-eslint/no-require-imports": "off",
+            "@typescript-eslint/no-unused-vars": [
+                "error",
+                {
+                    argsIgnorePattern: "^_",
+                    destructuredArrayIgnorePattern: "^_",
+                },
+            ],
+            "@typescript-eslint/no-unsafe-argument": "off",
+            "@typescript-eslint/no-unsafe-assignment": "off",
+            "@typescript-eslint/no-unsafe-call": "off",
+            "@typescript-eslint/no-unsafe-member-access": "off",
+            "@typescript-eslint/no-unsafe-return": "off",
+            "@typescript-eslint/restrict-template-expressions": "off",
+            "@typescript-eslint/prefer-nullish-coalescing": [
+                "error",
+                {
+                    ignoreConditionalTests: true,
+                    ignoreMixedLogicalExpressions: true,
+                },
+            ],
+        },
+    },
+);
diff --git a/examples/.vscode/launch.json b/examples/.vscode/launch.json
index 88687248dd..310016412d 100644
--- a/examples/.vscode/launch.json
+++ b/examples/.vscode/launch.json
@@ -1,59 +1,59 @@
 {
-    "version": "0.2.0",
-    "configurations": [
-        {
-            "type": "PowerShell",
-            "request": "launch",
-            "name": "PowerShell Launch Current File",
-            "script": "${file}",
-            "args": [],
-            "cwd": "${file}"
-        },
-        {
-            "type": "PowerShell",
-            "request": "launch",
-            "name": "PowerShell Launch Current File in Temporary Console",
-            "script": "${file}",
-            "args": [],
-            "cwd": "${file}",
-            "createTemporaryIntegratedConsole": true
-        },
-        {
-            "type": "PowerShell",
-            "request": "launch",
-            "name": "PowerShell Launch Current File w/Args Prompt",
-            "script": "${file}",
-            "args": [ "${command:SpecifyScriptArgs}" ],
-            "cwd": "${file}"
-        },
-        {
-            "type": "PowerShell",
-            "request": "launch",
-            "name": "PowerShell Launch DebugTest.ps1",
-            "script": "${workspaceRoot}/DebugTest.ps1",
-            "args": ["-Count 55 -DelayMilliseconds 250"],
-            "cwd": "${workspaceRoot}"
-        },
-        {
-            "type": "PowerShell",
-            "request": "launch",
-            "name": "PowerShell Interactive Session",
-            "cwd": "${workspaceRoot}"
-        },
-        {
-            "type": "PowerShell",
-            "request": "launch",
-            "name": "PowerShell Pester Tests",
-            "script": "Invoke-Pester",
-            "args": [],
-            "cwd": "${workspaceRoot}"
-        },
-        {
-            "type": "PowerShell",
-            "request": "attach",
-            "name": "PowerShell Attach to Host Process",
-            "processId": "${command:PickPSHostProcess}",
-            "runspaceId": 1
-        }
-    ]
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "PowerShell",
+      "request": "launch",
+      "name": "PowerShell Launch Current File",
+      "script": "${file}",
+      "args": [],
+      "cwd": "${file}"
+    },
+    {
+      "type": "PowerShell",
+      "request": "launch",
+      "name": "PowerShell Launch Current File in Temporary Console",
+      "script": "${file}",
+      "args": [],
+      "cwd": "${file}",
+      "createTemporaryIntegratedConsole": true
+    },
+    {
+      "type": "PowerShell",
+      "request": "launch",
+      "name": "PowerShell Launch Current File w/Args Prompt",
+      "script": "${file}",
+      "args": ["${command:SpecifyScriptArgs}"],
+      "cwd": "${file}"
+    },
+    {
+      "type": "PowerShell",
+      "request": "launch",
+      "name": "PowerShell Launch DebugTest.ps1",
+      "script": "${workspaceRoot}/DebugTest.ps1",
+      "args": ["-Count 55 -DelayMilliseconds 250"],
+      "cwd": "${workspaceRoot}"
+    },
+    {
+      "type": "PowerShell",
+      "request": "launch",
+      "name": "PowerShell Interactive Session",
+      "cwd": "${workspaceRoot}"
+    },
+    {
+      "type": "PowerShell",
+      "request": "launch",
+      "name": "PowerShell Pester Tests",
+      "script": "Invoke-Pester",
+      "args": [],
+      "cwd": "${workspaceRoot}"
+    },
+    {
+      "type": "PowerShell",
+      "request": "attach",
+      "name": "PowerShell Attach to Host Process",
+      "processId": "${command:PickPSHostProcess}",
+      "runspaceId": 1
+    }
+  ]
 }
diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json
index b0dfef11b6..23c9990db9 100644
--- a/examples/.vscode/settings.json
+++ b/examples/.vscode/settings.json
@@ -1,6 +1,6 @@
 {
-    // Use a custom PowerShell Script Analyzer settings file for this workspace.
-    // Relative paths for this setting are always relative to the workspace root dir.
-    "powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1",
-    "files.defaultLanguage": "powershell"
+  // Use a custom PowerShell Script Analyzer settings file for this workspace.
+  // Relative paths for this setting are always relative to the workspace root dir.
+  "powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1",
+  "files.defaultLanguage": "powershell"
 }
diff --git a/examples/.vscode/tasks.json b/examples/.vscode/tasks.json
index 9c5bf45ce1..8ae38829cc 100644
--- a/examples/.vscode/tasks.json
+++ b/examples/.vscode/tasks.json
@@ -30,73 +30,60 @@
 // ${cwd} the task runner's current working directory on startup
 // ${lineNumber} the current selected line number in the active file
 {
-    "version": "2.0.0",
-    "windows": {
-        "options": {
-            "shell": {
-                "executable": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
-                "args": [
-                    "-NoProfile",
-                    "-ExecutionPolicy",
-                    "Bypass",
-                    "-Command"
-                ]
-            }
-        }
+  "version": "2.0.0",
+  "windows": {
+    "options": {
+      "shell": {
+        "executable": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+        "args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command"]
+      }
+    }
+  },
+  "linux": {
+    "options": {
+      "shell": {
+        "executable": "/usr/bin/pwsh",
+        "args": ["-NoProfile", "-Command"]
+      }
+    }
+  },
+  "osx": {
+    "options": {
+      "shell": {
+        "executable": "/usr/local/bin/pwsh",
+        "args": ["-NoProfile", "-Command"]
+      }
+    }
+  },
+  "tasks": [
+    {
+      "label": "Clean",
+      "type": "shell",
+      "command": "Invoke-PSake build.ps1 -taskList Clean"
     },
-    "linux": {
-        "options": {
-            "shell": {
-                "executable": "/usr/bin/pwsh",
-                "args": [
-                    "-NoProfile",
-                    "-Command"
-                ]
-            }
-        }
+    {
+      "label": "Build",
+      "type": "shell",
+      "command": "Invoke-PSake build.ps1 -taskList Build",
+      "group": {
+        "kind": "build",
+        "isDefault": true
+      }
     },
-    "osx": {
-        "options": {
-            "shell": {
-                "executable": "/usr/local/bin/pwsh",
-                "args": [
-                    "-NoProfile",
-                    "-Command"
-                ]
-            }
-        }
+    {
+      "label": "Test",
+      "type": "shell",
+      "command": "Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true}",
+      "group": {
+        "kind": "test",
+        "isDefault": true
+      },
+      "problemMatcher": ["$pester"]
     },
-    "tasks": [
-        {
-            "label": "Clean",
-            "type": "shell",
-            "command": "Invoke-PSake build.ps1 -taskList Clean"
-        },
-        {
-            "label": "Build",
-            "type": "shell",
-            "command": "Invoke-PSake build.ps1 -taskList Build",
-            "group": {
-                "kind": "build",
-                "isDefault": true
-            }
-        },
-        {
-            "label": "Test",
-            "type": "shell",
-            "command": "Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true}",
-            "group": {
-                "kind": "test",
-                "isDefault": true
-            },
-            "problemMatcher": [
-                "$pester"
-            ]
-        },
-        {
-            "label": "Publish",
-            "type": "shell",
-            "command": "Invoke-PSake build.ps1 -taskList Publish"
-        }
-    ]
+    {
+      "label": "Publish",
+      "type": "shell",
+      "command": "Invoke-PSake build.ps1 -taskList Publish"
+    }
+  ]
 }
diff --git a/examples/ChildDebugSessionAttach.ps1 b/examples/ChildDebugSessionAttach.ps1
new file mode 100644
index 0000000000..c06a57f2a7
--- /dev/null
+++ b/examples/ChildDebugSessionAttach.ps1
@@ -0,0 +1,22 @@
+# Example on how Start-DebugAttachSession can be used to attach to another
+# process. This launches a child process that runs ChildDebugSessionTarget.ps1
+# but it can be adapted to attach to any other PowerShell process that is
+# either already running or started like this example. To test this example,
+# add a breakpoint to ChildDebugSessionTarget.ps1, select the
+# 'PowerShell Launch Current File' configuration and press F5.
+
+$pipeName = "TestPipe-$(New-Guid)"
+$scriptPath = Join-Path -Path $PSScriptRoot -ChildPath 'ChildDebugSessionTarget.ps1'
+
+$procParams = @{
+    FilePath = 'pwsh'
+    ArgumentList = ('-CustomPipeName {0} -File "{1}" -WaitForAttach' -f $pipeName, $scriptPath)
+    PassThru = $true
+}
+$proc = Start-Process @procParams
+
+Start-DebugAttachSession -CustomPipeName $pipeName -RunspaceId 1
+
+# We need to ensure this debug session stays alive until the process exits. If
+# we exit early then the child debug session will also exit.
+$proc | Wait-Process
diff --git a/examples/ChildDebugSessionTarget.ps1 b/examples/ChildDebugSessionTarget.ps1
new file mode 100644
index 0000000000..ed4c9f2a6a
--- /dev/null
+++ b/examples/ChildDebugSessionTarget.ps1
@@ -0,0 +1,31 @@
+[CmdletBinding()]
+param (
+    [Parameter()]
+    [switch]
+    $WaitForAttach
+)
+
+if ($WaitForAttach) {
+    # For an attach request we need to wait for the debug pipe runspace to be
+    # opened before continuing. There is no builtin way to do this so we
+    # poll the runspace list until a new one is created.
+    $runspaces = Get-Runspace
+    while ($true) {
+        if (Get-Runspace | Where-Object { $_.Id -notin $runspaces.Id }) {
+            break
+        }
+        Start-Sleep -Seconds 1
+    }
+
+    # Windows PowerShell 5.1 will not sync breakpoints until the debugger has
+    # stopped at least once. We use Wait-Debugger to make this happen.
+    if ($PSVersionTable.PSVersion -lt '6.0') {
+        Wait-Debugger
+    }
+    else {
+        Start-Sleep -Seconds 1  # Give the debugger time to sync breakpoints
+    }
+}
+
+$processInfo = "This process is running with PID $PID and has runspace ID $([Runspace]::DefaultRunspace.Id)"
+Write-Host $processInfo  # Place breakpoint here
diff --git a/examples/ContentViewTest.ps1 b/examples/ContentViewTest.ps1
deleted file mode 100644
index 21055149d5..0000000000
--- a/examples/ContentViewTest.ps1
+++ /dev/null
@@ -1,8 +0,0 @@
-$params = @{
-    HtmlBodyContent = "Testing JavaScript and CSS paths..."
-    JavaScriptPaths = ".\Assets\script.js"
-    StyleSheetPaths = ".\Assets\style.css"
-}
-
-$view = New-VSCodeHtmlContentView -Title "Test View" -ShowInColumn Two
-Set-VSCodeHtmlContentView -View $view @params
\ No newline at end of file
diff --git a/examples/PSScriptAnalyzerSettings.psd1 b/examples/PSScriptAnalyzerSettings.psd1
index 31fccb78d4..0b2f42c88f 100644
--- a/examples/PSScriptAnalyzerSettings.psd1
+++ b/examples/PSScriptAnalyzerSettings.psd1
@@ -1,6 +1,6 @@
 # Use the PowerShell extension setting `powershell.scriptAnalysis.settingsPath` to get the current workspace
 # to use this PSScriptAnalyzerSettings.psd1 file to configure code analysis in Visual Studio Code.
-# This setting is configured in the workspace's `.vscode\settings.json`.
+# This setting is configured in the workspace's `.vscode/settings.json`.
 #
 # For more information on PSScriptAnalyzer settings see:
 # https://github.com/PowerShell/PSScriptAnalyzer/blob/master/README.md#settings-support-in-scriptanalyzer
@@ -11,7 +11,8 @@
     # Only diagnostic records of the specified severity will be generated.
     # Uncomment the following line if you only want Errors and Warnings but
     # not Information diagnostic records.
-    #Severity = @('Error','Warning')
+    #
+    # Severity = @('Error', 'Warning')
 
     # Analyze **only** the following rules. Use IncludeRules when you want
     # to invoke only a small subset of the default rules.
@@ -28,14 +29,16 @@
     # Do not analyze the following rules. Use ExcludeRules when you have
     # commented out the IncludeRules settings above and want to include all
     # the default rules except for those you exclude below.
-    # Note: if a rule is in both IncludeRules and ExcludeRules, the rule
+    # Note that if a rule is in both IncludeRules and ExcludeRules, the rule
     # will be excluded.
-    #ExcludeRules = @('PSAvoidUsingWriteHost')
+    #
+    # ExcludeRules = @('PSAvoidUsingWriteHost')
 
     # You can use rule configuration to configure rules that support it:
-    #Rules = @{
-    #    PSAvoidUsingCmdletAliases = @{
-    #        Whitelist = @("cd")
-    #    }
-    #}
+    #
+    # Rules = @{
+    #     PSAvoidUsingCmdletAliases = @{
+    #         AllowList = @("cd")
+    #     }
+    # }
 }
diff --git a/extension-dev.code-workspace b/extension-dev.code-workspace
deleted file mode 100644
index 722bac94df..0000000000
--- a/extension-dev.code-workspace
+++ /dev/null
@@ -1,238 +0,0 @@
-{
-  "folders": [
-    {
-      "name": "Client",
-      "path": "."
-    },
-    {
-      "name": "Server",
-      "path": "../PowerShellEditorServices"
-    }
-  ],
-  "extensions": {
-    "recommendations": [
-      "davidanson.vscode-markdownlint",
-      "editorconfig.editorconfig",
-      "josefpihrt-vscode.roslynator",
-      "ms-azure-devops.azure-pipelines",
-      "ms-dotnettools.csharp",
-      "ms-vscode.powershell-preview",
-      "ms-vscode.vscode-typescript-tslint-plugin",
-    ]
-  },
-  "settings": {
-    "editor.tabSize": 4,
-    "editor.insertSpaces": true,
-    "files.trimTrailingWhitespace": true,
-    "files.insertFinalNewline": true,
-    "files.associations": {
-      // Use JSONC instead of JSON because (1) that's how VS Code interprets
-      // snippet files, and (2) it enables better source documentation.
-      "**/snippets/*.json": "jsonc",
-      "**/.vsts-ci/**/*.yml": "azure-pipelines",
-    },
-    // Ignore the Markdown rule:
-    "markdownlint.config": {
-      "MD024": false // no-duplicate-header
-    },
-    "powershell.codeFormatting.autoCorrectAliases": true,
-    "powershell.codeFormatting.newLineAfterCloseBrace": false,
-    "powershell.codeFormatting.trimWhitespaceAroundPipe": true,
-    "powershell.codeFormatting.useCorrectCasing": true,
-    "powershell.codeFormatting.whitespaceBeforeOpenBrace": false,
-    "powershell.codeFormatting.whitespaceBetweenParameters": true,
-    "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline",
-    // Lock the TypeScript SDK path to the version we use
-    "typescript.tsdk": "Client/node_modules/typescript/lib"
-  },
-  "tasks": {
-    "version": "2.0.0",
-    "windows": {
-      "options": {
-        "shell": {
-          "executable": "pwsh.exe",
-          "args": [
-            "-NoProfile",
-            "-ExecutionPolicy",
-            "Bypass",
-            "-Command"
-          ]
-        }
-      }
-    },
-    "linux": {
-      "options": {
-        "shell": {
-          "executable": "pwsh",
-          "args": [
-            "-NoProfile",
-            "-Command"
-          ]
-        }
-      }
-    },
-    "osx": {
-      "options": {
-        "shell": {
-          "executable": "/usr/local/bin/pwsh",
-          "args": [
-            "-NoProfile",
-            "-Command"
-          ]
-        }
-      }
-    },
-    "tasks": [
-      {
-        "label": "Build",
-        "type": "shell",
-        "options": {
-          "cwd": "${workspaceFolder:Client}"
-        },
-        "command": "Invoke-Build Build",
-        "problemMatcher": [
-          "$msCompile",
-          "$tsc"
-        ],
-        "group": {
-          "kind": "build",
-          "isDefault": true
-        }
-      },
-      {
-        "label": "Test Client",
-        "type": "shell",
-        "options": {
-          "cwd": "${workspaceFolder:Client}"
-        },
-        "command": "Invoke-Build Test",
-        "problemMatcher": [
-          "$msCompile",
-          "$tsc"
-        ],
-        "group": {
-          "kind": "test",
-          "isDefault": true
-        }
-      },
-      {
-        "label": "Test Server",
-        "type": "shell",
-        "options": {
-          "cwd": "${workspaceFolder:Server}"
-        },
-        "problemMatcher": [
-          "$msCompile"
-        ],
-        "command": "Invoke-Build TestServerPS72",
-        "group": {
-          "kind": "test",
-          "isDefault": true
-        }
-      },
-      {
-        "label": "Invoke-Build Client",
-        "type": "shell",
-        "options": {
-          "cwd": "${workspaceFolder:Client}"
-        },
-        "command": "Invoke-Build ${input:clientBuildCommand}",
-        "group": "build"
-      },
-      {
-        "label": "Invoke-Build Server",
-        "type": "shell",
-        "options": {
-          "cwd": "${workspaceFolder:Server}"
-        },
-        "command": "Invoke-Build ${input:serverBuildCommand}",
-        "group": "build"
-      }
-    ],
-    "inputs": [
-      {
-        "type": "pickString",
-        "id": "clientBuildCommand",
-        "description": "Which Invoke-Build Client Task?",
-        "options": [
-          "Restore",
-          "Clean",
-          "Build",
-          "Test",
-          "Package"
-        ],
-        "default": "Clean"
-      },
-      {
-        "type": "pickString",
-        "id": "serverBuildCommand",
-        "description": "Which Invoke-Build Server Task?",
-        "options": [
-          "SetupDotNet",
-          "BinClean",
-          "Clean",
-          "Build",
-          "Test",
-          "TestServer",
-          "TestServerPS72",
-          "TestE2E",
-        ],
-        "default": "Clean"
-      }
-    ]
-  },
-  "launch": {
-    "version": "0.2.0",
-    "configurations": [
-      {
-        // https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
-        "name": "Attach to Editor Services",
-        "type": "coreclr",
-        "request": "attach",
-        "processId": "${command:pickProcess}",
-        "justMyCode": false,
-        "suppressJITOptimizations": true,
-        "symbolOptions": {
-          "searchPaths": [],
-          "searchMicrosoftSymbolServer": true,
-          "searchNuGetOrgSymbolServer": true
-        }
-      },
-      {
-        "name": "Launch Extension",
-        "type": "extensionHost",
-        "request": "launch",
-        "runtimeExecutable": "${execPath}",
-        "args": [
-          "--disable-extensions",
-          "--extensionDevelopmentPath=${workspaceFolder:Client}"
-        ],
-        "sourceMaps": true,
-        "outFiles": [
-          "${workspaceFolder:Client}/out/main.js"
-        ],
-        "preLaunchTask": "${defaultBuildTask}",
-      },
-      {
-        "name": "Launch Extension Tests",
-        "type": "extensionHost",
-        "request": "launch",
-        "runtimeExecutable": "${execPath}",
-        "args": [
-          // The tests require Code be opened with a workspace, which exists in
-          // `test`, but this has to be passed as a CLI argument, not just `cwd`.
-          "${workspaceFolder:Client}/test",
-          "--disableExtensions",
-          "--extensionDevelopmentPath=${workspaceFolder:Client}",
-          "--extensionTestsPath=${workspaceFolder:Client}/out/test/index.js",
-        ],
-        "sourceMaps": true,
-        "outFiles": [
-          "${workspaceFolder:Client}/out/test/**/*.js"
-        ],
-        "preLaunchTask": "${defaultBuildTask}",
-        "internalConsoleOptions": "openOnSessionStart"
-      }
-    ]
-  }
-}
diff --git a/media/pwsh.svg b/media/pwsh.svg
deleted file mode 100644
index 681704b769..0000000000
--- a/media/pwsh.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32px" height="32px">
-    <path style="line-height:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;block-progression:tb;isolation:auto;mix-blend-mode:normal" d="M 8.0683594 5 C 7.5985478 5 7.0740085 5.0706042 6.6347656 5.4277344 C 6.1955227 5.7848645 6.0182993 6.2800756 5.9160156 6.7441406 C 4.6319924 12.607247 3.3484294 18.470878 2.0664062 24.333984 L 2.0664062 24.335938 C 1.9318566 24.956936 1.9940452 25.635268 2.3847656 26.175781 C 2.7754858 26.716249 3.4591241 27 4.125 27 L 24 27 C 24.514455 27 25.07303 26.820004 25.447266 26.451172 C 25.821502 26.08234 25.979845 25.634726 26.072266 25.212891 L 26.072266 25.210938 C 27.361317 19.31975 28.647572 13.427473 29.931641 7.5351562 C 30.063187 6.9314661 30.019975 6.2444204 29.595703 5.7167969 C 29.171432 5.1891733 28.509634 5 27.896484 5 L 8.0683594 5 z M 8.0683594 7 L 27.896484 7 C 27.959617 7 27.96256 7.0043131 27.992188 7.0078125 C 27.989342 7.0385555 27.99271 7.0442762 27.978516 7.109375 C 26.694585 13.001058 25.406136 18.89439 24.117188 24.785156 L 24.119141 24.783203 C 24.076503 24.977811 24.040539 25.0106 24.050781 25.001953 C 24.038906 25.001318 24.043479 25 24 25 L 4.125 25 C 3.9368759 25 3.9881392 24.979396 4.0058594 25.003906 C 4.0234384 25.028226 3.9740033 24.976286 4.0195312 24.761719 L 4.0195312 24.759766 C 5.3013723 18.897546 6.5852999 13.036101 7.8691406 7.1738281 C 7.8913694 7.0729753 7.905601 7.0435266 7.9179688 7.0097656 C 7.9510846 7.0057327 7.9748357 7 8.0683594 7 z M 11.533203 7.984375 A 1.50015 1.50015 0 0 0 10.40625 10.525391 L 15.25 15.695312 L 7.6132812 21.291016 A 1.50015 1.50015 0 1 0 9.3867188 23.708984 L 18.386719 17.115234 A 1.50015 1.50015 0 0 0 18.59375 14.878906 L 12.59375 8.4746094 A 1.50015 1.50015 0 0 0 11.533203 7.984375 z M 15.5 21 A 1.50015 1.50015 0 1 0 15.5 24 L 19.5 24 A 1.50015 1.50015 0 1 0 19.5 21 L 15.5 21 z" font-weight="400" font-family="sans-serif" white-space="normal" overflow="visible"/>
-</svg>
diff --git a/media/resources/dark/ClosePanel.svg b/media/resources/dark/ClosePanel.svg
deleted file mode 100644
index 2feafe7c06..0000000000
--- a/media/resources/dark/ClosePanel.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="19" height="16" xmlns="http://www.w3.org/2000/svg">
-  <line id="LeftBorder"   stroke="#C5C5C5" x1="0.5"  y1="0"    x2="0.5"  y2="16"/>
-  <line id="RightBorder"  stroke="#C5C5C5" x1="18.5" y1="0"    x2="18.5" y2="16"/>
-  <line id="TopBorder"    stroke="#C5C5C5" x1="1"    y1="0.5"  x2="18"   y2="0.5"/>
-  <line id="BottomBorder" stroke="#C5C5C5" x1="1"    y1="15.5" x2="18"   y2="15.5"/>
-  <line id="HeaderBorder" stroke="#C5C5C5" x1="1"    y1="4.5"  x2="18"   y2="4.5"/>
-  <line id="FakeButton1"  stroke="#C5C5C5" x1="13"   y1="1"    x2="13"   y2="4"/>
-  <line id="FakeButton2"  stroke="#C5C5C5" x1="16"   y1="1"    x2="16"   y2="4"/>
-</svg>
\ No newline at end of file
diff --git a/media/resources/dark/MovePanelBottom.svg b/media/resources/dark/MovePanelBottom.svg
deleted file mode 100644
index 8284a0976d..0000000000
--- a/media/resources/dark/MovePanelBottom.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="19" height="16" xmlns="http://www.w3.org/2000/svg">
-  <line id="LeftBorder"     stroke="#C5C5C5" x1="0.5"  y1="0"    x2="0.5"  y2="16"/>
-  <line id="RightBorder"    stroke="#C5C5C5" x1="18.5" y1="0"    x2="18.5" y2="16"/>
-  <line id="TopBorder"      stroke="#C5C5C5" x1="1"    y1="0.5"  x2="18"   y2="0.5"/>
-  <line id="BottomBorder"   stroke="#C5C5C5" x1="1"    y1="15.5" x2="18"   y2="15.5"/>
-  <line id="HeaderBorder"   stroke="#C5C5C5" x1="1"    y1="4.5"  x2="18"   y2="4.5"/>
-  <line id="FakeButton1"    stroke="#C5C5C5" x1="13"   y1="1"    x2="13"   y2="4"/>
-  <line id="FakeButton2"    stroke="#C5C5C5" x1="16"   y1="1"    x2="16"   y2="4"/>
-  <line id="TerminalBorder" stroke="#C5C5C5" x1="1"    y1="10.5" x2="18"   y2="10.5"/>
-</svg>
\ No newline at end of file
diff --git a/media/resources/dark/MovePanelLeft.svg b/media/resources/dark/MovePanelLeft.svg
deleted file mode 100644
index d7f7797e4c..0000000000
--- a/media/resources/dark/MovePanelLeft.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="19" height="16" xmlns="http://www.w3.org/2000/svg">
-  <line id="LeftBorder"     stroke="#C5C5C5" x1="0.5"  y1="0"    x2="0.5"  y2="16"/>
-  <line id="RightBorder"    stroke="#C5C5C5" x1="18.5" y1="0"    x2="18.5" y2="16"/>
-  <line id="TopBorder"      stroke="#C5C5C5" x1="1"    y1="0.5"  x2="18"   y2="0.5"/>
-  <line id="BottomBorder"   stroke="#C5C5C5" x1="1"    y1="15.5" x2="18"   y2="15.5"/>
-  <line id="HeaderBorder"   stroke="#C5C5C5" x1="1"    y1="4.5"  x2="18"   y2="4.5"/>
-  <line id="FakeButton1"    stroke="#C5C5C5" x1="13"   y1="1"    x2="13"   y2="4"/>
-  <line id="FakeButton2"    stroke="#C5C5C5" x1="16"   y1="1"    x2="16"   y2="4"/>
-  <line id="TerminalBorder" stroke="#C5C5C5" x1="9.5"  y1="5"    x2="9.5"  y2="15"/>
-</svg>
\ No newline at end of file
diff --git a/media/resources/dark/pencil.svg b/media/resources/dark/pencil.svg
deleted file mode 100644
index e4ba2d45a8..0000000000
--- a/media/resources/dark/pencil.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="14"
-   height="16"
-   viewBox="0 0 14 16"
-   version="1.1"
-   id="svg3715"
-   sodipodi:docname="pencil.svg"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)">
-  <metadata
-     id="metadata3721">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs3719" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="1137"
-     id="namedview3717"
-     showgrid="false"
-     inkscape:zoom="60.5"
-     inkscape:cx="4.3140496"
-     inkscape:cy="8"
-     inkscape:window-x="-8"
-     inkscape:window-y="-8"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg3715" />
-  <path
-     d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"
-     id="path3713"
-     fill-rule="evenodd"
-     style="opacity:1;stroke:none;stroke-opacity:1;fill:#fffffa;fill-opacity:1" />
-</svg>
diff --git a/media/resources/dark/play.svg b/media/resources/dark/play.svg
deleted file mode 100644
index 464ef5147e..0000000000
--- a/media/resources/dark/play.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="19" viewBox="0 0 16 19" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M7 6V18.4805L15.9146 12.2402L7 6ZM14.1809 12.2402L7.995 16.5684V7.91209L14.1809 12.2402Z" fill="#C5C5C5"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M0 1L1 0H7L7.70711 0.292893L10.7071 3.29289L11 4V8.80841V10L8 7.5V14H1L0 13L0 1ZM1 1V13H8V7.5L10 9.30203V8.10005V4L7 1H1Z" fill="#C5C5C5"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M6 1H7V4H10.5V5H6V1Z" fill="#C5C5C5"/>
-</svg>
diff --git a/media/resources/dark/question.svg b/media/resources/dark/question.svg
deleted file mode 100644
index b803dbf391..0000000000
--- a/media/resources/dark/question.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="14"
-   height="16"
-   viewBox="0 0 14 16"
-   version="1.1"
-   id="svg5984"
-   sodipodi:docname="question.svg"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)">
-  <metadata
-     id="metadata5990">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs5988" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="1137"
-     id="namedview5986"
-     showgrid="false"
-     inkscape:zoom="14.75"
-     inkscape:cx="-4.0169492"
-     inkscape:cy="8"
-     inkscape:window-x="-8"
-     inkscape:window-y="-8"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg5984" />
-  <path
-     fill-rule="evenodd"
-     d="M6 10h2v2H6v-2zm4-3.5C10 8.64 8 9 8 9H6c0-.55.45-1 1-1h.5c.28 0 .5-.22.5-.5v-1c0-.28-.22-.5-.5-.5h-1c-.28 0-.5.22-.5.5V7H4c0-1.5 1.5-3 3-3s3 1 3 2.5zM7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7z"
-     id="path5982"
-     style="stroke:none;stroke-opacity:1;fill:#ffffff;fill-opacity:1" />
-</svg>
diff --git a/media/resources/dark/run.svg b/media/resources/dark/run.svg
deleted file mode 100644
index 8b0a58eca9..0000000000
--- a/media/resources/dark/run.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2V14.4805L12.9146 8.24024L4 2ZM11.1809 8.24024L4.995 12.5684V3.91209L11.1809 8.24024Z" fill="#C5C5C5"/>
-</svg>
diff --git a/media/resources/dark/sync.svg b/media/resources/dark/sync.svg
deleted file mode 100644
index f3d5a1bc00..0000000000
--- a/media/resources/dark/sync.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="12"
-   height="16"
-   viewBox="0 0 12 16"
-   version="1.1"
-   id="svg6547"
-   sodipodi:docname="sync.svg"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)">
-  <metadata
-     id="metadata6553">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs6551" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="1137"
-     id="namedview6549"
-     showgrid="false"
-     inkscape:zoom="14.75"
-     inkscape:cx="-5.0169492"
-     inkscape:cy="8"
-     inkscape:window-x="-8"
-     inkscape:window-y="-8"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg6547" />
-  <path
-     fill-rule="evenodd"
-     d="M10.24 7.4a4.15 4.15 0 0 1-1.2 3.6 4.346 4.346 0 0 1-5.41.54L4.8 10.4.5 9.8l.6 4.2 1.31-1.26c2.36 1.74 5.7 1.57 7.84-.54a5.876 5.876 0 0 0 1.74-4.46l-1.75-.34zM2.96 5a4.346 4.346 0 0 1 5.41-.54L7.2 5.6l4.3.6-.6-4.2-1.31 1.26c-2.36-1.74-5.7-1.57-7.85.54C.5 5.03-.06 6.65.01 8.26l1.75.35A4.17 4.17 0 0 1 2.96 5z"
-     id="path6545"
-     style="fill:#ffffff;fill-opacity:1" />
-</svg>
diff --git a/media/resources/light/ClosePanel.svg b/media/resources/light/ClosePanel.svg
deleted file mode 100644
index 5db309662e..0000000000
--- a/media/resources/light/ClosePanel.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-<svg width="19" height="16" xmlns="http://www.w3.org/2000/svg">
-  <line id="LeftBorder"   stroke="#000000" x1="0.5"  y1="0"    x2="0.5"  y2="16"/>
-  <line id="RightBorder"  stroke="#000000" x1="18.5" y1="0"    x2="18.5" y2="16"/>
-  <line id="TopBorder"    stroke="#000000" x1="1"    y1="0.5"  x2="18"   y2="0.5"/>
-  <line id="BottomBorder" stroke="#000000" x1="1"    y1="15.5" x2="18"   y2="15.5"/>
-  <line id="HeaderBorder" stroke="#000000" x1="1"    y1="4.5"  x2="18"   y2="4.5"/>
-  <line id="FakeButton1"  stroke="#000000" x1="13"   y1="1"    x2="13"   y2="4"/>
-  <line id="FakeButton2"  stroke="#000000" x1="16"   y1="1"    x2="16"   y2="4"/>
-</svg>
\ No newline at end of file
diff --git a/media/resources/light/MovePanelBottom.svg b/media/resources/light/MovePanelBottom.svg
deleted file mode 100644
index 739c933e30..0000000000
--- a/media/resources/light/MovePanelBottom.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="19" height="16" xmlns="http://www.w3.org/2000/svg">
-  <line id="LeftBorder"     stroke="#000000" x1="0.5"  y1="0"    x2="0.5"  y2="16"/>
-  <line id="RightBorder"    stroke="#000000" x1="18.5" y1="0"    x2="18.5" y2="16"/>
-  <line id="TopBorder"      stroke="#000000" x1="1"    y1="0.5"  x2="18"   y2="0.5"/>
-  <line id="BottomBorder"   stroke="#000000" x1="1"    y1="15.5" x2="18"   y2="15.5"/>
-  <line id="HeaderBorder"   stroke="#000000" x1="1"    y1="4.5"  x2="18"   y2="4.5"/>
-  <line id="FakeButton1"    stroke="#000000" x1="13"   y1="1"    x2="13"   y2="4"/>
-  <line id="FakeButton2"    stroke="#000000" x1="16"   y1="1"    x2="16"   y2="4"/>
-  <line id="TerminalBorder" stroke="#000000" x1="1"    y1="10.5" x2="18"   y2="10.5"/>
-</svg>
\ No newline at end of file
diff --git a/media/resources/light/MovePanelLeft.svg b/media/resources/light/MovePanelLeft.svg
deleted file mode 100644
index 06c569437b..0000000000
--- a/media/resources/light/MovePanelLeft.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<svg width="19" height="16" xmlns="http://www.w3.org/2000/svg">
-  <line id="LeftBorder"     stroke="#000000" x1="0.5"  y1="0"    x2="0.5"  y2="16"/>
-  <line id="RightBorder"    stroke="#000000" x1="18.5" y1="0"    x2="18.5" y2="16"/>
-  <line id="TopBorder"      stroke="#000000" x1="1"    y1="0.5"  x2="18"   y2="0.5"/>
-  <line id="BottomBorder"   stroke="#000000" x1="1"    y1="15.5" x2="18"   y2="15.5"/>
-  <line id="HeaderBorder"   stroke="#000000" x1="1"    y1="4.5"  x2="18"   y2="4.5"/>
-  <line id="FakeButton1"    stroke="#000000" x1="13"   y1="1"    x2="13"   y2="4"/>
-  <line id="FakeButton2"    stroke="#000000" x1="16"   y1="1"    x2="16"   y2="4"/>
-  <line id="TerminalBorder" stroke="#000000" x1="9.5"  y1="5"    x2="9.5"  y2="15"/>
-</svg>
\ No newline at end of file
diff --git a/media/resources/light/pencil.svg b/media/resources/light/pencil.svg
deleted file mode 100644
index 8702f4dcec..0000000000
--- a/media/resources/light/pencil.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
\ No newline at end of file
diff --git a/media/resources/light/play.svg b/media/resources/light/play.svg
deleted file mode 100644
index 6f479653b5..0000000000
--- a/media/resources/light/play.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="19" viewBox="0 0 16 19" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M7 6V18.4805L15.9146 12.2402L7 6ZM14.1809 12.2402L7.995 16.5684V7.91209L14.1809 12.2402Z" fill="#424242"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M0 1L1 0H7L7.70711 0.292893L10.7071 3.29289L11 4V8.80841V10L8 7.5V14H1L0 13L0 1ZM1 1V13H8V7.5L10 9.30203V8.10005V4L7 1H1Z" fill="#424242"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M6 1H7V4H10.5V5H6V1Z" fill="#424242"/>
-</svg>
diff --git a/media/resources/light/question.svg b/media/resources/light/question.svg
deleted file mode 100644
index a6fc75310c..0000000000
--- a/media/resources/light/question.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6 10h2v2H6v-2zm4-3.5C10 8.64 8 9 8 9H6c0-.55.45-1 1-1h.5c.28 0 .5-.22.5-.5v-1c0-.28-.22-.5-.5-.5h-1c-.28 0-.5.22-.5.5V7H4c0-1.5 1.5-3 3-3s3 1 3 2.5zM7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7z"/></svg>
\ No newline at end of file
diff --git a/media/resources/light/run.svg b/media/resources/light/run.svg
deleted file mode 100644
index 2563bfa114..0000000000
--- a/media/resources/light/run.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M4 2V14.4805L12.9146 8.24024L4 2ZM11.1809 8.24024L4.995 12.5684V3.91209L11.1809 8.24024Z" fill="#424242"/>
-</svg>
diff --git a/media/resources/light/sync.svg b/media/resources/light/sync.svg
deleted file mode 100644
index 411f549b58..0000000000
--- a/media/resources/light/sync.svg
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="12"
-   height="16"
-   viewBox="0 0 12 16"
-   version="1.1"
-   id="svg6547"
-   sodipodi:docname="sync.svg"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)">
-  <metadata
-     id="metadata6553">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs6551" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1920"
-     inkscape:window-height="1137"
-     id="namedview6549"
-     showgrid="false"
-     inkscape:zoom="14.75"
-     inkscape:cx="-5.0169492"
-     inkscape:cy="8"
-     inkscape:window-x="-8"
-     inkscape:window-y="-8"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg6547" />
-  <path
-     fill-rule="evenodd"
-     d="M10.24 7.4a4.15 4.15 0 0 1-1.2 3.6 4.346 4.346 0 0 1-5.41.54L4.8 10.4.5 9.8l.6 4.2 1.31-1.26c2.36 1.74 5.7 1.57 7.84-.54a5.876 5.876 0 0 0 1.74-4.46l-1.75-.34zM2.96 5a4.346 4.346 0 0 1 5.41-.54L7.2 5.6l4.3.6-.6-4.2-1.31 1.26c-2.36-1.74-5.7-1.57-7.85.54C.5 5.03-.06 6.65.01 8.26l1.75.35A4.17 4.17 0 0 1 2.96 5z"
-     id="path6545"
-     style="fill:#000000;fill-opacity:1" />
-</svg>
diff --git a/media/walkthrough.md b/media/walkthrough.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/package-lock.json b/package-lock.json
index adf892efe6..523f0587e1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,2194 +1,2300 @@
 {
-  "name": "powershell-preview",
-  "version": "2022.2.1",
-  "lockfileVersion": 2,
+  "name": "powershell",
+  "version": "2025.2.0",
+  "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
-      "name": "powershell-preview",
-      "version": "2022.2.1",
+      "name": "powershell",
+      "version": "2025.2.0",
       "license": "SEE LICENSE IN LICENSE.txt",
       "dependencies": {
-        "node-fetch": "~2.6.7",
-        "semver": "~7.3.5",
-        "uuid": "~8.3.2",
-        "vscode-extension-telemetry": "~0.4.5",
-        "vscode-languageclient": "~7.0.0",
-        "vscode-languageserver-protocol": "~3.16.0"
+        "@vscode/extension-telemetry": "^0.9.9",
+        "semver": "^7.7.2",
+        "untildify": "^4.0.0",
+        "uuid": "^9.0.1",
+        "vscode-languageclient": "^9.0.1",
+        "vscode-languageserver-protocol": "^3.17.5"
       },
       "devDependencies": {
-        "@types/glob": "~7.2.0",
-        "@types/mocha": "~9.1.0",
-        "@types/mock-fs": "~4.13.1",
-        "@types/node": "~14.17.4",
-        "@types/node-fetch": "~2.6.1",
-        "@types/rewire": "~2.5.28",
-        "@types/semver": "~7.3.9",
-        "@types/sinon": "~10.0.11",
-        "@types/uuid": "~8.3.4",
-        "@types/vscode": "~1.56.0",
-        "@vscode/test-electron": "~2.1.2",
-        "esbuild": "^0.14.23",
-        "glob": "^7.2.0",
-        "mocha": "~9.2.1",
-        "mocha-multi-reporters": "~1.5.1",
-        "mock-fs": "~5.1.2",
-        "rewire": "~6.0.0",
-        "sinon": "~13.0.1",
-        "tslint": "~6.1.3",
-        "typescript": "~4.5.5",
-        "vsce": "~2.6.7"
-      },
-      "engines": {
-        "vscode": "^1.56.0"
-      }
-    },
-    "node_modules/@babel/code-frame": {
-      "version": "7.16.0",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
-      "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==",
-      "dev": true,
-      "dependencies": {
-        "@babel/highlight": "^7.16.0"
+        "@vscode/vsce": "^3.6.0",
+        "esbuild": "^0.25.8"
       },
       "engines": {
-        "node": ">=6.9.0"
-      }
+        "vscode": "^1.101.0"
+      },
+      "optionalDependencies": {
+        "@eslint/js": "^9.26.0",
+        "@types/mock-fs": "^4.13.4",
+        "@types/node": "^22.16.5",
+        "@types/semver": "^7.7.0",
+        "@types/sinon": "^17.0.4",
+        "@types/ungap__structured-clone": "^1.2.0",
+        "@types/uuid": "^9.0.8",
+        "@types/vscode": "~1.101.0",
+        "@ungap/structured-clone": "^1.3.0",
+        "@vscode/debugprotocol": "^1.68.0",
+        "@vscode/test-cli": "^0.0.10",
+        "@vscode/test-electron": "^2.5.2",
+        "esbuild-register": "^3.6.0",
+        "eslint": "^9.31.0",
+        "eslint-config-prettier": "^10.1.8",
+        "mock-fs": "^5.5.0",
+        "prettier": "^3.6.2",
+        "prettier-plugin-organize-imports": "^4.2.0",
+        "sinon": "^19.0.5",
+        "typescript": "^5.8.3",
+        "typescript-eslint": "^8.38.0"
+      }
+    },
+    "node_modules/@azu/format-text": {
+      "version": "1.0.2",
+      "integrity": "sha1-q9RtqyQi4xK9G/428NQnq2A5gl0=",
+      "dev": true,
+      "license": "BSD-3-Clause"
     },
-    "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.15.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
-      "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
+    "node_modules/@azu/style-format": {
+      "version": "1.0.1",
+      "integrity": "sha1-s2Q68MX+6dU+aal8g1xAS9yA95I=",
       "dev": true,
-      "engines": {
-        "node": ">=6.9.0"
+      "license": "WTFPL",
+      "dependencies": {
+        "@azu/format-text": "^1.0.1"
       }
     },
-    "node_modules/@babel/highlight": {
-      "version": "7.16.0",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz",
-      "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==",
+    "node_modules/@azure/abort-controller": {
+      "version": "2.1.2",
+      "integrity": "sha1-Qv4MyrI4QdmQWBLFjxCC0neEVm0=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.15.7",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
+        "tslib": "^2.6.2"
       },
       "engines": {
-        "node": ">=6.9.0"
+        "node": ">=18.0.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+    "node_modules/@azure/core-auth": {
+      "version": "1.10.0",
+      "integrity": "sha1-aNunA2CA4dnVaZxOSCFKt5b6c60=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "color-convert": "^1.9.0"
+        "@azure/abort-controller": "^2.0.0",
+        "@azure/core-util": "^1.11.0",
+        "tslib": "^2.6.2"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+    "node_modules/@azure/core-client": {
+      "version": "1.10.0",
+      "integrity": "sha1-n07JyJpjUWknhArmIMYOgRoLVKM=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
+        "@azure/abort-controller": "^2.0.0",
+        "@azure/core-auth": "^1.4.0",
+        "@azure/core-rest-pipeline": "^1.20.0",
+        "@azure/core-tracing": "^1.0.0",
+        "@azure/core-util": "^1.6.1",
+        "@azure/logger": "^1.0.0",
+        "tslib": "^2.6.2"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+    "node_modules/@azure/core-rest-pipeline": {
+      "version": "1.22.0",
+      "integrity": "sha1-duRKdQk6L0d/xUuE9GBJ3CzmWAA=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "color-name": "1.1.3"
+        "@azure/abort-controller": "^2.0.0",
+        "@azure/core-auth": "^1.8.0",
+        "@azure/core-tracing": "^1.0.1",
+        "@azure/core-util": "^1.11.0",
+        "@azure/logger": "^1.0.0",
+        "@typespec/ts-http-runtime": "^0.3.0",
+        "tslib": "^2.6.2"
+      },
+      "engines": {
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+    "node_modules/@azure/core-tracing": {
+      "version": "1.3.0",
+      "integrity": "sha1-NBFT9bKSdTnriYV3ZR7kjOmN2iU=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.6.2"
+      },
       "engines": {
-        "node": ">=0.8.0"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+    "node_modules/@azure/core-util": {
+      "version": "1.13.0",
+      "integrity": "sha1-/Cg0/FHh4rt0twwoS0D4JNhnQio=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@azure/abort-controller": "^2.0.0",
+        "@typespec/ts-http-runtime": "^0.3.0",
+        "tslib": "^2.6.2"
+      },
       "engines": {
-        "node": ">=4"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+    "node_modules/@azure/identity": {
+      "version": "4.10.2",
+      "integrity": "sha1-ZgnOOYgk/wu1PxrRBDqfHMk+Vrg=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "has-flag": "^3.0.0"
+        "@azure/abort-controller": "^2.0.0",
+        "@azure/core-auth": "^1.9.0",
+        "@azure/core-client": "^1.9.2",
+        "@azure/core-rest-pipeline": "^1.17.0",
+        "@azure/core-tracing": "^1.0.0",
+        "@azure/core-util": "^1.11.0",
+        "@azure/logger": "^1.0.0",
+        "@azure/msal-browser": "^4.2.0",
+        "@azure/msal-node": "^3.5.0",
+        "open": "^10.1.0",
+        "tslib": "^2.2.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@eslint/eslintrc": {
-      "version": "0.4.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
-      "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+    "node_modules/@azure/logger": {
+      "version": "1.3.0",
+      "integrity": "sha1-VQHPhdT1JjBgKozHXfdlaMlpqCc=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "ajv": "^6.12.4",
-        "debug": "^4.1.1",
-        "espree": "^7.3.0",
-        "globals": "^13.9.0",
-        "ignore": "^4.0.6",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
-        "strip-json-comments": "^3.1.1"
+        "@typespec/ts-http-runtime": "^0.3.0",
+        "tslib": "^2.6.2"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/@eslint/eslintrc/node_modules/argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+    "node_modules/@azure/msal-browser": {
+      "version": "4.16.0",
+      "integrity": "sha1-FbFWf2hz9ksNQ2ti8QaM4B/H8JA=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "sprintf-js": "~1.0.2"
+        "@azure/msal-common": "15.9.0"
+      },
+      "engines": {
+        "node": ">=0.8.0"
       }
     },
-    "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+    "node_modules/@azure/msal-common": {
+      "version": "15.9.0",
+      "integrity": "sha1-SbYqeY3RtHtBDm5UD9NgCfHU0Y4=",
       "dev": true,
-      "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.0"
       }
     },
-    "node_modules/@humanwhocodes/config-array": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
-      "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+    "node_modules/@azure/msal-node": {
+      "version": "3.6.4",
+      "integrity": "sha1-k38ON+c9SN+2irjzpQOgzyGmUoU=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@humanwhocodes/object-schema": "^1.2.0",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "@azure/msal-common": "15.9.0",
+        "jsonwebtoken": "^9.0.0",
+        "uuid": "^8.3.0"
       },
       "engines": {
-        "node": ">=10.10.0"
+        "node": ">=16"
       }
     },
-    "node_modules/@humanwhocodes/object-schema": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-      "dev": true
-    },
-    "node_modules/@sinonjs/commons": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
-      "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+    "node_modules/@azure/msal-node/node_modules/uuid": {
+      "version": "8.3.2",
+      "integrity": "sha1-gNW1ztJxu5r2xEXyGhoExgbO++I=",
       "dev": true,
-      "dependencies": {
-        "type-detect": "4.0.8"
+      "license": "MIT",
+      "bin": {
+        "uuid": "dist/bin/uuid"
       }
     },
-    "node_modules/@sinonjs/fake-timers": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
-      "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
+    "node_modules/@babel/code-frame": {
+      "version": "7.27.1",
+      "integrity": "sha1-IA9xXmbVKiOyIalDVTSpHME61b4=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@sinonjs/commons": "^1.7.0"
+        "@babel/helper-validator-identifier": "^7.27.1",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
-    "node_modules/@sinonjs/samsam": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz",
-      "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==",
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.27.1",
+      "integrity": "sha1-pwVNzBRaln3U3I/uhFpXwTFsnfg=",
       "dev": true,
-      "dependencies": {
-        "@sinonjs/commons": "^1.6.0",
-        "lodash.get": "^4.4.2",
-        "type-detect": "^4.0.8"
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
-    "node_modules/@sinonjs/text-encoding": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
-      "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
-      "dev": true
+    "node_modules/@bcoe/v8-coverage": {
+      "version": "0.2.3",
+      "integrity": "sha1-daLotRy3WKdVPWgEpZMteqznXDk=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/@tootallnate/once": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
-      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
-      "dev": true,
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.25.8",
+      "integrity": "sha1-oUFJA7s4AnOC+F8D3aYGUFZ1dyc=",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
       "engines": {
-        "node": ">= 6"
+        "node": ">=18"
       }
     },
-    "node_modules/@types/glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
-      "dev": true,
-      "dependencies": {
-        "@types/minimatch": "*",
-        "@types/node": "*"
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.25.8",
+      "integrity": "sha1-lqjyypHGzSnqkLGvedg3Yci6AFk=",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/@types/minimatch": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
-      "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
-      "dev": true
-    },
-    "node_modules/@types/mocha": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz",
-      "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==",
-      "dev": true
-    },
-    "node_modules/@types/mock-fs": {
-      "version": "4.13.1",
-      "resolved": "https://registry.npmjs.org/@types/mock-fs/-/mock-fs-4.13.1.tgz",
-      "integrity": "sha512-m6nFAJ3lBSnqbvDZioawRvpLXSaPyn52Srf7OfzjubYbYX8MTUdIgDxQl0wEapm4m/pNYSd9TXocpQ0TvZFlYA==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-yFmZQInpdnIkJpiEBh+J2ub7UcY=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/@types/node": {
-      "version": "14.17.33",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.33.tgz",
-      "integrity": "sha512-noEeJ06zbn3lOh4gqe2v7NMGS33jrulfNqYFDjjEbhpDEHR5VTxgYNQSBqBlJIsBJW3uEYDgD6kvMnrrhGzq8g==",
-      "dev": true
-    },
-    "node_modules/@types/node-fetch": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
-      "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*",
-        "form-data": "^3.0.0"
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-o6YmxP7EoCSp+ox2ecOZlukpFvA=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/@types/rewire": {
-      "version": "2.5.28",
-      "resolved": "https://registry.npmjs.org/@types/rewire/-/rewire-2.5.28.tgz",
-      "integrity": "sha512-uD0j/AQOa5le7afuK+u+woi8jNKF1vf3DN0H7LCJhft/lNNibUr7VcAesdgtWfEKveZol3ZG1CJqwx2Bhrnl8w==",
-      "dev": true
-    },
-    "node_modules/@types/semver": {
-      "version": "7.3.9",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
-      "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==",
-      "dev": true
-    },
-    "node_modules/@types/sinon": {
-      "version": "10.0.11",
-      "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz",
-      "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==",
-      "dev": true,
-      "dependencies": {
-        "@types/sinonjs__fake-timers": "*"
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-peElLKKYPVZq8cDqOa3tZXNvxm0=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/@types/sinonjs__fake-timers": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
-      "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
-      "dev": true
-    },
-    "node_modules/@types/uuid": {
-      "version": "8.3.4",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
-      "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
-      "dev": true
-    },
-    "node_modules/@types/vscode": {
-      "version": "1.56.0",
-      "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.56.0.tgz",
-      "integrity": "sha512-Q5VmQxOx+L1Y6lIJiGcJzwcyV3pQo/eiW8P+7sNLhFI16tJCwtua2DLjHRcpjbCLNVYpQM73kzfFo1Z0HyP9eQ==",
-      "dev": true
-    },
-    "node_modules/@ungap/promise-all-settled": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-      "dev": true
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-UnGw3yuxLOjfiGcEv90cfMAThdI=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
     },
-    "node_modules/@vscode/test-electron": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.2.tgz",
-      "integrity": "sha512-INjJ0YA9RgR1B/xBl8P4sxww4Dy2996f4Xn5oGTFfC0c2Mm45y/1Id8xmfuoba6tR5i8zZaUIHfEYWe7Rt4uZA==",
-      "dev": true,
-      "dependencies": {
-        "http-proxy-agent": "^4.0.1",
-        "https-proxy-agent": "^5.0.0",
-        "rimraf": "^3.0.2",
-        "unzipper": "^0.10.11"
-      },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-0KDn/fGXM7i7FWa4HfGqC7fkato=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
       "engines": {
-        "node": ">=8.9.3"
+        "node": ">=18"
       }
     },
-    "node_modules/acorn": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
-      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
-      "dev": true,
-      "bin": {
-        "acorn": "bin/acorn"
-      },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-Leiy4ImdCPHLHvMSjhWWFufoU0M=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">=18"
       }
     },
-    "node_modules/acorn-jsx": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
-      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true,
-      "peerDependencies": {
-        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.25.8",
+      "integrity": "sha1-zNnikcJM2NkULYGdRj4ucgDSWxk=",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/agent-base": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "dev": true,
-      "dependencies": {
-        "debug": "4"
-      },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-pCCe+twMKXVxZFhISk6QwjfEiuk=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
-        "node": ">= 6.0.0"
+        "node": ">=18"
       }
     },
-    "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.25.8",
+      "integrity": "sha1-AGrRU20MKyj7OhzwtTvLhar5LE0=",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/ansi-colors": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-      "dev": true,
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.25.8",
+      "integrity": "sha1-Ens/v7LC4IsTl+mFky9xjwmo9cQ=",
+      "cpu": [
+        "loong64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
-        "node": ">=6"
+        "node": ">=18"
       }
     },
-    "node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.25.8",
+      "integrity": "sha1-g30USVF3keP6fYJnWi0G2fVss0A=",
+      "cpu": [
+        "mips64el"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
-        "node": ">=8"
+        "node": ">=18"
       }
     },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.25.8",
+      "integrity": "sha1-qi472Tq43whCEvGJXKSwPELZ4P4=",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "node": ">=18"
       }
     },
-    "node_modules/anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
-      "dev": true,
-      "dependencies": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.25.8",
+      "integrity": "sha1-o0BiDjEJP+9ydn3SirBCFLNEIIM=",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
       "engines": {
-        "node": ">= 8"
+        "node": ">=18"
       }
     },
-    "node_modules/aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
-      "dev": true
-    },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "delegates": "^1.0.0",
-        "readable-stream": "^2.0.6"
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.25.8",
+      "integrity": "sha1-3f7SZsjBP177MQWgzUf23NDnnnE=",
+      "cpu": [
+        "s390x"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-mk94x1wFHowGAYPrs5omm6k2oqw=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
     },
-    "node_modules/astral-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
-      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
-      "dev": true,
+    "node_modules/@esbuild/netbsd-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-kCyA4dZ4BHkmOHIwvAN+Y+AGl9A=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
       "engines": {
-        "node": ">=8"
+        "node": ">=18"
       }
     },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-LZ60aSrdJoH/BaFM6Z3lT77XB5w=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
     },
-    "node_modules/azure-devops-node-api": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.0.1.tgz",
-      "integrity": "sha512-YMdjAw9l5p/6leiyIloxj3k7VIvYThKjvqgiQn88r3nhT93ENwsoDS3A83CyJ4uTWzCZ5f5jCi6c27rTU5Pz+A==",
-      "dev": true,
-      "dependencies": {
-        "tunnel": "0.0.6",
-        "typed-rest-client": "^1.8.4"
+    "node_modules/@esbuild/openbsd-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-icO5mMbec52zirf7cainaz+oSkU=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-LwFhXPRysOSMB3BFz9lrXBSTZcw=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
     },
-    "node_modules/base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
+    "node_modules/@esbuild/openharmony-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-ogH3IM0sPr+aYDP8w/6waaVLUJo=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
     },
-    "node_modules/big-integer": {
-      "version": "1.6.50",
-      "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz",
-      "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==",
-      "dev": true,
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-BwRsl3mFozNGZ/GearOgGoCGKvs=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
       "engines": {
-        "node": ">=0.6"
+        "node": ">=18"
       }
     },
-    "node_modules/binary": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
-      "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
-      "dev": true,
-      "dependencies": {
-        "buffers": "~0.1.1",
-        "chainsaw": "~0.1.0"
-      },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.25.8",
+      "integrity": "sha1-SlRwyvDRYSfAXUgz1JNCE8aTktE=",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
       "engines": {
-        "node": "*"
+        "node": ">=18"
       }
     },
-    "node_modules/binary-extensions": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
-      "dev": true,
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.25.8",
+      "integrity": "sha1-PePoRwt7Mo2Z28Pp7B6s4gflu8Q=",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
       "engines": {
-        "node": ">=8"
+        "node": ">=18"
       }
     },
-    "node_modules/bl": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.25.8",
+      "integrity": "sha1-YQ1+pTnS/Nvjkje1zBdessRFH5w=",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/bl/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-      "dev": true,
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.7.0",
+      "integrity": "sha1-YHCEYwxsAzmSoILebm+8GotSF1o=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
+        "eslint-visitor-keys": "^3.4.3"
       },
       "engines": {
-        "node": ">= 6"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
       }
     },
-    "node_modules/bluebird": {
-      "version": "3.4.7",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
-      "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=",
-      "dev": true
-    },
-    "node_modules/boolbase": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
-      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
-      "dev": true
+    "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+      "version": "3.4.3",
+      "integrity": "sha1-DNcv6FUOPC6uFWqWpN3c0cisWAA=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
     },
-    "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+    "node_modules/@eslint-community/regexpp": {
+      "version": "4.12.1",
+      "integrity": "sha1-z8bP/jnfOQo4Qc3iq8z5Lqp64OA=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
       }
     },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dev": true,
+    "node_modules/@eslint/config-array": {
+      "version": "0.21.0",
+      "integrity": "sha1-q9vL0WsSTGOAgXZjkqTWtQn3JjY=",
+      "license": "Apache-2.0",
+      "optional": true,
       "dependencies": {
-        "fill-range": "^7.0.1"
+        "@eslint/object-schema": "^2.1.6",
+        "debug": "^4.3.1",
+        "minimatch": "^3.1.2"
       },
       "engines": {
-        "node": ">=8"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       }
     },
-    "node_modules/browser-stdout": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
-      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
-      "dev": true
-    },
-    "node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
+    "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
-    "node_modules/buffer-crc32": {
-      "version": "0.2.13",
-      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
-      "dev": true,
+    "node_modules/@eslint/config-array/node_modules/minimatch": {
+      "version": "3.1.2",
+      "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
       "engines": {
         "node": "*"
       }
     },
-    "node_modules/buffer-indexof-polyfill": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
-      "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
-      "dev": true,
+    "node_modules/@eslint/config-helpers": {
+      "version": "0.3.0",
+      "integrity": "sha1-PgmpDfuH4ABcdpR5HljpcHcnEoY=",
+      "license": "Apache-2.0",
+      "optional": true,
       "engines": {
-        "node": ">=0.10"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       }
     },
-    "node_modules/buffers": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
-      "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=",
-      "dev": true,
+    "node_modules/@eslint/core": {
+      "version": "0.15.1",
+      "integrity": "sha1-1TDUQgnL/i+C74bWugh2AZbdO2A=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.15"
+      },
       "engines": {
-        "node": ">=0.2.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       }
     },
-    "node_modules/builtin-modules": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
+    "node_modules/@eslint/eslintrc": {
+      "version": "3.3.1",
+      "integrity": "sha1-5V9/HdQAYA3QZtu6NJxMC6yRaWQ=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "ajv": "^6.12.4",
+        "debug": "^4.3.2",
+        "espree": "^10.0.1",
+        "globals": "^14.0.0",
+        "ignore": "^5.2.0",
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "minimatch": "^3.1.2",
+        "strip-json-comments": "^3.1.1"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
     },
-    "node_modules/call-bind": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
-      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
-      "dev": true,
+    "node_modules/@eslint/eslintrc/node_modules/ajv": {
+      "version": "6.12.6",
+      "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2"
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
       },
       "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "node_modules/callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
+    "node_modules/@eslint/eslintrc/node_modules/argparse": {
+      "version": "2.0.1",
+      "integrity": "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=",
+      "license": "Python-2.0",
+      "optional": true
+    },
+    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
-    "node_modules/camelcase": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
-      "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
+    "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
+      "version": "4.1.0",
+      "integrity": "sha1-wftl+PUBeQHN0slRhkuhhFihBgI=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "argparse": "^2.0.1"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/chainsaw": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
-      "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
-      "dev": true,
+    "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+      "version": "3.1.2",
+      "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "traverse": ">=0.3.0 <0.4"
+        "brace-expansion": "^1.1.7"
       },
       "engines": {
         "node": "*"
       }
     },
-    "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
+    "node_modules/@eslint/js": {
+      "version": "9.31.0",
+      "integrity": "sha1-rbHzmVPYxHXEOEtntnVBsNcgbtg=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=10"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       },
       "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "url": "https://eslint.org/donate"
       }
     },
-    "node_modules/chalk/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
+    "node_modules/@eslint/object-schema": {
+      "version": "2.1.6",
+      "integrity": "sha1-WDaatbWzyhF4gMD2wLDzL2lQ8k8=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      }
+    },
+    "node_modules/@eslint/plugin-kit": {
+      "version": "0.3.4",
+      "integrity": "sha1-xrnxZelL9Nn91JPxwCipSq9fwcw=",
+      "license": "Apache-2.0",
+      "optional": true,
       "dependencies": {
-        "has-flag": "^4.0.0"
+        "@eslint/core": "^0.15.1",
+        "levn": "^0.4.1"
       },
       "engines": {
-        "node": ">=8"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       }
     },
-    "node_modules/cheerio": {
-      "version": "1.0.0-rc.10",
-      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
-      "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
-      "dev": true,
+    "node_modules/@humanfs/core": {
+      "version": "0.19.1",
+      "integrity": "sha1-F8Vcp9Qmcz/jxWGQa4Fzwza0Cnc=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": ">=18.18.0"
+      }
+    },
+    "node_modules/@humanfs/node": {
+      "version": "0.16.6",
+      "integrity": "sha1-7ioQ6qvRExmHvwSI/ZuCAXTNdl4=",
+      "license": "Apache-2.0",
+      "optional": true,
       "dependencies": {
-        "cheerio-select": "^1.5.0",
-        "dom-serializer": "^1.3.2",
-        "domhandler": "^4.2.0",
-        "htmlparser2": "^6.1.0",
-        "parse5": "^6.0.1",
-        "parse5-htmlparser2-tree-adapter": "^6.0.1",
-        "tslib": "^2.2.0"
+        "@humanfs/core": "^0.19.1",
+        "@humanwhocodes/retry": "^0.3.0"
       },
       "engines": {
-        "node": ">= 6"
+        "node": ">=18.18.0"
+      }
+    },
+    "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+      "version": "0.3.1",
+      "integrity": "sha1-xypcdqn7rzSI4jGxPcUsDae6tCo=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": ">=18.18"
       },
       "funding": {
-        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
       }
     },
-    "node_modules/cheerio-select": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
-      "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
-      "dev": true,
-      "dependencies": {
-        "css-select": "^4.1.3",
-        "css-what": "^5.0.1",
-        "domelementtype": "^2.2.0",
-        "domhandler": "^4.2.0",
-        "domutils": "^2.7.0"
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "integrity": "sha1-r1smkaIrRL6EewyoFkHF+2rQFyw=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": ">=12.22"
       },
       "funding": {
-        "url": "https://github.com/sponsors/fb55"
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
       }
     },
-    "node_modules/cheerio/node_modules/tslib": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
-      "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
-      "dev": true
-    },
-    "node_modules/chokidar": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://paulmillr.com/funding/"
-        }
-      ],
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
+    "node_modules/@humanwhocodes/retry": {
+      "version": "0.4.3",
+      "integrity": "sha1-wrnS43TuYsWG062+qHGZsdenpro=",
+      "license": "Apache-2.0",
+      "optional": true,
       "engines": {
-        "node": ">= 8.10.0"
+        "node": ">=18.18"
       },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
       }
     },
-    "node_modules/chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-      "dev": true
-    },
-    "node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+    "node_modules/@isaacs/balanced-match": {
+      "version": "4.0.1",
+      "integrity": "sha1-MIHa28NGBmG3UedZHX+upd853Sk=",
       "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
+      "license": "MIT",
+      "engines": {
+        "node": "20 || >=22"
       }
     },
-    "node_modules/code-point-at": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+    "node_modules/@isaacs/brace-expansion": {
+      "version": "5.0.0",
+      "integrity": "sha1-Sz2rq32OdaQpQUqWvWe/TB0T4PM=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@isaacs/balanced-match": "^4.0.1"
+      },
       "engines": {
-        "node": ">=0.10.0"
+        "node": "20 || >=22"
       }
     },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
+    "node_modules/@isaacs/cliui": {
+      "version": "8.0.2",
+      "integrity": "sha1-s3Znt7wYHBaHgiWbq0JHT79StVA=",
+      "devOptional": true,
+      "license": "ISC",
       "dependencies": {
-        "color-name": "~1.1.4"
+        "string-width": "^5.1.2",
+        "string-width-cjs": "npm:string-width@^4.2.0",
+        "strip-ansi": "^7.0.1",
+        "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+        "wrap-ansi": "^8.1.0",
+        "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
       },
       "engines": {
-        "node": ">=7.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
+    "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "integrity": "sha1-hAyIA7DYBH9P8M+WMXazLU7z7XI=",
+      "devOptional": true,
+      "license": "MIT"
     },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
+    "node_modules/@isaacs/cliui/node_modules/string-width": {
+      "version": "5.1.2",
+      "integrity": "sha1-FPja7G2B5yIdKjV+Zoyrc728p5Q=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "delayed-stream": "~1.0.0"
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
       },
       "engines": {
-        "node": ">= 0.8"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "dev": true
+    "node_modules/@istanbuljs/schema": {
+      "version": "0.1.3",
+      "integrity": "sha1-5F44TkuOwWvOL9kDr3hFD2v37Jg=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "integrity": "sha1-eg7mAfYPmaIMfHxf8MgDiMEYm9Y=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
     },
-    "node_modules/console-control-strings": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-      "dev": true
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.5.4",
+      "integrity": "sha1-c1gENDOy5dpWmqAsvEwSHaOvJ9c=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/core-util-is": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
-      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-      "dev": true
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.29",
+      "integrity": "sha1-pY0x6q2vksZpVoCy4dRkqbj79/w=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
     },
-    "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
+    "node_modules/@microsoft/1ds-core-js": {
+      "version": "4.3.9",
+      "integrity": "sha1-kSqK1QiFFPBodHO6ePD2rPf2eZE=",
+      "license": "MIT",
       "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
+        "@microsoft/applicationinsights-core-js": "3.3.9",
+        "@microsoft/applicationinsights-shims": "3.0.1",
+        "@microsoft/dynamicproto-js": "^2.0.3",
+        "@nevware21/ts-async": ">= 0.5.4 < 2.x",
+        "@nevware21/ts-utils": ">= 0.11.8 < 2.x"
       }
     },
-    "node_modules/css-select": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
-      "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
-      "dev": true,
+    "node_modules/@microsoft/1ds-post-js": {
+      "version": "4.3.9",
+      "integrity": "sha1-LSzc16kSzWw6x14Fd/6XasSK6Ys=",
+      "license": "MIT",
       "dependencies": {
-        "boolbase": "^1.0.0",
-        "css-what": "^5.0.0",
-        "domhandler": "^4.2.0",
-        "domutils": "^2.6.0",
-        "nth-check": "^2.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/fb55"
+        "@microsoft/1ds-core-js": "4.3.9",
+        "@microsoft/applicationinsights-shims": "3.0.1",
+        "@microsoft/dynamicproto-js": "^2.0.3",
+        "@nevware21/ts-async": ">= 0.5.4 < 2.x",
+        "@nevware21/ts-utils": ">= 0.11.8 < 2.x"
       }
     },
-    "node_modules/css-what": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
-      "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
+    "node_modules/@microsoft/applicationinsights-channel-js": {
+      "version": "3.3.9",
+      "integrity": "sha1-QN0OaXRLduCae9ub2sHOMVCOha4=",
+      "license": "MIT",
+      "dependencies": {
+        "@microsoft/applicationinsights-common": "3.3.9",
+        "@microsoft/applicationinsights-core-js": "3.3.9",
+        "@microsoft/applicationinsights-shims": "3.0.1",
+        "@microsoft/dynamicproto-js": "^2.0.3",
+        "@nevware21/ts-async": ">= 0.5.4 < 2.x",
+        "@nevware21/ts-utils": ">= 0.11.8 < 2.x"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/fb55"
+      "peerDependencies": {
+        "tslib": ">= 1.0.0"
       }
     },
-    "node_modules/debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
-      "dev": true,
+    "node_modules/@microsoft/applicationinsights-common": {
+      "version": "3.3.9",
+      "integrity": "sha1-IZP6OgZT5ryUeTB7+W5dp32WEUI=",
+      "license": "MIT",
       "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
+        "@microsoft/applicationinsights-core-js": "3.3.9",
+        "@microsoft/applicationinsights-shims": "3.0.1",
+        "@microsoft/dynamicproto-js": "^2.0.3",
+        "@nevware21/ts-utils": ">= 0.11.8 < 2.x"
       },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
+      "peerDependencies": {
+        "tslib": ">= 1.0.0"
       }
     },
-    "node_modules/decamelize": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
-      "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
+    "node_modules/@microsoft/applicationinsights-core-js": {
+      "version": "3.3.9",
+      "integrity": "sha1-OpijcfM1njy22QKOHmlDUqYUNiI=",
+      "license": "MIT",
+      "dependencies": {
+        "@microsoft/applicationinsights-shims": "3.0.1",
+        "@microsoft/dynamicproto-js": "^2.0.3",
+        "@nevware21/ts-async": ">= 0.5.4 < 2.x",
+        "@nevware21/ts-utils": ">= 0.11.8 < 2.x"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "peerDependencies": {
+        "tslib": ">= 1.0.0"
       }
     },
-    "node_modules/decompress-response": {
-      "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,
+    "node_modules/@microsoft/applicationinsights-shims": {
+      "version": "3.0.1",
+      "integrity": "sha1-OGW3Os6EBbnEYYzFxXHy/jh28G8=",
+      "license": "MIT",
       "dependencies": {
-        "mimic-response": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=8"
+        "@nevware21/ts-utils": ">= 0.9.4 < 2.x"
       }
     },
-    "node_modules/deep-extend": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0.0"
+    "node_modules/@microsoft/applicationinsights-web-basic": {
+      "version": "3.3.9",
+      "integrity": "sha1-fHT3Q8NvMpI8tgOb6oyn+jmIhHY=",
+      "license": "MIT",
+      "dependencies": {
+        "@microsoft/applicationinsights-channel-js": "3.3.9",
+        "@microsoft/applicationinsights-common": "3.3.9",
+        "@microsoft/applicationinsights-core-js": "3.3.9",
+        "@microsoft/applicationinsights-shims": "3.0.1",
+        "@microsoft/dynamicproto-js": "^2.0.3",
+        "@nevware21/ts-async": ">= 0.5.4 < 2.x",
+        "@nevware21/ts-utils": ">= 0.11.8 < 2.x"
+      },
+      "peerDependencies": {
+        "tslib": ">= 1.0.0"
       }
     },
-    "node_modules/deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true
+    "node_modules/@microsoft/dynamicproto-js": {
+      "version": "2.0.3",
+      "integrity": "sha1-ritAgGHj/wGpcHhCn8doMx4jklY=",
+      "license": "MIT",
+      "dependencies": {
+        "@nevware21/ts-utils": ">= 0.10.4 < 2.x"
+      }
     },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.0"
+    "node_modules/@nevware21/ts-async": {
+      "version": "0.5.4",
+      "integrity": "sha1-UvhEndCzsWqjF6GLRmL2+xOhNfE=",
+      "license": "MIT",
+      "dependencies": {
+        "@nevware21/ts-utils": ">= 0.11.6 < 2.x"
       }
     },
-    "node_modules/delegates": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
-      "dev": true
+    "node_modules/@nevware21/ts-utils": {
+      "version": "0.12.5",
+      "integrity": "sha1-/jPBDRGui3JMyqox0tAQnRhgHaY=",
+      "license": "MIT"
     },
-    "node_modules/detect-libc": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
-      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
-      "dev": true,
-      "bin": {
-        "detect-libc": "bin/detect-libc.js"
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "integrity": "sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.5",
+        "run-parallel": "^1.1.9"
       },
       "engines": {
-        "node": ">=0.10"
+        "node": ">= 8"
       }
     },
-    "node_modules/diff": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
-      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
-      "dev": true,
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.5",
+      "integrity": "sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos=",
+      "devOptional": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=0.3.1"
+        "node": ">= 8"
       }
     },
-    "node_modules/doctrine": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-      "dev": true,
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "integrity": "sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "esutils": "^2.0.2"
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
       },
       "engines": {
-        "node": ">=6.0.0"
+        "node": ">= 8"
       }
     },
-    "node_modules/dom-serializer": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
-      "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
+    "node_modules/@pkgjs/parseargs": {
+      "version": "0.11.0",
+      "integrity": "sha1-p36nQvqyV3UUVDTrHSMoz1ATrDM=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/@secretlint/config-creator": {
+      "version": "10.2.1",
+      "integrity": "sha1-hnyIdB+MsimIcIkZ5IAzDl+makQ=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "domelementtype": "^2.0.1",
-        "domhandler": "^4.2.0",
-        "entities": "^2.0.0"
+        "@secretlint/types": "^10.2.1"
       },
-      "funding": {
-        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      "engines": {
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/domelementtype": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
-      "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/fb55"
-        }
-      ]
-    },
-    "node_modules/domhandler": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
-      "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
+    "node_modules/@secretlint/config-loader": {
+      "version": "10.2.1",
+      "integrity": "sha1-is/xW09SqVaeQDzvmf7ijTMAQao=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "domelementtype": "^2.2.0"
+        "@secretlint/profiler": "^10.2.1",
+        "@secretlint/resolver": "^10.2.1",
+        "@secretlint/types": "^10.2.1",
+        "ajv": "^8.17.1",
+        "debug": "^4.4.1",
+        "rc-config-loader": "^4.1.3"
       },
       "engines": {
-        "node": ">= 4"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/domhandler?sponsor=1"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/domutils": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
-      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+    "node_modules/@secretlint/core": {
+      "version": "10.2.1",
+      "integrity": "sha1-pycXT7/Xt/XY9jtGRwwUBbvoXKs=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "dom-serializer": "^1.0.1",
-        "domelementtype": "^2.2.0",
-        "domhandler": "^4.2.0"
+        "@secretlint/profiler": "^10.2.1",
+        "@secretlint/types": "^10.2.1",
+        "debug": "^4.4.1",
+        "structured-source": "^4.0.0"
       },
-      "funding": {
-        "url": "https://github.com/fb55/domutils?sponsor=1"
+      "engines": {
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/duplexer2": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
-      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+    "node_modules/@secretlint/formatter": {
+      "version": "10.2.1",
+      "integrity": "sha1-oJ7QDbuRoXR23Dz4hTh3IrUiWIE=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "readable-stream": "^2.0.2"
+        "@secretlint/resolver": "^10.2.1",
+        "@secretlint/types": "^10.2.1",
+        "@textlint/linter-formatter": "^15.2.0",
+        "@textlint/module-interop": "^15.2.0",
+        "@textlint/types": "^15.2.0",
+        "chalk": "^5.4.1",
+        "debug": "^4.4.1",
+        "pluralize": "^8.0.0",
+        "strip-ansi": "^7.1.0",
+        "table": "^6.9.0",
+        "terminal-link": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true
-    },
-    "node_modules/end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+    "node_modules/@secretlint/formatter/node_modules/chalk": {
+      "version": "5.4.1",
+      "integrity": "sha1-G0i/CWPsFY3OKqz2nAk64t0gktg=",
       "dev": true,
-      "dependencies": {
-        "once": "^1.4.0"
+      "license": "MIT",
+      "engines": {
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/enquirer": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
-      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+    "node_modules/@secretlint/node": {
+      "version": "10.2.1",
+      "integrity": "sha1-T/CaJEUA7JxfnSpRK9BH67+py5c=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "ansi-colors": "^4.1.1"
+        "@secretlint/config-loader": "^10.2.1",
+        "@secretlint/core": "^10.2.1",
+        "@secretlint/formatter": "^10.2.1",
+        "@secretlint/profiler": "^10.2.1",
+        "@secretlint/source-creator": "^10.2.1",
+        "@secretlint/types": "^10.2.1",
+        "debug": "^4.4.1",
+        "p-map": "^7.0.3"
       },
       "engines": {
-        "node": ">=8.6"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/entities": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
-      "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+    "node_modules/@secretlint/profiler": {
+      "version": "10.2.1",
+      "integrity": "sha1-61MsdUm2jGOd45l2DGVFKdgyflE=",
       "dev": true,
-      "funding": {
-        "url": "https://github.com/fb55/entities?sponsor=1"
-      }
+      "license": "MIT"
     },
-    "node_modules/esbuild": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.23.tgz",
-      "integrity": "sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==",
+    "node_modules/@secretlint/resolver": {
+      "version": "10.2.1",
+      "integrity": "sha1-UT4uSRbQn9lurY9wIICKU3N5TLg=",
       "dev": true,
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "esbuild-android-arm64": "0.14.23",
-        "esbuild-darwin-64": "0.14.23",
-        "esbuild-darwin-arm64": "0.14.23",
-        "esbuild-freebsd-64": "0.14.23",
-        "esbuild-freebsd-arm64": "0.14.23",
-        "esbuild-linux-32": "0.14.23",
-        "esbuild-linux-64": "0.14.23",
-        "esbuild-linux-arm": "0.14.23",
-        "esbuild-linux-arm64": "0.14.23",
-        "esbuild-linux-mips64le": "0.14.23",
-        "esbuild-linux-ppc64le": "0.14.23",
-        "esbuild-linux-riscv64": "0.14.23",
-        "esbuild-linux-s390x": "0.14.23",
-        "esbuild-netbsd-64": "0.14.23",
-        "esbuild-openbsd-64": "0.14.23",
-        "esbuild-sunos-64": "0.14.23",
-        "esbuild-windows-32": "0.14.23",
-        "esbuild-windows-64": "0.14.23",
-        "esbuild-windows-arm64": "0.14.23"
-      }
-    },
-    "node_modules/esbuild-android-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz",
-      "integrity": "sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==",
-      "cpu": [
-        "arm64"
-      ],
+      "license": "MIT"
+    },
+    "node_modules/@secretlint/secretlint-formatter-sarif": {
+      "version": "10.2.1",
+      "integrity": "sha1-Zed/UxORQEGzU60iFhM0GonVu4A=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
+      "license": "MIT",
+      "dependencies": {
+        "node-sarif-builder": "^3.2.0"
       }
     },
-    "node_modules/esbuild-darwin-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz",
-      "integrity": "sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==",
-      "cpu": [
-        "x64"
-      ],
+    "node_modules/@secretlint/secretlint-rule-no-dotenv": {
+      "version": "10.2.1",
+      "integrity": "sha1-LCcr7s1sJittV0E8cv56rlfxs+s=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
+      "license": "MIT",
+      "dependencies": {
+        "@secretlint/types": "^10.2.1"
+      },
       "engines": {
-        "node": ">=12"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/esbuild-darwin-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz",
-      "integrity": "sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==",
-      "cpu": [
-        "arm64"
-      ],
+    "node_modules/@secretlint/secretlint-rule-preset-recommend": {
+      "version": "10.2.1",
+      "integrity": "sha1-wA+9IlcyjskJ2kNDGCbN+3KaIYU=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
+      "license": "MIT",
       "engines": {
-        "node": ">=12"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/esbuild-freebsd-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz",
-      "integrity": "sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==",
-      "cpu": [
-        "x64"
-      ],
+    "node_modules/@secretlint/source-creator": {
+      "version": "10.2.1",
+      "integrity": "sha1-GxwcZNtncDTinBo9t43M1g2onTI=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
+      "license": "MIT",
+      "dependencies": {
+        "@secretlint/types": "^10.2.1",
+        "istextorbinary": "^9.5.0"
+      },
       "engines": {
-        "node": ">=12"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/esbuild-freebsd-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz",
-      "integrity": "sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==",
-      "cpu": [
-        "arm64"
-      ],
+    "node_modules/@secretlint/types": {
+      "version": "10.2.1",
+      "integrity": "sha1-AY8lKjdUqf8jcbPhMiJtKBvoUVs=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
+      "license": "MIT",
       "engines": {
-        "node": ">=12"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/esbuild-linux-32": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz",
-      "integrity": "sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==",
-      "cpu": [
-        "ia32"
-      ],
+    "node_modules/@sindresorhus/merge-streams": {
+      "version": "2.3.0",
+      "integrity": "sha1-cZ33+0F2a8FDNp6qDdVtjch8mVg=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
+      "license": "MIT",
       "engines": {
-        "node": ">=12"
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/esbuild-linux-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz",
-      "integrity": "sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
+    "node_modules/@sinonjs/commons": {
+      "version": "3.0.1",
+      "integrity": "sha1-ECk1fkTKkBphVYX20nc428iQhM0=",
+      "license": "BSD-3-Clause",
       "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
+      "dependencies": {
+        "type-detect": "4.0.8"
       }
     },
-    "node_modules/esbuild-linux-arm": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz",
-      "integrity": "sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
+    "node_modules/@sinonjs/fake-timers": {
+      "version": "13.0.5",
+      "integrity": "sha1-NrnbwhrVVGSG6pFz1r6gY+sXF9U=",
+      "license": "BSD-3-Clause",
       "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
+      "dependencies": {
+        "@sinonjs/commons": "^3.0.1"
       }
     },
-    "node_modules/esbuild-linux-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz",
-      "integrity": "sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
+    "node_modules/@sinonjs/samsam": {
+      "version": "8.0.2",
+      "integrity": "sha1-5Dhr9mj/NslZSeVaONxfWJL8Jok=",
+      "license": "BSD-3-Clause",
       "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
+      "dependencies": {
+        "@sinonjs/commons": "^3.0.1",
+        "lodash.get": "^4.4.2",
+        "type-detect": "^4.1.0"
       }
     },
-    "node_modules/esbuild-linux-mips64le": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz",
-      "integrity": "sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==",
-      "cpu": [
-        "mips64el"
-      ],
-      "dev": true,
+    "node_modules/@sinonjs/samsam/node_modules/type-detect": {
+      "version": "4.1.0",
+      "integrity": "sha1-3rJFPo8I3K566YxiaxPd2wFVkGw=",
+      "license": "MIT",
       "optional": true,
-      "os": [
-        "linux"
-      ],
       "engines": {
-        "node": ">=12"
+        "node": ">=4"
       }
     },
-    "node_modules/esbuild-linux-ppc64le": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz",
-      "integrity": "sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==",
-      "cpu": [
-        "ppc64"
-      ],
+    "node_modules/@sinonjs/text-encoding": {
+      "version": "0.7.3",
+      "integrity": "sha1-KCBG8D6IbjUrLV9dpet1XgFFfz8=",
+      "license": "(Unlicense OR Apache-2.0)",
+      "optional": true
+    },
+    "node_modules/@textlint/ast-node-types": {
+      "version": "15.2.0",
+      "integrity": "sha1-IuSUaEDRkVL8c+bown180AXNUck=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
+      "license": "MIT"
     },
-    "node_modules/esbuild-linux-riscv64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz",
-      "integrity": "sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==",
-      "cpu": [
-        "riscv64"
-      ],
+    "node_modules/@textlint/linter-formatter": {
+      "version": "15.2.0",
+      "integrity": "sha1-1Eer6KlqTnMnMvYx/Cl7KQmfEe8=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
+      "license": "MIT",
+      "dependencies": {
+        "@azu/format-text": "^1.0.2",
+        "@azu/style-format": "^1.0.1",
+        "@textlint/module-interop": "15.2.0",
+        "@textlint/resolver": "15.2.0",
+        "@textlint/types": "15.2.0",
+        "chalk": "^4.1.2",
+        "debug": "^4.4.1",
+        "js-yaml": "^3.14.1",
+        "lodash": "^4.17.21",
+        "pluralize": "^2.0.0",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1",
+        "table": "^6.9.0",
+        "text-table": "^0.2.0"
       }
     },
-    "node_modules/esbuild-linux-s390x": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz",
-      "integrity": "sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==",
-      "cpu": [
-        "s390x"
-      ],
+    "node_modules/@textlint/linter-formatter/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ],
+      "license": "MIT",
       "engines": {
-        "node": ">=12"
+        "node": ">=8"
       }
     },
-    "node_modules/esbuild-netbsd-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz",
-      "integrity": "sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==",
-      "cpu": [
-        "x64"
-      ],
+    "node_modules/@textlint/linter-formatter/node_modules/pluralize": {
+      "version": "2.0.0",
+      "integrity": "sha1-crcmqm+sHt7uQiVsfY3CVrM1Z38=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
+      "license": "MIT"
     },
-    "node_modules/esbuild-openbsd-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz",
-      "integrity": "sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==",
-      "cpu": [
-        "x64"
-      ],
+    "node_modules/@textlint/linter-formatter/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
       "engines": {
-        "node": ">=12"
+        "node": ">=8"
       }
     },
-    "node_modules/esbuild-sunos-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz",
-      "integrity": "sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==",
-      "cpu": [
-        "x64"
-      ],
+    "node_modules/@textlint/module-interop": {
+      "version": "15.2.0",
+      "integrity": "sha1-DWRIaS5nbCm5jM7A7cYBhTXdLdw=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
+      "license": "MIT"
     },
-    "node_modules/esbuild-windows-32": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz",
-      "integrity": "sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==",
-      "cpu": [
-        "ia32"
-      ],
+    "node_modules/@textlint/resolver": {
+      "version": "15.2.0",
+      "integrity": "sha1-YeCdiui3Uhj7Tns5zPesHnIW4Kk=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
+      "license": "MIT"
     },
-    "node_modules/esbuild-windows-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz",
-      "integrity": "sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==",
-      "cpu": [
-        "x64"
-      ],
+    "node_modules/@textlint/types": {
+      "version": "15.2.0",
+      "integrity": "sha1-C9Wm++Tbwj1SbYtFJ80vUQVjMiE=",
       "dev": true,
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
+      "license": "MIT",
+      "dependencies": {
+        "@textlint/ast-node-types": "15.2.0"
       }
     },
-    "node_modules/esbuild-windows-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz",
-      "integrity": "sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
+    "node_modules/@types/estree": {
+      "version": "1.0.8",
+      "integrity": "sha1-lYuRyZGxhnztMYvt6g4hXuBQcm4=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/istanbul-lib-coverage": {
+      "version": "2.0.6",
+      "integrity": "sha1-dznCMqH+6bTTzomF8xTAxtM1Sdc=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.15",
+      "integrity": "sha1-WWoXRyM2lNUPatinhp/Lb1bPWEE=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/mocha": {
+      "version": "10.0.10",
+      "integrity": "sha1-kfYpBejSPL1mIlMS8jlFSiO+v6A=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/mock-fs": {
+      "version": "4.13.4",
+      "integrity": "sha1-5z7bS0iJ1E0j8eoC1u6+UKowsJo=",
+      "license": "MIT",
       "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
+      "dependencies": {
+        "@types/node": "*"
       }
     },
-    "node_modules/escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
+    "node_modules/@types/node": {
+      "version": "22.16.5",
+      "integrity": "sha1-zEasOZTNlXAA0MEQlaCx2uLqI2g=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "undici-types": "~6.21.0"
       }
     },
-    "node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.4",
+      "integrity": "sha1-VuLMJsOXwDj6sOOpF6EtXFkJ6QE=",
       "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
+      "license": "MIT"
     },
-    "node_modules/eslint": {
-      "version": "7.32.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
-      "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+    "node_modules/@types/sarif": {
+      "version": "2.1.7",
+      "integrity": "sha1-2rTRa6dWjphGxFSodk8zxdmOVSQ=",
       "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@types/semver": {
+      "version": "7.7.0",
+      "integrity": "sha1-ZMRBva4DOzeLbu99DD13wym5N44=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/sinon": {
+      "version": "17.0.4",
+      "integrity": "sha1-/Zo+jgfuoaP0pvgqlyyJnld482k=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "@babel/code-frame": "7.12.11",
-        "@eslint/eslintrc": "^0.4.3",
-        "@humanwhocodes/config-array": "^0.5.0",
-        "ajv": "^6.10.0",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.2",
-        "debug": "^4.0.1",
-        "doctrine": "^3.0.0",
-        "enquirer": "^2.3.5",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^5.1.1",
-        "eslint-utils": "^2.1.0",
-        "eslint-visitor-keys": "^2.0.0",
-        "espree": "^7.3.1",
-        "esquery": "^1.4.0",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^6.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^5.1.2",
-        "globals": "^13.6.0",
-        "ignore": "^4.0.6",
-        "import-fresh": "^3.0.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "js-yaml": "^3.13.1",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.0.4",
+        "@types/sinonjs__fake-timers": "*"
+      }
+    },
+    "node_modules/@types/sinonjs__fake-timers": {
+      "version": "8.1.5",
+      "integrity": "sha1-X9NZL/EMHpaV03cCDAMxFswoifI=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/ungap__structured-clone": {
+      "version": "1.2.0",
+      "integrity": "sha1-Ern9SrPmqCKS1gBISSsF63W0pI8=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/uuid": {
+      "version": "9.0.8",
+      "integrity": "sha1-dUW6T8PAA9bHVvZR878WPY8PKbo=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@types/vscode": {
+      "version": "1.101.0",
+      "integrity": "sha1-BiLKJuoVqvvlcNxNJZF8dcr+V4o=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@typescript-eslint/eslint-plugin": {
+      "version": "8.38.0",
+      "integrity": "sha1-blIg0W8mkattmDwXN91bNuF2Qbc=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.10.0",
+        "@typescript-eslint/scope-manager": "8.38.0",
+        "@typescript-eslint/type-utils": "8.38.0",
+        "@typescript-eslint/utils": "8.38.0",
+        "@typescript-eslint/visitor-keys": "8.38.0",
+        "graphemer": "^1.4.0",
+        "ignore": "^7.0.0",
         "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
-        "progress": "^2.0.0",
-        "regexpp": "^3.1.0",
-        "semver": "^7.2.1",
-        "strip-ansi": "^6.0.0",
-        "strip-json-comments": "^3.1.0",
-        "table": "^6.0.9",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
+        "ts-api-utils": "^2.1.0"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       },
       "funding": {
-        "url": "https://opencollective.com/eslint"
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/parser": "^8.38.0",
+        "eslint": "^8.57.0 || ^9.0.0",
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-      "dev": true,
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
-      },
+    "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+      "version": "7.0.5",
+      "integrity": "sha1-TLX2zX1MerA2VzjHrqiIuqbX79k=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=8.0.0"
+        "node": ">= 4"
       }
     },
-    "node_modules/eslint-utils": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-      "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
-      "dev": true,
+    "node_modules/@typescript-eslint/parser": {
+      "version": "8.38.0",
+      "integrity": "sha1-ZyOl6ogeF3eVaxBFy6ML5eqDgpM=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "eslint-visitor-keys": "^1.1.0"
+        "@typescript-eslint/scope-manager": "8.38.0",
+        "@typescript-eslint/types": "8.38.0",
+        "@typescript-eslint/typescript-estree": "8.38.0",
+        "@typescript-eslint/visitor-keys": "8.38.0",
+        "debug": "^4.3.4"
       },
       "engines": {
-        "node": ">=6"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
-    "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-      "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/eslint-visitor-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/eslint/node_modules/@babel/code-frame": {
-      "version": "7.12.11",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
-      "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
-      "dev": true,
-      "dependencies": {
-        "@babel/highlight": "^7.10.4"
-      }
-    },
-    "node_modules/eslint/node_modules/argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "dev": true,
-      "dependencies": {
-        "sprintf-js": "~1.0.2"
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0",
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/eslint/node_modules/js-yaml": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
-      "dev": true,
+    "node_modules/@typescript-eslint/project-service": {
+      "version": "8.38.0",
+      "integrity": "sha1-SQB3H5QxYwJ/19ICCgYokgVrXi8=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
+        "@typescript-eslint/tsconfig-utils": "^8.38.0",
+        "@typescript-eslint/types": "^8.38.0",
+        "debug": "^4.3.4"
       },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/espree": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
-      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
-      "dev": true,
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "8.38.0",
+      "integrity": "sha1-Wg78tcnPbkEhtY+Hly9WfGlSkiY=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "acorn": "^7.4.0",
-        "acorn-jsx": "^5.3.1",
-        "eslint-visitor-keys": "^1.3.0"
+        "@typescript-eslint/types": "8.38.0",
+        "@typescript-eslint/visitor-keys": "8.38.0"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
       }
     },
-    "node_modules/espree/node_modules/eslint-visitor-keys": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-      "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-      "dev": true,
+    "node_modules/@typescript-eslint/tsconfig-utils": {
+      "version": "8.38.0",
+      "integrity": "sha1-beTOIkp3lgGo32Z9tWUnJVxCxNA=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/esprima": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-      "dev": true,
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       },
-      "engines": {
-        "node": ">=4"
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
-      "dev": true,
+    "node_modules/@typescript-eslint/type-utils": {
+      "version": "8.38.0",
+      "integrity": "sha1-pWzYR2X6bsE1/iUrXbYeMEQDqFs=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "estraverse": "^5.1.0"
+        "@typescript-eslint/types": "8.38.0",
+        "@typescript-eslint/typescript-estree": "8.38.0",
+        "@typescript-eslint/utils": "8.38.0",
+        "debug": "^4.3.4",
+        "ts-api-utils": "^2.1.0"
       },
       "engines": {
-        "node": ">=0.10"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0",
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/esquery/node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
+    "node_modules/@typescript-eslint/types": {
+      "version": "8.38.0",
+      "integrity": "sha1-KXNRyZSXa5PIKsDw4gbIFDqoJSk=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=4.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
       }
     },
-    "node_modules/esrecurse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-      "dev": true,
+    "node_modules/@typescript-eslint/typescript-estree": {
+      "version": "8.38.0",
+      "integrity": "sha1-giYhmetneLuiijGeJa0FsRWJV98=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "estraverse": "^5.2.0"
+        "@typescript-eslint/project-service": "8.38.0",
+        "@typescript-eslint/tsconfig-utils": "8.38.0",
+        "@typescript-eslint/types": "8.38.0",
+        "@typescript-eslint/visitor-keys": "8.38.0",
+        "debug": "^4.3.4",
+        "fast-glob": "^3.3.2",
+        "is-glob": "^4.0.3",
+        "minimatch": "^9.0.4",
+        "semver": "^7.6.0",
+        "ts-api-utils": "^2.1.0"
       },
       "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/esrecurse/node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "dev": true,
+    "node_modules/@typescript-eslint/utils": {
+      "version": "8.38.0",
+      "integrity": "sha1-XxAVmJnTDrkrpw5kLKb3VL3b8Vo=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.7.0",
+        "@typescript-eslint/scope-manager": "8.38.0",
+        "@typescript-eslint/types": "8.38.0",
+        "@typescript-eslint/typescript-estree": "8.38.0"
+      },
       "engines": {
-        "node": ">=4.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0",
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true,
+    "node_modules/@typescript-eslint/visitor-keys": {
+      "version": "8.38.0",
+      "integrity": "sha1-qXZaUnsILLj8YP2KFuR8etW2DqU=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@typescript-eslint/types": "8.38.0",
+        "eslint-visitor-keys": "^4.2.1"
+      },
       "engines": {
-        "node": ">=0.10.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
       }
     },
-    "node_modules/expand-template": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
-      "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+    "node_modules/@typespec/ts-http-runtime": {
+      "version": "0.3.0",
+      "integrity": "sha1-9Qb/IXDllKJX+OeKoZYIjzpGoi0=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "http-proxy-agent": "^7.0.0",
+        "https-proxy-agent": "^7.0.0",
+        "tslib": "^2.6.2"
+      },
       "engines": {
-        "node": ">=6"
+        "node": ">=20.0.0"
       }
     },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
+    "node_modules/@ungap/structured-clone": {
+      "version": "1.3.0",
+      "integrity": "sha1-0Gu7OE689sUF/eHD0O1N3/4Kr/g=",
+      "license": "ISC",
+      "optional": true
     },
-    "node_modules/fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
-      "dev": true
+    "node_modules/@vscode/debugprotocol": {
+      "version": "1.68.0",
+      "integrity": "sha1-5Vi6av/hvnr/TsgkWZ8xa2HZpp0=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/fd-slicer": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
-      "dev": true,
+    "node_modules/@vscode/extension-telemetry": {
+      "version": "0.9.9",
+      "integrity": "sha1-WIROcqx4YOsEl4mFRcLE9YCWRl4=",
+      "license": "MIT",
       "dependencies": {
-        "pend": "~1.2.0"
+        "@microsoft/1ds-core-js": "^4.3.4",
+        "@microsoft/1ds-post-js": "^4.3.4",
+        "@microsoft/applicationinsights-web-basic": "^3.3.4"
+      },
+      "engines": {
+        "vscode": "^1.75.0"
       }
     },
-    "node_modules/file-entry-cache": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
-      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
-      "dev": true,
+    "node_modules/@vscode/test-cli": {
+      "version": "0.0.10",
+      "integrity": "sha1-NfDoHC4P+NrOsiPpnRtlMGwVgiw=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "flat-cache": "^3.0.4"
+        "@types/mocha": "^10.0.2",
+        "c8": "^9.1.0",
+        "chokidar": "^3.5.3",
+        "enhanced-resolve": "^5.15.0",
+        "glob": "^10.3.10",
+        "minimatch": "^9.0.3",
+        "mocha": "^10.2.0",
+        "supports-color": "^9.4.0",
+        "yargs": "^17.7.2"
+      },
+      "bin": {
+        "vscode-test": "out/bin.mjs"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": ">=18"
       }
     },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dev": true,
+    "node_modules/@vscode/test-electron": {
+      "version": "2.5.2",
+      "integrity": "sha1-99QHjoIwzpyUMi8qKcwWwXlUCF0=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "to-regex-range": "^5.0.1"
+        "http-proxy-agent": "^7.0.2",
+        "https-proxy-agent": "^7.0.5",
+        "jszip": "^3.10.1",
+        "ora": "^8.1.0",
+        "semver": "^7.6.2"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=16"
       }
     },
-    "node_modules/find-up": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
+    "node_modules/@vscode/vsce": {
+      "version": "3.6.0",
+      "integrity": "sha1-cQLLhG24PtcOxxGZhq99fGnPNTg=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@azure/identity": "^4.1.0",
+        "@secretlint/node": "^10.1.1",
+        "@secretlint/secretlint-formatter-sarif": "^10.1.1",
+        "@secretlint/secretlint-rule-no-dotenv": "^10.1.1",
+        "@secretlint/secretlint-rule-preset-recommend": "^10.1.1",
+        "@vscode/vsce-sign": "^2.0.0",
+        "azure-devops-node-api": "^12.5.0",
+        "chalk": "^4.1.2",
+        "cheerio": "^1.0.0-rc.9",
+        "cockatiel": "^3.1.2",
+        "commander": "^12.1.0",
+        "form-data": "^4.0.0",
+        "glob": "^11.0.0",
+        "hosted-git-info": "^4.0.2",
+        "jsonc-parser": "^3.2.0",
+        "leven": "^3.1.0",
+        "markdown-it": "^14.1.0",
+        "mime": "^1.3.4",
+        "minimatch": "^3.0.3",
+        "parse-semver": "^1.1.1",
+        "read": "^1.0.7",
+        "secretlint": "^10.1.1",
+        "semver": "^7.5.2",
+        "tmp": "^0.2.3",
+        "typed-rest-client": "^1.8.4",
+        "url-join": "^4.0.1",
+        "xml2js": "^0.5.0",
+        "yauzl": "^2.3.1",
+        "yazl": "^2.2.2"
+      },
+      "bin": {
+        "vsce": "vsce"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">= 20"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "optionalDependencies": {
+        "keytar": "^7.7.0"
       }
     },
-    "node_modules/flat": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
-      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+    "node_modules/@vscode/vsce-sign": {
+      "version": "2.0.6",
+      "integrity": "sha1-orEeKdq1Y3nFE+DMUmFe2tHTTNM=",
       "dev": true,
-      "bin": {
-        "flat": "cli.js"
-      }
-    },
-    "node_modules/flat-cache": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
-      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+      "hasInstallScript": true,
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optionalDependencies": {
+        "@vscode/vsce-sign-alpine-arm64": "2.0.5",
+        "@vscode/vsce-sign-alpine-x64": "2.0.5",
+        "@vscode/vsce-sign-darwin-arm64": "2.0.5",
+        "@vscode/vsce-sign-darwin-x64": "2.0.5",
+        "@vscode/vsce-sign-linux-arm": "2.0.5",
+        "@vscode/vsce-sign-linux-arm64": "2.0.5",
+        "@vscode/vsce-sign-linux-x64": "2.0.5",
+        "@vscode/vsce-sign-win32-arm64": "2.0.5",
+        "@vscode/vsce-sign-win32-x64": "2.0.5"
+      }
+    },
+    "node_modules/@vscode/vsce-sign-alpine-arm64": {
+      "version": "2.0.5",
+      "integrity": "sha1-40y/kfToamz1KrwubnUISuGPbEo=",
+      "cpu": [
+        "arm64"
+      ],
       "dev": true,
-      "dependencies": {
-        "flatted": "^3.1.0",
-        "rimraf": "^3.0.2"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      }
-    },
-    "node_modules/flatted": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz",
-      "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==",
-      "dev": true
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "alpine"
+      ]
     },
-    "node_modules/form-data": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
-      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+    "node_modules/@vscode/vsce-sign-alpine-x64": {
+      "version": "2.0.5",
+      "integrity": "sha1-dEPA6DnnTwP84MwxRTMPDSqAzIc=",
+      "cpu": [
+        "x64"
+      ],
       "dev": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fs-constants": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
-      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
-      "dev": true
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-      "dev": true
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "alpine"
+      ]
     },
-    "node_modules/fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+    "node_modules/@vscode/vsce-sign-darwin-arm64": {
+      "version": "2.0.5",
+      "integrity": "sha1-LqusfYNxKSqNIqFbP/V/GYjCnWs=",
+      "cpu": [
+        "arm64"
+      ],
       "dev": true,
-      "hasInstallScript": true,
+      "license": "SEE LICENSE IN LICENSE.txt",
       "optional": true,
       "os": [
         "darwin"
+      ]
+    },
+    "node_modules/@vscode/vsce-sign-darwin-x64": {
+      "version": "2.0.5",
+      "integrity": "sha1-lvsDKcijZxhMID1iV0+akhkwItg=",
+      "cpu": [
+        "x64"
       ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
+      "dev": true,
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
     },
-    "node_modules/fstream": {
-      "version": "1.0.12",
-      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
-      "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+    "node_modules/@vscode/vsce-sign-linux-arm": {
+      "version": "2.0.5",
+      "integrity": "sha1-vwc0DbH+Ncs6iiIrLaSqJTEO4lE=",
+      "cpu": [
+        "arm"
+      ],
       "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "inherits": "~2.0.0",
-        "mkdirp": ">=0.5 0",
-        "rimraf": "2"
-      },
-      "engines": {
-        "node": ">=0.6"
-      }
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
     },
-    "node_modules/fstream/node_modules/rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+    "node_modules/@vscode/vsce-sign-linux-arm64": {
+      "version": "2.0.5",
+      "integrity": "sha1-wEUCMqukP76t/1MJg4pWVdxwOcg=",
+      "cpu": [
+        "arm64"
+      ],
       "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      }
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
     },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
+    "node_modules/@vscode/vsce-sign-linux-x64": {
+      "version": "2.0.5",
+      "integrity": "sha1-I4KZJPQIZ+kNXju4Yejo+gResO4=",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
     },
-    "node_modules/functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
-      "dev": true
+    "node_modules/@vscode/vsce-sign-win32-arm64": {
+      "version": "2.0.5",
+      "integrity": "sha1-GO8nH199mzHAMSdYLBscUfJuI7Q=",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
     },
-    "node_modules/gauge": {
-      "version": "2.7.4",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+    "node_modules/@vscode/vsce-sign-win32-x64": {
+      "version": "2.0.5",
+      "integrity": "sha1-g7iTk+RFHPp+OiGCrqQlD15xrKg=",
+      "cpu": [
+        "x64"
+      ],
       "dev": true,
-      "dependencies": {
-        "aproba": "^1.0.3",
-        "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.0",
-        "object-assign": "^4.1.0",
-        "signal-exit": "^3.0.0",
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wide-align": "^1.1.0"
-      }
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
     },
-    "node_modules/gauge/node_modules/ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+    "node_modules/@vscode/vsce/node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=",
       "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
-    "node_modules/gauge/node_modules/is-fullwidth-code-point": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+    "node_modules/@vscode/vsce/node_modules/glob": {
+      "version": "11.0.3",
+      "integrity": "sha1-nYCH5tct2zxHB7HSd4+A6j6u/NY=",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "number-is-nan": "^1.0.0"
+        "foreground-child": "^3.3.1",
+        "jackspeak": "^4.1.1",
+        "minimatch": "^10.0.3",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^2.0.0"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": "20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/gauge/node_modules/string-width": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+    "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": {
+      "version": "10.0.3",
+      "integrity": "sha1-z3oDFKFsTZq3OncwoOjjw1AtR6o=",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "code-point-at": "^1.0.0",
-        "is-fullwidth-code-point": "^1.0.0",
-        "strip-ansi": "^3.0.0"
+        "@isaacs/brace-expansion": "^5.0.0"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": "20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/gauge/node_modules/strip-ansi": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+    "node_modules/@vscode/vsce/node_modules/jackspeak": {
+      "version": "4.1.1",
+      "integrity": "sha1-lodgMPRQUCBH/H6Mf8+M6BJOQ64=",
       "dev": true,
+      "license": "BlueOak-1.0.0",
       "dependencies": {
-        "ansi-regex": "^2.0.0"
+        "@isaacs/cliui": "^8.0.2"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": "20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+    "node_modules/@vscode/vsce/node_modules/lru-cache": {
+      "version": "11.1.0",
+      "integrity": "sha1-r6+wYGBxCBMtvBz4rmYa+2lIYRc=",
       "dev": true,
+      "license": "ISC",
       "engines": {
-        "node": "6.* || 8.* || >= 10.*"
+        "node": "20 || >=22"
       }
     },
-    "node_modules/get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+    "node_modules/@vscode/vsce/node_modules/minimatch": {
+      "version": "3.1.2",
+      "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "brace-expansion": "^1.1.7"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+      "engines": {
+        "node": "*"
       }
     },
-    "node_modules/github-from-package": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
-      "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
-      "dev": true
-    },
-    "node_modules/glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+    "node_modules/@vscode/vsce/node_modules/path-scurry": {
+      "version": "2.0.0",
+      "integrity": "sha1-nwUiifI62L+Tl6KgQl57hhXFhYA=",
       "dev": true,
+      "license": "BlueOak-1.0.0",
       "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "lru-cache": "^11.0.0",
+        "minipass": "^7.1.2"
       },
       "engines": {
-        "node": "*"
+        "node": "20 || >=22"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "dependencies": {
-        "is-glob": "^4.0.1"
+    "node_modules/acorn": {
+      "version": "8.15.0",
+      "integrity": "sha1-o2CJi8QV7arEbIJB9jg5dbkwuBY=",
+      "license": "MIT",
+      "optional": true,
+      "bin": {
+        "acorn": "bin/acorn"
       },
       "engines": {
-        "node": ">= 6"
+        "node": ">=0.4.0"
       }
     },
-    "node_modules/globals": {
-      "version": "13.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
-      "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
-      "dev": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+    "node_modules/acorn-jsx": {
+      "version": "5.3.2",
+      "integrity": "sha1-ftW7VZCLOy8bxVxq8WU7rafweTc=",
+      "license": "MIT",
+      "optional": true,
+      "peerDependencies": {
+        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
       }
     },
-    "node_modules/graceful-fs": {
-      "version": "4.2.8",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
-      "dev": true
-    },
-    "node_modules/growl": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-      "dev": true,
+    "node_modules/agent-base": {
+      "version": "7.1.4",
+      "integrity": "sha1-48121MVI7oldPD/Y3B9sW5Ay56g=",
+      "devOptional": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=4.x"
+        "node": ">= 14"
       }
     },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+    "node_modules/ajv": {
+      "version": "8.17.1",
+      "integrity": "sha1-N9mlx3ava8ktf0+VEOukwKYNEaY=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "function-bind": "^1.1.1"
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
       },
-      "engines": {
-        "node": ">= 0.4.0"
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
+    "node_modules/ansi-colors": {
+      "version": "4.1.3",
+      "integrity": "sha1-N2ETQOsiQ+cMxgTK011jJw1IeBs=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=6"
       }
     },
-    "node_modules/has-symbols": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
-      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+    "node_modules/ansi-escapes": {
+      "version": "7.0.0",
+      "integrity": "sha1-APwZ9JG7sY4dSBuXhoIE+SEJv+c=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "environment": "^1.0.0"
+      },
       "engines": {
-        "node": ">= 0.4"
+        "node": ">=18"
       },
       "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/has-unicode": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
-      "dev": true
+    "node_modules/ansi-regex": {
+      "version": "6.1.0",
+      "integrity": "sha1-lexAnGlhnWyxuLNPFLZg7yjr1lQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
     },
-    "node_modules/he": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true,
-      "bin": {
-        "he": "bin/he"
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/hosted-git-info": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
-      "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
-      "dev": true,
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "integrity": "sha1-eQxYsZuhcgqEIFtXxhjVrYUklz4=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "lru-cache": "^6.0.0"
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">= 8"
       }
     },
-    "node_modules/htmlparser2": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
-      "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+    "node_modules/argparse": {
+      "version": "1.0.10",
+      "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
       "dev": true,
-      "funding": [
-        "https://github.com/fb55/htmlparser2?sponsor=1",
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/fb55"
-        }
-      ],
+      "license": "MIT",
       "dependencies": {
-        "domelementtype": "^2.0.1",
-        "domhandler": "^4.0.0",
-        "domutils": "^2.5.2",
-        "entities": "^2.0.0"
+        "sprintf-js": "~1.0.2"
       }
     },
-    "node_modules/http-proxy-agent": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
-      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+    "node_modules/astral-regex": {
+      "version": "2.0.0",
+      "integrity": "sha1-SDFDxWeu7UeFdZwIZXhtx319LjE=",
       "dev": true,
-      "dependencies": {
-        "@tootallnate/once": "1",
-        "agent-base": "6",
-        "debug": "4"
-      },
+      "license": "MIT",
       "engines": {
-        "node": ">= 6"
+        "node": ">=8"
       }
     },
-    "node_modules/https-proxy-agent": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
-      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
       "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/azure-devops-node-api": {
+      "version": "12.5.0",
+      "integrity": "sha1-OLnv18WsdDVP5Ojb5CaX2wuOhaU=",
+      "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
+        "tunnel": "0.0.6",
+        "typed-rest-client": "^1.8.4"
       }
     },
-    "node_modules/ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=",
+      "license": "MIT"
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=",
       "dev": true,
       "funding": [
         {
@@ -2203,252 +2309,225 @@
           "type": "consulting",
           "url": "https://feross.org/support"
         }
-      ]
+      ],
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/ignore": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
-      "dev": true,
+    "node_modules/binary-extensions": {
+      "version": "2.3.0",
+      "integrity": "sha1-9uFKl4WNMnJSIAJC1Mz+UixEVSI=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">= 4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/import-fresh": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+    "node_modules/binaryextensions": {
+      "version": "6.11.0",
+      "integrity": "sha1-w2s+a1xZ5iFgVwmwmc2o3agkzHI=",
       "dev": true,
+      "license": "Artistic-2.0",
       "dependencies": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
+        "editions": "^6.21.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=4"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.19"
+        "url": "https://bevry.me/fund"
       }
     },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+    "node_modules/bl": {
+      "version": "4.1.0",
+      "integrity": "sha1-RRU1JkGCvsL7vIOmKrmM8R2fezo=",
       "dev": true,
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
+        "buffer": "^5.5.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.4.0"
       }
     },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "node_modules/ini": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
-      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "dev": true
-    },
-    "node_modules/is-binary-path": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
-      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+    "node_modules/bl/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "integrity": "sha1-VqmzbqllwAxak+8x6xEaDxEFaWc=",
       "dev": true,
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "binary-extensions": "^2.0.0"
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">= 6"
       }
     },
-    "node_modules/is-core-module": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
-      "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
+    "node_modules/boolbase": {
+      "version": "1.0.0",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
       "dev": true,
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
+      "license": "ISC"
     },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+    "node_modules/boundary": {
+      "version": "2.0.0",
+      "integrity": "sha1-FpyLHw1Ezywlk4lnoyjzfgpOXvw=",
       "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/brace-expansion": {
+      "version": "2.0.2",
+      "integrity": "sha1-VPxTI3phPYVMe9N0Y6rRffhyFOc=",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
       }
     },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "integrity": "sha1-SQMy9AkZRSJy1VqEgK3AxEE1h4k=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
       "engines": {
         "node": ">=8"
       }
     },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+    "node_modules/browser-stdout": {
+      "version": "1.3.1",
+      "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=",
+      "license": "ISC",
+      "optional": true
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "integrity": "sha1-umLnwTEzBTWCGXFghRqPZI6Z7tA=",
       "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
       }
     },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+    "node_modules/buffer-crc32": {
+      "version": "0.2.13",
+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=0.12.0"
+        "node": "*"
       }
     },
-    "node_modules/is-plain-obj": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
-      "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=",
       "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
+      "license": "BSD-3-Clause"
     },
-    "node_modules/is-unicode-supported": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+    "node_modules/bundle-name": {
+      "version": "4.1.0",
+      "integrity": "sha1-87lrNBYNZDGhnXaIE1r3z7h5eIk=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "run-applescript": "^7.0.0"
+      },
       "engines": {
-        "node": ">=10"
+        "node": ">=18"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "node_modules/js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
+    "node_modules/c8": {
+      "version": "9.1.0",
+      "integrity": "sha1-Dle6Ornllgqx1lC0qG9x5Ty2gRI=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "argparse": "^2.0.1"
+        "@bcoe/v8-coverage": "^0.2.3",
+        "@istanbuljs/schema": "^0.1.3",
+        "find-up": "^5.0.0",
+        "foreground-child": "^3.1.1",
+        "istanbul-lib-coverage": "^3.2.0",
+        "istanbul-lib-report": "^3.0.1",
+        "istanbul-reports": "^3.1.6",
+        "test-exclude": "^6.0.0",
+        "v8-to-istanbul": "^9.0.0",
+        "yargs": "^17.7.2",
+        "yargs-parser": "^21.1.1"
       },
       "bin": {
-        "js-yaml": "bin/js-yaml.js"
+        "c8": "bin/c8.js"
+      },
+      "engines": {
+        "node": ">=14.14.0"
       }
     },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "node_modules/json-stable-stringify-without-jsonify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
-      "dev": true
-    },
-    "node_modules/just-extend": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
-      "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
-      "dev": true
-    },
-    "node_modules/keytar": {
-      "version": "7.7.0",
-      "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.7.0.tgz",
-      "integrity": "sha512-YEY9HWqThQc5q5xbXbRwsZTh2PJ36OSYRjSv3NN2xf5s5dpLTjEZnC2YikR29OaVybf9nQ0dJ/80i40RS97t/A==",
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "integrity": "sha1-S1QowiK+mF15w9gmV0edvgtZstY=",
       "dev": true,
-      "hasInstallScript": true,
+      "license": "MIT",
       "dependencies": {
-        "node-addon-api": "^3.0.0",
-        "prebuild-install": "^6.0.0"
-      }
-    },
-    "node_modules/leven": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
-      "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
-      "dev": true,
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
       "engines": {
-        "node": ">=6"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/levn": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "integrity": "sha1-I43pNdKippKSjFOMfM+pEGf9Bio=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
       },
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/linkify-it": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
-      "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
-      "dev": true,
-      "dependencies": {
-        "uc.micro": "^1.0.1"
+    "node_modules/callsites": {
+      "version": "3.1.0",
+      "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
       }
     },
-    "node_modules/listenercount": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
-      "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=",
-      "dev": true
-    },
-    "node_modules/locate-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^5.0.0"
-      },
+    "node_modules/camelcase": {
+      "version": "6.3.0",
+      "integrity": "sha1-VoW5XrIJrJwMF3Rnd4ychN9Yupo=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
         "node": ">=10"
       },
@@ -2456,4989 +2535,4659 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true
-    },
-    "node_modules/lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
-      "dev": true
-    },
-    "node_modules/lodash.merge": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
-      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
-      "dev": true
-    },
-    "node_modules/lodash.truncate": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
-      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
-      "dev": true
-    },
-    "node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "dev": true,
+    "node_modules/chalk": {
+      "version": "4.1.2",
+      "integrity": "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
         "node": ">=10"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+    "node_modules/chalk/node_modules/supports-color": {
+      "version": "7.2.0",
+      "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "yallist": "^4.0.0"
+        "has-flag": "^4.0.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=8"
       }
     },
-    "node_modules/markdown-it": {
-      "version": "12.3.2",
-      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
-      "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+    "node_modules/cheerio": {
+      "version": "1.1.2",
+      "integrity": "sha1-Jq936JM2yBxj6oMZf4aLTL01E2k=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "argparse": "^2.0.1",
-        "entities": "~2.1.0",
-        "linkify-it": "^3.0.1",
-        "mdurl": "^1.0.1",
-        "uc.micro": "^1.0.5"
+        "cheerio-select": "^2.1.0",
+        "dom-serializer": "^2.0.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.2.2",
+        "encoding-sniffer": "^0.2.1",
+        "htmlparser2": "^10.0.0",
+        "parse5": "^7.3.0",
+        "parse5-htmlparser2-tree-adapter": "^7.1.0",
+        "parse5-parser-stream": "^7.1.2",
+        "undici": "^7.12.0",
+        "whatwg-mimetype": "^4.0.0"
       },
-      "bin": {
-        "markdown-it": "bin/markdown-it.js"
+      "engines": {
+        "node": ">=20.18.1"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
       }
     },
-    "node_modules/mdurl": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
-      "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
-      "dev": true
-    },
-    "node_modules/mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+    "node_modules/cheerio-select": {
+      "version": "2.1.0",
+      "integrity": "sha1-TYZzKGuBJsoqjkJ0DV48SISuIbQ=",
       "dev": true,
-      "bin": {
-        "mime": "cli.js"
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-select": "^5.1.0",
+        "css-what": "^6.1.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.0.1"
       },
-      "engines": {
-        "node": ">=4"
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
       }
     },
-    "node_modules/mime-db": {
-      "version": "1.51.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
-      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
-      "dev": true,
+    "node_modules/chokidar": {
+      "version": "3.6.0",
+      "integrity": "sha1-GXxsxmnvKo3F57TZfuTgksPrDVs=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
       "engines": {
-        "node": ">= 0.6"
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
       }
     },
-    "node_modules/mime-types": {
-      "version": "2.1.34",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
-      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+    "node_modules/chownr": {
+      "version": "1.1.4",
+      "integrity": "sha1-b8nXtC0ypYNZYzdmbn0ICE2izGs=",
       "dev": true,
+      "license": "ISC",
+      "optional": true
+    },
+    "node_modules/cli-cursor": {
+      "version": "5.0.0",
+      "integrity": "sha1-JKSDHs9aawHd6zL7caSyCIsNzjg=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "mime-db": "1.51.0"
+        "restore-cursor": "^5.0.0"
       },
       "engines": {
-        "node": ">= 0.6"
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/mimic-response": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
-      "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
-      "dev": true,
+    "node_modules/cli-spinners": {
+      "version": "2.9.2",
+      "integrity": "sha1-F3Oo9LnE1qwxVj31Oz/B15Ri/kE=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=6"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+    "node_modules/cliui": {
+      "version": "8.0.1",
+      "integrity": "sha1-DASwddsCy/5g3I5s8vVIaxo2CKo=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "brace-expansion": "^1.1.7"
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
       },
       "engines": {
-        "node": "*"
+        "node": ">=12"
       }
     },
-    "node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
+    "node_modules/cliui/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "node_modules/mkdirp": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
-      "dev": true,
+    "node_modules/cliui/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "minimist": "^1.2.5"
+        "ansi-regex": "^5.0.1"
       },
-      "bin": {
-        "mkdirp": "bin/cmd.js"
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/mkdirp-classic": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
-      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
-      "dev": true
-    },
-    "node_modules/mocha": {
-      "version": "9.2.1",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz",
-      "integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==",
-      "dev": true,
-      "dependencies": {
-        "@ungap/promise-all-settled": "1.1.2",
-        "ansi-colors": "4.1.1",
-        "browser-stdout": "1.3.1",
-        "chokidar": "3.5.3",
-        "debug": "4.3.3",
-        "diff": "5.0.0",
-        "escape-string-regexp": "4.0.0",
-        "find-up": "5.0.0",
-        "glob": "7.2.0",
-        "growl": "1.10.5",
-        "he": "1.2.0",
-        "js-yaml": "4.1.0",
-        "log-symbols": "4.1.0",
-        "minimatch": "3.0.4",
-        "ms": "2.1.3",
-        "nanoid": "3.2.0",
-        "serialize-javascript": "6.0.0",
-        "strip-json-comments": "3.1.1",
-        "supports-color": "8.1.1",
-        "which": "2.0.2",
-        "workerpool": "6.2.0",
-        "yargs": "16.2.0",
-        "yargs-parser": "20.2.4",
-        "yargs-unparser": "2.0.0"
-      },
-      "bin": {
-        "_mocha": "bin/_mocha",
-        "mocha": "bin/mocha"
+    "node_modules/cliui/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
       },
       "engines": {
-        "node": ">= 12.0.0"
+        "node": ">=10"
       },
       "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/mochajs"
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
-    "node_modules/mocha-multi-reporters": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/mocha-multi-reporters/-/mocha-multi-reporters-1.5.1.tgz",
-      "integrity": "sha512-Yb4QJOaGLIcmB0VY7Wif5AjvLMUFAdV57D2TWEva1Y0kU/3LjKpeRVmlMIfuO1SVbauve459kgtIizADqxMWPg==",
+    "node_modules/cockatiel": {
+      "version": "3.2.1",
+      "integrity": "sha1-V1+Te8QECiCuJzUqbQfJxadBmB8=",
       "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=16"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "debug": "^4.1.1",
-        "lodash": "^4.17.15"
+        "color-name": "~1.1.4"
       },
       "engines": {
-        "node": ">=6.0.0"
-      },
-      "peerDependencies": {
-        "mocha": ">=3.1.2"
+        "node": ">=7.0.0"
       }
     },
-    "node_modules/mocha/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
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+      "devOptional": true,
+      "license": "MIT"
     },
-    "node_modules/mock-fs": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.1.2.tgz",
-      "integrity": "sha512-YkjQkdLulFrz0vD4BfNQdQRVmgycXTV7ykuHMlyv+C8WCHazpkiQRDthwa02kSyo8wKnY9wRptHfQLgmf0eR+A==",
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
       "engines": {
-        "node": ">=12.0.0"
+        "node": ">= 0.8"
       }
     },
-    "node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
-    "node_modules/mute-stream": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
-      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-      "dev": true
-    },
-    "node_modules/nanoid": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
+    "node_modules/commander": {
+      "version": "12.1.0",
+      "integrity": "sha1-AUI7NvUBJZ/arE0OTWDJbJkVhdM=",
       "dev": true,
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
+      "license": "MIT",
       "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+        "node": ">=18"
       }
     },
-    "node_modules/napi-build-utils": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
-      "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
-      "dev": true
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "devOptional": true,
+      "license": "MIT"
     },
-    "node_modules/natural-compare": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
-      "dev": true
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "integrity": "sha1-S1YPZJ/E6RjdCrdc9JYei8iC2Co=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/nise": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz",
-      "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==",
-      "dev": true,
+    "node_modules/core-util-is": {
+      "version": "1.0.3",
+      "integrity": "sha1-pgQtNjTCsn6TKPg3uWX6yDgI24U=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/cross-spawn": {
+      "version": "7.0.6",
+      "integrity": "sha1-ilj+ePANzXDDcEUXWd+/rwPo7p8=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "@sinonjs/commons": "^1.8.3",
-        "@sinonjs/fake-timers": ">=5",
-        "@sinonjs/text-encoding": "^0.7.1",
-        "just-extend": "^4.0.2",
-        "path-to-regexp": "^1.7.0"
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "node_modules/node-abi": {
-      "version": "2.30.1",
-      "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz",
-      "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==",
+    "node_modules/css-select": {
+      "version": "5.2.2",
+      "integrity": "sha1-Abbo0WNje7LdbJgspO1lhjaCeG4=",
       "dev": true,
+      "license": "BSD-2-Clause",
       "dependencies": {
-        "semver": "^5.4.1"
+        "boolbase": "^1.0.0",
+        "css-what": "^6.1.0",
+        "domhandler": "^5.0.2",
+        "domutils": "^3.0.1",
+        "nth-check": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
       }
     },
-    "node_modules/node-abi/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+    "node_modules/css-what": {
+      "version": "6.2.2",
+      "integrity": "sha1-zcyPm2l3cZ/fvR3nrsJKv3Vrneo=",
       "dev": true,
-      "bin": {
-        "semver": "bin/semver"
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
       }
     },
-    "node_modules/node-addon-api": {
-      "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
-    },
-    "node_modules/node-fetch": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+    "node_modules/debug": {
+      "version": "4.4.1",
+      "integrity": "sha1-5ai8bLxMbNPmQwiwaTo9T6VQGJs=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "whatwg-url": "^5.0.0"
+        "ms": "^2.1.3"
       },
       "engines": {
-        "node": "4.x || >=6.0.0"
-      },
-      "peerDependencies": {
-        "encoding": "^0.1.0"
+        "node": ">=6.0"
       },
       "peerDependenciesMeta": {
-        "encoding": {
+        "supports-color": {
           "optional": true
         }
       }
     },
-    "node_modules/normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true,
+    "node_modules/decamelize": {
+      "version": "4.0.0",
+      "integrity": "sha1-qkcte/Zg6xXzSU79UxyrfypwmDc=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/npmlog": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+    "node_modules/decompress-response": {
+      "version": "6.0.0",
+      "integrity": "sha1-yjh2Et234QS9FthaqwDV7PCcZvw=",
       "dev": true,
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "are-we-there-yet": "~1.1.2",
-        "console-control-strings": "~1.1.0",
-        "gauge": "~2.7.3",
-        "set-blocking": "~2.0.0"
+        "mimic-response": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/nth-check": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
-      "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
+    "node_modules/deep-extend": {
+      "version": "0.6.0",
+      "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw=",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/deep-is": {
+      "version": "0.1.4",
+      "integrity": "sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/default-browser": {
+      "version": "5.2.1",
+      "integrity": "sha1-e3umEgT/PkJbVWhprm0+nZ8XEs8=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "boolbase": "^1.0.0"
+        "bundle-name": "^4.1.0",
+        "default-browser-id": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
       },
       "funding": {
-        "url": "https://github.com/fb55/nth-check?sponsor=1"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/number-is-nan": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+    "node_modules/default-browser-id": {
+      "version": "5.0.0",
+      "integrity": "sha1-odmL+WDBUILYo/pp6DFQzMzDryY=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+    "node_modules/define-lazy-prop": {
+      "version": "3.0.0",
+      "integrity": "sha1-27Ga37dG1/xtc0oGty9KANAhJV8=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/object-inspect": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
-      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
       "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
       }
     },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+    "node_modules/detect-libc": {
+      "version": "2.0.4",
+      "integrity": "sha1-8EcVuLqBXlO02BCWVbZQimhlp+g=",
       "dev": true,
-      "dependencies": {
-        "wrappy": "1"
+      "license": "Apache-2.0",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+    "node_modules/diff": {
+      "version": "5.2.0",
+      "integrity": "sha1-Jt7QR80RebeLlTfV73JVA84a5TE=",
+      "license": "BSD-3-Clause",
+      "optional": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "integrity": "sha1-5BuALh7t+fbK4YPOXmIteJ19jlM=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
       },
-      "engines": {
-        "node": ">= 0.8.0"
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
       }
     },
-    "node_modules/p-limit": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+    "node_modules/domelementtype": {
+      "version": "2.3.0",
+      "integrity": "sha1-XEXo6GmVJiYzHXqrMm0B2vZdWJ0=",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/domhandler": {
+      "version": "5.0.3",
+      "integrity": "sha1-zDhff3UfHR/GUMITdIBCVFOMfTE=",
       "dev": true,
+      "license": "BSD-2-Clause",
       "dependencies": {
-        "yocto-queue": "^0.1.0"
+        "domelementtype": "^2.3.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">= 4"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
       }
     },
-    "node_modules/p-locate": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+    "node_modules/domutils": {
+      "version": "3.2.2",
+      "integrity": "sha1-7b/itmiwwdl8JLrw8QYrEyIhvHg=",
       "dev": true,
+      "license": "BSD-2-Clause",
       "dependencies": {
-        "p-limit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/fb55/domutils?sponsor=1"
       }
     },
-    "node_modules/parent-module": {
+    "node_modules/dunder-proto": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "integrity": "sha1-165mfh3INIL4tw/Q9u78UNow9Yo=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "callsites": "^3.0.0"
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/parse-semver": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
-      "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
+    "node_modules/eastasianwidth": {
+      "version": "0.2.0",
+      "integrity": "sha1-aWzi7Aqg5uqTo5f/zySqeEDIJ8s=",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "integrity": "sha1-rg8PothQRe8UqBfao86azQSJ5b8=",
       "dev": true,
+      "license": "Apache-2.0",
       "dependencies": {
-        "semver": "^5.1.0"
+        "safe-buffer": "^5.0.1"
       }
     },
-    "node_modules/parse-semver/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+    "node_modules/editions": {
+      "version": "6.21.0",
+      "integrity": "sha1-jaLYVhEQbgiRpyYZt77o4MgwCJs=",
       "dev": true,
-      "bin": {
-        "semver": "bin/semver"
+      "license": "Artistic-2.0",
+      "dependencies": {
+        "version-range": "^4.13.0"
+      },
+      "engines": {
+        "node": ">=4"
+      },
+      "funding": {
+        "url": "https://bevry.me/fund"
       }
     },
-    "node_modules/parse5": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
-      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
-      "dev": true
+    "node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
+      "devOptional": true,
+      "license": "MIT"
     },
-    "node_modules/parse5-htmlparser2-tree-adapter": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
-      "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+    "node_modules/encoding-sniffer": {
+      "version": "0.2.1",
+      "integrity": "sha1-OW7JesIs5aA3ukSvGZKsnUanuBk=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "parse5": "^6.0.1"
+        "iconv-lite": "^0.6.3",
+        "whatwg-encoding": "^3.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
       }
     },
-    "node_modules/path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+    "node_modules/end-of-stream": {
+      "version": "1.4.5",
+      "integrity": "sha1-c0TXEd6kDgt0q8LtSXeHQ8ztsIw=",
       "dev": true,
-      "engines": {
-        "node": ">=8"
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "once": "^1.4.0"
       }
     },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-      "dev": true,
+    "node_modules/enhanced-resolve": {
+      "version": "5.18.2",
+      "integrity": "sha1-eQPFsy/9SyFD7rS5JHK9aO/9VGQ=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=10.13.0"
       }
     },
-    "node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+    "node_modules/entities": {
+      "version": "4.5.0",
+      "integrity": "sha1-XSaOpecRPsdMTQM7eepaNaSI+0g=",
       "dev": true,
+      "license": "BSD-2-Clause",
       "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-      "dev": true
-    },
-    "node_modules/path-to-regexp": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
-      "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
-      "dev": true,
-      "dependencies": {
-        "isarray": "0.0.1"
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
-    "node_modules/pend": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
-      "dev": true
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+    "node_modules/environment": {
+      "version": "1.1.0",
+      "integrity": "sha1-jobGaxgPNjx6sxF4fgJZZl9FqfE=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=8.6"
+        "node": ">=18"
       },
       "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prebuild-install": {
-      "version": "6.1.4",
-      "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz",
-      "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==",
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "integrity": "sha1-mD6y+aZyTpMD9hrd8BHHLgngsPo=",
       "dev": true,
-      "dependencies": {
-        "detect-libc": "^1.0.3",
-        "expand-template": "^2.0.3",
-        "github-from-package": "0.0.0",
-        "minimist": "^1.2.3",
-        "mkdirp-classic": "^0.5.3",
-        "napi-build-utils": "^1.0.1",
-        "node-abi": "^2.21.0",
-        "npmlog": "^4.0.1",
-        "pump": "^3.0.0",
-        "rc": "^1.2.7",
-        "simple-get": "^3.0.3",
-        "tar-fs": "^2.0.0",
-        "tunnel-agent": "^0.6.0"
-      },
-      "bin": {
-        "prebuild-install": "bin.js"
-      },
+      "license": "MIT",
       "engines": {
-        "node": ">=6"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/prelude-ls": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
-      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "integrity": "sha1-BfdaJdq5jk+x3NXhRywFRtUFfI8=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/process-nextick-args": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "dev": true
-    },
-    "node_modules/progress": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+    "node_modules/es-object-atoms": {
+      "version": "1.1.1",
+      "integrity": "sha1-HE8sSDcydZfOadLKGQp/3RcjOME=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/pump": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "integrity": "sha1-8x274MGDsAptJutjJcgQwP0YvU0=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "node_modules/punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true,
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
       "engines": {
-        "node": ">=6"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/qs": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
-      "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
-      "dev": true,
-      "dependencies": {
-        "side-channel": "^1.0.4"
+    "node_modules/esbuild": {
+      "version": "0.25.8",
+      "integrity": "sha1-SC1CGYtCfJwvOoG2PXZjrssd2gc=",
+      "devOptional": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
       },
       "engines": {
-        "node": ">=0.6"
+        "node": ">=18"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/randombytes": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-      "dev": true,
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.25.8",
+        "@esbuild/android-arm": "0.25.8",
+        "@esbuild/android-arm64": "0.25.8",
+        "@esbuild/android-x64": "0.25.8",
+        "@esbuild/darwin-arm64": "0.25.8",
+        "@esbuild/darwin-x64": "0.25.8",
+        "@esbuild/freebsd-arm64": "0.25.8",
+        "@esbuild/freebsd-x64": "0.25.8",
+        "@esbuild/linux-arm": "0.25.8",
+        "@esbuild/linux-arm64": "0.25.8",
+        "@esbuild/linux-ia32": "0.25.8",
+        "@esbuild/linux-loong64": "0.25.8",
+        "@esbuild/linux-mips64el": "0.25.8",
+        "@esbuild/linux-ppc64": "0.25.8",
+        "@esbuild/linux-riscv64": "0.25.8",
+        "@esbuild/linux-s390x": "0.25.8",
+        "@esbuild/linux-x64": "0.25.8",
+        "@esbuild/netbsd-arm64": "0.25.8",
+        "@esbuild/netbsd-x64": "0.25.8",
+        "@esbuild/openbsd-arm64": "0.25.8",
+        "@esbuild/openbsd-x64": "0.25.8",
+        "@esbuild/openharmony-arm64": "0.25.8",
+        "@esbuild/sunos-x64": "0.25.8",
+        "@esbuild/win32-arm64": "0.25.8",
+        "@esbuild/win32-ia32": "0.25.8",
+        "@esbuild/win32-x64": "0.25.8"
+      }
+    },
+    "node_modules/esbuild-register": {
+      "version": "3.6.0",
+      "integrity": "sha1-zycM+md7rrvAAQrAJLgjy/cjo20=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "safe-buffer": "^5.1.0"
+        "debug": "^4.3.4"
+      },
+      "peerDependencies": {
+        "esbuild": ">=0.12 <1"
       }
     },
-    "node_modules/rc": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
-      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
-      "dev": true,
-      "dependencies": {
-        "deep-extend": "^0.6.0",
-        "ini": "~1.3.0",
-        "minimist": "^1.2.0",
-        "strip-json-comments": "~2.0.1"
-      },
-      "bin": {
-        "rc": "cli.js"
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "integrity": "sha1-ARo/aYVroYnf+n3I/M6Z0qh5A+U=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
       }
     },
-    "node_modules/rc/node_modules/strip-json-comments": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
-      "dev": true,
+    "node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "integrity": "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/read": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
-      "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
-      "dev": true,
+    "node_modules/eslint": {
+      "version": "9.31.0",
+      "integrity": "sha1-mkiObadbvgV4XNYuQ8XqmTVtIbo=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "mute-stream": "~0.0.4"
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.12.1",
+        "@eslint/config-array": "^0.21.0",
+        "@eslint/config-helpers": "^0.3.0",
+        "@eslint/core": "^0.15.0",
+        "@eslint/eslintrc": "^3.3.1",
+        "@eslint/js": "9.31.0",
+        "@eslint/plugin-kit": "^0.3.1",
+        "@humanfs/node": "^0.16.6",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@humanwhocodes/retry": "^0.4.2",
+        "@types/estree": "^1.0.6",
+        "@types/json-schema": "^7.0.15",
+        "ajv": "^6.12.4",
+        "chalk": "^4.0.0",
+        "cross-spawn": "^7.0.6",
+        "debug": "^4.3.2",
+        "escape-string-regexp": "^4.0.0",
+        "eslint-scope": "^8.4.0",
+        "eslint-visitor-keys": "^4.2.1",
+        "espree": "^10.4.0",
+        "esquery": "^1.5.0",
+        "esutils": "^2.0.2",
+        "fast-deep-equal": "^3.1.3",
+        "file-entry-cache": "^8.0.0",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "ignore": "^5.2.0",
+        "imurmurhash": "^0.1.4",
+        "is-glob": "^4.0.0",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "lodash.merge": "^4.6.2",
+        "minimatch": "^3.1.2",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.9.3"
+      },
+      "bin": {
+        "eslint": "bin/eslint.js"
       },
       "engines": {
-        "node": ">=0.8"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://eslint.org/donate"
+      },
+      "peerDependencies": {
+        "jiti": "*"
+      },
+      "peerDependenciesMeta": {
+        "jiti": {
+          "optional": true
+        }
       }
     },
-    "node_modules/readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
+    "node_modules/eslint-config-prettier": {
+      "version": "10.1.8",
+      "integrity": "sha1-FXNM5K+MJ3jMMvCwGzewtc0ey5c=",
+      "license": "MIT",
+      "optional": true,
+      "bin": {
+        "eslint-config-prettier": "bin/cli.js"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint-config-prettier"
+      },
+      "peerDependencies": {
+        "eslint": ">=7.0.0"
       }
     },
-    "node_modules/readable-stream/node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
+    "node_modules/eslint-scope": {
+      "version": "8.4.0",
+      "integrity": "sha1-iOZGogf61hQ2/6OetQUUcgBlXII=",
+      "license": "BSD-2-Clause",
+      "optional": true,
       "dependencies": {
-        "picomatch": "^2.2.1"
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
       },
       "engines": {
-        "node": ">=8.10.0"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
+    "node_modules/eslint-visitor-keys": {
+      "version": "4.2.1",
+      "integrity": "sha1-TP6mD+fdCtjoFuHtAmwdUlG1EsE=",
+      "license": "Apache-2.0",
+      "optional": true,
       "engines": {
-        "node": ">=8"
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+    "node_modules/eslint/node_modules/ajv": {
+      "version": "6.12.6",
+      "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "node_modules/require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+    "node_modules/eslint/node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
-    "node_modules/resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
-      "dev": true,
+    "node_modules/eslint/node_modules/glob-parent": {
+      "version": "6.0.2",
+      "integrity": "sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-glob": "^4.0.3"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=10.13.0"
       }
     },
-    "node_modules/rewire": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/rewire/-/rewire-6.0.0.tgz",
-      "integrity": "sha512-7sZdz5dptqBCapJYocw9EcppLU62KMEqDLIILJnNET2iqzXHaQfaVP5SOJ06XvjX+dNIDJbzjw0ZWzrgDhtjYg==",
-      "dev": true,
+    "node_modules/eslint/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/eslint/node_modules/minimatch": {
+      "version": "3.1.2",
+      "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "eslint": "^7.32.0"
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dev": true,
+    "node_modules/espree": {
+      "version": "10.4.0",
+      "integrity": "sha1-1U9JSdRikAWh+haNk3w/8ffiqDc=",
+      "license": "BSD-2-Clause",
+      "optional": true,
       "dependencies": {
-        "glob": "^7.1.3"
+        "acorn": "^8.15.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^4.2.1"
       },
-      "bin": {
-        "rimraf": "bin.js"
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/isaacs"
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/safe-buffer": {
-      "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
-    },
-    "node_modules/sax": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-      "dev": true
-    },
-    "node_modules/semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
+    "node_modules/esprima": {
+      "version": "4.0.1",
+      "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=",
+      "dev": true,
+      "license": "BSD-2-Clause",
       "bin": {
-        "semver": "bin/semver.js"
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=4"
       }
     },
-    "node_modules/serialize-javascript": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
-      "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
-      "dev": true,
+    "node_modules/esquery": {
+      "version": "1.6.0",
+      "integrity": "sha1-kUGSNPgE2FKoLc7sPhbNwiz52uc=",
+      "license": "BSD-3-Clause",
+      "optional": true,
       "dependencies": {
-        "randombytes": "^2.1.0"
+        "estraverse": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
       }
     },
-    "node_modules/set-blocking": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-      "dev": true
-    },
-    "node_modules/setimmediate": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
-      "dev": true
-    },
-    "node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=",
+      "license": "BSD-2-Clause",
+      "optional": true,
       "dependencies": {
-        "shebang-regex": "^3.0.0"
+        "estraverse": "^5.2.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=4.0"
       }
     },
-    "node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
+    "node_modules/estraverse": {
+      "version": "5.3.0",
+      "integrity": "sha1-LupSkHAvJquP5TcDcP+GyWXSESM=",
+      "license": "BSD-2-Clause",
+      "optional": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=4.0"
       }
     },
-    "node_modules/side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=",
+      "license": "BSD-2-Clause",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/expand-template": {
+      "version": "2.0.3",
+      "integrity": "sha1-bhSz/O4POmNA7LV9LokYaSBSpHw=",
       "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
+      "license": "(MIT OR WTFPL)",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/fast-glob": {
+      "version": "3.3.3",
+      "integrity": "sha1-0G1YXOjbqQoWsFBcVDw8z7OuuBg=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.2",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.8"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+      "engines": {
+        "node": ">=8.6.0"
       }
     },
-    "node_modules/signal-exit": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz",
-      "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==",
-      "dev": true
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/simple-concat": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
-      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+    "node_modules/fast-levenshtein": {
+      "version": "2.0.6",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/fast-uri": {
+      "version": "3.0.6",
+      "integrity": "sha1-iPEwt3z66iN41Wv5cN6iElemh0g=",
       "dev": true,
       "funding": [
         {
           "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
+          "url": "https://github.com/sponsors/fastify"
         },
         {
-          "type": "consulting",
-          "url": "https://feross.org/support"
+          "type": "opencollective",
+          "url": "https://opencollective.com/fastify"
         }
-      ]
+      ],
+      "license": "BSD-3-Clause"
     },
-    "node_modules/simple-get": {
-      "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,
+    "node_modules/fastq": {
+      "version": "1.19.1",
+      "integrity": "sha1-1Q6rqAPIhGqIPBZJKCHrzSzaVfU=",
+      "devOptional": true,
+      "license": "ISC",
       "dependencies": {
-        "decompress-response": "^4.2.0",
-        "once": "^1.3.1",
-        "simple-concat": "^1.0.0"
+        "reusify": "^1.0.4"
       }
     },
-    "node_modules/sinon": {
-      "version": "13.0.1",
-      "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
-      "integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
+    "node_modules/fd-slicer": {
+      "version": "1.1.0",
+      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@sinonjs/commons": "^1.8.3",
-        "@sinonjs/fake-timers": "^9.0.0",
-        "@sinonjs/samsam": "^6.1.1",
-        "diff": "^5.0.0",
-        "nise": "^5.1.1",
-        "supports-color": "^7.2.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/sinon"
+        "pend": "~1.2.0"
       }
     },
-    "node_modules/sinon/node_modules/@sinonjs/fake-timers": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.0.0.tgz",
-      "integrity": "sha512-+shXA2X7KNP7H7qNbQTJ3SA+NQc0pZDSBrdvFSRwF8sAo/ohw+ZQFD8Moc+gnz51+1eRXtEQBpKWPiQ4jsRC/w==",
-      "dev": true,
+    "node_modules/file-entry-cache": {
+      "version": "8.0.0",
+      "integrity": "sha1-d4e93PETG/+5JjbGlFe7wO3W2B8=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "@sinonjs/commons": "^1.7.0"
+        "flat-cache": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=16.0.0"
       }
     },
-    "node_modules/sinon/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "integrity": "sha1-RCZdPKwH4+p9wkdRY4BkN1SgUpI=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "has-flag": "^4.0.0"
+        "to-regex-range": "^5.0.1"
       },
       "engines": {
         "node": ">=8"
       }
     },
-    "node_modules/slice-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-      "dev": true,
+    "node_modules/find-up": {
+      "version": "5.0.0",
+      "integrity": "sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
       },
       "engines": {
         "node": ">=10"
       },
       "funding": {
-        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
-    },
-    "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,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
+    "node_modules/flat": {
+      "version": "5.0.2",
+      "integrity": "sha1-jKb+MyBp/6nTJMMnGYxZglnOskE=",
+      "license": "BSD-3-Clause",
+      "optional": true,
+      "bin": {
+        "flat": "cli.js"
       }
     },
-    "node_modules/string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
+    "node_modules/flat-cache": {
+      "version": "4.0.1",
+      "integrity": "sha1-Ds45/LFO4BL0sEEL0z3ZwfAREnw=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
+        "flatted": "^3.2.9",
+        "keyv": "^4.5.4"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=16"
       }
     },
-    "node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
+    "node_modules/flatted": {
+      "version": "3.3.3",
+      "integrity": "sha1-Z8j62VRUp8er6/dLt47nSkQCM1g=",
+      "license": "ISC",
+      "optional": true
+    },
+    "node_modules/foreground-child": {
+      "version": "3.3.1",
+      "integrity": "sha1-Mujp7Rtoo0l777msK2rfkqY4V28=",
+      "devOptional": true,
+      "license": "ISC",
       "dependencies": {
-        "ansi-regex": "^5.0.1"
+        "cross-spawn": "^7.0.6",
+        "signal-exit": "^4.0.1"
       },
       "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-json-comments": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
+        "node": ">=14"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/supports-color": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+    "node_modules/form-data": {
+      "version": "4.0.4",
+      "integrity": "sha1-eEzczgZpqdaOlNEaxO6pgIjt0sQ=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "has-flag": "^4.0.0"
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "hasown": "^2.0.2",
+        "mime-types": "^2.1.12"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/supports-color?sponsor=1"
+        "node": ">= 6"
       }
     },
-    "node_modules/table": {
-      "version": "6.7.5",
-      "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz",
-      "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==",
+    "node_modules/fs-constants": {
+      "version": "1.0.0",
+      "integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0=",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/fs-extra": {
+      "version": "11.3.0",
+      "integrity": "sha1-DaztE2u69lpVWjJnGa+TGtx6MU0=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "ajv": "^8.0.1",
-        "lodash.truncate": "^4.4.2",
-        "slice-ansi": "^4.0.0",
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1"
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
       },
       "engines": {
-        "node": ">=10.0.0"
+        "node": ">=14.14"
+      }
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "license": "ISC",
+      "optional": true
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "integrity": "sha1-ysZAd4XQNnWipeGlMFxpezR9kNY=",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
       }
     },
-    "node_modules/table/node_modules/ajv": {
-      "version": "8.8.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
-      "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw=",
       "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2",
-        "uri-js": "^4.2.2"
-      },
+      "license": "MIT",
       "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/table/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
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=",
+      "license": "ISC",
+      "optional": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
     },
-    "node_modules/tar-fs": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
-      "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
-      "dev": true,
-      "dependencies": {
-        "chownr": "^1.1.1",
-        "mkdirp-classic": "^0.5.2",
-        "pump": "^3.0.0",
-        "tar-stream": "^2.1.4"
+    "node_modules/get-east-asian-width": {
+      "version": "1.3.0",
+      "integrity": "sha1-IbQHHuWO0E7g22UzcbVbQpmHU4k=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/tar-stream": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
-      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "integrity": "sha1-dD8OO2lkqTpUke0b/6rgVNf5jQE=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "bl": "^4.0.3",
-        "end-of-stream": "^1.4.1",
-        "fs-constants": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.1.1"
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/tar-stream/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "integrity": "sha1-FQs/J0OGnvPoUewMSdFbHRTQDuE=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
       },
       "engines": {
-        "node": ">= 6"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/text-table": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
-      "dev": true
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+    "node_modules/github-from-package": {
+      "version": "0.0.0",
+      "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
       "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/glob": {
+      "version": "10.4.5",
+      "integrity": "sha1-9NnwuQ/9urCcnXf18ptCYlF7CVY=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "is-number": "^7.0.0"
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
       },
-      "engines": {
-        "node": ">=8.0"
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
-    },
-    "node_modules/traverse": {
-      "version": "0.3.9",
-      "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
-      "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=",
-      "dev": true,
+    "node_modules/glob-parent": {
+      "version": "5.1.2",
+      "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=",
+      "devOptional": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
       "engines": {
-        "node": "*"
+        "node": ">= 6"
       }
     },
-    "node_modules/tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "dev": true
-    },
-    "node_modules/tslint": {
-      "version": "6.1.3",
-      "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
-      "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
-      "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.",
-      "dev": true,
-      "dependencies": {
-        "@babel/code-frame": "^7.0.0",
-        "builtin-modules": "^1.1.1",
-        "chalk": "^2.3.0",
-        "commander": "^2.12.1",
-        "diff": "^4.0.1",
-        "glob": "^7.1.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
-        "mkdirp": "^0.5.3",
-        "resolve": "^1.3.2",
-        "semver": "^5.3.0",
-        "tslib": "^1.13.0",
-        "tsutils": "^2.29.0"
-      },
-      "bin": {
-        "tslint": "bin/tslint"
-      },
+    "node_modules/globals": {
+      "version": "14.0.0",
+      "integrity": "sha1-iY10E8Kbq89rr+Vvyt3thYrack4=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=4.8.0"
+        "node": ">=18"
       },
-      "peerDependencies": {
-        "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/tslint/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+    "node_modules/globby": {
+      "version": "14.1.0",
+      "integrity": "sha1-E4t453z1qNeU4yexXc6Avx+wpz4=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "color-convert": "^1.9.0"
+        "@sindresorhus/merge-streams": "^2.1.0",
+        "fast-glob": "^3.3.3",
+        "ignore": "^7.0.3",
+        "path-type": "^6.0.0",
+        "slash": "^5.1.0",
+        "unicorn-magic": "^0.3.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/tslint/node_modules/argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+    "node_modules/globby/node_modules/ignore": {
+      "version": "7.0.5",
+      "integrity": "sha1-TLX2zX1MerA2VzjHrqiIuqbX79k=",
       "dev": true,
-      "dependencies": {
-        "sprintf-js": "~1.0.2"
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
       }
     },
-    "node_modules/tslint/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "integrity": "sha1-ifVrghe9vIgCvSmd9tfxCB1+UaE=",
       "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
+      "license": "MIT",
       "engines": {
-        "node": ">=4"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/tslint/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "integrity": "sha1-QYPk6L8Iu24Fu7L30uDI9xLKQOM=",
+      "devOptional": true,
+      "license": "ISC"
     },
-    "node_modules/tslint/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
+    "node_modules/graphemer": {
+      "version": "1.4.0",
+      "integrity": "sha1-+y8dVeDjoYSa7/yQxPoN1ToOZsY=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/tslint/node_modules/diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true,
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+      "devOptional": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=0.3.1"
+        "node": ">=8"
       }
     },
-    "node_modules/tslint/node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "integrity": "sha1-/JxqeDoISVHQuXH+EBjegTcHozg=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=0.8.0"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/tslint/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "integrity": "sha1-LNxC1AvvLltO6rfAGnPFTOerWrw=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
       "engines": {
-        "node": ">=4"
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/tslint/node_modules/js-yaml": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+    "node_modules/hasown": {
+      "version": "2.0.2",
+      "integrity": "sha1-AD6vkb563DcuhOxZ3DclLO24AAM=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
+        "function-bind": "^1.1.2"
       },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
+      "engines": {
+        "node": ">= 0.4"
       }
     },
-    "node_modules/tslint/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
+    "node_modules/he": {
+      "version": "1.2.0",
+      "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=",
+      "license": "MIT",
+      "optional": true,
       "bin": {
-        "semver": "bin/semver"
+        "he": "bin/he"
       }
     },
-    "node_modules/tslint/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+    "node_modules/hosted-git-info": {
+      "version": "4.1.0",
+      "integrity": "sha1-gnuChn6f8cjQxNnVOIA5fSyG0iQ=",
       "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "has-flag": "^3.0.0"
+        "lru-cache": "^6.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=10"
       }
     },
-    "node_modules/tsutils": {
-      "version": "2.29.0",
-      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
-      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+    "node_modules/html-escaper": {
+      "version": "2.0.2",
+      "integrity": "sha1-39YAJ9o2o238viNiYsAKWCJoFFM=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/htmlparser2": {
+      "version": "10.0.0",
+      "integrity": "sha1-d60kkDe2a/jMmcbihu9zuDrrYh0=",
       "dev": true,
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "MIT",
       "dependencies": {
-        "tslib": "^1.8.1"
-      },
-      "peerDependencies": {
-        "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev"
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.2.1",
+        "entities": "^6.0.0"
       }
     },
-    "node_modules/tunnel": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
-      "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+    "node_modules/htmlparser2/node_modules/entities": {
+      "version": "6.0.1",
+      "integrity": "sha1-wow0pDN5yn9h0HQTCy9fcCCjBpQ=",
       "dev": true,
+      "license": "BSD-2-Clause",
       "engines": {
-        "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
-    "node_modules/tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
+    "node_modules/http-proxy-agent": {
+      "version": "7.0.2",
+      "integrity": "sha1-mosfJGhmwChQlIZYX2K48sGMJw4=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "safe-buffer": "^5.0.1"
+        "agent-base": "^7.1.0",
+        "debug": "^4.3.4"
       },
       "engines": {
-        "node": "*"
+        "node": ">= 14"
       }
     },
-    "node_modules/type-check": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
-      "dev": true,
+    "node_modules/https-proxy-agent": {
+      "version": "7.0.6",
+      "integrity": "sha1-2o3+rH2hMLBcK6S1nJts1mYRprk=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "prelude-ls": "^1.2.1"
+        "agent-base": "^7.1.2",
+        "debug": "4"
       },
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">= 14"
       }
     },
-    "node_modules/type-detect": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
-      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "integrity": "sha1-pS+AvzjaGVLrXGgXkHGYcaGnJQE=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
       "engines": {
-        "node": ">=4"
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/type-fest": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "integrity": "sha1-jrehCmP/8l0VpXsAFYbRd9Gw01I=",
       "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "BSD-3-Clause",
+      "optional": true
+    },
+    "node_modules/ignore": {
+      "version": "5.3.2",
+      "integrity": "sha1-PNQOcp82Q/2HywTlC/DrcivFlvU=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=10"
+        "node": ">= 4"
+      }
+    },
+    "node_modules/immediate": {
+      "version": "3.0.6",
+      "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/import-fresh": {
+      "version": "3.3.1",
+      "integrity": "sha1-nOy1ZQPAraHydB271lRuSxO1fM8=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/typed-rest-client": {
-      "version": "1.8.6",
-      "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.6.tgz",
-      "integrity": "sha512-xcQpTEAJw2DP7GqVNECh4dD+riS+C1qndXLfBCJ3xk0kqprtGN491P5KlmrDbKdtuW8NEcP/5ChxiJI3S9WYTA==",
-      "dev": true,
-      "dependencies": {
-        "qs": "^6.9.1",
-        "tunnel": "0.0.6",
-        "underscore": "^1.12.1"
+    "node_modules/imurmurhash": {
+      "version": "0.1.4",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.8.19"
       }
     },
-    "node_modules/typescript": {
-      "version": "4.5.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
-      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+    "node_modules/index-to-position": {
+      "version": "1.1.0",
+      "integrity": "sha1-LlC9VMgEC91tmz2V7CqP7fhrTUQ=",
       "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
+      "license": "MIT",
       "engines": {
-        "node": ">=4.2.0"
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/uc.micro": {
+    "node_modules/inflight": {
       "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
-      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
-      "dev": true
-    },
-    "node_modules/underscore": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
-      "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
-      "dev": true
-    },
-    "node_modules/unzipper": {
-      "version": "0.10.11",
-      "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz",
-      "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==",
-      "dev": true,
-      "dependencies": {
-        "big-integer": "^1.6.17",
-        "binary": "~0.3.0",
-        "bluebird": "~3.4.1",
-        "buffer-indexof-polyfill": "~1.0.0",
-        "duplexer2": "~0.1.4",
-        "fstream": "^1.0.12",
-        "graceful-fs": "^4.2.2",
-        "listenercount": "~1.0.1",
-        "readable-stream": "~2.3.6",
-        "setimmediate": "~1.0.4"
-      }
-    },
-    "node_modules/uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "punycode": "^2.1.0"
+        "once": "^1.3.0",
+        "wrappy": "1"
       }
     },
-    "node_modules/url-join": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
-      "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
-      "dev": true
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=",
+      "license": "ISC",
+      "optional": true
     },
-    "node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "dev": true
+    "node_modules/ini": {
+      "version": "1.3.8",
+      "integrity": "sha1-op2kJbSIBvNHZ6Tvzjlyaa8oQyw=",
+      "dev": true,
+      "license": "ISC",
+      "optional": true
     },
-    "node_modules/uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
-      "bin": {
-        "uuid": "dist/bin/uuid"
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
-    },
-    "node_modules/vsce": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.6.7.tgz",
-      "integrity": "sha512-5dEtdi/yzWQbOU7JDUSOs8lmSzzkewBR5P122BUkmXE6A/DEdFsKNsg2773NGXJTwwF1MfsOgUR6QVF3cLLJNQ==",
+    "node_modules/is-docker": {
+      "version": "3.0.0",
+      "integrity": "sha1-kAk6oxBid9inelkQ265xdH4VogA=",
       "dev": true,
-      "dependencies": {
-        "azure-devops-node-api": "^11.0.1",
-        "chalk": "^2.4.2",
-        "cheerio": "^1.0.0-rc.9",
-        "commander": "^6.1.0",
-        "glob": "^7.0.6",
-        "hosted-git-info": "^4.0.2",
-        "keytar": "^7.7.0",
-        "leven": "^3.1.0",
-        "markdown-it": "^12.3.2",
-        "mime": "^1.3.4",
-        "minimatch": "^3.0.3",
-        "parse-semver": "^1.1.1",
-        "read": "^1.0.7",
-        "semver": "^5.1.0",
-        "tmp": "^0.2.1",
-        "typed-rest-client": "^1.8.4",
-        "url-join": "^4.0.1",
-        "xml2js": "^0.4.23",
-        "yauzl": "^2.3.1",
-        "yazl": "^2.2.2"
-      },
+      "license": "MIT",
       "bin": {
-        "vsce": "vsce"
+        "is-docker": "cli.js"
       },
       "engines": {
-        "node": ">= 14"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/vsce/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "devOptional": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=4"
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/vsce/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
+      "devOptional": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
-    "node_modules/vsce/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=",
+      "devOptional": true,
+      "license": "MIT",
       "dependencies": {
-        "color-name": "1.1.3"
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/vsce/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "node_modules/vsce/node_modules/commander": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
-      "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+    "node_modules/is-inside-container": {
+      "version": "1.0.0",
+      "integrity": "sha1-6B+6aZZi6zHb2vJnZqYdSBRxfqQ=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-docker": "^3.0.0"
+      },
+      "bin": {
+        "is-inside-container": "cli.js"
+      },
       "engines": {
-        "node": ">= 6"
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/vsce/node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-      "dev": true,
+    "node_modules/is-interactive": {
+      "version": "2.0.0",
+      "integrity": "sha1-QMV2FFk4JtoRAK3mBZd41ZfxbpA=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=0.8.0"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/vsce/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true,
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+      "devOptional": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=4"
+        "node": ">=0.12.0"
       }
     },
-    "node_modules/vsce/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
+    "node_modules/is-plain-obj": {
+      "version": "2.1.0",
+      "integrity": "sha1-ReQuN/zPH0Dajl927iFRWEDAkoc=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/vsce/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
+    "node_modules/is-unicode-supported": {
+      "version": "0.1.0",
+      "integrity": "sha1-PybHaoCVk7Ur+i7LVxDtJ3m1Iqc=",
+      "license": "MIT",
+      "optional": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/vsce/node_modules/tmp": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
-      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+    "node_modules/is-wsl": {
+      "version": "3.1.0",
+      "integrity": "sha1-4cZX45wQCQr8vt7GFyD2uSTDy9I=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "rimraf": "^3.0.0"
+        "is-inside-container": "^1.0.0"
       },
       "engines": {
-        "node": ">=8.17.0"
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/vscode-extension-telemetry": {
-      "version": "0.4.5",
-      "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.4.5.tgz",
-      "integrity": "sha512-YhPiPcelqM5xyYWmD46jIcsxLYWkPZhAxlBkzqmpa218fMtTT17ERdOZVCXcs1S5AjvDHlq43yCgi8TaVQjjEg==",
-      "engines": {
-        "vscode": "^1.60.0"
-      }
+    "node_modules/isarray": {
+      "version": "1.0.0",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/vscode-jsonrpc": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
-      "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "devOptional": true,
+      "license": "ISC"
+    },
+    "node_modules/istanbul-lib-coverage": {
+      "version": "3.2.2",
+      "integrity": "sha1-LRZsSwZE1Do58Ev2wu3R5YXzF1Y=",
+      "license": "BSD-3-Clause",
+      "optional": true,
       "engines": {
-        "node": ">=8.0.0 || >=10.0.0"
+        "node": ">=8"
       }
     },
-    "node_modules/vscode-languageclient": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
-      "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
+    "node_modules/istanbul-lib-report": {
+      "version": "3.0.1",
+      "integrity": "sha1-kIMFusmlvRdaxqdEier9D8JEWn0=",
+      "license": "BSD-3-Clause",
+      "optional": true,
       "dependencies": {
-        "minimatch": "^3.0.4",
-        "semver": "^7.3.4",
-        "vscode-languageserver-protocol": "3.16.0"
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^4.0.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
-        "vscode": "^1.52.0"
+        "node": ">=10"
       }
     },
-    "node_modules/vscode-languageserver-protocol": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
-      "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
+    "node_modules/istanbul-lib-report/node_modules/supports-color": {
+      "version": "7.2.0",
+      "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "vscode-jsonrpc": "6.0.0",
-        "vscode-languageserver-types": "3.16.0"
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/vscode-languageserver-types": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
-      "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
-    },
-    "node_modules/webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
-    },
-    "node_modules/whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+    "node_modules/istanbul-reports": {
+      "version": "3.1.7",
+      "integrity": "sha1-2u0SueHcpRjhXAVuHlN+dBKA+gs=",
+      "license": "BSD-3-Clause",
+      "optional": true,
       "dependencies": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+    "node_modules/istextorbinary": {
+      "version": "9.5.0",
+      "integrity": "sha1-5uE/6/HBaFEAriZICaT49G4B39M=",
       "dev": true,
+      "license": "Artistic-2.0",
       "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
+        "binaryextensions": "^6.11.0",
+        "editions": "^6.21.0",
+        "textextensions": "^6.11.0"
       },
       "engines": {
-        "node": ">= 8"
+        "node": ">=4"
+      },
+      "funding": {
+        "url": "https://bevry.me/fund"
       }
     },
-    "node_modules/wide-align": {
-      "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,
+    "node_modules/jackspeak": {
+      "version": "3.4.3",
+      "integrity": "sha1-iDOp2Jq0rN5hiJQr0cU7Y5DtWoo=",
+      "license": "BlueOak-1.0.0",
+      "optional": true,
       "dependencies": {
-        "string-width": "^1.0.2 || 2 || 3 || 4"
+        "@isaacs/cliui": "^8.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      },
+      "optionalDependencies": {
+        "@pkgjs/parseargs": "^0.11.0"
       }
     },
-    "node_modules/word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=",
       "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+      "license": "MIT"
+    },
+    "node_modules/js-yaml": {
+      "version": "3.14.1",
+      "integrity": "sha1-2ugS/bOCX6MGYJqHFzg8UMNqBTc=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/workerpool": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
-      "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
-      "dev": true
+    "node_modules/json-buffer": {
+      "version": "3.0.1",
+      "integrity": "sha1-kziAKjDTtmBfvgYT4JQAjKjAWhM=",
+      "license": "MIT",
+      "optional": true
     },
-    "node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+    "node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "integrity": "sha1-rnvLNlard6c7pcSb9lTzjmtoYOI=",
       "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
+      "license": "MIT"
+    },
+    "node_modules/json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "integrity": "sha1-eM1vGhm9wStz21rQxh79ZsHikoM=",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "json5": "lib/cli.js"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+        "node": ">=6"
       }
     },
-    "node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
+    "node_modules/jsonc-parser": {
+      "version": "3.3.1",
+      "integrity": "sha1-8qUktPf9EePXkeVZl3rWC5i3mLQ=",
+      "dev": true,
+      "license": "MIT"
     },
-    "node_modules/xml2js": {
-      "version": "0.4.23",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
-      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+    "node_modules/jsonfile": {
+      "version": "6.1.0",
+      "integrity": "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "sax": ">=0.6.0",
-        "xmlbuilder": "~11.0.0"
+        "universalify": "^2.0.0"
       },
-      "engines": {
-        "node": ">=4.0.0"
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
       }
     },
-    "node_modules/xmlbuilder": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
-      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+    "node_modules/jsonwebtoken": {
+      "version": "9.0.2",
+      "integrity": "sha1-Zf+R9KvvF4RpfUCVK7GZjFBMqvM=",
       "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^7.5.4"
+      },
       "engines": {
-        "node": ">=4.0"
+        "node": ">=12",
+        "npm": ">=6"
       }
     },
-    "node_modules/y18n": {
-      "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+    "node_modules/jszip": {
+      "version": "3.10.1",
+      "integrity": "sha1-NK7nDrGOofrsL1iSCKFX0f6wkcI=",
+      "license": "(MIT OR GPL-3.0-or-later)",
+      "optional": true,
+      "dependencies": {
+        "lie": "~3.3.0",
+        "pako": "~1.0.2",
+        "readable-stream": "~2.3.6",
+        "setimmediate": "^1.0.5"
+      }
+    },
+    "node_modules/just-extend": {
+      "version": "6.2.0",
+      "integrity": "sha1-uBar+z1n7oYEgudAFWRnJVgWOUc=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/jwa": {
+      "version": "1.4.2",
+      "integrity": "sha1-FgEaxttI3nsQJ3fleJeQFSDux7k=",
       "dev": true,
-      "engines": {
-        "node": ">=10"
+      "license": "MIT",
+      "dependencies": {
+        "buffer-equal-constant-time": "^1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
       }
     },
-    "node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "integrity": "sha1-ABCZ82OUaMlBQADpmZX6UvtHgwQ=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
     },
-    "node_modules/yargs": {
-      "version": "16.2.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+    "node_modules/keytar": {
+      "version": "7.9.0",
+      "integrity": "sha1-TGIlcI9RtQy/d8Wq6BchlkwpGMs=",
       "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "cliui": "^7.0.2",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
-      },
-      "engines": {
-        "node": ">=10"
+        "node-addon-api": "^4.3.0",
+        "prebuild-install": "^7.0.1"
       }
     },
-    "node_modules/yargs-parser": {
-      "version": "20.2.4",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
-      "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+    "node_modules/keyv": {
+      "version": "4.5.4",
+      "integrity": "sha1-qHmpnilFL5QkOfKkBeOvizHU3pM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "json-buffer": "3.0.1"
+      }
+    },
+    "node_modules/leven": {
+      "version": "3.1.0",
+      "integrity": "sha1-d4kd6DQGTMy6gq54QrtrFKE+1/I=",
       "dev": true,
+      "license": "MIT",
       "engines": {
-        "node": ">=10"
+        "node": ">=6"
       }
     },
-    "node_modules/yargs-unparser": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
-      "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
-      "dev": true,
+    "node_modules/levn": {
+      "version": "0.4.1",
+      "integrity": "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "camelcase": "^6.0.0",
-        "decamelize": "^4.0.0",
-        "flat": "^5.0.2",
-        "is-plain-obj": "^2.1.0"
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">= 0.8.0"
       }
     },
-    "node_modules/yauzl": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
-      "dev": true,
+    "node_modules/lie": {
+      "version": "3.3.0",
+      "integrity": "sha1-3Pgt7lRfRgdNryAMfBxaCOD0D2o=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "buffer-crc32": "~0.2.3",
-        "fd-slicer": "~1.1.0"
+        "immediate": "~3.0.5"
       }
     },
-    "node_modules/yazl": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
-      "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+    "node_modules/linkify-it": {
+      "version": "5.0.0",
+      "integrity": "sha1-nvI4v6bccL2Of5VytS02mvVptCE=",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "buffer-crc32": "~0.2.3"
+        "uc.micro": "^2.0.0"
       }
     },
-    "node_modules/yocto-queue": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true,
+    "node_modules/locate-path": {
+      "version": "6.0.0",
+      "integrity": "sha1-VTIeswn+u8WcSAHZMackUqaB0oY=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "p-locate": "^5.0.0"
+      },
       "engines": {
         "node": ">=10"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
-    }
-  },
-  "dependencies": {
-    "@babel/code-frame": {
-      "version": "7.16.0",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
-      "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.16.0"
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.15.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
-      "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
-      "dev": true
-    },
-    "@babel/highlight": {
-      "version": "7.16.0",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz",
-      "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.15.7",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
-      }
     },
-    "@eslint/eslintrc": {
-      "version": "0.4.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
-      "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=",
       "dev": true,
-      "requires": {
-        "ajv": "^6.12.4",
-        "debug": "^4.1.1",
-        "espree": "^7.3.0",
-        "globals": "^13.9.0",
-        "ignore": "^4.0.6",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
-        "strip-json-comments": "^3.1.1"
-      },
-      "dependencies": {
-        "argparse": {
-          "version": "1.0.10",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-          "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-          "dev": true,
-          "requires": {
-            "sprintf-js": "~1.0.2"
-          }
-        },
-        "js-yaml": {
-          "version": "3.14.1",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-          "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
-          "dev": true,
-          "requires": {
-            "argparse": "^1.0.7",
-            "esprima": "^4.0.0"
-          }
-        }
-      }
+      "license": "MIT"
     },
-    "@humanwhocodes/config-array": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
-      "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+    "node_modules/lodash.get": {
+      "version": "4.4.2",
+      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=",
       "dev": true,
-      "requires": {
-        "@humanwhocodes/object-schema": "^1.2.0",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
-      }
+      "license": "MIT"
     },
-    "@humanwhocodes/object-schema": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-      "dev": true
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=",
+      "dev": true,
+      "license": "MIT"
     },
-    "@sinonjs/commons": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
-      "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=",
       "dev": true,
-      "requires": {
-        "type-detect": "4.0.8"
-      }
+      "license": "MIT"
     },
-    "@sinonjs/fake-timers": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
-      "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=",
       "dev": true,
-      "requires": {
-        "@sinonjs/commons": "^1.7.0"
-      }
+      "license": "MIT"
     },
-    "@sinonjs/samsam": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz",
-      "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==",
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
       "dev": true,
-      "requires": {
-        "@sinonjs/commons": "^1.6.0",
-        "lodash.get": "^4.4.2",
-        "type-detect": "^4.0.8"
-      }
+      "license": "MIT"
     },
-    "@sinonjs/text-encoding": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
-      "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
-      "dev": true
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=",
+      "dev": true,
+      "license": "MIT"
     },
-    "@tootallnate/once": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
-      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
-      "dev": true
+    "node_modules/lodash.merge": {
+      "version": "4.6.2",
+      "integrity": "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo=",
+      "license": "MIT",
+      "optional": true
     },
-    "@types/glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=",
       "dev": true,
-      "requires": {
-        "@types/minimatch": "*",
-        "@types/node": "*"
-      }
+      "license": "MIT"
     },
-    "@types/minimatch": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
-      "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
-      "dev": true
+    "node_modules/lodash.truncate": {
+      "version": "4.4.2",
+      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+      "dev": true,
+      "license": "MIT"
     },
-    "@types/mocha": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz",
-      "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==",
-      "dev": true
+    "node_modules/log-symbols": {
+      "version": "4.1.0",
+      "integrity": "sha1-P727lbRoOsn8eFER55LlWNSr1QM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "chalk": "^4.1.0",
+        "is-unicode-supported": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "@types/mock-fs": {
-      "version": "4.13.1",
-      "resolved": "https://registry.npmjs.org/@types/mock-fs/-/mock-fs-4.13.1.tgz",
-      "integrity": "sha512-m6nFAJ3lBSnqbvDZioawRvpLXSaPyn52Srf7OfzjubYbYX8MTUdIgDxQl0wEapm4m/pNYSd9TXocpQ0TvZFlYA==",
+    "node_modules/lru-cache": {
+      "version": "6.0.0",
+      "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=",
       "dev": true,
-      "requires": {
-        "@types/node": "*"
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "@types/node": {
-      "version": "14.17.33",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.33.tgz",
-      "integrity": "sha512-noEeJ06zbn3lOh4gqe2v7NMGS33jrulfNqYFDjjEbhpDEHR5VTxgYNQSBqBlJIsBJW3uEYDgD6kvMnrrhGzq8g==",
-      "dev": true
+    "node_modules/make-dir": {
+      "version": "4.0.0",
+      "integrity": "sha1-w8IwencSd82WODBfkVwprnQbYU4=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "@types/node-fetch": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
-      "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
+    "node_modules/markdown-it": {
+      "version": "14.1.0",
+      "integrity": "sha1-PDxZkog8Yz20cUzLTXtZNdmLfUU=",
       "dev": true,
-      "requires": {
-        "@types/node": "*",
-        "form-data": "^3.0.0"
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^2.0.1",
+        "entities": "^4.4.0",
+        "linkify-it": "^5.0.0",
+        "mdurl": "^2.0.0",
+        "punycode.js": "^2.3.1",
+        "uc.micro": "^2.1.0"
+      },
+      "bin": {
+        "markdown-it": "bin/markdown-it.mjs"
       }
     },
-    "@types/rewire": {
-      "version": "2.5.28",
-      "resolved": "https://registry.npmjs.org/@types/rewire/-/rewire-2.5.28.tgz",
-      "integrity": "sha512-uD0j/AQOa5le7afuK+u+woi8jNKF1vf3DN0H7LCJhft/lNNibUr7VcAesdgtWfEKveZol3ZG1CJqwx2Bhrnl8w==",
-      "dev": true
-    },
-    "@types/semver": {
-      "version": "7.3.9",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz",
-      "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==",
-      "dev": true
+    "node_modules/markdown-it/node_modules/argparse": {
+      "version": "2.0.1",
+      "integrity": "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=",
+      "dev": true,
+      "license": "Python-2.0"
     },
-    "@types/sinon": {
-      "version": "10.0.11",
-      "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz",
-      "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==",
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "integrity": "sha1-oN10voHiqlwvJ+Zc4oNgXuTit/k=",
       "dev": true,
-      "requires": {
-        "@types/sinonjs__fake-timers": "*"
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
       }
     },
-    "@types/sinonjs__fake-timers": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
-      "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
-      "dev": true
-    },
-    "@types/uuid": {
-      "version": "8.3.4",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
-      "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
-      "dev": true
-    },
-    "@types/vscode": {
-      "version": "1.56.0",
-      "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.56.0.tgz",
-      "integrity": "sha512-Q5VmQxOx+L1Y6lIJiGcJzwcyV3pQo/eiW8P+7sNLhFI16tJCwtua2DLjHRcpjbCLNVYpQM73kzfFo1Z0HyP9eQ==",
-      "dev": true
-    },
-    "@ungap/promise-all-settled": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
-      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
-      "dev": true
-    },
-    "@vscode/test-electron": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.2.tgz",
-      "integrity": "sha512-INjJ0YA9RgR1B/xBl8P4sxww4Dy2996f4Xn5oGTFfC0c2Mm45y/1Id8xmfuoba6tR5i8zZaUIHfEYWe7Rt4uZA==",
+    "node_modules/mdurl": {
+      "version": "2.0.0",
+      "integrity": "sha1-gGduwEMwJd0+F+6YPQ/o3loiN+A=",
       "dev": true,
-      "requires": {
-        "http-proxy-agent": "^4.0.1",
-        "https-proxy-agent": "^5.0.0",
-        "rimraf": "^3.0.2",
-        "unzipper": "^0.10.11"
+      "license": "MIT"
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "acorn": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
-      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
-      "dev": true
+    "node_modules/micromatch": {
+      "version": "4.0.8",
+      "integrity": "sha1-1m+hjzpHB2eJMgubGvMr2G2fogI=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
     },
-    "acorn-jsx": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
-      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=",
       "dev": true,
-      "requires": {}
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
     },
-    "agent-base": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "integrity": "sha1-u6vNwChZ9JhzAchW4zh85exDv3A=",
       "dev": true,
-      "requires": {
-        "debug": "4"
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
       }
     },
-    "ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "integrity": "sha1-OBqHG2KnNEUGYK497uRIE/cNlZo=",
       "dev": true,
-      "requires": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
       }
     },
-    "ansi-colors": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
-      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-      "dev": true
-    },
-    "ansi-regex": {
+    "node_modules/mimic-function": {
       "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "requires": {
-        "color-convert": "^2.0.1"
+      "integrity": "sha1-rL4rM0n5m53qyn+3Dki4PpTmcHY=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+    "node_modules/mimic-response": {
+      "version": "3.1.0",
+      "integrity": "sha1-LR1Zr5wbEpgVrMwsRqAipc4fo8k=",
       "dev": true,
-      "requires": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
-      "dev": true
+    "node_modules/minimatch": {
+      "version": "9.0.5",
+      "integrity": "sha1-10+d1rV9g9jpjPuCEzsDl4vJKeU=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
     },
-    "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==",
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "integrity": "sha1-waRk52kzAuCCoHXO4MBXdBrEdyw=",
       "dev": true,
-      "requires": {
-        "delegates": "^1.0.0",
-        "readable-stream": "^2.0.6"
+      "license": "MIT",
+      "optional": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true
-    },
-    "astral-regex": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
-      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
-      "dev": true
-    },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
+    "node_modules/minipass": {
+      "version": "7.1.2",
+      "integrity": "sha1-k6libOXl5mvU24aEnnUV6SNApwc=",
+      "devOptional": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
     },
-    "azure-devops-node-api": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.0.1.tgz",
-      "integrity": "sha512-YMdjAw9l5p/6leiyIloxj3k7VIvYThKjvqgiQn88r3nhT93ENwsoDS3A83CyJ4uTWzCZ5f5jCi6c27rTU5Pz+A==",
+    "node_modules/mkdirp-classic": {
+      "version": "0.5.3",
+      "integrity": "sha1-+hDJEVzG2IZb4iG6R+6b7XhgERM=",
       "dev": true,
-      "requires": {
-        "tunnel": "0.0.6",
-        "typed-rest-client": "^1.8.4"
-      }
+      "license": "MIT",
+      "optional": true
     },
-    "balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+    "node_modules/mocha": {
+      "version": "10.8.2",
+      "integrity": "sha1-jYNC0BbtQRsSpCnrcxuCX5Ya+5Y=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "ansi-colors": "^4.1.3",
+        "browser-stdout": "^1.3.1",
+        "chokidar": "^3.5.3",
+        "debug": "^4.3.5",
+        "diff": "^5.2.0",
+        "escape-string-regexp": "^4.0.0",
+        "find-up": "^5.0.0",
+        "glob": "^8.1.0",
+        "he": "^1.2.0",
+        "js-yaml": "^4.1.0",
+        "log-symbols": "^4.1.0",
+        "minimatch": "^5.1.6",
+        "ms": "^2.1.3",
+        "serialize-javascript": "^6.0.2",
+        "strip-json-comments": "^3.1.1",
+        "supports-color": "^8.1.1",
+        "workerpool": "^6.5.1",
+        "yargs": "^16.2.0",
+        "yargs-parser": "^20.2.9",
+        "yargs-unparser": "^2.0.0"
+      },
+      "bin": {
+        "_mocha": "bin/_mocha",
+        "mocha": "bin/mocha.js"
+      },
+      "engines": {
+        "node": ">= 14.0.0"
+      }
     },
-    "base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true
+    "node_modules/mocha/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "big-integer": {
-      "version": "1.6.50",
-      "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz",
-      "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==",
-      "dev": true
+    "node_modules/mocha/node_modules/argparse": {
+      "version": "2.0.1",
+      "integrity": "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=",
+      "license": "Python-2.0",
+      "optional": true
     },
-    "binary": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
-      "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
-      "dev": true,
-      "requires": {
-        "buffers": "~0.1.1",
-        "chainsaw": "~0.1.0"
+    "node_modules/mocha/node_modules/cliui": {
+      "version": "7.0.4",
+      "integrity": "sha1-oCZe5lVHb8gHrqnfPfjfd4OAi08=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
       }
     },
-    "binary-extensions": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
-      "dev": true
+    "node_modules/mocha/node_modules/glob": {
+      "version": "8.1.0",
+      "integrity": "sha1-04j2Vlk+9wjuPjRkD9+5mp/Rwz4=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
     },
-    "bl": {
+    "node_modules/mocha/node_modules/js-yaml": {
       "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "dev": true,
-      "requires": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
-      },
+      "integrity": "sha1-wftl+PUBeQHN0slRhkuhhFihBgI=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        }
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "bluebird": {
-      "version": "3.4.7",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
-      "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=",
-      "dev": true
-    },
-    "boolbase": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
-      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
-      "dev": true
-    },
-    "brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "requires": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+    "node_modules/mocha/node_modules/minimatch": {
+      "version": "5.1.6",
+      "integrity": "sha1-HPy4z1Ui6mmVLNKvla4JR38SKpY=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dev": true,
-      "requires": {
-        "fill-range": "^7.0.1"
+    "node_modules/mocha/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "browser-stdout": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
-      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
-      "dev": true
-    },
-    "buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
-      "requires": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
+    "node_modules/mocha/node_modules/supports-color": {
+      "version": "8.1.1",
+      "integrity": "sha1-zW/BfihQDP9WwbhsCn/UpUpzAFw=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
-    "buffer-crc32": {
-      "version": "0.2.13",
-      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
-      "dev": true
-    },
-    "buffer-indexof-polyfill": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
-      "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
-      "dev": true
-    },
-    "buffers": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
-      "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=",
-      "dev": true
+    "node_modules/mocha/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
     },
-    "builtin-modules": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
-      "dev": true
+    "node_modules/mocha/node_modules/yargs": {
+      "version": "16.2.0",
+      "integrity": "sha1-HIK/D2tqZur85+8w43b0mhJHf2Y=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
     },
-    "call-bind": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
-      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2"
+    "node_modules/mocha/node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "integrity": "sha1-LrfcOwKJcY/ClfNidThFxBoMlO4=",
+      "license": "ISC",
+      "optional": true,
+      "engines": {
+        "node": ">=10"
       }
     },
-    "callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true
+    "node_modules/mock-fs": {
+      "version": "5.5.0",
+      "integrity": "sha1-lKRtKZqqWI5zWiAcvoI8h26R84U=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=12.0.0"
+      }
     },
-    "camelcase": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
-      "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
-      "dev": true
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=",
+      "devOptional": true,
+      "license": "MIT"
     },
-    "chainsaw": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
-      "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
+    "node_modules/mute-stream": {
+      "version": "0.0.8",
+      "integrity": "sha1-FjDEKyJR/4HiooPelqVJfqkuXg0=",
       "dev": true,
-      "requires": {
-        "traverse": ">=0.3.0 <0.4"
-      }
+      "license": "ISC"
     },
-    "chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+    "node_modules/napi-build-utils": {
+      "version": "2.0.0",
+      "integrity": "sha1-E8IsAYf8/MzhRhhEE2NypH3cAn4=",
       "dev": true,
-      "requires": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/natural-compare": {
+      "version": "1.4.0",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/nise": {
+      "version": "6.1.1",
+      "integrity": "sha1-eOqTzEm+Ei5Ey3yP31l7Dod4tko=",
+      "license": "BSD-3-Clause",
+      "optional": true,
       "dependencies": {
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
+        "@sinonjs/commons": "^3.0.1",
+        "@sinonjs/fake-timers": "^13.0.1",
+        "@sinonjs/text-encoding": "^0.7.3",
+        "just-extend": "^6.2.0",
+        "path-to-regexp": "^8.1.0"
       }
     },
-    "cheerio": {
-      "version": "1.0.0-rc.10",
-      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
-      "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+    "node_modules/node-abi": {
+      "version": "3.75.0",
+      "integrity": "sha1-L5KakakKDQKzJcQ3MTFIAjV+12Q=",
       "dev": true,
-      "requires": {
-        "cheerio-select": "^1.5.0",
-        "dom-serializer": "^1.3.2",
-        "domhandler": "^4.2.0",
-        "htmlparser2": "^6.1.0",
-        "parse5": "^6.0.1",
-        "parse5-htmlparser2-tree-adapter": "^6.0.1",
-        "tslib": "^2.2.0"
-      },
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "tslib": {
-          "version": "2.3.1",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
-          "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
-          "dev": true
-        }
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "cheerio-select": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
-      "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
+    "node_modules/node-addon-api": {
+      "version": "4.3.0",
+      "integrity": "sha1-UqGgtHUZPgko6Y4EJqDRJUeCt38=",
       "dev": true,
-      "requires": {
-        "css-select": "^4.1.3",
-        "css-what": "^5.0.1",
-        "domelementtype": "^2.2.0",
-        "domhandler": "^4.2.0",
-        "domutils": "^2.7.0"
-      }
+      "license": "MIT",
+      "optional": true
     },
-    "chokidar": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+    "node_modules/node-sarif-builder": {
+      "version": "3.2.0",
+      "integrity": "sha1-ugCJldixZVcMPzgwDlYpmpNTHbE=",
       "dev": true,
-      "requires": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "fsevents": "~2.3.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
+      "license": "MIT",
+      "dependencies": {
+        "@types/sarif": "^2.1.7",
+        "fs-extra": "^11.1.1"
+      },
+      "engines": {
+        "node": ">=18"
       }
     },
-    "chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
-      "dev": true
-    },
-    "cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+    "node_modules/normalize-package-data": {
+      "version": "6.0.2",
+      "integrity": "sha1-p7wiFn/iQCVBK8/wqWUet2iwNQY=",
       "dev": true,
-      "requires": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "hosted-git-info": "^7.0.0",
+        "semver": "^7.3.5",
+        "validate-npm-package-license": "^3.0.4"
+      },
+      "engines": {
+        "node": "^16.14.0 || >=18.0.0"
       }
     },
-    "code-point-at": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-      "dev": true
-    },
-    "color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+    "node_modules/normalize-package-data/node_modules/hosted-git-info": {
+      "version": "7.0.2",
+      "integrity": "sha1-m3UaysCXdXZn8wEUYH73tmH/Txc=",
       "dev": true,
-      "requires": {
-        "color-name": "~1.1.4"
+      "license": "ISC",
+      "dependencies": {
+        "lru-cache": "^10.0.1"
+      },
+      "engines": {
+        "node": "^16.14.0 || >=18.0.0"
       }
     },
-    "color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+    "node_modules/normalize-package-data/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "integrity": "sha1-QQ/IoXtw5ZgBPfJXwkRrfzOD8Rk=",
       "dev": true,
-      "requires": {
-        "delayed-stream": "~1.0.0"
-      }
-    },
-    "commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "dev": true
-    },
-    "concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+      "license": "ISC"
     },
-    "console-control-strings": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-      "dev": true
-    },
-    "core-util-is": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
-      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-      "dev": true
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+    "node_modules/nth-check": {
+      "version": "2.1.1",
+      "integrity": "sha1-yeq0KO/842zWuSySS9sADvHx7R0=",
       "dev": true,
-      "requires": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/nth-check?sponsor=1"
       }
     },
-    "css-select": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
-      "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
+    "node_modules/object-inspect": {
+      "version": "1.13.4",
+      "integrity": "sha1-g3UmXiG8IND6WCwi4bE0hdbgAhM=",
       "dev": true,
-      "requires": {
-        "boolbase": "^1.0.0",
-        "css-what": "^5.0.0",
-        "domhandler": "^4.2.0",
-        "domutils": "^2.6.0",
-        "nth-check": "^2.0.0"
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "css-what": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
-      "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==",
-      "dev": true
-    },
-    "debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
-      "dev": true,
-      "requires": {
-        "ms": "2.1.2"
+    "node_modules/once": {
+      "version": "1.4.0",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "wrappy": "1"
       }
     },
-    "decamelize": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
-      "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
-      "dev": true
+    "node_modules/onetime": {
+      "version": "7.0.0",
+      "integrity": "sha1-nxbJLYye9RIOOs2d2ZV8zuzBq2A=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "mimic-function": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "decompress-response": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
-      "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+    "node_modules/open": {
+      "version": "10.2.0",
+      "integrity": "sha1-udhVvgB2IOgLb7BfrJgUH+Yttzw=",
       "dev": true,
-      "requires": {
-        "mimic-response": "^2.0.0"
+      "license": "MIT",
+      "dependencies": {
+        "default-browser": "^5.2.1",
+        "define-lazy-prop": "^3.0.0",
+        "is-inside-container": "^1.0.0",
+        "wsl-utils": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "deep-extend": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
-      "dev": true
-    },
-    "deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true
-    },
-    "delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true
+    "node_modules/optionator": {
+      "version": "0.9.4",
+      "integrity": "sha1-fqHBpdkddk+yghOciP4R4YKjpzQ=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "deep-is": "^0.1.3",
+        "fast-levenshtein": "^2.0.6",
+        "levn": "^0.4.1",
+        "prelude-ls": "^1.2.1",
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.5"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
     },
-    "delegates": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
-      "dev": true
+    "node_modules/ora": {
+      "version": "8.2.0",
+      "integrity": "sha1-j7u3FRr+M7VA3RU/Fx/6i9OOmGE=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "chalk": "^5.3.0",
+        "cli-cursor": "^5.0.0",
+        "cli-spinners": "^2.9.2",
+        "is-interactive": "^2.0.0",
+        "is-unicode-supported": "^2.0.0",
+        "log-symbols": "^6.0.0",
+        "stdin-discarder": "^0.2.2",
+        "string-width": "^7.2.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "detect-libc": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
-      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
-      "dev": true
+    "node_modules/ora/node_modules/chalk": {
+      "version": "5.4.1",
+      "integrity": "sha1-G0i/CWPsFY3OKqz2nAk64t0gktg=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
     },
-    "diff": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
-      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
-      "dev": true
+    "node_modules/ora/node_modules/emoji-regex": {
+      "version": "10.4.0",
+      "integrity": "sha1-A1U6/qgLOXV0nPyzb3dsomjkE9Q=",
+      "license": "MIT",
+      "optional": true
     },
-    "doctrine": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-      "dev": true,
-      "requires": {
-        "esutils": "^2.0.2"
+    "node_modules/ora/node_modules/is-unicode-supported": {
+      "version": "2.1.0",
+      "integrity": "sha1-CfCrDebTdE1I0mXruY9l0R8qmzo=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "dom-serializer": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
-      "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
-      "dev": true,
-      "requires": {
-        "domelementtype": "^2.0.1",
-        "domhandler": "^4.2.0",
-        "entities": "^2.0.0"
+    "node_modules/ora/node_modules/log-symbols": {
+      "version": "6.0.0",
+      "integrity": "sha1-u5Xl8FMiZRysMMD+tkBPnyqKlDk=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "chalk": "^5.3.0",
+        "is-unicode-supported": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "domelementtype": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
-      "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
-      "dev": true
-    },
-    "domhandler": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz",
-      "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==",
-      "dev": true,
-      "requires": {
-        "domelementtype": "^2.2.0"
+    "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": {
+      "version": "1.3.0",
+      "integrity": "sha1-2CSYS2FsKSouGYIH1KYJmDhC9xQ=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "domutils": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
-      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
-      "dev": true,
-      "requires": {
-        "dom-serializer": "^1.0.1",
-        "domelementtype": "^2.2.0",
-        "domhandler": "^4.2.0"
+    "node_modules/ora/node_modules/string-width": {
+      "version": "7.2.0",
+      "integrity": "sha1-tbuOIWXOJ11NQ0dt0nAK2Qkdttw=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "emoji-regex": "^10.3.0",
+        "get-east-asian-width": "^1.0.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "duplexer2": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
-      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
-      "dev": true,
-      "requires": {
-        "readable-stream": "^2.0.2"
+    "node_modules/p-limit": {
+      "version": "3.1.0",
+      "integrity": "sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true
-    },
-    "end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "dev": true,
-      "requires": {
-        "once": "^1.4.0"
+    "node_modules/p-locate": {
+      "version": "5.0.0",
+      "integrity": "sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "enquirer": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
-      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+    "node_modules/p-map": {
+      "version": "7.0.3",
+      "integrity": "sha1-esIQotNvgewotzYTSBD3ukQYzbY=",
       "dev": true,
-      "requires": {
-        "ansi-colors": "^4.1.1"
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "entities": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
-      "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
-      "dev": true
-    },
-    "esbuild": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.23.tgz",
-      "integrity": "sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==",
-      "dev": true,
-      "requires": {
-        "esbuild-android-arm64": "0.14.23",
-        "esbuild-darwin-64": "0.14.23",
-        "esbuild-darwin-arm64": "0.14.23",
-        "esbuild-freebsd-64": "0.14.23",
-        "esbuild-freebsd-arm64": "0.14.23",
-        "esbuild-linux-32": "0.14.23",
-        "esbuild-linux-64": "0.14.23",
-        "esbuild-linux-arm": "0.14.23",
-        "esbuild-linux-arm64": "0.14.23",
-        "esbuild-linux-mips64le": "0.14.23",
-        "esbuild-linux-ppc64le": "0.14.23",
-        "esbuild-linux-riscv64": "0.14.23",
-        "esbuild-linux-s390x": "0.14.23",
-        "esbuild-netbsd-64": "0.14.23",
-        "esbuild-openbsd-64": "0.14.23",
-        "esbuild-sunos-64": "0.14.23",
-        "esbuild-windows-32": "0.14.23",
-        "esbuild-windows-64": "0.14.23",
-        "esbuild-windows-arm64": "0.14.23"
-      }
-    },
-    "esbuild-android-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz",
-      "integrity": "sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==",
-      "dev": true,
+    "node_modules/package-json-from-dist": {
+      "version": "1.0.1",
+      "integrity": "sha1-TxRxoBCCeob5TP2bByfjbSZ95QU=",
+      "devOptional": true,
+      "license": "BlueOak-1.0.0"
+    },
+    "node_modules/pako": {
+      "version": "1.0.11",
+      "integrity": "sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=",
+      "license": "(MIT AND Zlib)",
       "optional": true
     },
-    "esbuild-darwin-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz",
-      "integrity": "sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==",
-      "dev": true,
-      "optional": true
+    "node_modules/parent-module": {
+      "version": "1.0.1",
+      "integrity": "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "esbuild-darwin-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz",
-      "integrity": "sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==",
+    "node_modules/parse-json": {
+      "version": "8.3.0",
+      "integrity": "sha1-iKGVohVwJROaIxek8vklK2EwTtU=",
       "dev": true,
-      "optional": true
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.26.2",
+        "index-to-position": "^1.1.0",
+        "type-fest": "^4.39.1"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "esbuild-freebsd-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz",
-      "integrity": "sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==",
+    "node_modules/parse-semver": {
+      "version": "1.1.1",
+      "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
       "dev": true,
-      "optional": true
+      "license": "MIT",
+      "dependencies": {
+        "semver": "^5.1.0"
+      }
     },
-    "esbuild-freebsd-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz",
-      "integrity": "sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==",
+    "node_modules/parse-semver/node_modules/semver": {
+      "version": "5.7.2",
+      "integrity": "sha1-SNVdtzfDKHzUg14X+hP+rOHEHvg=",
       "dev": true,
-      "optional": true
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver"
+      }
     },
-    "esbuild-linux-32": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz",
-      "integrity": "sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==",
+    "node_modules/parse5": {
+      "version": "7.3.0",
+      "integrity": "sha1-1+Ik+nI5nHoXUJn0X8KtAksF7AU=",
       "dev": true,
-      "optional": true
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
     },
-    "esbuild-linux-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz",
-      "integrity": "sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==",
+    "node_modules/parse5-htmlparser2-tree-adapter": {
+      "version": "7.1.0",
+      "integrity": "sha1-tagGVI7Yk6Q+JMy0L7t4BpMR6Bs=",
       "dev": true,
-      "optional": true
+      "license": "MIT",
+      "dependencies": {
+        "domhandler": "^5.0.3",
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
     },
-    "esbuild-linux-arm": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz",
-      "integrity": "sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==",
+    "node_modules/parse5-parser-stream": {
+      "version": "7.1.2",
+      "integrity": "sha1-18IOrcN5aNJy4sAmYP/5LdJ+YOE=",
       "dev": true,
-      "optional": true
+      "license": "MIT",
+      "dependencies": {
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
     },
-    "esbuild-linux-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz",
-      "integrity": "sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==",
+    "node_modules/parse5/node_modules/entities": {
+      "version": "6.0.1",
+      "integrity": "sha1-wow0pDN5yn9h0HQTCy9fcCCjBpQ=",
       "dev": true,
-      "optional": true
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
     },
-    "esbuild-linux-mips64le": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz",
-      "integrity": "sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==",
-      "dev": true,
-      "optional": true
-    },
-    "esbuild-linux-ppc64le": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz",
-      "integrity": "sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==",
-      "dev": true,
-      "optional": true
+    "node_modules/path-exists": {
+      "version": "4.0.0",
+      "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "esbuild-linux-riscv64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz",
-      "integrity": "sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==",
-      "dev": true,
-      "optional": true
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "esbuild-linux-s390x": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz",
-      "integrity": "sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==",
-      "dev": true,
-      "optional": true
+    "node_modules/path-key": {
+      "version": "3.1.1",
+      "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "esbuild-netbsd-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz",
-      "integrity": "sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==",
-      "dev": true,
-      "optional": true
+    "node_modules/path-scurry": {
+      "version": "1.11.1",
+      "integrity": "sha1-eWCmaIiFlKByCxKpEdGnQqufEdI=",
+      "license": "BlueOak-1.0.0",
+      "optional": true,
+      "dependencies": {
+        "lru-cache": "^10.2.0",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
     },
-    "esbuild-openbsd-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz",
-      "integrity": "sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==",
-      "dev": true,
+    "node_modules/path-scurry/node_modules/lru-cache": {
+      "version": "10.4.3",
+      "integrity": "sha1-QQ/IoXtw5ZgBPfJXwkRrfzOD8Rk=",
+      "license": "ISC",
       "optional": true
     },
-    "esbuild-sunos-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz",
-      "integrity": "sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==",
-      "dev": true,
-      "optional": true
+    "node_modules/path-to-regexp": {
+      "version": "8.2.0",
+      "integrity": "sha1-c5kMwp5Xo/8qDZFAlRVt9dt56LQ=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=16"
+      }
     },
-    "esbuild-windows-32": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz",
-      "integrity": "sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==",
+    "node_modules/path-type": {
+      "version": "6.0.0",
+      "integrity": "sha1-Lxu2eRqRzpkZTK7eXWxZIO2B61E=",
       "dev": true,
-      "optional": true
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "esbuild-windows-64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz",
-      "integrity": "sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==",
+    "node_modules/pend": {
+      "version": "1.2.0",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
       "dev": true,
-      "optional": true
+      "license": "MIT"
     },
-    "esbuild-windows-arm64": {
-      "version": "0.14.23",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz",
-      "integrity": "sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==",
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "integrity": "sha1-PTIa8+q5ObCDyPkpodEs2oHCa2s=",
       "dev": true,
-      "optional": true
-    },
-    "escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-      "dev": true
+      "license": "ISC"
     },
-    "escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true
-    },
-    "eslint": {
-      "version": "7.32.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
-      "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "7.12.11",
-        "@eslint/eslintrc": "^0.4.3",
-        "@humanwhocodes/config-array": "^0.5.0",
-        "ajv": "^6.10.0",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.2",
-        "debug": "^4.0.1",
-        "doctrine": "^3.0.0",
-        "enquirer": "^2.3.5",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^5.1.1",
-        "eslint-utils": "^2.1.0",
-        "eslint-visitor-keys": "^2.0.0",
-        "espree": "^7.3.1",
-        "esquery": "^1.4.0",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^6.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^5.1.2",
-        "globals": "^13.6.0",
-        "ignore": "^4.0.6",
-        "import-fresh": "^3.0.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "js-yaml": "^3.13.1",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.0.4",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
-        "progress": "^2.0.0",
-        "regexpp": "^3.1.0",
-        "semver": "^7.2.1",
-        "strip-ansi": "^6.0.0",
-        "strip-json-comments": "^3.1.0",
-        "table": "^6.0.9",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
-      },
-      "dependencies": {
-        "@babel/code-frame": {
-          "version": "7.12.11",
-          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
-          "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "^7.10.4"
-          }
-        },
-        "argparse": {
-          "version": "1.0.10",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-          "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-          "dev": true,
-          "requires": {
-            "sprintf-js": "~1.0.2"
-          }
-        },
-        "js-yaml": {
-          "version": "3.14.1",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-          "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
-          "dev": true,
-          "requires": {
-            "argparse": "^1.0.7",
-            "esprima": "^4.0.0"
-          }
-        }
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "integrity": "sha1-O6ODNzNkbZ0+SZWUbBNlpn+wekI=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
-    "eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+    "node_modules/pluralize": {
+      "version": "8.0.0",
+      "integrity": "sha1-Gm+hajjRKhkB4DIPoBcFHFOc47E=",
       "dev": true,
-      "requires": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
       }
     },
-    "eslint-utils": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-      "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+    "node_modules/prebuild-install": {
+      "version": "7.1.3",
+      "integrity": "sha1-1jCrrSsUdEPyCiEpF76uaLgJLuw=",
       "dev": true,
-      "requires": {
-        "eslint-visitor-keys": "^1.1.0"
-      },
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "eslint-visitor-keys": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-          "dev": true
-        }
+        "detect-libc": "^2.0.0",
+        "expand-template": "^2.0.3",
+        "github-from-package": "0.0.0",
+        "minimist": "^1.2.3",
+        "mkdirp-classic": "^0.5.3",
+        "napi-build-utils": "^2.0.0",
+        "node-abi": "^3.3.0",
+        "pump": "^3.0.0",
+        "rc": "^1.2.7",
+        "simple-get": "^4.0.0",
+        "tar-fs": "^2.0.0",
+        "tunnel-agent": "^0.6.0"
+      },
+      "bin": {
+        "prebuild-install": "bin.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "eslint-visitor-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-      "dev": true
-    },
-    "espree": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
-      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
-      "dev": true,
-      "requires": {
-        "acorn": "^7.4.0",
-        "acorn-jsx": "^5.3.1",
-        "eslint-visitor-keys": "^1.3.0"
-      },
-      "dependencies": {
-        "eslint-visitor-keys": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-          "dev": true
-        }
+    "node_modules/prelude-ls": {
+      "version": "1.2.1",
+      "integrity": "sha1-3rxkidem5rDnYRiIzsiAM30xY5Y=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">= 0.8.0"
       }
     },
-    "esprima": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-      "dev": true
-    },
-    "esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
-      "dev": true,
-      "requires": {
-        "estraverse": "^5.1.0"
+    "node_modules/prettier": {
+      "version": "3.6.2",
+      "integrity": "sha1-zNoCoQA+u7K/2m+DoHSXj2CLk5M=",
+      "license": "MIT",
+      "optional": true,
+      "bin": {
+        "prettier": "bin/prettier.cjs"
       },
-      "dependencies": {
-        "estraverse": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
       }
     },
-    "esrecurse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-      "dev": true,
-      "requires": {
-        "estraverse": "^5.2.0"
+    "node_modules/prettier-plugin-organize-imports": {
+      "version": "4.2.0",
+      "integrity": "sha1-kqxI4j5kl7rk12HUPRet7RgFpG0=",
+      "license": "MIT",
+      "optional": true,
+      "peerDependencies": {
+        "prettier": ">=2.0",
+        "typescript": ">=2.9",
+        "vue-tsc": "^2.1.0 || 3"
       },
-      "dependencies": {
-        "estraverse": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-          "dev": true
+      "peerDependenciesMeta": {
+        "vue-tsc": {
+          "optional": true
         }
       }
     },
-    "estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "dev": true
-    },
-    "esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true
-    },
-    "expand-template": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
-      "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
-      "dev": true
-    },
-    "fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
-    },
-    "fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
-      "dev": true
+    "node_modules/process-nextick-args": {
+      "version": "2.0.1",
+      "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=",
+      "license": "MIT",
+      "optional": true
     },
-    "fd-slicer": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+    "node_modules/pump": {
+      "version": "3.0.3",
+      "integrity": "sha1-FR2XnxopZo3AAl7FiaRVtTKCJo0=",
       "dev": true,
-      "requires": {
-        "pend": "~1.2.0"
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
       }
     },
-    "file-entry-cache": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
-      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
-      "dev": true,
-      "requires": {
-        "flat-cache": "^3.0.4"
+    "node_modules/punycode": {
+      "version": "2.3.1",
+      "integrity": "sha1-AnQi4vrsCyXhVJw+G9gwm5EztuU=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
       }
     },
-    "fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+    "node_modules/punycode.js": {
+      "version": "2.3.1",
+      "integrity": "sha1-a1PlatdViCNOefSv+pCXLH3Yzbc=",
       "dev": true,
-      "requires": {
-        "to-regex-range": "^5.0.1"
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
       }
     },
-    "find-up": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+    "node_modules/qs": {
+      "version": "6.14.0",
+      "integrity": "sha1-xj+kBoDSxclBQSoOiZyJr2DAqTA=",
       "dev": true,
-      "requires": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "side-channel": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "flat": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
-      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
-      "dev": true
+    "node_modules/queue-microtask": {
+      "version": "1.2.3",
+      "integrity": "sha1-SSkii7xyTfrEPg77BYyve2z7YkM=",
+      "devOptional": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
     },
-    "flat-cache": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
-      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
-      "dev": true,
-      "requires": {
-        "flatted": "^3.1.0",
-        "rimraf": "^3.0.2"
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
       }
     },
-    "flatted": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz",
-      "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==",
-      "dev": true
-    },
-    "form-data": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
-      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+    "node_modules/rc": {
+      "version": "1.2.8",
+      "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=",
       "dev": true,
-      "requires": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
+      "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+      "optional": true,
+      "dependencies": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      },
+      "bin": {
+        "rc": "cli.js"
       }
     },
-    "fs-constants": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
-      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
-      "dev": true
-    },
-    "fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-      "dev": true
-    },
-    "fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+    "node_modules/rc-config-loader": {
+      "version": "4.1.3",
+      "integrity": "sha1-E1KYa4otjZbW/QVKW7GaYMV2h2o=",
       "dev": true,
-      "optional": true
-    },
-    "fstream": {
-      "version": "1.0.12",
-      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
-      "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.2",
-        "inherits": "~2.0.0",
-        "mkdirp": ">=0.5 0",
-        "rimraf": "2"
-      },
-      "dependencies": {
-        "rimraf": {
-          "version": "2.7.1",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-          "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        }
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.3.4",
+        "js-yaml": "^4.1.0",
+        "json5": "^2.2.2",
+        "require-from-string": "^2.0.2"
       }
     },
-    "function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
+    "node_modules/rc-config-loader/node_modules/argparse": {
+      "version": "2.0.1",
+      "integrity": "sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=",
+      "dev": true,
+      "license": "Python-2.0"
     },
-    "functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
-      "dev": true
-    },
-    "gauge": {
-      "version": "2.7.4",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
-      "dev": true,
-      "requires": {
-        "aproba": "^1.0.3",
-        "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.0",
-        "object-assign": "^4.1.0",
-        "signal-exit": "^3.0.0",
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wide-align": "^1.1.0"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-          "dev": true,
-          "requires": {
-            "number-is-nan": "^1.0.0"
-          }
-        },
-        "string-width": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-          "dev": true,
-          "requires": {
-            "code-point-at": "^1.0.0",
-            "is-fullwidth-code-point": "^1.0.0",
-            "strip-ansi": "^3.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        }
+    "node_modules/rc-config-loader/node_modules/js-yaml": {
+      "version": "4.1.0",
+      "integrity": "sha1-wftl+PUBeQHN0slRhkuhhFihBgI=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true
-    },
-    "get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+    "node_modules/rc/node_modules/strip-json-comments": {
+      "version": "2.0.1",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
       "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "github-from-package": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
-      "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
-      "dev": true
-    },
-    "glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+    "node_modules/read": {
+      "version": "1.0.7",
+      "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
       "dev": true,
-      "requires": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+      "license": "ISC",
+      "dependencies": {
+        "mute-stream": "~0.0.4"
+      },
+      "engines": {
+        "node": ">=0.8"
       }
     },
-    "glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+    "node_modules/read-pkg": {
+      "version": "9.0.1",
+      "integrity": "sha1-sbgfsVEE9duxIba73um7yXOfVps=",
       "dev": true,
-      "requires": {
-        "is-glob": "^4.0.1"
+      "license": "MIT",
+      "dependencies": {
+        "@types/normalize-package-data": "^2.4.3",
+        "normalize-package-data": "^6.0.0",
+        "parse-json": "^8.0.0",
+        "type-fest": "^4.6.0",
+        "unicorn-magic": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "globals": {
-      "version": "13.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
-      "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+    "node_modules/read-pkg/node_modules/unicorn-magic": {
+      "version": "0.1.0",
+      "integrity": "sha1-G7mlHII6r51zqL/NPRoj3elLDOQ=",
       "dev": true,
-      "requires": {
-        "type-fest": "^0.20.2"
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "graceful-fs": {
-      "version": "4.2.8",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
-      "dev": true
-    },
-    "growl": {
-      "version": "1.10.5",
-      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
-      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
-      "dev": true
-    },
-    "has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1"
+    "node_modules/readable-stream": {
+      "version": "2.3.8",
+      "integrity": "sha1-kRJegEK7obmIf0k0X2J3Anzovps=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
       }
     },
-    "has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true
-    },
-    "has-symbols": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
-      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
-      "dev": true
-    },
-    "has-unicode": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
-      "dev": true
-    },
-    "he": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true
+    "node_modules/readable-stream/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
+      "license": "MIT",
+      "optional": true
     },
-    "hosted-git-info": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
-      "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
-      "dev": true,
-      "requires": {
-        "lru-cache": "^6.0.0"
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "integrity": "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
       }
     },
-    "htmlparser2": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
-      "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
-      "dev": true,
-      "requires": {
-        "domelementtype": "^2.0.1",
-        "domhandler": "^4.0.0",
-        "domutils": "^2.5.2",
-        "entities": "^2.0.0"
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "http-proxy-agent": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
-      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "integrity": "sha1-iaf92TgmEmcxjq/hT5wy5ZjDaQk=",
       "dev": true,
-      "requires": {
-        "@tootallnate/once": "1",
-        "agent-base": "6",
-        "debug": "4"
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "https-proxy-agent": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
-      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
-      "dev": true,
-      "requires": {
-        "agent-base": "6",
-        "debug": "4"
+    "node_modules/resolve-from": {
+      "version": "4.0.0",
+      "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=4"
       }
     },
-    "ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true
-    },
-    "ignore": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
-      "dev": true
-    },
-    "import-fresh": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-      "dev": true,
-      "requires": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
+    "node_modules/restore-cursor": {
+      "version": "5.1.0",
+      "integrity": "sha1-B2bZVpnvrLFBUJk/VbrwlT6h6+c=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "onetime": "^7.0.0",
+        "signal-exit": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true
-    },
-    "inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-      "dev": true,
-      "requires": {
-        "once": "^1.3.0",
-        "wrappy": "1"
+    "node_modules/reusify": {
+      "version": "1.1.0",
+      "integrity": "sha1-D+E7lSLhRz9RtVjueW4I8R+bSJ8=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
       }
     },
-    "inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "ini": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
-      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "dev": true
-    },
-    "is-binary-path": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
-      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+    "node_modules/run-applescript": {
+      "version": "7.0.0",
+      "integrity": "sha1-5aVTwr/9Yg4WnSdsHNjxtkd4++s=",
       "dev": true,
-      "requires": {
-        "binary-extensions": "^2.0.0"
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "is-core-module": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
-      "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
-      "dev": true,
-      "requires": {
-        "has": "^1.0.3"
+    "node_modules/run-parallel": {
+      "version": "1.2.0",
+      "integrity": "sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4=",
+      "devOptional": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "queue-microtask": "^1.2.2"
       }
     },
-    "is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
-      "dev": true
-    },
-    "is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=",
+      "devOptional": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
     },
-    "is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=",
       "dev": true,
-      "requires": {
-        "is-extglob": "^2.1.1"
-      }
-    },
-    "is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true
-    },
-    "is-plain-obj": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
-      "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
-      "dev": true
+      "license": "MIT"
     },
-    "is-unicode-supported": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "dev": true
-    },
-    "isarray": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-      "dev": true
-    },
-    "isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+    "node_modules/sax": {
+      "version": "1.4.1",
+      "integrity": "sha1-RMyJiDd/EmME07P8EBDHM7kp7w8=",
       "dev": true,
-      "requires": {
-        "argparse": "^2.0.1"
-      }
-    },
-    "json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "json-stable-stringify-without-jsonify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
-      "dev": true
-    },
-    "just-extend": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
-      "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
-      "dev": true
+      "license": "ISC"
     },
-    "keytar": {
-      "version": "7.7.0",
-      "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.7.0.tgz",
-      "integrity": "sha512-YEY9HWqThQc5q5xbXbRwsZTh2PJ36OSYRjSv3NN2xf5s5dpLTjEZnC2YikR29OaVybf9nQ0dJ/80i40RS97t/A==",
+    "node_modules/secretlint": {
+      "version": "10.2.1",
+      "integrity": "sha1-Ah6iW7d/I++6Is53jRoAGxXed7E=",
       "dev": true,
-      "requires": {
-        "node-addon-api": "^3.0.0",
-        "prebuild-install": "^6.0.0"
+      "license": "MIT",
+      "dependencies": {
+        "@secretlint/config-creator": "^10.2.1",
+        "@secretlint/formatter": "^10.2.1",
+        "@secretlint/node": "^10.2.1",
+        "@secretlint/profiler": "^10.2.1",
+        "debug": "^4.4.1",
+        "globby": "^14.1.0",
+        "read-pkg": "^9.0.1"
+      },
+      "bin": {
+        "secretlint": "bin/secretlint.js"
+      },
+      "engines": {
+        "node": ">=20.0.0"
       }
     },
-    "leven": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
-      "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
-      "dev": true
-    },
-    "levn": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
-      "dev": true,
-      "requires": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
+    "node_modules/semver": {
+      "version": "7.7.2",
+      "integrity": "sha1-Z9mf3NNc7CHm+Lh6f9UVoz+YK1g=",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "linkify-it": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
-      "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
-      "dev": true,
-      "requires": {
-        "uc.micro": "^1.0.1"
+    "node_modules/serialize-javascript": {
+      "version": "6.0.2",
+      "integrity": "sha1-3voeBVyDv21Z6oBdjahiJU62psI=",
+      "license": "BSD-3-Clause",
+      "optional": true,
+      "dependencies": {
+        "randombytes": "^2.1.0"
       }
     },
-    "listenercount": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
-      "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=",
-      "dev": true
+    "node_modules/setimmediate": {
+      "version": "1.0.5",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "license": "MIT",
+      "optional": true
     },
-    "locate-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
-      "dev": true,
-      "requires": {
-        "p-locate": "^5.0.0"
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true
-    },
-    "lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
-      "dev": true
-    },
-    "lodash.merge": {
-      "version": "4.6.2",
-      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
-      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
-      "dev": true
-    },
-    "lodash.truncate": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
-      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
-      "dev": true
-    },
-    "log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "dev": true,
-      "requires": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
+    "node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
       }
     },
-    "lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "requires": {
-        "yallist": "^4.0.0"
+    "node_modules/side-channel": {
+      "version": "1.1.0",
+      "integrity": "sha1-w/z/nE2pMnhIczNeyXZfqU/2a8k=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3",
+        "side-channel-list": "^1.0.0",
+        "side-channel-map": "^1.0.1",
+        "side-channel-weakmap": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "markdown-it": {
-      "version": "12.3.2",
-      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
-      "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+    "node_modules/side-channel-list": {
+      "version": "1.0.0",
+      "integrity": "sha1-EMtZhCYxFdO3oOM2WR4pCoMK+K0=",
       "dev": true,
-      "requires": {
-        "argparse": "^2.0.1",
-        "entities": "~2.1.0",
-        "linkify-it": "^3.0.1",
-        "mdurl": "^1.0.1",
-        "uc.micro": "^1.0.5"
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "mdurl": {
+    "node_modules/side-channel-map": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
-      "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
-      "dev": true
-    },
-    "mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "dev": true
-    },
-    "mime-db": {
-      "version": "1.51.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
-      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
-      "dev": true
-    },
-    "mime-types": {
-      "version": "2.1.34",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
-      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
+      "integrity": "sha1-1rtrN5Asb+9RdOX1M/q0xzKib0I=",
       "dev": true,
-      "requires": {
-        "mime-db": "1.51.0"
-      }
-    },
-    "mimic-response": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
-      "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
-      "dev": true
-    },
-    "minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "requires": {
-        "brace-expansion": "^1.1.7"
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
-    },
-    "mkdirp": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+    "node_modules/side-channel-weakmap": {
+      "version": "1.0.2",
+      "integrity": "sha1-Ed2hnVNo5Azp7CvcH7DsvAeQ7Oo=",
       "dev": true,
-      "requires": {
-        "minimist": "^1.2.5"
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.5",
+        "object-inspect": "^1.13.3",
+        "side-channel-map": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "mkdirp-classic": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
-      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
-      "dev": true
-    },
-    "mocha": {
-      "version": "9.2.1",
-      "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz",
-      "integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==",
-      "dev": true,
-      "requires": {
-        "@ungap/promise-all-settled": "1.1.2",
-        "ansi-colors": "4.1.1",
-        "browser-stdout": "1.3.1",
-        "chokidar": "3.5.3",
-        "debug": "4.3.3",
-        "diff": "5.0.0",
-        "escape-string-regexp": "4.0.0",
-        "find-up": "5.0.0",
-        "glob": "7.2.0",
-        "growl": "1.10.5",
-        "he": "1.2.0",
-        "js-yaml": "4.1.0",
-        "log-symbols": "4.1.0",
-        "minimatch": "3.0.4",
-        "ms": "2.1.3",
-        "nanoid": "3.2.0",
-        "serialize-javascript": "6.0.0",
-        "strip-json-comments": "3.1.1",
-        "supports-color": "8.1.1",
-        "which": "2.0.2",
-        "workerpool": "6.2.0",
-        "yargs": "16.2.0",
-        "yargs-parser": "20.2.4",
-        "yargs-unparser": "2.0.0"
-      },
-      "dependencies": {
-        "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
-        }
+    "node_modules/signal-exit": {
+      "version": "4.1.0",
+      "integrity": "sha1-lSGIwcvVRgcOLdIND0HArgUwywQ=",
+      "devOptional": true,
+      "license": "ISC",
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "mocha-multi-reporters": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/mocha-multi-reporters/-/mocha-multi-reporters-1.5.1.tgz",
-      "integrity": "sha512-Yb4QJOaGLIcmB0VY7Wif5AjvLMUFAdV57D2TWEva1Y0kU/3LjKpeRVmlMIfuO1SVbauve459kgtIizADqxMWPg==",
+    "node_modules/simple-concat": {
+      "version": "1.0.1",
+      "integrity": "sha1-9Gl2CCujXCJj8cirXt/ibEHJVS8=",
       "dev": true,
-      "requires": {
-        "debug": "^4.1.1",
-        "lodash": "^4.17.15"
-      }
-    },
-    "mock-fs": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.1.2.tgz",
-      "integrity": "sha512-YkjQkdLulFrz0vD4BfNQdQRVmgycXTV7ykuHMlyv+C8WCHazpkiQRDthwa02kSyo8wKnY9wRptHfQLgmf0eR+A==",
-      "dev": true
-    },
-    "ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
-    "mute-stream": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
-      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-      "dev": true
-    },
-    "nanoid": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
-      "dev": true
-    },
-    "napi-build-utils": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
-      "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
-      "dev": true
-    },
-    "natural-compare": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
-      "dev": true
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "optional": true
     },
-    "nise": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz",
-      "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==",
+    "node_modules/simple-get": {
+      "version": "4.0.1",
+      "integrity": "sha1-SjnbVJKHyXnTUhEvoD/Zn9a8NUM=",
       "dev": true,
-      "requires": {
-        "@sinonjs/commons": "^1.8.3",
-        "@sinonjs/fake-timers": ">=5",
-        "@sinonjs/text-encoding": "^0.7.1",
-        "just-extend": "^4.0.2",
-        "path-to-regexp": "^1.7.0"
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "decompress-response": "^6.0.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
       }
     },
-    "node-abi": {
-      "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,
-      "requires": {
-        "semver": "^5.4.1"
-      },
+    "node_modules/sinon": {
+      "version": "19.0.5",
+      "integrity": "sha1-ZP0vhHhqBD9yEkbECza+9MS3azw=",
+      "license": "BSD-3-Clause",
+      "optional": true,
       "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
+        "@sinonjs/commons": "^3.0.1",
+        "@sinonjs/fake-timers": "^13.0.5",
+        "@sinonjs/samsam": "^8.0.1",
+        "diff": "^7.0.0",
+        "nise": "^6.1.1",
+        "supports-color": "^7.2.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/sinon"
       }
     },
-    "node-addon-api": {
-      "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
-    },
-    "node-fetch": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
-      "requires": {
-        "whatwg-url": "^5.0.0"
+    "node_modules/sinon/node_modules/diff": {
+      "version": "7.0.0",
+      "integrity": "sha1-P7NNOHzXbYA/buvqZ7kh2rAYKpo=",
+      "license": "BSD-3-Clause",
+      "optional": true,
+      "engines": {
+        "node": ">=0.3.1"
       }
     },
-    "normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true
+    "node_modules/sinon/node_modules/supports-color": {
+      "version": "7.2.0",
+      "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "npmlog": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+    "node_modules/slash": {
+      "version": "5.1.0",
+      "integrity": "sha1-vjrd3N8JrDjuvo3Nx7GlenWwlc4=",
       "dev": true,
-      "requires": {
-        "are-we-there-yet": "~1.1.2",
-        "console-control-strings": "~1.1.0",
-        "gauge": "~2.7.3",
-        "set-blocking": "~2.0.0"
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "nth-check": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
-      "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
+    "node_modules/slice-ansi": {
+      "version": "4.0.0",
+      "integrity": "sha1-UA6N0P1VsFgVCGJVsxla3ypF/ms=",
       "dev": true,
-      "requires": {
-        "boolbase": "^1.0.0"
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
       }
     },
-    "number-is-nan": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-      "dev": true
-    },
-    "object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true
-    },
-    "object-inspect": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
-      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
-      "dev": true
-    },
-    "once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "integrity": "sha1-T1qwZo8AWeNPnADc4zF4ShLeTpw=",
       "dev": true,
-      "requires": {
-        "wrappy": "1"
+      "license": "Apache-2.0",
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
       }
     },
-    "optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+    "node_modules/spdx-exceptions": {
+      "version": "2.5.0",
+      "integrity": "sha1-XWB9J/yAb2bXtkp2ZlD6iQ8E7WY=",
       "dev": true,
-      "requires": {
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
-      }
+      "license": "CC-BY-3.0"
     },
-    "p-limit": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+    "node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "integrity": "sha1-z3D1BILu/cmOPOCmgz5KU87rpnk=",
       "dev": true,
-      "requires": {
-        "yocto-queue": "^0.1.0"
+      "license": "MIT",
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
       }
     },
-    "p-locate": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.21",
+      "integrity": "sha1-bW6YDJ3ytvyQU0OjstcCpiOVNsM=",
       "dev": true,
-      "requires": {
-        "p-limit": "^3.0.2"
-      }
+      "license": "CC0-1.0"
     },
-    "parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+    "node_modules/sprintf-js": {
+      "version": "1.0.3",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true,
-      "requires": {
-        "callsites": "^3.0.0"
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/stdin-discarder": {
+      "version": "0.2.2",
+      "integrity": "sha1-OQA39ExK4aGuU1xf443Dq6jZl74=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "parse-semver": {
+    "node_modules/string_decoder": {
       "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
-      "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
-      "dev": true,
-      "requires": {
-        "semver": "^5.1.0"
-      },
+      "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
+        "safe-buffer": "~5.1.0"
       }
     },
-    "parse5": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
-      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
-      "dev": true
+    "node_modules/string_decoder/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
+      "license": "MIT",
+      "optional": true
     },
-    "parse5-htmlparser2-tree-adapter": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
-      "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
-      "dev": true,
-      "requires": {
-        "parse5": "^6.0.1"
+    "node_modules/string-width": {
+      "version": "4.2.3",
+      "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true
-    },
-    "path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-      "dev": true
-    },
-    "path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true
-    },
-    "path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-      "dev": true
-    },
-    "path-to-regexp": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
-      "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
-      "dev": true,
-      "requires": {
-        "isarray": "0.0.1"
+    "node_modules/string-width-cjs": {
+      "name": "string-width",
+      "version": "4.2.3",
+      "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "pend": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
-      "dev": true
-    },
-    "picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true
+    "node_modules/string-width-cjs/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "prebuild-install": {
-      "version": "6.1.4",
-      "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz",
-      "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==",
-      "dev": true,
-      "requires": {
-        "detect-libc": "^1.0.3",
-        "expand-template": "^2.0.3",
-        "github-from-package": "0.0.0",
-        "minimist": "^1.2.3",
-        "mkdirp-classic": "^0.5.3",
-        "napi-build-utils": "^1.0.1",
-        "node-abi": "^2.21.0",
-        "npmlog": "^4.0.1",
-        "pump": "^3.0.0",
-        "rc": "^1.2.7",
-        "simple-get": "^3.0.3",
-        "tar-fs": "^2.0.0",
-        "tunnel-agent": "^0.6.0"
+    "node_modules/string-width-cjs/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "prelude-ls": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
-      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-      "dev": true
+    "node_modules/string-width/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "process-nextick-args": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "dev": true
+    "node_modules/string-width/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "progress": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
-      "dev": true
+    "node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "integrity": "sha1-1bZWjKaJ2FYTcLBwdoXSJDT6/0U=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
     },
-    "pump": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
-      "requires": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
+    "node_modules/strip-ansi-cjs": {
+      "name": "strip-ansi",
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true
+    "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "qs": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
-      "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
-      "dev": true,
-      "requires": {
-        "side-channel": "^1.0.4"
+    "node_modules/strip-json-comments": {
+      "version": "3.1.1",
+      "integrity": "sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "randombytes": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
-      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+    "node_modules/structured-source": {
+      "version": "4.0.0",
+      "integrity": "sha1-DJ5Z7kPe3Y/GCmNzH2DjWBAqSUg=",
       "dev": true,
-      "requires": {
-        "safe-buffer": "^5.1.0"
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boundary": "^2.0.0"
       }
     },
-    "rc": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
-      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
-      "dev": true,
-      "requires": {
-        "deep-extend": "^0.6.0",
-        "ini": "~1.3.0",
-        "minimist": "^1.2.0",
-        "strip-json-comments": "~2.0.1"
+    "node_modules/supports-color": {
+      "version": "9.4.0",
+      "integrity": "sha1-F7/PaGKI9THbPeoyFVEGIcy1WVQ=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
       },
-      "dependencies": {
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
-          "dev": true
-        }
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
-    "read": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
-      "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+    "node_modules/supports-hyperlinks": {
+      "version": "3.2.0",
+      "integrity": "sha1-uOSFsXloHepJah56vfiYW9MUVGE=",
       "dev": true,
-      "requires": {
-        "mute-stream": "~0.0.4"
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0",
+        "supports-color": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
       }
     },
-    "readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+    "node_modules/supports-hyperlinks/node_modules/supports-color": {
+      "version": "7.2.0",
+      "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
       "dev": true,
-      "requires": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      },
+      "license": "MIT",
       "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        }
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+    "node_modules/table": {
+      "version": "6.9.0",
+      "integrity": "sha1-UAQK+mJkFBx1ZrO4HU2CxHqGaPU=",
       "dev": true,
-      "requires": {
-        "picomatch": "^2.2.1"
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "ajv": "^8.0.1",
+        "lodash.truncate": "^4.4.2",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
       }
     },
-    "regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true
-    },
-    "require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true
-    },
-    "require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "dev": true
-    },
-    "resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+    "node_modules/table/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
       "dev": true,
-      "requires": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
       }
     },
-    "resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true
-    },
-    "rewire": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/rewire/-/rewire-6.0.0.tgz",
-      "integrity": "sha512-7sZdz5dptqBCapJYocw9EcppLU62KMEqDLIILJnNET2iqzXHaQfaVP5SOJ06XvjX+dNIDJbzjw0ZWzrgDhtjYg==",
+    "node_modules/table/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
       "dev": true,
-      "requires": {
-        "eslint": "^7.32.0"
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dev": true,
-      "requires": {
-        "glob": "^7.1.3"
+    "node_modules/tapable": {
+      "version": "2.2.2",
+      "integrity": "sha1-q0mENA0wy5mJpJADLwhtu4tW2HI=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
       }
     },
-    "safe-buffer": {
-      "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
-    },
-    "sax": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-      "dev": true
-    },
-    "semver": {
-      "version": "7.3.5",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
-      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
-      "requires": {
-        "lru-cache": "^6.0.0"
+    "node_modules/tar-fs": {
+      "version": "2.1.3",
+      "integrity": "sha1-+zuIQ6JrbxOgjmBveSKHXrH7v5I=",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "mkdirp-classic": "^0.5.2",
+        "pump": "^3.0.0",
+        "tar-stream": "^2.1.4"
       }
     },
-    "serialize-javascript": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
-      "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+    "node_modules/tar-stream": {
+      "version": "2.2.0",
+      "integrity": "sha1-rK2EwoQTawYNw/qmRHSqmuvXcoc=",
       "dev": true,
-      "requires": {
-        "randombytes": "^2.1.0"
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "bl": "^4.0.3",
+        "end-of-stream": "^1.4.1",
+        "fs-constants": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.1.1"
+      },
+      "engines": {
+        "node": ">=6"
       }
     },
-    "set-blocking": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-      "dev": true
-    },
-    "setimmediate": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
-      "dev": true
-    },
-    "shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+    "node_modules/tar-stream/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "integrity": "sha1-VqmzbqllwAxak+8x6xEaDxEFaWc=",
       "dev": true,
-      "requires": {
-        "shebang-regex": "^3.0.0"
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true
-    },
-    "side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+    "node_modules/terminal-link": {
+      "version": "4.0.0",
+      "integrity": "sha1-Xz5QMpQg+tl9B9Yk998YUdgpY/E=",
       "dev": true,
-      "requires": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
+      "license": "MIT",
+      "dependencies": {
+        "ansi-escapes": "^7.0.0",
+        "supports-hyperlinks": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "signal-exit": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz",
-      "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==",
-      "dev": true
-    },
-    "simple-concat": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
-      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
-      "dev": true
+    "node_modules/test-exclude": {
+      "version": "6.0.0",
+      "integrity": "sha1-BKhphmHYBepvopO2y55jrARO8V4=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "@istanbuljs/schema": "^0.1.2",
+        "glob": "^7.1.4",
+        "minimatch": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "simple-get": {
-      "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,
-      "requires": {
-        "decompress-response": "^4.2.0",
-        "once": "^1.3.1",
-        "simple-concat": "^1.0.0"
+    "node_modules/test-exclude/node_modules/brace-expansion": {
+      "version": "1.1.12",
+      "integrity": "sha1-q5tFRGblqMw6GHvqrVgEEqnFuEM=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
-    "sinon": {
-      "version": "13.0.1",
-      "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
-      "integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
-      "dev": true,
-      "requires": {
-        "@sinonjs/commons": "^1.8.3",
-        "@sinonjs/fake-timers": "^9.0.0",
-        "@sinonjs/samsam": "^6.1.1",
-        "diff": "^5.0.0",
-        "nise": "^5.1.1",
-        "supports-color": "^7.2.0"
-      },
+    "node_modules/test-exclude/node_modules/glob": {
+      "version": "7.2.3",
+      "integrity": "sha1-uN8PuAK7+o6JvR2Ti04WV47UTys=",
+      "license": "ISC",
+      "optional": true,
       "dependencies": {
-        "@sinonjs/fake-timers": {
-          "version": "9.0.0",
-          "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.0.0.tgz",
-          "integrity": "sha512-+shXA2X7KNP7H7qNbQTJ3SA+NQc0pZDSBrdvFSRwF8sAo/ohw+ZQFD8Moc+gnz51+1eRXtEQBpKWPiQ4jsRC/w==",
-          "dev": true,
-          "requires": {
-            "@sinonjs/commons": "^1.7.0"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "slice-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
+    "node_modules/test-exclude/node_modules/minimatch": {
+      "version": "3.1.2",
+      "integrity": "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
+    "node_modules/text-table": {
+      "version": "0.2.0",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true,
+      "license": "MIT"
     },
-    "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==",
+    "node_modules/textextensions": {
+      "version": "6.11.0",
+      "integrity": "sha1-hkU10J9JAmFQyW8LDXnx+ghp2xU=",
       "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.0"
+      "license": "Artistic-2.0",
+      "dependencies": {
+        "editions": "^6.21.0"
+      },
+      "engines": {
+        "node": ">=4"
+      },
+      "funding": {
+        "url": "https://bevry.me/fund"
       }
     },
-    "string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+    "node_modules/tmp": {
+      "version": "0.2.3",
+      "integrity": "sha1-63g8wivB6L69BnFHbUbqTrMqea4=",
       "dev": true,
-      "requires": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.14"
       }
     },
-    "strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "requires": {
-        "ansi-regex": "^5.0.1"
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
       }
     },
-    "strip-json-comments": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true
+    "node_modules/ts-api-utils": {
+      "version": "2.1.0",
+      "integrity": "sha1-WV9wlORu7TZME/0j51+VE9Kbr5E=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=18.12"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.8.4"
+      }
     },
-    "supports-color": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "integrity": "sha1-YS7+TtI11Wfoq6Xypfq3AoCt6D8=",
+      "license": "0BSD"
+    },
+    "node_modules/tunnel": {
+      "version": "0.0.6",
+      "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=",
       "dev": true,
-      "requires": {
-        "has-flag": "^4.0.0"
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
       }
     },
-    "table": {
-      "version": "6.7.5",
-      "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz",
-      "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==",
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
       "dev": true,
-      "requires": {
-        "ajv": "^8.0.1",
-        "lodash.truncate": "^4.4.2",
-        "slice-ansi": "^4.0.0",
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1"
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
       },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/type-check": {
+      "version": "0.4.0",
+      "integrity": "sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE=",
+      "license": "MIT",
+      "optional": true,
       "dependencies": {
-        "ajv": {
-          "version": "8.8.2",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
-          "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "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
-        }
+        "prelude-ls": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
       }
     },
-    "tar-fs": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
-      "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
-      "dev": true,
-      "requires": {
-        "chownr": "^1.1.1",
-        "mkdirp-classic": "^0.5.2",
-        "pump": "^3.0.0",
-        "tar-stream": "^2.1.4"
+    "node_modules/type-detect": {
+      "version": "4.0.8",
+      "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=4"
       }
     },
-    "tar-stream": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
-      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+    "node_modules/type-fest": {
+      "version": "4.41.0",
+      "integrity": "sha1-auHI5XMSc8K/H1itOcuuLJGkbFg=",
       "dev": true,
-      "requires": {
-        "bl": "^4.0.3",
-        "end-of-stream": "^1.4.1",
-        "fs-constants": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.1.1"
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=16"
       },
-      "dependencies": {
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        }
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "text-table": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
-      "dev": true
-    },
-    "to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+    "node_modules/typed-rest-client": {
+      "version": "1.8.11",
+      "integrity": "sha1-aQbwLjyR6NhRV58lWr8P1ggAoE0=",
       "dev": true,
-      "requires": {
-        "is-number": "^7.0.0"
+      "license": "MIT",
+      "dependencies": {
+        "qs": "^6.9.1",
+        "tunnel": "0.0.6",
+        "underscore": "^1.12.1"
       }
     },
-    "tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
-    },
-    "traverse": {
-      "version": "0.3.9",
-      "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
-      "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=",
-      "dev": true
-    },
-    "tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "dev": true
-    },
-    "tslint": {
-      "version": "6.1.3",
-      "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
-      "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "builtin-modules": "^1.1.1",
-        "chalk": "^2.3.0",
-        "commander": "^2.12.1",
-        "diff": "^4.0.1",
-        "glob": "^7.1.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
-        "mkdirp": "^0.5.3",
-        "resolve": "^1.3.2",
-        "semver": "^5.3.0",
-        "tslib": "^1.13.0",
-        "tsutils": "^2.29.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "argparse": {
-          "version": "1.0.10",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-          "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-          "dev": true,
-          "requires": {
-            "sprintf-js": "~1.0.2"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "diff": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-          "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-          "dev": true
-        },
-        "js-yaml": {
-          "version": "3.14.1",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-          "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
-          "dev": true,
-          "requires": {
-            "argparse": "^1.0.7",
-            "esprima": "^4.0.0"
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
+    "node_modules/typescript": {
+      "version": "5.8.3",
+      "integrity": "sha1-kvij5ePPSXNW9BeMNM1lp/XoRA4=",
+      "license": "Apache-2.0",
+      "optional": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/typescript-eslint": {
+      "version": "8.38.0",
+      "integrity": "sha1-5zr3YYE58HsW4vrnFe7aq7Qe6LA=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@typescript-eslint/eslint-plugin": "8.38.0",
+        "@typescript-eslint/parser": "8.38.0",
+        "@typescript-eslint/typescript-estree": "8.38.0",
+        "@typescript-eslint/utils": "8.38.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.57.0 || ^9.0.0",
+        "typescript": ">=4.8.4 <5.9.0"
       }
     },
-    "tsutils": {
-      "version": "2.29.0",
-      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
-      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+    "node_modules/uc.micro": {
+      "version": "2.1.0",
+      "integrity": "sha1-+NP30OxMPeo1p+PI76TLi0XJ5+4=",
       "dev": true,
-      "requires": {
-        "tslib": "^1.8.1"
-      }
+      "license": "MIT"
     },
-    "tunnel": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
-      "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
-      "dev": true
+    "node_modules/underscore": {
+      "version": "1.13.7",
+      "integrity": "sha1-lw4zljr5p92iKPF+voOZ5fvmOhA=",
+      "dev": true,
+      "license": "MIT"
     },
-    "tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+    "node_modules/undici": {
+      "version": "7.12.0",
+      "integrity": "sha1-6TJE+kk4PooOGkKVBI/UVFQcfMs=",
       "dev": true,
-      "requires": {
-        "safe-buffer": "^5.0.1"
+      "license": "MIT",
+      "engines": {
+        "node": ">=20.18.1"
       }
     },
-    "type-check": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+    "node_modules/undici-types": {
+      "version": "6.21.0",
+      "integrity": "sha1-aR0ArzkJvpOn+qE75hs6W1DvEss=",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/unicorn-magic": {
+      "version": "0.3.0",
+      "integrity": "sha1-Tv1FyFpp4N1XbSVTL7+iKqXIoQQ=",
       "dev": true,
-      "requires": {
-        "prelude-ls": "^1.2.1"
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "type-detect": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
-      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
-      "dev": true
-    },
-    "type-fest": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-      "dev": true
-    },
-    "typed-rest-client": {
-      "version": "1.8.6",
-      "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.6.tgz",
-      "integrity": "sha512-xcQpTEAJw2DP7GqVNECh4dD+riS+C1qndXLfBCJ3xk0kqprtGN491P5KlmrDbKdtuW8NEcP/5ChxiJI3S9WYTA==",
-      "dev": true,
-      "requires": {
-        "qs": "^6.9.1",
-        "tunnel": "0.0.6",
-        "underscore": "^1.12.1"
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "integrity": "sha1-Fo78IYCWTmOG0GHglN9hr+I5sY0=",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.0.0"
       }
     },
-    "typescript": {
-      "version": "4.5.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
-      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
-      "dev": true
-    },
-    "uc.micro": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
-      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
-      "dev": true
-    },
-    "underscore": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
-      "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
-      "dev": true
-    },
-    "unzipper": {
-      "version": "0.10.11",
-      "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz",
-      "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==",
-      "dev": true,
-      "requires": {
-        "big-integer": "^1.6.17",
-        "binary": "~0.3.0",
-        "bluebird": "~3.4.1",
-        "buffer-indexof-polyfill": "~1.0.0",
-        "duplexer2": "~0.1.4",
-        "fstream": "^1.0.12",
-        "graceful-fs": "^4.2.2",
-        "listenercount": "~1.0.1",
-        "readable-stream": "~2.3.6",
-        "setimmediate": "~1.0.4"
+    "node_modules/untildify": {
+      "version": "4.0.0",
+      "integrity": "sha1-K8lHuVNlJIfkYAlJ+wkeOujNkZs=",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
       }
     },
-    "uri-js": {
+    "node_modules/uri-js": {
       "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "requires": {
+      "integrity": "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=",
+      "license": "BSD-2-Clause",
+      "optional": true,
+      "dependencies": {
         "punycode": "^2.1.0"
       }
     },
-    "url-join": {
+    "node_modules/url-join": {
       "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
-      "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
-      "dev": true
+      "integrity": "sha1-tkLiGiZGgI/6F4xMX9o5hE4Szec=",
+      "dev": true,
+      "license": "MIT"
     },
-    "util-deprecate": {
+    "node_modules/util-deprecate": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "dev": true
+      "license": "MIT",
+      "optional": true
     },
-    "uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
+    "node_modules/uuid": {
+      "version": "9.0.1",
+      "integrity": "sha1-4YjUyIU8xyIiA5LEJM1jfzIpPzA=",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
+      "license": "MIT",
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
     },
-    "v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
-    },
-    "vsce": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.6.7.tgz",
-      "integrity": "sha512-5dEtdi/yzWQbOU7JDUSOs8lmSzzkewBR5P122BUkmXE6A/DEdFsKNsg2773NGXJTwwF1MfsOgUR6QVF3cLLJNQ==",
-      "dev": true,
-      "requires": {
-        "azure-devops-node-api": "^11.0.1",
-        "chalk": "^2.4.2",
-        "cheerio": "^1.0.0-rc.9",
-        "commander": "^6.1.0",
-        "glob": "^7.0.6",
-        "hosted-git-info": "^4.0.2",
-        "keytar": "^7.7.0",
-        "leven": "^3.1.0",
-        "markdown-it": "^12.3.2",
-        "mime": "^1.3.4",
-        "minimatch": "^3.0.3",
-        "parse-semver": "^1.1.1",
-        "read": "^1.0.7",
-        "semver": "^5.1.0",
-        "tmp": "^0.2.1",
-        "typed-rest-client": "^1.8.4",
-        "url-join": "^4.0.1",
-        "xml2js": "^0.4.23",
-        "yauzl": "^2.3.1",
-        "yazl": "^2.2.2"
+    "node_modules/v8-to-istanbul": {
+      "version": "9.3.0",
+      "integrity": "sha1-uVcqv6Yr1VbBbXX968GkEdX/MXU=",
+      "license": "ISC",
+      "optional": true,
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.12",
+        "@types/istanbul-lib-coverage": "^2.0.1",
+        "convert-source-map": "^2.0.0"
       },
+      "engines": {
+        "node": ">=10.12.0"
+      }
+    },
+    "node_modules/validate-npm-package-license": {
+      "version": "3.0.4",
+      "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=",
+      "dev": true,
+      "license": "Apache-2.0",
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "commander": {
-          "version": "6.2.1",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
-          "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-          "dev": true
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        },
-        "tmp": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
-          "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
-          "dev": true,
-          "requires": {
-            "rimraf": "^3.0.0"
-          }
-        }
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
       }
     },
-    "vscode-extension-telemetry": {
-      "version": "0.4.5",
-      "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.4.5.tgz",
-      "integrity": "sha512-YhPiPcelqM5xyYWmD46jIcsxLYWkPZhAxlBkzqmpa218fMtTT17ERdOZVCXcs1S5AjvDHlq43yCgi8TaVQjjEg=="
+    "node_modules/version-range": {
+      "version": "4.14.0",
+      "integrity": "sha1-kcEuRmV1apEB0a9D+u2jmavg7ew=",
+      "dev": true,
+      "license": "Artistic-2.0",
+      "engines": {
+        "node": ">=4"
+      },
+      "funding": {
+        "url": "https://bevry.me/fund"
+      }
     },
-    "vscode-jsonrpc": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
-      "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="
+    "node_modules/vscode-jsonrpc": {
+      "version": "8.2.0",
+      "integrity": "sha1-9D36NftR52PRfNlNzKDJRY81q/k=",
+      "license": "MIT",
+      "engines": {
+        "node": ">=14.0.0"
+      }
     },
-    "vscode-languageclient": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
-      "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
-      "requires": {
-        "minimatch": "^3.0.4",
-        "semver": "^7.3.4",
-        "vscode-languageserver-protocol": "3.16.0"
+    "node_modules/vscode-languageclient": {
+      "version": "9.0.1",
+      "integrity": "sha1-zf4gJncmyNTbg53B6dGBbhKW6FQ=",
+      "license": "MIT",
+      "dependencies": {
+        "minimatch": "^5.1.0",
+        "semver": "^7.3.7",
+        "vscode-languageserver-protocol": "3.17.5"
+      },
+      "engines": {
+        "vscode": "^1.82.0"
       }
     },
-    "vscode-languageserver-protocol": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
-      "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
-      "requires": {
-        "vscode-jsonrpc": "6.0.0",
-        "vscode-languageserver-types": "3.16.0"
+    "node_modules/vscode-languageclient/node_modules/minimatch": {
+      "version": "5.1.6",
+      "integrity": "sha1-HPy4z1Ui6mmVLNKvla4JR38SKpY=",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "vscode-languageserver-types": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
-      "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
+    "node_modules/vscode-languageserver-protocol": {
+      "version": "3.17.5",
+      "integrity": "sha1-hkqLjzkINVcvThO9n4MT0OOsS+o=",
+      "license": "MIT",
+      "dependencies": {
+        "vscode-jsonrpc": "8.2.0",
+        "vscode-languageserver-types": "3.17.5"
+      }
     },
-    "webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+    "node_modules/vscode-languageserver-types": {
+      "version": "3.17.5",
+      "integrity": "sha1-MnNnbwzy6rQLP0TQhay7fwijnYo=",
+      "license": "MIT"
     },
-    "whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
-      "requires": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
+    "node_modules/whatwg-encoding": {
+      "version": "3.1.1",
+      "integrity": "sha1-0PTvdpkF1CbhaI8+NDgambYLduU=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "iconv-lite": "0.6.3"
+      },
+      "engines": {
+        "node": ">=18"
       }
     },
-    "which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+    "node_modules/whatwg-mimetype": {
+      "version": "4.0.0",
+      "integrity": "sha1-vBv5SphdxQOI1UqSWKxAXDyi/Ao=",
       "dev": true,
-      "requires": {
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/which": {
+      "version": "2.0.2",
+      "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=",
+      "devOptional": true,
+      "license": "ISC",
+      "dependencies": {
         "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "wide-align": {
-      "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,
-      "requires": {
-        "string-width": "^1.0.2 || 2 || 3 || 4"
+    "node_modules/word-wrap": {
+      "version": "1.2.5",
+      "integrity": "sha1-0sRcbdT7zmIaZvE2y+Mor9BBCzQ=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
-      "dev": true
+    "node_modules/workerpool": {
+      "version": "6.5.1",
+      "integrity": "sha1-Bg9zs50Mr5fG22TaAEzQG0wJlUQ=",
+      "license": "Apache-2.0",
+      "optional": true
     },
-    "workerpool": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
-      "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
-      "dev": true
+    "node_modules/wrap-ansi": {
+      "version": "8.1.0",
+      "integrity": "sha1-VtwiNo7lcPrOG0mBmXXZuaXq0hQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.1.0",
+        "string-width": "^5.0.1",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
     },
-    "wrap-ansi": {
+    "node_modules/wrap-ansi-cjs": {
+      "name": "wrap-ansi",
       "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "requires": {
+      "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
         "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-styles": {
+      "version": "6.2.1",
+      "integrity": "sha1-DmIyDPmcIa//OzASGSVGqsv7BcU=",
+      "devOptional": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "integrity": "sha1-hAyIA7DYBH9P8M+WMXazLU7z7XI=",
+      "devOptional": true,
+      "license": "MIT"
+    },
+    "node_modules/wrap-ansi/node_modules/string-width": {
+      "version": "5.1.2",
+      "integrity": "sha1-FPja7G2B5yIdKjV+Zoyrc728p5Q=",
+      "devOptional": true,
+      "license": "MIT",
+      "dependencies": {
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "wrappy": {
+    "node_modules/wrappy": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
+      "license": "ISC",
+      "optional": true
     },
-    "xml2js": {
-      "version": "0.4.23",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
-      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+    "node_modules/wsl-utils": {
+      "version": "0.1.0",
+      "integrity": "sha1-h4PU32cdTVA2W+LuTHGRegVXuqs=",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-wsl": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/xml2js": {
+      "version": "0.5.0",
+      "integrity": "sha1-2UQGMfuy7YACA/rRBvJyT2LEk7c=",
       "dev": true,
-      "requires": {
+      "license": "MIT",
+      "dependencies": {
         "sax": ">=0.6.0",
         "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
       }
     },
-    "xmlbuilder": {
+    "node_modules/xmlbuilder": {
       "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
-      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
-      "dev": true
+      "integrity": "sha1-vpuuHIoEbnazESdyY0fQrXACvrM=",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      }
     },
-    "y18n": {
+    "node_modules/y18n": {
       "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true
+      "integrity": "sha1-f0k00PfKjFb5UxSTndzS3ZHOHVU=",
+      "license": "ISC",
+      "optional": true,
+      "engines": {
+        "node": ">=10"
+      }
     },
-    "yallist": {
+    "node_modules/yallist": {
       "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
-    },
-    "yargs": {
-      "version": "16.2.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=",
       "dev": true,
-      "requires": {
-        "cliui": "^7.0.2",
+      "license": "ISC"
+    },
+    "node_modules/yargs": {
+      "version": "17.7.2",
+      "integrity": "sha1-mR3zmspnWhkrgW4eA2P5110qomk=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
+        "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
+        "yargs-parser": "^21.1.1"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
-    "yargs-parser": {
-      "version": "20.2.4",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
-      "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
-      "dev": true
+    "node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "integrity": "sha1-kJa87r+ZDSG7MfqVFuDt4pSnfTU=",
+      "license": "ISC",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
     },
-    "yargs-unparser": {
+    "node_modules/yargs-unparser": {
       "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
-      "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
-      "dev": true,
-      "requires": {
+      "integrity": "sha1-8TH5ImkRrl2a04xDL+gJNmwjJes=",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
         "camelcase": "^6.0.0",
         "decamelize": "^4.0.0",
         "flat": "^5.0.2",
         "is-plain-obj": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "yauzl": {
+    "node_modules/yauzl": {
       "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
       "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
       "dev": true,
-      "requires": {
+      "license": "MIT",
+      "dependencies": {
         "buffer-crc32": "~0.2.3",
         "fd-slicer": "~1.1.0"
       }
     },
-    "yazl": {
+    "node_modules/yazl": {
       "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
-      "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+      "integrity": "sha1-o9ZdPdZZpbCTeFDoYJ8i//orXDU=",
       "dev": true,
-      "requires": {
+      "license": "MIT",
+      "dependencies": {
         "buffer-crc32": "~0.2.3"
       }
     },
-    "yocto-queue": {
+    "node_modules/yocto-queue": {
       "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true
+      "integrity": "sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     }
   }
 }
diff --git a/package.json b/package.json
index b403f49871..f86e867977 100644
--- a/package.json
+++ b/package.json
@@ -1,87 +1,118 @@
 {
-  "name": "powershell-preview",
-  "displayName": "PowerShell Preview",
-  "version": "2022.2.2",
-  "preview": true,
+  "name": "powershell",
+  "displayName": "PowerShell",
+  "version": "2025.2.0",
+  "preview": false,
   "publisher": "ms-vscode",
-  "description": "(Preview) Develop PowerShell modules, commands and scripts in Visual Studio Code!",
+  "description": "Develop PowerShell modules, commands and scripts in Visual Studio Code!",
   "engines": {
-    "vscode": "^1.56.0"
+    "vscode": "^1.101.0"
   },
+  "author": "Microsoft Corporation",
   "license": "SEE LICENSE IN LICENSE.txt",
-  "homepage": "https://github.com/PowerShell/vscode-powershell/blob/master/README.md",
+  "homepage": "https://github.com/PowerShell/vscode-powershell/blob/main/README.md",
   "categories": [
     "Debuggers",
+    "Formatters",
     "Programming Languages",
     "Snippets",
-    "Linters"
+    "Linters",
+    "Themes"
   ],
-  "icon": "media/PowerShell_Preview_Icon.png",
+  "keywords": [
+    "PowerShell",
+    "pwsh"
+  ],
+  "icon": "media/PowerShell_Icon.png",
   "galleryBanner": {
     "color": "#ACD1EC",
     "theme": "light"
   },
+  "badges": [
+    {
+      "url": "https://github.com/PowerShell/vscode-powershell/actions/workflows/ci-test.yml/badge.svg",
+      "href": "https://github.com/PowerShell/vscode-powershell/actions/workflows/ci-test.yml?query=branch%3Amain",
+      "description": "Build Status"
+    },
+    {
+      "url": "https://img.shields.io/discord/180528040881815552.svg?label=%23vscode&logo=discord&logoColor=white",
+      "href": "https://aka.ms/powershell-vscode-discord",
+      "description": "Join the chat on Discord"
+    },
+    {
+      "url": "https://badges.gitter.im/PowerShell/vscode-powershell.svg",
+      "href": "https://gitter.im/PowerShell/vscode-powershell?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge",
+      "description": "Join the chat on Gitter"
+    }
+  ],
   "repository": {
     "type": "git",
     "url": "https://github.com/PowerShell/vscode-powershell.git"
   },
+  "bugs": {
+    "url": "https://github.com/PowerShell/vscode-powershell/issues"
+  },
   "activationEvents": [
-    "onDebugInitialConfigurations",
     "onDebugResolve:PowerShell",
     "onLanguage:powershell",
-    "onCommand:PowerShell.NewProjectFromTemplate",
-    "onCommand:PowerShell.OpenExamplesFolder",
     "onCommand:PowerShell.PickPSHostProcess",
     "onCommand:PowerShell.PickRunspace",
-    "onCommand:PowerShell.SpecifyScriptArgs",
-    "onCommand:PowerShell.ShowSessionConsole",
-    "onCommand:PowerShell.ShowSessionMenu",
-    "onCommand:PowerShell.RestartSession",
-    "onCommand:PowerShell.EnableISEMode",
-    "onCommand:PowerShell.DisableISEMode",
-    "onView:PowerShellCommands"
+    "onCommand:PowerShell.SpecifyScriptArgs"
   ],
   "dependencies": {
-    "node-fetch": "~2.6.7",
-    "semver": "~7.3.5",
-    "uuid": "~8.3.2",
-    "vscode-extension-telemetry": "~0.4.5",
-    "vscode-languageclient": "~7.0.0",
-    "vscode-languageserver-protocol": "~3.16.0"
+    "@vscode/extension-telemetry": "^0.9.9",
+    "semver": "^7.7.2",
+    "untildify": "^4.0.0",
+    "uuid": "^9.0.1",
+    "vscode-languageclient": "^9.0.1",
+    "vscode-languageserver-protocol": "^3.17.5"
   },
   "devDependencies": {
-    "@types/glob": "~7.2.0",
-    "@types/mocha": "~9.1.0",
-    "@types/mock-fs": "~4.13.1",
-    "@types/node": "~14.17.4",
-    "@types/node-fetch": "~2.6.1",
-    "@types/rewire": "~2.5.28",
-    "@types/semver": "~7.3.9",
-    "@types/sinon": "~10.0.11",
-    "@types/uuid": "~8.3.4",
-    "@types/vscode": "~1.56.0",
-    "@vscode/test-electron": "~2.1.2",
-    "esbuild": "^0.14.23",
-    "glob": "^7.2.0",
-    "mocha": "~9.2.1",
-    "mocha-multi-reporters": "~1.5.1",
-    "mock-fs": "~5.1.2",
-    "rewire": "~6.0.0",
-    "sinon": "~13.0.1",
-    "tslint": "~6.1.3",
-    "typescript": "~4.5.5",
-    "vsce": "~2.6.7"
+    "@vscode/vsce": "^3.6.0",
+    "esbuild": "^0.25.8"
+  },
+  "optionalDependencies": {
+    "@eslint/js": "^9.26.0",
+    "@types/mock-fs": "^4.13.4",
+    "@types/node": "^22.16.5",
+    "@types/semver": "^7.7.0",
+    "@types/sinon": "^17.0.4",
+    "@types/ungap__structured-clone": "^1.2.0",
+    "@types/uuid": "^9.0.8",
+    "@types/vscode": "~1.101.0",
+    "@ungap/structured-clone": "^1.3.0",
+    "@vscode/debugprotocol": "^1.68.0",
+    "@vscode/test-cli": "^0.0.10",
+    "@vscode/test-electron": "^2.5.2",
+    "esbuild-register": "^3.6.0",
+    "eslint": "^9.31.0",
+    "eslint-config-prettier": "^10.1.8",
+    "mock-fs": "^5.5.0",
+    "prettier": "^3.6.2",
+    "prettier-plugin-organize-imports": "^4.2.0",
+    "sinon": "^19.0.5",
+    "typescript": "^5.8.3",
+    "typescript-eslint": "^8.38.0"
   },
   "extensionDependencies": [
     "vscode.powershell"
   ],
-  "main": "./out/main.js",
+  "main": "./dist/extension.js",
   "scripts": {
-    "lint": "tslint --project tsconfig.json",
-    "build": "tsc --project tsconfig.json && esbuild ./src/main.ts --outdir=out --bundle --external:vscode --platform=node",
-    "test": "node ./out/test/runTests.js",
-    "package": "vsce package --no-gitHubIssueLinking",
-    "publish": "vsce publish"
+    "compile": "esbuild ./src/extension.ts --outdir=dist --sourcemap --bundle --external:vscode --platform=node",
+    "watch": "npm run compile -- --watch",
+    "lint": "eslint src test --ext .ts",
+    "format": "prettier --check '**/*.{ts,json,yml,mjs,code-workspace}'",
+    "package": "vsce package --out out/ --no-gitHubIssueLinking",
+    "publish": "vsce publish",
+    "pretest": "npm run compile",
+    "test": "vscode-test"
+  },
+  "prettier": {
+    "endOfLine": "auto",
+    "plugins": [
+      "prettier-plugin-organize-imports"
+    ]
   },
   "contributes": {
     "breakpoints": [
@@ -92,17 +123,17 @@
     "viewsContainers": {
       "activitybar": [
         {
-          "id": "PowerShellCommandExplorer",
-          "title": "(Preview) PowerShell Command Explorer",
-          "icon": "media/pwsh.svg"
+          "id": "PowerShell",
+          "title": "PowerShell",
+          "icon": "$(terminal-powershell)"
         }
       ]
     },
     "views": {
-      "PowerShellCommandExplorer": [
+      "PowerShell": [
         {
           "id": "PowerShellCommands",
-          "name": "PowerShell Commands",
+          "name": "Command Explorer",
           "when": "config.powershell.sideBar.CommandExplorerVisibility"
         }
       ]
@@ -152,59 +183,44 @@
         "title": "Disable ISE Mode (restore to defaults)",
         "category": "PowerShell"
       },
+      {
+        "command": "PowerShell.ToggleISEMode",
+        "title": "Toggle ISE Mode",
+        "category": "PowerShell"
+      },
       {
         "command": "PowerShell.RefreshCommandsExplorer",
         "title": "Refresh Command Explorer",
-        "icon": {
-          "light": "media/resources/light/sync.svg",
-          "dark": "media/resources/dark/sync.svg"
-        },
-        "category": "PowerShell"
+        "category": "PowerShell",
+        "icon": "$(sync)"
       },
       {
         "command": "PowerShell.InsertCommand",
         "title": "Insert Command",
-        "icon": {
-          "light": "media/resources/light/pencil.svg",
-          "dark": "media/resources/dark/pencil.svg"
-        },
-        "category": "PowerShell"
-      },
-      {
-        "command": "PowerShell.OnlineHelp",
-        "title": "Get Online Help for Command (Deprecated)",
-        "category": "PowerShell"
+        "category": "PowerShell",
+        "icon": "$(pencil)"
       },
       {
         "command": "PowerShell.ShowHelp",
         "title": "Get Help for Command",
-        "icon": {
-          "light": "media/resources/light/question.svg",
-          "dark": "media/resources/dark/question.svg"
-        },
-        "category": "PowerShell"
+        "category": "PowerShell",
+        "icon": "$(question)"
       },
       {
         "command": "PowerShell.Debug.Start",
         "title": "Run",
         "category": "PowerShell",
-        "icon": {
-          "light": "media/resources/light/run.svg",
-          "dark": "media/resources/dark/run.svg"
-        }
+        "icon": "$(run)"
       },
       {
         "command": "PowerShell.RunSelection",
         "title": "Run Selection",
         "category": "PowerShell",
-        "icon": {
-          "light": "media/resources/light/play.svg",
-          "dark": "media/resources/dark/play.svg"
-        }
+        "icon": "$(debug-line-by-line)"
       },
       {
         "command": "PowerShell.RestartSession",
-        "title": "Restart Current Session",
+        "title": "Restart Session",
         "category": "PowerShell"
       },
       {
@@ -219,7 +235,7 @@
       },
       {
         "command": "PowerShell.GenerateBugReport",
-        "title": "Upload Bug Report to Github",
+        "title": "Upload Bug Report to GitHub",
         "category": "PowerShell"
       },
       {
@@ -230,7 +246,8 @@
       {
         "command": "PowerShell.PowerShellFindModule",
         "title": "Find/Install PowerShell Modules from the Gallery",
-        "category": "PowerShell"
+        "category": "PowerShell",
+        "deprecationMessage": "This feature is no longer available, we're sorry!"
       },
       {
         "command": "PowerShell.ShowAdditionalCommands",
@@ -244,12 +261,7 @@
       },
       {
         "command": "PowerShell.ShowSessionConsole",
-        "title": "Show Integrated Console",
-        "category": "PowerShell"
-      },
-      {
-        "command": "PowerShell.NewProjectFromTemplate",
-        "title": "Create New Project from Plaster Template",
+        "title": "Show Extension Terminal",
         "category": "PowerShell"
       },
       {
@@ -275,29 +287,29 @@
       {
         "command": "PowerShell.ClosePanel",
         "title": "Close panel",
-        "category": "PowerShell",
-        "icon": {
-          "light": "media/resources/light/ClosePanel.svg",
-          "dark": "media/resources/dark/ClosePanel.svg"
-        }
+        "category": "PowerShell"
       },
       {
         "command": "PowerShell.PositionPanelLeft",
         "title": "Move panel left",
         "category": "PowerShell",
-        "icon": {
-          "light": "media/resources/light/MovePanelLeft.svg",
-          "dark": "media/resources/dark/MovePanelLeft.svg"
-        }
+        "icon": "$(layout-sidebar-left)"
       },
       {
         "command": "PowerShell.PositionPanelBottom",
         "title": "Move panel to bottom",
         "category": "PowerShell",
-        "icon": {
-          "light": "media/resources/light/MovePanelBottom.svg",
-          "dark": "media/resources/dark/MovePanelBottom.svg"
-        }
+        "icon": "$(layout-panel-right)"
+      },
+      {
+        "title": "[PowerShell Debug Input Task] Wait for and return PSES startup PID",
+        "command": "PowerShell.WaitForPsesActivationAndReturnProcessId",
+        "enablement": "false"
+      },
+      {
+        "title": "[PowerShell Debug Input Task] Get the VS Code Session ID for writing the PID file",
+        "command": "GetVsCodeSessionId",
+        "enablement": "false"
       }
     ],
     "menus": {
@@ -348,11 +360,6 @@
           "command": "PowerShell.PositionPanelLeft",
           "group": "navigation@98"
         },
-        {
-          "when": "editorLangId == powershell && config.powershell.buttons.showPanelMovementButtons",
-          "command": "PowerShell.ClosePanel",
-          "group": "navigation@99"
-        },
         {
           "when": "editorLangId == powershell && config.powershell.buttons.showRunButtons",
           "command": "PowerShell.Debug.Start",
@@ -442,7 +449,7 @@
               "type": "PowerShell",
               "request": "launch",
               "script": "^\"\\${file}\"",
-              "cwd": "^\"\\${file}\""
+              "cwd": "^\"\\${cwd}\""
             }
           },
           {
@@ -452,18 +459,18 @@
               "name": "PowerShell Launch Script",
               "type": "PowerShell",
               "request": "launch",
-              "script": "^\"enter path or command to execute e.g.: \\${workspaceFolder}/src/foo.ps1 or Invoke-Pester\"",
-              "cwd": "^\"\\${workspaceFolder}\""
+              "script": "^\"Enter path or command to execute, for example, \\${workspaceFolder}/src/foo.ps1 or Invoke-Pester\"",
+              "cwd": "^\"\\${cwd}\""
             }
           },
           {
             "label": "PowerShell: Interactive Session",
-            "description": "Debug commands executed from the Integrated Console",
+            "description": "Debug commands executed from the Extension Terminal",
             "body": {
               "name": "PowerShell Interactive Session",
               "type": "PowerShell",
               "request": "launch",
-              "cwd": ""
+              "cwd": "^\"\\${cwd}\""
             }
           },
           {
@@ -472,18 +479,63 @@
             "body": {
               "name": "PowerShell Attach to Host Process",
               "type": "PowerShell",
-              "request": "attach",
-              "runspaceId": 1
+              "request": "attach"
+            }
+          },
+          {
+            "label": "PowerShell: Run Pester Tests",
+            "description": "Debug Pester Tests detected in your current directory (runs Invoke-Pester)",
+            "body": {
+              "name": "PowerShell Run Pester Tests",
+              "type": "PowerShell",
+              "request": "launch",
+              "script": "Invoke-Pester",
+              "createTemporaryIntegratedConsole": true,
+              "attachDotnetDebugger": true
+            }
+          },
+          {
+            "label": "PowerShell: Interactive Session (Module)",
+            "description": "Debug commands executed from the PowerShell Extension Terminal after auto-loading your module",
+            "body": {
+              "name": "PowerShell: Module Interactive Session",
+              "type": "PowerShell",
+              "request": "launch",
+              "script": "Enter command to import your binary module, for example: \"Import-Module -Force ${workspaceFolder}/path/to/module.psd1|dll\""
+            }
+          },
+          {
+            "label": "PowerShell: Interactive Session (Binary Module)",
+            "description": "Debug a .NET binary or hybrid module loaded into a PowerShell session. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
+            "body": {
+              "name": "PowerShell: Binary Module Interactive",
+              "type": "PowerShell",
+              "request": "launch",
+              "script": "Enter command to import your binary module, for example: \"Import-Module -Force ${workspaceFolder}/path/to/module.psd1|dll\"",
+              "createTemporaryIntegratedConsole": true,
+              "attachDotnetDebugger": true
+            }
+          },
+          {
+            "label": "PowerShell: Run Pester Tests (Binary Module)",
+            "description": "Debug a .NET binary or hybrid module by running Pester tests. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
+            "body": {
+              "name": "PowerShell: Binary Module Pester Tests",
+              "type": "PowerShell",
+              "request": "launch",
+              "script": "Invoke-Pester",
+              "createTemporaryIntegratedConsole": true,
+              "attachDotnetDebugger": true
             }
           },
           {
-            "label": "PowerShell: Attach Interactive Session Runspace",
-            "description": "Open runspace picker to select runspace to attach debugger to",
+            "label": "PowerShell: Windows PowerShell",
+            "description": "(Windows Only) Launch a temporary Windows PowerShell console for debugging. This is useful for debugging legacy scripts that require Windows PowerShell.",
             "body": {
-              "name": "PowerShell Attach Interactive Session Runspace",
+              "name": "PowerShell: Windows PowerShell",
               "type": "PowerShell",
-              "request": "attach",
-              "processId": "current"
+              "request": "launch",
+              "sessionName": "Windows PowerShell (x64)"
             }
           }
         ],
@@ -509,7 +561,25 @@
               },
               "createTemporaryIntegratedConsole": {
                 "type": "boolean",
-                "description": "Determines whether a temporary PowerShell Integrated Console is created for each debugging session, useful for debugging PowerShell classes and binary modules.  Overrides the user setting 'powershell.debugging.createTemporaryIntegratedConsole'.",
+                "description": "Determines whether a temporary PowerShell Extension Terminal is created for each debugging session, useful for debugging PowerShell classes and binary modules.  Overrides the user setting 'powershell.debugging.createTemporaryIntegratedConsole'.",
+                "default": false
+              },
+              "sessionName": {
+                "type": [
+                  "string",
+                  "null"
+                ],
+                "description": "If specified, uses the PowerShell session name to launch the debug configuration. Will always launch in a temporary console if specified.",
+                "default": null
+              },
+              "attachDotnetDebugger": {
+                "type": "boolean",
+                "description": "If specified, a C# debug session will be started and attached to the new temporary extension terminal. This does nothing unless 'powershell.debugging.createTemporaryIntegratedConsole' is also specified.",
+                "default": false
+              },
+              "dotnetDebuggerConfigName": {
+                "type": "string",
+                "description": "If you would like to use a custom coreclr attach debug launch configuration for the debug session, specify the name here. Otherwise a default basic config will be used. The config must be a coreclr attach config. Launch configs are not supported.",
                 "default": false
               }
             }
@@ -518,30 +588,33 @@
             "properties": {
               "computerName": {
                 "type": "string",
-                "description": "Optional: The computer name to which a remote session will be established.  Works only on PowerShell 4 and above."
+                "description": "Optional: The computer name to which a remote session will be established.",
+                "default": null
               },
               "processId": {
-                "type": "string",
-                "description": "The process id of the PowerShell host process to attach to.  Works only on PowerShell 5 and above.",
+                "type": "number",
+                "description": "Optional: The ID of the PowerShell host process that should be attached. Will prompt if unspecified.",
                 "default": null
               },
               "runspaceId": {
-                "type": [
-                  "string",
-                  "number"
-                ],
-                "description": "Optional: The ID of the runspace to debug in the attached process.  Defaults to 1.  Works only on PowerShell 5 and above.",
+                "type": "number",
+                "description": "Optional: The ID of the runspace to debug in the attached process. Will prompt if unspecified.",
                 "default": null
               },
               "runspaceName": {
                 "type": "string",
-                "description": "Optional: The Name of the runspace to debug in the attached process.  Works only on PowerShell 5 and above.",
+                "description": "Optional: The name of the runspace to debug in the attached process.",
                 "default": null
               },
               "customPipeName": {
                 "type": "string",
-                "description": "The custom pipe name of the PowerShell host process to attach to.  Works only on PowerShell 6.2 and above.",
+                "description": "The custom pipe name of the PowerShell host process to attach to.",
                 "default": null
+              },
+              "createTemporaryIntegratedConsole": {
+                "type": "boolean",
+                "description": "Determines whether a temporary PowerShell Extension Terminal is created for each debugging session, useful for debugging PowerShell classes and binary modules.  Overrides the user setting 'powershell.debugging.createTemporaryIntegratedConsole'.",
+                "default": false
               }
             }
           }
@@ -549,342 +622,464 @@
         "initialConfigurations": []
       }
     ],
-    "configuration": {
-      "type": "object",
-      "title": "PowerShell Configuration",
-      "properties": {
-        "powershell.sideBar.CommandExplorerVisibility": {
-          "type": "boolean",
-          "default": true,
-          "description": "Specifies the visibility of the Command Explorer in the PowerShell Side Bar."
-        },
-        "powershell.sideBar.CommandExplorerExcludeFilter": {
-          "type": "array",
-          "default": [],
-          "description": "Specify array of Modules to exclude from Command Explorer listing."
-        },
-        "powershell.powerShellAdditionalExePaths": {
-          "type": "array",
-          "description": "Specifies an array of versionName / exePath pairs where exePath points to a non-standard install location for PowerShell and versionName can be used to reference this path with the powershell.powerShellDefaultVersion setting.",
-          "scope": "machine",
-          "uniqueItems": true,
-          "items": {
-            "type": "object",
-            "required": [
-              "versionName",
-              "exePath"
+    "configuration": [
+      {
+        "title": "Interface",
+        "properties": {
+          "powershell.buttons.showRunButtons": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Show the `Run` and `Run Selection` buttons in the editor's title bar."
+          },
+          "powershell.buttons.showPanelMovementButtons": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Show buttons in the editor's title bar for moving the terminals pane (with the PowerShell Extension Terminal) around."
+          },
+          "powershell.enableReferencesCodeLens": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Specifies if Code Lenses are displayed above function definitions, used to show the number of times the function is referenced in the workspace and navigate to those references. Large workspaces may want to disable this setting if performance is compromised. See also `#powershell.analyzeOpenDocumentsOnly#`."
+          },
+          "powershell.codeFolding.enable": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Enables syntax based code folding. When disabled, the default indentation based code folding is used."
+          },
+          "powershell.codeFolding.showLastLine": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Shows the last line of a folded section similar to the default VS Code folding style. When disabled, the entire folded region is hidden."
+          },
+          "powershell.helpCompletion": {
+            "type": "string",
+            "default": "BlockComment",
+            "enum": [
+              "Disabled",
+              "BlockComment",
+              "LineComment"
             ],
-            "properties": {
-              "versionName": {
-                "type": "string",
-                "description": "Specifies the version name of this PowerShell executable. The version name can be referenced via the powershell.powerShellDefaultVersion setting."
-              },
-              "exePath": {
-                "type": "string",
-                "description": "Specifies the path to the PowerShell executable. Typically this is a path to a non-standard install location."
-              }
+            "markdownEnumDescriptions": [
+              "Disables the feature.",
+              "Inserts a block style help comment, for example:\n\n`<#`\n\n`.<help keyword>`\n\n`<help content>`\n\n`#>`",
+              "Inserts a line style help comment, for example:\n\n`# .<help keyword>`\n\n`# <help content>`"
+            ],
+            "markdownDescription": "Specifies the [comment based help](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help) completion style triggered by typing ` ##`."
+          },
+          "powershell.sideBar.CommandExplorerVisibility": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Specifies the visibility of the Command Explorer in the side bar."
+          },
+          "powershell.sideBar.CommandExplorerExcludeFilter": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "default": [],
+            "markdownDescription": "Specifies an array of modules to exclude from Command Explorer listing."
+          },
+          "powershell.promptToUpdatePowerShell": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Specifies whether you may be prompted to update your version of PowerShell."
+          },
+          "powershell.promptToUpdatePackageManagement": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "**Deprecated:** Specifies whether you should be prompted to update your version of `PackageManagement` if it's under 1.4.6.",
+            "markdownDeprecationMessage": "**Deprecated:** This prompt has been removed as it's no longer strictly necessary to upgrade the `PackageManagement` module."
+          },
+          "powershell.suppressAdditionalExeNotFoundWarning": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Suppresses the warning message when any of `#powershell.powerShellAdditionalExePaths#` is not found."
+          }
+        }
+      },
+      {
+        "title": "Formatting",
+        "properties": {
+          "powershell.codeFormatting.preset": {
+            "type": "string",
+            "default": "Custom",
+            "enum": [
+              "Custom",
+              "Allman",
+              "OTBS",
+              "Stroustrup"
+            ],
+            "markdownEnumDescriptions": [
+              "The three brace settings are respected as-is.",
+              "Sets `#powershell.codeFormatting.openBraceOnSameLine#` to `false`, `#powershell.codeFormatting.newLineAfterOpenBrace#` to `true`, and `#powershell.codeFormatting.newLineAfterCloseBrace#` to `true`.",
+              "Sets `#powershell.codeFormatting.openBraceOnSameLine#` to `true`, `#powershell.codeFormatting.newLineAfterOpenBrace#` to `true`, and `#powershell.codeFormatting.newLineAfterCloseBrace#` to `false`.",
+              "Sets `#powershell.codeFormatting.openBraceOnSameLine#` to `true`, `#powershell.codeFormatting.newLineAfterOpenBrace#` to `true`, and `#powershell.codeFormatting.newLineAfterCloseBrace#` to `true`."
+            ],
+            "markdownDescription": "Sets the code formatting options to follow the given indent style in a way that is compatible with PowerShell syntax. Any setting other than `Custom` will configure (and override) the settings:\n\n* `#powershell.codeFormatting.openBraceOnSameLine#`\n\n* `#powershell.codeFormatting.newLineAfterOpenBrace#`\n\n* `#powershell.codeFormatting.newLineAfterCloseBrace#`\n\nFor more information about the brace styles, please see [PoshCode's discussion](https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/81)."
+          },
+          "powershell.codeFormatting.autoCorrectAliases": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Replaces aliases with their aliased name."
+          },
+          "powershell.codeFormatting.avoidSemicolonsAsLineTerminators": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Removes redundant semicolon(s) at the end of a line where a line terminator is sufficient."
+          },
+          "powershell.codeFormatting.openBraceOnSameLine": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Places open brace on the same line as its associated statement."
+          },
+          "powershell.codeFormatting.newLineAfterOpenBrace": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a newline (line break) after an open brace."
+          },
+          "powershell.codeFormatting.newLineAfterCloseBrace": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a newline (line break) after a closing brace."
+          },
+          "powershell.codeFormatting.pipelineIndentationStyle": {
+            "type": "string",
+            "default": "NoIndentation",
+            "enum": [
+              "IncreaseIndentationForFirstPipeline",
+              "IncreaseIndentationAfterEveryPipeline",
+              "NoIndentation",
+              "None"
+            ],
+            "markdownEnumDescriptions": [
+              "Indent once after the first pipeline and keep this indentation.",
+              "Indent more after the first pipeline and keep this indentation.",
+              "Do not increase indentation.",
+              "Do not change any existing pipeline indentation (disables feature)."
+            ],
+            "markdownDescription": "Whether to increase indentation after a pipeline for multi-line statements. See [PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer/blob/a94d9f5666bba9f569cdf9c1bc99556934f2b8f4/docs/Rules/UseConsistentIndentation.md#pipelineindentation-string-default-value-is-increaseindentationforfirstpipeline) for examples. It is suggested to use `IncreaseIndentationForFirstPipeline` instead of the default `NoIndentation`. **This default may change in the future,** please see the [Request For Comment](https://github.com/PowerShell/vscode-powershell/issues/4296)."
+          },
+          "powershell.codeFormatting.whitespaceBeforeOpenBrace": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a space between a keyword and its associated script-block expression."
+          },
+          "powershell.codeFormatting.whitespaceBeforeOpenParen": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a space between a keyword (`if`, `elseif`, `while`, `switch`, etc.) and its associated conditional expression."
+          },
+          "powershell.codeFormatting.whitespaceAroundOperator": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds spaces before and after an operator (`=`, `+`, `-`, etc.)."
+          },
+          "powershell.codeFormatting.whitespaceAfterSeparator": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a space after a separator (`,` and `;`)."
+          },
+          "powershell.codeFormatting.whitespaceInsideBrace": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a space after an opening brace (`{`) and before a closing brace (`}`)."
+          },
+          "powershell.codeFormatting.whitespaceBetweenParameters": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Removes redundant whitespace between parameters."
+          },
+          "powershell.codeFormatting.whitespaceAroundPipe": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "**Deprecated:** Please use the `#powershell.codeFormatting.addWhitespaceAroundPipe#` setting instead. If you've used this setting before, we have moved it for you automatically.",
+            "markdownDeprecationMessage": "**Deprecated:** Please use the `#powershell.codeFormatting.addWhitespaceAroundPipe#` setting instead. If you've used this setting before, we have moved it for you automatically."
+          },
+          "powershell.codeFormatting.addWhitespaceAroundPipe": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Adds a space before and after the pipeline operator (`|`) if it is missing."
+          },
+          "powershell.codeFormatting.trimWhitespaceAroundPipe": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Trims extraneous whitespace (more than one character) before and after the pipeline operator (`|`)."
+          },
+          "powershell.codeFormatting.ignoreOneLineBlock": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Does not reformat one-line code blocks, such as: `if (...) {...} else {...}`."
+          },
+          "powershell.codeFormatting.alignPropertyValuePairs": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Align assignment statements in a hashtable or a DSC Configuration."
+          },
+          "powershell.codeFormatting.useConstantStrings": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Use single quotes if a string is not interpolated and its value does not contain a single quote."
+          },
+          "powershell.codeFormatting.useCorrectCasing": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Use correct casing for cmdlets."
+          }
+        }
+      },
+      {
+        "title": "Editor Services",
+        "properties": {
+          "powershell.powerShellDefaultVersion": {
+            "type": "string",
+            "default": "",
+            "markdownDescription": "Specifies the default PowerShell version started by the extension. The name must match what is displayed in the [Session Menu command](command:PowerShell.ShowSessionMenu), for example, `Windows PowerShell (x86)`. You can specify additional PowerShell executables with the `#powershell.powerShellAdditionalExePaths#` setting."
+          },
+          "powershell.enableProfileLoading": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Specifies whether the extension loads [PowerShell profiles](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles). Note that the extension's \"Current Host\" profile is `Microsoft.VSCode_profile.ps1`, which will be loaded instead of the default \"Current Host\" profile of `Microsoft.PowerShell_profile.ps1`. Use the \"All Hosts\" profile `profile.ps1` for common configuration."
+          },
+          "powershell.startAutomatically": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Starts the PowerShell extension automatically when a PowerShell file is opened. If `false`, to start the extension use the [Restart Session command](command:PowerShell.RestartSession). **IntelliSense, code navigation, the Extension Terminal, code formatting, and other features are not enabled until the extension starts.**"
+          },
+          "powershell.scriptAnalysis.enable": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Enables real-time script analysis using [PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer) that populates the [Problems view](command:workbench.panel.markers.view.focus)."
+          },
+          "powershell.scriptAnalysis.settingsPath": {
+            "type": "string",
+            "default": "PSScriptAnalyzerSettings.psd1",
+            "markdownDescription": "Specifies the path to a [PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer) settings file. **This setting may not work as expected currently!**"
+          },
+          "powershell.analyzeOpenDocumentsOnly": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Specifies to search for references only within open documents instead of all workspace files. An alternative to `#powershell.enableReferencesCodeLens#` that allows large workspaces to support some references without the performance impact."
+          },
+          "powershell.debugging.createTemporaryIntegratedConsole": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Creates a temporary PowerShell Extension Terminal for each debugging session. This is useful for debugging PowerShell classes and binary modules."
+          },
+          "powershell.debugging.executeMode": {
+            "type": "string",
+            "enum": [
+              "DotSource",
+              "Call"
+            ],
+            "default": "DotSource",
+            "markdownEnumDescriptions": [
+              "Use the Dot-Source operator `.` to launch the script, for example, `. 'C:\\Data\\MyScript.ps1'`",
+              "Use the Call operator `&` to launch the script, for example, `& 'C:\\Data\\MyScript.ps1'`"
+            ],
+            "markdownDescription": "Sets the operator used to launch scripts."
+          },
+          "powershell.powerShellExePath": {
+            "type": "string",
+            "default": "",
+            "scope": "machine",
+            "markdownDescription": "**Deprecated:** Specifies the path to the PowerShell executable.",
+            "markdownDeprecationMessage": "**Deprecated:** Please use the `#powershell.powerShellAdditionalExePaths#` setting instead."
+          },
+          "powershell.powerShellAdditionalExePaths": {
+            "type": "object",
+            "default": {},
+            "markdownDescription": "Specifies a list of Item / Value pairs where the **Item** is a user-chosen name and the **Value** is an absolute path to a PowerShell executable. The name appears in the [Session Menu Command](command:PowerShell.ShowSessionMenu) and is used to reference this executable in the `#powershell.powerShellDefaultVersion#` setting.",
+            "additionalProperties": {
+              "type": "string"
             }
+          },
+          "powershell.cwd": {
+            "type": "string",
+            "default": "",
+            "markdownDescription": "A path where the Extension Terminal will be launched. Both the PowerShell process's and the shell's location will be set to this directory. Does not support variables, but does support the use of '~' and paths relative to a single workspace. **For multi-root workspaces, use the name of the folder you wish to have as the cwd.**"
+          },
+          "powershell.startAsLoginShell.osx": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Starts the PowerShell extension's underlying PowerShell process as a login shell, if applicable."
+          },
+          "powershell.startAsLoginShell.linux": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Starts the PowerShell extension's underlying PowerShell process as a login shell, if applicable."
+          },
+          "powershell.useX86Host": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "**Deprecated:** Uses the 32-bit language service on 64-bit Windows. This setting has no effect on 32-bit Windows or on the PowerShell extension debugger, which has its own architecture configuration.",
+            "markdownDeprecationMessage": "**Deprecated:** This setting was removed when the PowerShell installation searcher was added. Please use the `#powershell.powerShellAdditionalExePaths#` setting instead."
+          }
+        }
+      },
+      {
+        "title": "Pester",
+        "properties": {
+          "powershell.pester.useLegacyCodeLens": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Use a CodeLens that is compatible with Pester 4. Disabling this will show `Run Tests` on all `It`, `Describe` and `Context` blocks, and will correctly work only with Pester 5 and newer."
+          },
+          "powershell.pester.codeLens": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "This setting controls the appearance of the `Run Tests` and `Debug Tests` CodeLenses that appears above Pester tests."
+          },
+          "powershell.pester.outputVerbosity": {
+            "type": "string",
+            "default": "FromPreference",
+            "enum": [
+              "FromPreference",
+              "None",
+              "Minimal",
+              "Normal",
+              "Detailed",
+              "Diagnostic"
+            ],
+            "markdownDescription": "Defines the verbosity of output to be used. For Pester 5 and newer the default value `FromPreference` will use the `Output` settings from the `$PesterPreference` defined in the caller's context, and will default to `Normal` if there is none. For Pester 4 the `FromPreference` and `Normal` options map to `All`, and `Minimal` option maps to `Fails`."
+          },
+          "powershell.pester.debugOutputVerbosity": {
+            "type": "string",
+            "enum": [
+              "None",
+              "Minimal",
+              "Normal",
+              "Detailed",
+              "Diagnostic"
+            ],
+            "default": "Diagnostic",
+            "markdownDescription": "Defines the verbosity of output to be used when debugging a test or a block. For Pester 5 and newer the default value `Diagnostic` will print additional information about discovery, skipped and filtered tests, mocking and more."
+          }
+        }
+      },
+      {
+        "title": "Terminal",
+        "properties": {
+          "powershell.integratedConsole.suppressStartupBanner": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Do not show the startup banner in the PowerShell Extension Terminal."
+          },
+          "powershell.integratedConsole.showOnStartup": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Shows the Extension Terminal when the PowerShell extension is initialized. When disabled, the pane is not opened on startup, but the Extension Terminal is still created in order to power the extension's features."
+          },
+          "powershell.integratedConsole.startInBackground": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Starts the Extension Terminal in the background. **If this is enabled, to access the terminal you must run the [Show Extension Terminal command](command:PowerShell.ShowSessionConsole), and once shown it cannot be put back into the background.** This option completely hides the Extension Terminal from the terminals view. You are probably looking for the `#powershell.integratedConsole.showOnStartup#` option instead."
+          },
+          "powershell.integratedConsole.startLocation": {
+            "type": "string",
+            "default": "Panel",
+            "enum": [
+              "Editor",
+              "Panel"
+            ],
+            "markdownEnumDescriptions": [
+              "Creates the Extension Terminal in Editor area",
+              "Creates the Extension Terminal in Panel area"
+            ],
+            "markdownDescription": "Sets the startup location for Extension Terminal."
+          },
+          "powershell.integratedConsole.focusConsoleOnExecute": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "Switches focus to the console when a script selection is run or a script file is debugged."
+          },
+          "powershell.integratedConsole.useLegacyReadLine": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "This will disable the use of PSReadLine in the PowerShell Extension Terminal and use a legacy implementation. **This setting is not recommended and likely to be deprecated!**"
+          },
+          "powershell.integratedConsole.forceClearScrollbackBuffer": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Use the VS Code API to clear the terminal since that's the only reliable way to clear the scrollback buffer. Turn this on if you're used to `Clear-Host` clearing scroll history. **This setting is not recommended and likely to be deprecated!**"
+          }
+        }
+      },
+      {
+        "title": "Developer",
+        "properties": {
+          "powershell.developer.editorServicesLogLevel": {
+            "type": "string",
+            "default": "Warning",
+            "enum": [
+              "Trace",
+              "Debug",
+              "Information",
+              "Warning",
+              "Error",
+              "None"
+            ],
+            "markdownEnumDescriptions": [
+              "Enables all logging possible, please use this setting when submitting logs for bug reports!",
+              "Enables more detailed logging of the extension",
+              "Logs high-level information about what the extension is doing.",
+              "Only log warnings and errors. This is the default setting",
+              "Only log errors.",
+              "Disable all logging possible. No log files will be written!"
+            ],
+            "markdownDescription": "Sets the log verbosity for both the extension and its LSP server, PowerShell Editor Services. **Please set to `Trace` when recording logs for a bug report!**"
+          },
+          "powershell.trace.server": {
+            "type": "string",
+            "enum": [
+              "off",
+              "messages",
+              "verbose"
+            ],
+            "default": "off",
+            "markdownDescription": "Traces the communication between VS Code and the PowerShell Editor Services [LSP Server](https://microsoft.github.io/language-server-protocol/). The output will be logged and also visible in the Output pane, where the verbosity is configurable. **For extension developers and issue troubleshooting only!**"
+          },
+          "powershell.developer.traceDap": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Traces the DAP communication between VS Code and the PowerShell Editor Services [DAP Server](https://microsoft.github.io/debug-adapter-protocol/). The output will be logged and also visible in the Output pane, where the verbosity is configurable. **For extension developers and issue troubleshooting only!**"
+          },
+          "powershell.developer.editorServicesWaitForDebugger": {
+            "type": "boolean",
+            "default": false,
+            "markdownDescription": "Launches the LSP server with the `/waitForDebugger` flag to force it to wait for a .NET debugger to attach before proceeding, and emit its PID until then. **This setting is only meant for extension developers and requires the extension to be run in development mode!**"
+          },
+          "powershell.developer.setExecutionPolicy": {
+            "type": "boolean",
+            "default": true,
+            "markdownDescription": "On Windows we launch the PowerShell executable with `-ExecutionPolicy Bypass` so that the LSP server (PowerShell Editor Services module) will launch without issue. Some anti-virus programs disallow this command-line argument and this flag can be used to remove it. **Using this setting may require trusting the script manually in order for it to launch!**"
+          },
+          "powershell.developer.bundledModulesPath": {
+            "type": "string",
+            "default": "../../PowerShellEditorServices/module",
+            "markdownDescription": "Specifies an alternative path to the folder containing modules that are bundled with the PowerShell extension, that is: PowerShell Editor Services, PSScriptAnalyzer and PSReadLine. **This setting is only meant for extension developers and requires the extension to be run in development mode!**"
+          },
+          "powershell.developer.featureFlags": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "default": [],
+            "markdownDescription": "An array of strings that enable experimental features in the PowerShell extension. **No flags are currently available!**"
+          },
+          "powershell.developer.waitForSessionFileTimeoutSeconds": {
+            "type": "number",
+            "default": 240,
+            "markdownDescription": "Specifies how many seconds the extension will wait for the LSP server, PowerShell Editor Services, to connect. The default is four minutes; try increasing this value if your computer is particularly slow (often caused by overactive anti-malware programs)."
+          },
+          "powershell.bugReporting.project": {
+            "type": "string",
+            "default": "https://github.com/PowerShell/vscode-powershell",
+            "markdownDescription": "**Deprecated:** Specifies the URL of the GitHub project in which to generate bug reports.",
+            "markdownDeprecationMessage": "**Deprecated:** This setting was never meant to be changed!"
           }
-        },
-        "powershell.powerShellDefaultVersion": {
-          "type": "string",
-          "description": "Specifies the PowerShell version name, as displayed by the 'PowerShell: Show Session Menu' command, used when the extension loads e.g \"Windows PowerShell (x86)\" or \"PowerShell Core 6 (x64)\". You can specify additional PowerShell executables by using the \"powershell.powerShellAdditionalExePaths\" setting."
-        },
-        "powershell.powerShellExePath": {
-          "type": "string",
-          "default": "",
-          "scope": "machine",
-          "description": "REMOVED. Please use the \"powershell.powerShellDefaultVersion\" setting instead."
-        },
-        "powershell.promptToUpdatePowerShell": {
-          "type": "boolean",
-          "description": "Specifies whether you should be prompted to update your version of PowerShell.",
-          "default": true
-        },
-        "powershell.promptToUpdatePackageManagement": {
-          "type": "boolean",
-          "description": "Specifies whether you should be prompted to update your version of PackageManagement if it's under 1.4.6.",
-          "default": true
-        },
-        "powershell.startAsLoginShell.osx": {
-          "type": "boolean",
-          "default": true,
-          "description": "Starts the PowerShell extension's underlying PowerShell process as a login shell, if applicable."
-        },
-        "powershell.startAsLoginShell.linux": {
-          "type": "boolean",
-          "default": false,
-          "description": "Starts the PowerShell extension's underlying PowerShell process as a login shell, if applicable."
-        },
-        "powershell.startAutomatically": {
-          "type": "boolean",
-          "default": true,
-          "description": "Starts PowerShell extension features automatically when a PowerShell file opens. If false, to start the extension, use the 'PowerShell: Restart Current Session' command. IntelliSense, code navigation, integrated console, code formatting, and other features are not enabled until the extension starts."
-        },
-        "powershell.useX86Host": {
-          "type": "boolean",
-          "default": false,
-          "description": "Uses the 32-bit language service on 64-bit Windows. This setting has no effect on 32-bit Windows or on the PowerShell extension debugger, which has its own architecture configuration."
-        },
-        "powershell.enableProfileLoading": {
-          "type": "boolean",
-          "default": true,
-          "description": "Loads user and system-wide PowerShell profiles (profile.ps1 and Microsoft.VSCode_profile.ps1) into the PowerShell session. This affects IntelliSense and interactive script execution, but it does not affect the debugger."
-        },
-        "powershell.bugReporting.project": {
-          "type": "string",
-          "default": "https://github.com/PowerShell/vscode-powershell",
-          "description": "Specifies the url of the GitHub project in which to generate bug reports."
-        },
-        "powershell.helpCompletion": {
-          "type": "string",
-          "enum": [
-            "Disabled",
-            "BlockComment",
-            "LineComment"
-          ],
-          "default": "BlockComment",
-          "description": "Controls the comment-based help completion behavior triggered by typing '##'. Set the generated help style with 'BlockComment' or 'LineComment'. Disable the feature with 'Disabled'."
-        },
-        "powershell.cwd": {
-          "type": "string",
-          "default": null,
-          "description": "An explicit start path where the Powershell Integrated Console will be launched. Both the PowerShell process and the shell's location will be set to this directory. Predefined variables can be used (i.e. ${fileDirname} to use the current opened file's directory)."
-        },
-        "powershell.scriptAnalysis.enable": {
-          "type": "boolean",
-          "default": true,
-          "description": "Enables real-time script analysis from PowerShell Script Analyzer. Uses the newest installed version of the PSScriptAnalyzer module or the version bundled with this extension, if it is newer."
-        },
-        "powershell.scriptAnalysis.settingsPath": {
-          "type": "string",
-          "default": "PSScriptAnalyzerSettings.psd1",
-          "description": "Specifies the path to a PowerShell Script Analyzer settings file. To override the default settings for all projects, enter an absolute path, or enter a path relative to your workspace."
-        },
-        "powershell.codeFolding.enable": {
-          "type": "boolean",
-          "default": true,
-          "description": "Enables syntax based code folding. When disabled, the default indentation based code folding is used."
-        },
-        "powershell.codeFolding.showLastLine": {
-          "type": "boolean",
-          "default": true,
-          "description": "Shows the last line of a folded section similar to the default VSCode folding style. When disabled, the entire folded region is hidden."
-        },
-        "powershell.codeFormatting.autoCorrectAliases": {
-          "type": "boolean",
-          "default": false,
-          "description": "Replaces aliases with their aliased name."
-        },
-        "powershell.codeFormatting.preset": {
-          "type": "string",
-          "enum": [
-            "Custom",
-            "Allman",
-            "OTBS",
-            "Stroustrup"
-          ],
-          "default": "Custom",
-          "description": "Sets the codeformatting options to follow the given indent style in a way that is compatible with PowerShell syntax. For more information about the brace styles please refer to https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/81."
-        },
-        "powershell.codeFormatting.openBraceOnSameLine": {
-          "type": "boolean",
-          "default": true,
-          "description": "Places open brace on the same line as its associated statement."
-        },
-        "powershell.codeFormatting.newLineAfterOpenBrace": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a newline (line break) after an open brace."
-        },
-        "powershell.codeFormatting.newLineAfterCloseBrace": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a newline (line break) after a closing brace."
-        },
-        "powershell.codeFormatting.pipelineIndentationStyle": {
-          "type": "string",
-          "enum": [
-            "IncreaseIndentationForFirstPipeline",
-            "IncreaseIndentationAfterEveryPipeline",
-            "NoIndentation",
-            "None"
-          ],
-          "default": "NoIndentation",
-          "description": "Multi-line pipeline style settings (default: NoIndentation)."
-        },
-        "powershell.codeFormatting.whitespaceBeforeOpenBrace": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a space between a keyword and its associated scriptblock expression."
-        },
-        "powershell.codeFormatting.whitespaceBeforeOpenParen": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a space between a keyword (if, elseif, while, switch, etc) and its associated conditional expression."
-        },
-        "powershell.codeFormatting.whitespaceAroundOperator": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds spaces before and after an operator ('=', '+', '-', etc.)."
-        },
-        "powershell.codeFormatting.whitespaceAfterSeparator": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a space after a separator (',' and ';')."
-        },
-        "powershell.codeFormatting.whitespaceInsideBrace": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a space after an opening brace ('{') and before a closing brace ('}')."
-        },
-        "powershell.codeFormatting.whitespaceBetweenParameters": {
-          "type": "boolean",
-          "default": false,
-          "description": "Removes redundant whitespace between parameters."
-        },
-        "powershell.codeFormatting.whitespaceAroundPipe": {
-          "type": "boolean",
-          "default": true,
-          "description": "REMOVED. Please use the \"powershell.codeFormatting.addWhitespaceAroundPipe\" setting instead. If you've used this setting before, we have moved it for you automatically."
-        },
-        "powershell.codeFormatting.addWhitespaceAroundPipe": {
-          "type": "boolean",
-          "default": true,
-          "description": "Adds a space before and after the pipeline operator ('|') if it is missing."
-        },
-        "powershell.codeFormatting.trimWhitespaceAroundPipe": {
-          "type": "boolean",
-          "default": false,
-          "description": "Trims extraneous whitespace (more than 1 character) before and after the pipeline operator ('|')."
-        },
-        "powershell.codeFormatting.ignoreOneLineBlock": {
-          "type": "boolean",
-          "default": true,
-          "description": "Does not reformat one-line code blocks, such as \"if (...) {...} else {...}\"."
-        },
-        "powershell.codeFormatting.alignPropertyValuePairs": {
-          "type": "boolean",
-          "default": true,
-          "description": "Align assignment statements in a hashtable or a DSC Configuration."
-        },
-        "powershell.codeFormatting.useConstantStrings": {
-          "type": "boolean",
-          "default": false,
-          "description": "Use single quotes if a string is not interpolated and its value does not contain a single quote."
-        },
-        "powershell.codeFormatting.useCorrectCasing": {
-          "type": "boolean",
-          "default": false,
-          "description": "Use correct casing for cmdlets."
-        },
-        "powershell.integratedConsole.showOnStartup": {
-          "type": "boolean",
-          "default": true,
-          "description": "Shows the integrated console when the PowerShell extension is initialized."
-        },
-        "powershell.integratedConsole.focusConsoleOnExecute": {
-          "type": "boolean",
-          "default": true,
-          "description": "Switches focus to the console when a script selection is run or a script file is debugged. This is an accessibility feature. To disable it, set to false."
-        },
-        "powershell.integratedConsole.useLegacyReadLine": {
-          "type": "boolean",
-          "default": false,
-          "description": "Falls back to the legacy (lightweight) ReadLine experience. This will disable the use of PSReadLine in the PowerShell Integrated Console."
-        },
-        "powershell.integratedConsole.forceClearScrollbackBuffer": {
-          "type": "boolean",
-          "description": "Use the vscode API to clear the terminal since that's the only reliable way to clear the scrollback buffer. Turn this on if you're used to 'Clear-Host' clearing scroll history as well as clear-terminal-via-lsp."
-        },
-        "powershell.integratedConsole.suppressStartupBanner": {
-          "type": "boolean",
-          "default": false,
-          "description": "Do not show the Powershell Integrated Console banner on launch"
-        },
-        "powershell.debugging.createTemporaryIntegratedConsole": {
-          "type": "boolean",
-          "default": false,
-          "description": "Determines whether a temporary PowerShell Integrated Console is created for each debugging session, useful for debugging PowerShell classes and binary modules."
-        },
-        "powershell.developer.bundledModulesPath": {
-          "type": "string",
-          "description": "Specifies an alternate path to the folder containing modules that are bundled with the PowerShell extension (i.e. PowerShell Editor Services, PSScriptAnalyzer, Plaster)"
-        },
-        "powershell.developer.editorServicesLogLevel": {
-          "type": "string",
-          "enum": [
-            "Diagnostic",
-            "Verbose",
-            "Normal",
-            "Warning",
-            "Error"
-          ],
-          "default": "Normal",
-          "description": "Sets the logging verbosity level for the PowerShell Editor Services host executable.  Valid values are 'Diagnostic', 'Verbose', 'Normal', 'Warning', and 'Error'"
-        },
-        "powershell.developer.editorServicesWaitForDebugger": {
-          "type": "boolean",
-          "default": false,
-          "description": "Launches the language service with the /waitForDebugger flag to force it to wait for a .NET debugger to attach before proceeding."
-        },
-        "powershell.developer.featureFlags": {
-          "type": "array",
-          "default": null,
-          "description": "An array of strings that enable experimental features in the PowerShell extension."
-        },
-        "powershell.developer.waitForSessionFileTimeoutSeconds": {
-          "type": "number",
-          "default": 240,
-          "description": "When the PowerShell extension is starting up, it checks for a session file in order to connect to the language server. This setting determines how long until checking for the session file times out. (default is 240 seconds or 4 minutes)"
-        },
-        "powershell.pester.useLegacyCodeLens": {
-          "type": "boolean",
-          "default": true,
-          "description": "Use a CodeLens that is compatible with Pester 4. Disabling this will show 'Run Tests' on all It, Describe and Context blocks, and will correctly work only with Pester 5 and newer."
-        },
-        "powershell.pester.codeLens": {
-          "type": "boolean",
-          "default": true,
-          "description": "This setting controls the appearance of the 'Run Tests' and 'Debug Tests' CodeLenses that appears above Pester tests."
-        },
-        "powershell.pester.outputVerbosity": {
-          "type": "string",
-          "enum": [
-            "FromPreference",
-            "None",
-            "Minimal",
-            "Normal",
-            "Detailed",
-            "Diagnostic"
-          ],
-          "default": "FromPreference",
-          "description": "Defines the verbosity of output to be used. For Pester 5 and newer the default value FromPreference, will use the Output settings from the $PesterPreference defined in the caller context, and will default to Normal if there is none. For Pester 4 the FromPreference and Normal options map to All, and Minimal option maps to Fails."
-        },
-        "powershell.pester.debugOutputVerbosity": {
-          "type": "string",
-          "enum": [
-            "None",
-            "Minimal",
-            "Normal",
-            "Detailed",
-            "Diagnostic"
-          ],
-          "default": "Diagnostic",
-          "description": "Defines the verbosity of output to be used when debugging a test or a block. For Pester 5 and newer the default value Diagnostic will print additional information about discovery, skipped and filtered tests, mocking and more."
-        },
-        "powershell.buttons.showRunButtons": {
-          "type": "boolean",
-          "default": true,
-          "description": "Show the Run and Run Selection buttons in the editor titlebar."
-        },
-        "powershell.buttons.showPanelMovementButtons": {
-          "type": "boolean",
-          "default": false,
-          "description": "Show buttons in the editor titlebar for moving the panel around."
         }
       }
-    },
+    ],
     "capabilities": {
       "untrustedWorkspaces": {
         "supported": false
@@ -903,6 +1098,88 @@
         "uiTheme": "vs",
         "path": "./themes/theme-psise/theme.json"
       }
+    ],
+    "walkthroughs": [
+      {
+        "id": "PowerShell",
+        "title": "Get Started with PowerShell",
+        "description": "Set up your environment and see what the PowerShell Extension in Visual Studio Code can help you achieve!",
+        "steps": [
+          {
+            "id": "install-windows",
+            "title": "Choose a version of PowerShell",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "There are multiple versions of PowerShell that you can use with the extension! Choose the version that best fits your needs here.\nFor the newest version of PowerShell, install PowerShell 7 or run ``iex \"& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI\"``\n[Install PowerShell 7](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows)\n⭐️ Latest version ― if you want the latest and greatest capabilities.\n💻 Can be used to manage multiple operating systems.\n👥 [Open source](https://github.com/powershell/powershell) and community-focused!",
+            "when": "isWindows"
+          },
+          {
+            "id": "install-mac",
+            "title": "Install PowerShell",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "💻 PowerShell 7 is cross-platform! See the instructions to [install on macOS](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-macos).\n⭐️ If you already have [Homebrew](https://brew.sh) installed, you can run ``brew install --cask powershell`` to install ``pwsh``.\n👥 PowerShell is [open source](https://github.com/powershell/powershell) and community-focused!",
+            "when": "isMac"
+          },
+          {
+            "id": "install-linux",
+            "title": "Install PowerShell",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "💻 PowerShell 7 is cross-platform!\n⭐️ See the instructions to [install on Linux](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux).\n👥 PowerShell is [open source](https://github.com/powershell/powershell) and community-focused!",
+            "when": "isLinux"
+          },
+          {
+            "id": "file",
+            "title": "Create a PowerShell file",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "[Create](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22powershell%22%7D) or [open](command:toSide:workbench.action.files.openFolder) a PowerShell file, make sure to save it as ``.ps1``\n[Create a File](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22powershell%22%7D)\n**Tip:** Use keyboard shortcut ``Ctrl+N`` to open a new script file or ``Ctrl+O`` to open a file."
+          },
+          {
+            "id": "sessions",
+            "title": "Switch sessions",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "To switch between PowerShell 7 and Windows PowerShell 5.1, use the menu:\n[Open PowerShell Sessions Menu](command:PowerShell.ShowSessionMenu)\nYou can pin the [PowerShell Language Status Icon](https://github.com/PowerShell/vscode-powershell/blob/main/docs/troubleshooting.md#how-do-i-change-the-powershell-version) to the status bar in the bottom right-hand corner to easily switch sessions.",
+            "completionEvents": [
+              "onCommand:PowerShell.ShowSessionConsole"
+            ]
+          },
+          {
+            "id": "ise",
+            "title": "Try ISE mode",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "If you are familiar with the Windows PowerShell ISE and would like to configure your settings to simulate the ISE Experience, try the ISE Mode.\n[Toggle ISE Mode](command:PowerShell.ToggleISEMode)",
+            "completionEvents": [
+              "onCommand:PowerShell.ToggleISEMode"
+            ]
+          },
+          {
+            "id": "terminal",
+            "title": "Open the PowerShell Extension Terminal",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "The PowerShell Extension Terminal will run whenever the extension starts in order to enable the its features.\n[Show Panel](command:PowerShell.ShowSessionConsole)\nIf you don't want the terminal panel to open on startup, you can keep the panel closed by configuring ``powershell.integratedConsole.showOnStartup`` in your settings.\n[Close Panel](command:PowerShell.ClosePanel)\n**Tip:** Use keyboard shortcut ``Ctrl+``` to open and close terminal."
+          },
+          {
+            "id": "explore",
+            "title": "Explore more resources",
+            "media": {
+              "markdown": "media/walkthrough.md"
+            },
+            "description": "Now you are ready to start using the PowerShell Extension on your own and explore more resources!\n📚 See the PowerShell Extension's [documentation](https://docs.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/using-vscode?view=powershell-7.2)\nℹ️ View Visual Studio Code's [documentation](https://code.visualstudio.com/docs/languages/powershell)\n🔌 Plug into the [PowerShell Community](https://docs.microsoft.com/en-us/powershell/scripting/community/community-support?view=powershell-7.2)\n📄 Take a look at our [Release Notes](https://docs.microsoft.com/en-us/powershell/scripting/whats-new/what-s-new-in-powershell-73?view=powershell-7.2)"
+          }
+        ]
+      }
     ]
   },
   "private": true
diff --git a/pwsh-extension-dev.code-workspace b/pwsh-extension-dev.code-workspace
new file mode 100644
index 0000000000..dc4208242f
--- /dev/null
+++ b/pwsh-extension-dev.code-workspace
@@ -0,0 +1,412 @@
+{
+  "folders": [
+    {
+      "name": "Client",
+      "path": ".",
+    },
+    {
+      "name": "Server",
+      "path": "../PowerShellEditorServices",
+    },
+  ],
+  "extensions": {
+    "recommendations": [
+      "davidanson.vscode-markdownlint",
+      "dbaeumer.vscode-eslint",
+      "editorconfig.editorconfig",
+      "esbenp.prettier-vscode",
+      "ms-dotnettools.csharp",
+      "ms-vscode.powershell",
+      "connor4312.esbuild-problem-matchers",
+      "ms-vscode.extension-test-runner",
+    ],
+  },
+  "settings": {
+    "window.title": "PowerShell VS Code Extension Development",
+    "debug.onTaskErrors": "prompt",
+    "editor.formatOnSave": true,
+    "editor.formatOnSaveMode": "modifications",
+    "editor.formatOnPaste": true,
+    "editor.codeActionsOnSave": {
+      "source.fixAll": "explicit",
+    },
+    "[typescript][javascript][json][jsonc]": {
+      "editor.defaultFormatter": "esbenp.prettier-vscode",
+      "editor.formatOnSaveMode": "file",
+    },
+    "files.associations": {
+      "**/snippets/*.json": "jsonc", // Use JSONC instead of JSON because that's how VS Code interprets snippet files, and it enables better source documentation.
+    },
+    // Ignore the Markdown rule:
+    "markdownlint.config": {
+      "MD024": false, // no-duplicate-header
+    },
+    "powershell.cwd": "Client",
+    "powershell.codeFormatting.autoCorrectAliases": true,
+    "powershell.codeFormatting.avoidSemicolonsAsLineTerminators": true,
+    "powershell.codeFormatting.newLineAfterCloseBrace": false,
+    "powershell.codeFormatting.trimWhitespaceAroundPipe": true,
+    "powershell.codeFormatting.useCorrectCasing": true,
+    "powershell.codeFormatting.whitespaceBeforeOpenBrace": false,
+    "powershell.codeFormatting.whitespaceBetweenParameters": true,
+    "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationForFirstPipeline",
+    "typescript.tsdk": "Client/node_modules/typescript/lib", // Lock the TypeScript SDK path to the version we use
+    "typescript.tsserver.experimental.enableProjectDiagnostics": true,
+    "testExplorer.useNativeTesting": true,
+  },
+  "tasks": {
+    "version": "2.0.0",
+    "windows": {
+      "options": {
+        "shell": {
+          "executable": "pwsh.exe",
+          "args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command"],
+        },
+      },
+    },
+    "linux": {
+      "options": {
+        "shell": {
+          "executable": "pwsh",
+          "args": ["-NoProfile", "-Command"],
+        },
+      },
+    },
+    "osx": {
+      "options": {
+        "shell": {
+          "executable": "pwsh",
+          "args": ["-NoProfile", "-Command"],
+        },
+      },
+    },
+    "tasks": [
+      {
+        "label": "Build",
+        "icon": {
+          "id": "tools",
+        },
+        "type": "shell",
+        "options": {
+          "cwd": "${workspaceFolder:Client}",
+        },
+        "command": "Invoke-Build Build",
+        "problemMatcher": ["$msCompile", "$tsc"],
+        "group": {
+          "kind": "build",
+          "isDefault": true,
+        },
+      },
+      {
+        "label": "Extension: Watch",
+        "type": "shell",
+        "isBackground": true,
+        "options": {
+          "cwd": "${workspaceFolder:Client}",
+        },
+        "command": "npm run watch",
+        "problemMatcher": {
+          "owner": "esbuild-watch",
+          "pattern": {
+            "regexp": "^\\[ERROR\\] (.+)\\n\\n\\s+([^:]+):(\\d+):(\\d+):",
+            "message": 1,
+            "file": 2,
+            "line": 3,
+            "column": 4,
+          },
+          "background": {
+            "activeOnStart": true,
+            "beginsPattern": "^\\[watch\\] build started",
+            "endsPattern": "^\\[watch\\] build finished",
+          },
+        },
+        "icon": {
+          "id": "sync",
+          "color": "terminal.ansiCyan",
+        },
+        "group": {
+          "kind": "build",
+        },
+      },
+      {
+        "label": "PSES: BuildIfChanged",
+        "type": "shell",
+        "options": {
+          "cwd": "${workspaceFolder:Server}",
+        },
+        "command": "Invoke-Build BuildIfChanged",
+        "problemMatcher": "$msCompile",
+        "icon": {
+          "id": "tools",
+          "color": "terminal.ansiCyan",
+        },
+        "group": {
+          "kind": "build",
+        },
+      },
+      {
+        "label": "PreLaunch",
+        "dependsOn": ["Extension: Watch", "PSES: BuildIfChanged"],
+        "dependsOrder": "parallel",
+      },
+      {
+        "label": "Test Client",
+        "type": "shell",
+        "options": {
+          "cwd": "${workspaceFolder:Client}",
+        },
+        "command": "Invoke-Build Test",
+        "problemMatcher": ["$msCompile", "$tsc"],
+        "group": {
+          "kind": "test",
+          "isDefault": true,
+        },
+      },
+      {
+        "label": "Test Server",
+        "type": "shell",
+        "options": {
+          "cwd": "${workspaceFolder:Server}",
+        },
+        "problemMatcher": ["$msCompile"],
+        "command": "Invoke-Build TestPS74",
+        "group": {
+          "kind": "test",
+          "isDefault": true,
+        },
+      },
+      {
+        "label": "Invoke-Build Client",
+        "type": "shell",
+        "options": {
+          "cwd": "${workspaceFolder:Client}",
+        },
+        "command": "Invoke-Build ${input:clientBuildCommand}",
+        "group": "build",
+      },
+      {
+        "label": "Invoke-Build Server",
+        "type": "shell",
+        "options": {
+          "cwd": "${workspaceFolder:Server}",
+        },
+        "command": "Invoke-Build ${input:serverBuildCommand}",
+        "group": "build",
+      },
+    ],
+    "inputs": [
+      {
+        "type": "pickString",
+        "id": "clientBuildCommand",
+        "description": "Which Invoke-Build Client Task?",
+        "options": ["Restore", "Clean", "Build", "Test", "Package"],
+        "default": "Clean",
+      },
+      {
+        "type": "pickString",
+        "id": "serverBuildCommand",
+        "description": "Which Invoke-Build Server Task?",
+        "options": [
+          "SetupDotNet",
+          "BinClean",
+          "Clean",
+          "Build",
+          "Test",
+          "TestPS74",
+          "TestE2EPwsh",
+          "TestPS51",
+          "TestE2EPowerShell",
+        ],
+        "default": "Clean",
+      },
+    ],
+  },
+  "launch": {
+    "version": "0.2.0",
+    "compounds": [
+      {
+        "name": "Launch Extension",
+        "configurations": ["Launch", "PowerShell Editor Services"],
+        "preLaunchTask": "Build",
+        "stopAll": true,
+        "presentation": {
+          "hidden": false,
+          "group": "Test",
+          "order": 1,
+        },
+      },
+      {
+        "name": "Launch Extension - Temp Profile",
+        "configurations": ["Launch-Temp", "PowerShell Editor Services"],
+        "preLaunchTask": "PreLaunch",
+        "stopAll": true,
+        "presentation": {
+          "hidden": false,
+          "group": "Test",
+          "order": 2,
+        },
+      },
+      {
+        "name": "Launch Extension - Isolated Profile",
+        "configurations": ["Launch-Isolated", "PowerShell Editor Services"],
+        "preLaunchTask": "Build",
+        "stopAll": true,
+        "presentation": {
+          "hidden": false,
+          "group": "Test",
+          "order": 3,
+        },
+      },
+    ],
+    "configurations": [
+      {
+        "name": "Launch",
+        "type": "extensionHost",
+        "request": "launch",
+        "env": {
+          "VSCODE_PARENT_SESSION_ID": "${command:GetVsCodeSessionId}",
+        },
+        "runtimeExecutable": "${execPath}",
+        "args": [
+          "--extensionDevelopmentPath=${workspaceFolder:Client}",
+          "${workspaceFolder:Client}/examples",
+        ],
+        "sourceMaps": true,
+        // This speeds up source map detection and makes smartStep work correctly
+        "outFiles": ["${workspaceFolder:Client}/dist/*.js"],
+        "skipFiles": [
+          "<node_internals>/**",
+          "**/node_modules/**",
+          "**/.vscode-test/**",
+          "**/app/out/vs/**", // Skips Extension Host internals
+        ],
+        "presentation": {
+          "hidden": true,
+        },
+      },
+      {
+        "name": "Launch-Temp",
+        "type": "extensionHost",
+        "request": "launch",
+        "env": {
+          "VSCODE_PARENT_SESSION_ID": "${command:GetVsCodeSessionId}",
+        },
+        "runtimeExecutable": "${execPath}",
+        "args": [
+          // Runs the extension in an empty temp profile that is automatically cleaned up after use
+          // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220
+          "--profile-temp",
+          "--extensionDevelopmentPath=${workspaceFolder:Client}",
+          "${workspaceFolder:Client}/examples",
+        ],
+        "sourceMaps": true,
+        // This speeds up source map detection and makes smartStep work correctly
+        "outFiles": ["${workspaceFolder:Client}/dist/*.js"],
+        "skipFiles": [
+          "<node_internals>/**",
+          "**/node_modules/**",
+          "**/.vscode-test/**",
+          "**/app/out/vs/**", // Skips Extension Host internals
+        ],
+        "presentation": {
+          "hidden": true,
+        },
+      },
+      {
+        "name": "Launch-Isolated",
+        "type": "extensionHost",
+        "request": "launch",
+        "env": {
+          "VSCODE_PARENT_SESSION_ID": "${command:GetVsCodeSessionId}",
+        },
+        "runtimeExecutable": "${execPath}",
+        "args": [
+          // Runs the extension in an empty temp profile that is automatically cleaned up after use
+          // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220
+          "--profile=pwsh-debug",
+          "--extensionDevelopmentPath=${workspaceFolder:Client}",
+          "${workspaceFolder:Client}/examples",
+        ],
+        "sourceMaps": true,
+        // This speeds up source map detection and makes smartStep work correctly
+        "outFiles": ["${workspaceFolder:Client}/dist/*.js"],
+        "skipFiles": [
+          "<node_internals>/**",
+          "**/node_modules/**",
+          "**/.vscode-test/**",
+          "**/app/out/vs/**", // Skips Extension Host internals
+        ],
+        "presentation": {
+          "hidden": true,
+        },
+      },
+      {
+        // https://code.visualstudio.com/docs/csharp/debugger-settings
+        "name": "Attach to Editor Services",
+        "type": "coreclr",
+        "request": "attach",
+        "processId": "${command:PowerShell.PickPSHostProcess}",
+        "justMyCode": true,
+        "suppressJITOptimizations": true,
+        "symbolOptions": {
+          "searchPaths": [],
+          "searchMicrosoftSymbolServer": false,
+          "searchNuGetOrgSymbolServer": false,
+        },
+        "presentation": {
+          "hidden": false,
+          "group": "Test",
+          "order": 5,
+        },
+        "logging": {
+          "moduleLoad": false,
+        },
+      },
+      {
+        // https://code.visualstudio.com/docs/csharp/debugger-settings
+        "name": "PowerShell Editor Services",
+        "type": "coreclr",
+        "request": "attach",
+        // Waits for the extension terminal to become available and gets the PID, saves having to enter it manually.
+        "processId": "${command:PowerShell.WaitForPsesActivationAndReturnProcessId}",
+        "justMyCode": true,
+        "suppressJITOptimizations": true,
+        "symbolOptions": {
+          "searchPaths": [],
+          "searchMicrosoftSymbolServer": false,
+          "searchNuGetOrgSymbolServer": false,
+        },
+        "presentation": {
+          "hidden": true,
+        },
+        "logging": {
+          "moduleLoad": false,
+        },
+      },
+      {
+        // Runs the extension in an isolated but persistent profile separate from the user settings
+        // Undocumented: https://github.com/microsoft/vscode-docs/issues/6220
+        "name": "Launch Extension - Rename Test Cases",
+        "type": "extensionHost",
+        "request": "launch",
+        "runtimeExecutable": "${execPath}",
+        "args": [
+          "--profile=debug",
+          "--extensionDevelopmentPath=${workspaceFolder:Client}",
+          "${workspaceFolder:Server}/test/PowerShellEditorServices.Test.Shared/Refactoring",
+        ],
+        "sourceMaps": true,
+        // This speeds up source map detection and makes smartStep work correctly
+        "outFiles": ["${workspaceFolder:Client}/dist/*.js"],
+        "skipFiles": [
+          "<node_internals>/**",
+          "**/node_modules/**",
+          "**/.vscode-test/**", // Skips Extension Host internals
+        ],
+        "presentation": {
+          "hidden": true,
+        },
+      },
+    ],
+  },
+}
diff --git a/scripts/Install-VSCode.ps1 b/scripts/Install-VSCode.ps1
index 32ff6084ce..bac756d5d8 100644
--- a/scripts/Install-VSCode.ps1
+++ b/scripts/Install-VSCode.ps1
@@ -1,6 +1,6 @@
 <#PSScriptInfo
 
-.VERSION 1.4.2
+.VERSION 1.4.3
 
 .GUID 539e5585-7a02-4dd6-b9a6-5dd288d0a5d0
 
@@ -12,9 +12,9 @@
 
 .TAGS install vscode installer
 
-.LICENSEURI https://github.com/PowerShell/vscode-powershell/blob/master/LICENSE.txt
+.LICENSEURI https://github.com/PowerShell/vscode-powershell/blob/main/LICENSE.txt
 
-.PROJECTURI https://github.com/PowerShell/vscode-powershell/blob/master/scripts/Install-VSCode.ps1
+.PROJECTURI https://github.com/PowerShell/vscode-powershell/blob/main/scripts/Install-VSCode.ps1
 
 .ICONURI
 
@@ -62,7 +62,7 @@
 
     Please contribute improvements to this script on GitHub!
 
-    https://github.com/PowerShell/vscode-powershell/blob/master/scripts/Install-VSCode.ps1
+    https://github.com/PowerShell/vscode-powershell/blob/main/scripts/Install-VSCode.ps1
 
 .PARAMETER Architecture
     A validated string defining the bit version to download. Values can be either 64-bit or 32-bit.
diff --git a/snippets/PowerShell.json b/snippets/PowerShell.json
index 5c1b58e2cc..ffbdb35e84 100644
--- a/snippets/PowerShell.json
+++ b/snippets/PowerShell.json
@@ -1,1137 +1,707 @@
-// The "Requires *" snippets should be removed if-and-when intellisense is implemented for the script requirement directive syntax.
 {
-    "ModuleManifest": {
-        "prefix": "manifest",
-        "body": [
-          "@{",
-          "\t# If authoring a script module, the RootModule is the name of your .psm1 file",
-          "\tRootModule = '${module:MyModule}.psm1'",
-          "",
-          "\tAuthor = '${author:Cool Person <coolperson@email.local>}'",
-          "",
-          "\tCompanyName = '${company:Contoso Inc.}'",
-          "",
-          "\tModuleVersion = '${ModuleVersion:0.1}'",
-          "",
-          "\t# Use the New-Guid command to generate a GUID, and copy/paste into the next line",
-          "\tGUID = '<pasteNewGUIDhere>'",
-          "",
-          "\tCopyright = '2017 ${company:Copyright Holder}'",
-          "",
-          "\tDescription = '${Description:What does this module do?}'",
-          "",
-          "\t# Minimum PowerShell version supported by this module (optional, recommended)",
-          "\t# PowerShellVersion = ''",
-          "",
-          "\t# Which PowerShell Editions does this module work with? (Core, Desktop)",
-          "\tCompatiblePSEditions = @('Desktop', 'Core')",
-          "",
-          "\t# Which PowerShell functions are exported from your module? (eg. Get-CoolObject)",
-          "\tFunctionsToExport = @('')",
-          "",
-          "\t# Which PowerShell aliases are exported from your module? (eg. gco)",
-          "\tAliasesToExport = @('')",
-          "",
-          "\t# Which PowerShell variables are exported from your module? (eg. Fruits, Vegetables)",
-          "\tVariablesToExport = @('')",
-          "",
-          "\t# PowerShell Gallery: Define your module's metadata",
-          "\tPrivateData = @{",
-          "\t\tPSData = @{",
-          "\t\t\t# What keywords represent your PowerShell module? (eg. cloud, tools, framework, vendor)",
-          "\t\t\tTags = @('${tag1:cooltag1}', '${tag2:cooltag2}')",
-          "",
-          "\t\t\t# What software license is your code being released under? (see https://opensource.org/licenses)",
-          "\t\t\tLicenseUri = ''",
-          "",
-          "\t\t\t# What is the URL to your project's website?",
-          "\t\t\tProjectUri = ''",
-          "",
-          "\t\t\t# What is the URI to a custom icon file for your project? (optional)",
-          "\t\t\tIconUri = ''",
-          "",
-          "\t\t\t# What new features, bug fixes, or deprecated features, are part of this release?",
-          "\t\t\tReleaseNotes = @'",
-          "'@",
-          "\t\t}",
-          "\t}",
-          "",
-          "\t# If your module supports updateable help, what is the URI to the help archive? (optional)",
-          "\t# HelpInfoURI = ''",
-          "}"
-        ],
-        "description": "Basic skeleton for a PowerShell module manifest, complete with PowerShell Gallery metadata."
-    },
-    "Example-Class": {
-        "prefix": "ex-class",
-        "body": [
-            "class ${1:MyClass} {",
-            "\t# Property: Holds name",
-            "\t[String] \\$Name",
-            "",
-            "\t# Constructor: Creates a new MyClass object, with the specified name",
-            "\t${1:MyClass}([String] \\$NewName) {",
-            "\t\t# Set name for ${1:MyClass}",
-            "\t\t\\$this.Name = \\$NewName",
-            "\t}",
-            "",
-            "\t# Method: Method that changes \\$Name to the default name",
-            "\t[void] ChangeNameToDefault() {",
-            "\t\t\\$this.Name = \"DefaultName\"",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: class snippet with a constructor, property and a method"
-    },
-    "Example-Cmdlet": {
-        "prefix": "ex-cmdlet",
-        "body": [
-            "<#",
-            ".SYNOPSIS",
-            "\tShort description",
-            ".DESCRIPTION",
-            "\tLong description",
-            ".EXAMPLE",
-            "\tExample of how to use this cmdlet",
-            ".EXAMPLE",
-            "\tAnother example of how to use this cmdlet",
-            ".INPUTS",
-            "\tInputs to this cmdlet (if any)",
-            ".OUTPUTS",
-            "\tOutput from this cmdlet (if any)",
-            ".NOTES",
-            "\tGeneral notes",
-            ".COMPONENT",
-            "\tThe component this cmdlet belongs to",
-            ".ROLE",
-            "\tThe role this cmdlet belongs to",
-            ".FUNCTIONALITY",
-            "\tThe functionality that best describes this cmdlet",
-            "#>",
-            "function ${name:Verb-Noun} {",
-            "\t[CmdletBinding(DefaultParameterSetName='Parameter Set 1',",
-            "\t               SupportsShouldProcess=\\$true,",
-            "\t               PositionalBinding=\\$false,",
-            "\t               HelpUri = 'http://www.microsoft.com/',",
-            "\t               ConfirmImpact='Medium')]",
-            "\t[Alias()]",
-            "\t[OutputType([String])]",
-            "\tParam (",
-            "\t\t# Param1 help description",
-            "\t\t[Parameter(Mandatory=\\$true,",
-            "\t\t           Position=0,",
-            "\t\t           ValueFromPipeline=\\$true,",
-            "\t\t           ValueFromPipelineByPropertyName=\\$true,",
-            "\t\t           ValueFromRemainingArguments=\\$false, ",
-            "\t\t           ParameterSetName='Parameter Set 1')]",
-            "\t\t[ValidateNotNull()]",
-            "\t\t[ValidateNotNullOrEmpty()]",
-            "\t\t[ValidateCount(0,5)]",
-            "\t\t[ValidateSet(\"sun\", \"moon\", \"earth\")]",
-            "\t\t[Alias(\"p1\")] ",
-            "\t\t\\$Param1,",
-            "\t\t",
-            "\t\t# Param2 help description",
-            "\t\t[Parameter(ParameterSetName='Parameter Set 1')]",
-            "\t\t[AllowNull()]",
-            "\t\t[AllowEmptyCollection()]",
-            "\t\t[AllowEmptyString()]",
-            "\t\t[ValidateScript({\\$true})]",
-            "\t\t[ValidateRange(0,5)]",
-            "\t\t[int]",
-            "\t\t\\$Param2,",
-            "\t\t",
-            "\t\t# Param3 help description",
-            "\t\t[Parameter(ParameterSetName='Another Parameter Set')]",
-            "\t\t[ValidatePattern(\"[a-z]*\")]",
-            "\t\t[ValidateLength(0,15)]",
-            "\t\t[String]",
-            "\t\t\\$Param3",
-            "\t)",
-            "\t",
-            "\tbegin {",
-            "\t}",
-            "\t",
-            "\tprocess {",
-            "\t\tif (\\$pscmdlet.ShouldProcess(\"Target\", \"Operation\")) {",
-            "\t\t\t$0",
-            "\t\t}",
-            "\t}",
-            "\t",
-            "\tend {",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: script cmdlet snippet with all attributes and inline help fields"
-    },
-    "Example-DSC Configuration": {
-        "prefix": "ex-DSC config",
-        "body": [
-            "configuration Name {",
-            "\t# One can evaluate expressions to get the node list",
-            "\t# E.g: \\$AllNodes.Where(\"Role -eq Web\").NodeName",
-            "\tnode (\"Node1\",\"Node2\",\"Node3\")",
-            "\t{",
-            "\t\t# Call Resource Provider",
-            "\t\t# E.g: WindowsFeature, File",
-            "\t\tWindowsFeature FriendlyName",
-            "\t\t{",
-            "\t\t\tEnsure = \"Present\"",
-            "\t\t\tName = \"Feature Name\"",
-            "\t\t}",
-            "",
-            "\t\tFile FriendlyName",
-            "\t\t{",
-            "\t\t\tEnsure = \"Present\"",
-            "\t\t\tSourcePath = \\$SourcePath",
-            "\t\t\tDestinationPath = \\$DestinationPath",
-            "\t\t\tType = \"Directory\"",
-            "\t\t\tDependsOn = \"[WindowsFeature]FriendlyName\"",
-            "\t\t}",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: DSC configuration snippet that uses built-in resource providers"
-    },
-    "Example-DSC Resource Provider (class-based)": {
-        "prefix": "ex-DSC resource provider (class-based)",
-        "body": [
-            "# Defines the values for the resource's Ensure property.",
-            "enum Ensure {",
-            "\t# The resource must be absent.",
-            "\tAbsent",
-            "\t# The resource must be present.",
-            "\tPresent",
-            "}",
-            "",
-            "# [DscResource()] indicates the class is a DSC resource.",
-            "[DscResource()]",
-            "class NameOfResource {",
-            "\t# A DSC resource must define at least one key property.",
-            "\t[DscProperty(Key)]",
-            "\t[string] \\$P1",
-            "\t",
-            "\t# Mandatory indicates the property is required and DSC will guarantee it is set.",
-            "\t[DscProperty(Mandatory)]",
-            "\t[Ensure] \\$P2",
-            "\t",
-            "\t# NotConfigurable properties return additional information about the state of the resource.",
-            "\t# For example, a Get() method might return the date a resource was last modified.",
-            "\t# NOTE: These properties are only used by the Get() method and cannot be set in configuration.",
-            "\t[DscProperty(NotConfigurable)]",
-            "\t[Nullable[datetime]] \\$P3",
-            "\t",
-            "\t[DscProperty()]",
-            "\t[ValidateSet(\"val1\", \"val2\")]",
-            "\t[string] \\$P4",
-            "\t",
-            "\t# Gets the resource's current state.",
-            "\t[NameOfResource] Get() {",
-            "\t\t# NotConfigurable properties are set in the Get method.",
-            "\t\t\\$this.P3 = something",
-            "\t\t# Return this instance or construct a new instance.",
-            "\t\treturn \\$this",
-            "\t}",
-            "\t",
-            "\t# Sets the desired state of the resource.",
-            "\t[void] Set() {",
-            "\t}",
-            "\t",
-            "\t# Tests if the resource is in the desired state.",
-            "\t[bool] Test() {",
-            "\t\t return \\$true",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: class-based DSC resource provider snippet"
-    },
-    "Example-DSC Resource Provider (function based)": {
-        "prefix": "ex-DSC resource provider (function based)",
-        "body": [
-            "function Get-TargetResource {",
-            "\t# TODO: Add parameters here",
-            "\t# Make sure to use the same parameters for",
-            "\t# Get-TargetResource, Set-TargetResource, and Test-TargetResource",
-            "\tparam (",
-            "\t)",
-            "}",
-            "function Set-TargetResource {",
-            "\t# TODO: Add parameters here",
-            "\t# Make sure to use the same parameters for",
-            "\t# Get-TargetResource, Set-TargetResource, and Test-TargetResource",
-            "\tparam (",
-            "\t)",
-            "}",
-            "function Test-TargetResource {",
-            "\t# TODO: Add parameters here",
-            "\t# Make sure to use the same parameters for",
-            "\t# Get-TargetResource, Set-TargetResource, and Test-TargetResource",
-            "\tparam (",
-            "\t)",
-            "}"
-        ],
-        "description": "Example: function-based DSC resource provider snippet"
-    },
-    "Example-Path Processing for Non-Existing Paths": {
-        "prefix": "ex-path processing for non-existing paths",
-        "body": [
-            "# Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=\\$true)]",
-            "\\$paths = @()",
-            "foreach (\\$aPath in \\$Path) {",
-            "\t# Resolve any relative paths",
-            "\t\\$paths += \\$psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\\$aPath)",
-            "}",
-            "",
-            "foreach (\\$aPath in \\$paths) {",
-            "\tif (\\$pscmdlet.ShouldProcess(\\$aPath, 'Operation')) {",
-            "\t\t# Process each path",
-            "\t\t$0",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: processing non-existing paths typically used in New-* commands (for use in process block). See parameter-path snippet."
-    },
-    "Example-Path Processing for No Wildcards Allowed": {
-        "prefix": "ex-path processing for no wildcards allowed",
-        "body": [
-            "# Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=\\$true)]",
-            "\\$paths = @()",
-            "foreach (\\$aPath in \\$Path) {",
-            "\tif (!(Test-Path -LiteralPath \\$aPath)) {",
-            "\t\t\\$ex = New-Object System.Management.Automation.ItemNotFoundException \"Cannot find path '\\$aPath' because it does not exist.\"",
-            "\t\t\\$category = [System.Management.Automation.ErrorCategory]::ObjectNotFound",
-            "\t\t\\$errRecord = New-Object System.Management.Automation.ErrorRecord \\$ex,'PathNotFound',\\$category,\\$aPath",
-            "\t\t\\$psCmdlet.WriteError(\\$errRecord)",
-            "\t\tcontinue",
-            "\t}",
-            "",
-            "\t# Resolve any relative paths",
-            "\t\\$paths += \\$psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\\$aPath)",
-            "}",
-            "",
-            "foreach (\\$aPath in \\$paths) {",
-            "\tif (\\$pscmdlet.ShouldProcess(\\$aPath, 'Operation')) {",
-            "\t\t# Process each path",
-            "\t\t$0",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: processing non-wildcard paths that must exist (for use in process block). See parameter-path snippets."
-    },
-    "Example-Path Processing for Wildcards Allowed": {
-        "prefix": "ex-path processing for wildcards allowed",
-        "body": [
-            "# Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=\\$true, DefaultParameterSetName='Path')]",
-            "\\$paths = @()",
-            "if (\\$psCmdlet.ParameterSetName -eq 'Path') {",
-            "\tforeach (\\$aPath in \\$Path) {",
-            "\t\tif (!(Test-Path -Path \\$aPath)) {",
-            "\t\t\t\\$ex = New-Object System.Management.Automation.ItemNotFoundException \"Cannot find path '\\$aPath' because it does not exist.\"",
-            "\t\t\t\\$category = [System.Management.Automation.ErrorCategory]::ObjectNotFound",
-            "\t\t\t\\$errRecord = New-Object System.Management.Automation.ErrorRecord \\$ex,'PathNotFound',\\$category,\\$aPath",
-            "\t\t\t\\$psCmdlet.WriteError(\\$errRecord)",
-            "\t\t\tcontinue",
-            "\t\t}",
-            "\t",
-            "\t\t# Resolve any wildcards that might be in the path",
-            "\t\t\\$provider = \\$null",
-            "\t\t\\$paths += \\$psCmdlet.SessionState.Path.GetResolvedProviderPathFromPSPath(\\$aPath, [ref]\\$provider)",
-            "\t}",
-            "}",
-            "else {",
-            "\tforeach (\\$aPath in \\$LiteralPath) {",
-            "\t\tif (!(Test-Path -LiteralPath \\$aPath)) {",
-            "\t\t\t\\$ex = New-Object System.Management.Automation.ItemNotFoundException \"Cannot find path '\\$aPath' because it does not exist.\"",
-            "\t\t\t\\$category = [System.Management.Automation.ErrorCategory]::ObjectNotFound",
-            "\t\t\t\\$errRecord = New-Object System.Management.Automation.ErrorRecord \\$ex,'PathNotFound',\\$category,\\$aPath",
-            "\t\t\t\\$psCmdlet.WriteError(\\$errRecord)",
-            "\t\t\tcontinue",
-            "\t\t}",
-            "\t",
-            "\t\t# Resolve any relative paths",
-            "\t\t\\$paths += \\$psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\\$aPath)",
-            "\t}",
-            "}",
-            "",
-            "foreach (\\$aPath in \\$paths) {",
-            "\tif (\\$pscmdlet.ShouldProcess(\\$aPath, 'Operation')) {",
-            "\t\t# Process each path",
-            "\t\t$0",
-            "\t}",
-            "}"
-        ],
-        "description": "Example: processing wildcard paths that must exist (for use in process block). See parameter-path-wildcards and parameter-literalpath snippets."
-    },
-    "Example-Splatting": {
-        "prefix": "ex-splat",
-        "body": [
-            "\\$Params = @{",
-            "\tModule = '*'",
-            "\tVerb = 'Get'",
-            "}",
-            "Get-Command @Params"
-        ],
-        "description": "Example: PowerShell splatting technique snippet"
-    },
-    "Example-Switch": {
-        "prefix": "ex-switch",
-        "body": [
-            "switch (${variable:\\$x})",
-            "{",
-            "\t'${val:value1}' { $1 }",
-            "\t{\\$_ -in 'A','B','C'} {}",
-            "\t'value3' {}",
-            "\tDefault {}",
-            "}"
-        ],
-        "description": "Example: switch statement snippet"
-    },
-    "Example-Advanced Workflow": {
-        "prefix": "ex-advanced workflow",
-        "body": [
-            "<#",
-            ".Synopsis",
-            "\tShort description",
-            ".DESCRIPTION",
-            "\tLong description",
-            ".EXAMPLE",
-            "\tExample of how to use this workflow",
-            ".EXAMPLE",
-            "\tAnother example of how to use this workflow",
-            ".INPUTS",
-            "\tInputs to this workflow (if any)",
-            ".OUTPUTS",
-            "\tOutput from this workflow (if any)",
-            ".NOTES",
-            "\tGeneral notes",
-            ".FUNCTIONALITY",
-            "\tThe functionality that best describes this workflow",
-            "#>",
-            "workflow ${name:Verb-Noun} {",
-            "\t[CmdletBinding(DefaultParameterSetName='Parameter Set 1',",
-            "\t               HelpUri = 'http://www.microsoft.com/',",
-            "\t               ConfirmImpact='Medium')]",
-            "\t[Alias()]",
-            "\t[OutputType([String])]",
-            "\tparam (",
-            "\t\t# Param1 help description",
-            "\t\t[Parameter(Mandatory=\\$true, ",
-            "\t\t           Position=0,",
-            "\t\t           ParameterSetName='Parameter Set 1')]",
-            "\t\t[ValidateNotNull()]",
-            "\t\t[Alias(\"p1\")] ",
-            "\t\t\\$Param1,",
-            "",
-            "\t\t# Param2 help description",
-            "\t\t[int]",
-            "\t\t\\$Param2",
-            "\t)",
-            "",
-            "\t# Saves (persists) the current workflow state and output",
-            "\t# Checkpoint-Workflow",
-            "\t# Suspends the workflow",
-            "\t# Suspend-Workflow",
-            "",
-            "\t# Workflow common parameters are available as variables such as:",
-            "\t\\$PSPersist ",
-            "\t\\$PSComputerName",
-            "\t\\$PSCredential",
-            "\t\\$PSUseSsl",
-            "\t\\$PSAuthentication",
-            "",
-            "\t# Workflow runtime information can be accessed by using the following variables:",
-            "\t\\$Input",
-            "\t\\$PSSenderInfo",
-            "\t\\$PSWorkflowRoot",
-            "\t\\$JobCommandName",
-            "\t\\$ParentCommandName",
-            "\t\\$JobId",
-            "\t\\$ParentJobId",
-            "\t\\$WorkflowInstanceId",
-            "\t\\$JobInstanceId",
-            "\t\\$ParentJobInstanceId",
-            "\t\\$JobName",
-            "\t\\$ParentJobName",
-            "",
-            "\t# Set the progress message ParentActivityId",
-            "\t\\$PSParentActivityId",
-            "",
-            "\t# Preference variables that control runtime behavior",
-            "\t\\$PSRunInProcessPreference",
-            "\t\\$PSPersistPreference",
-            "}"
-        ],
-        "description": "Example: advanced workflow snippet"
-    },
-    "Class": {
-        "prefix": "class",
-        "body": [
-            "class ${1:ClassName} {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Class definition snippet"
-    },
-    "Constructor": {
-        "prefix": "ctor",
-        "body": [
-            "${1:ClassName}(${2:OptionalParameters}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Class constructor definition snippet"
-    },
-    "Hidden Property": {
-        "prefix": "proph",
-        "body": [
-            "hidden [${1:string}] $${0:PropertyName}"
-        ],
-        "description": "Class hidden property definition snippet"
-    },
-    "Property": {
-        "prefix": "prop",
-        "body": [
-            "[${1:string}] $${0:PropertyName}"
-        ],
-        "description": "Class property definition snippet"
-    },
-    "Method": {
-        "prefix": "method",
-        "body": [
-            "[${1:void}] ${2:MethodName}($${3:OptionalParameters}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Class method definition snippet"
-    },
-    "Enum": {
-        "prefix": "enum",
-        "body": [
-            "enum ${1:EnumName} {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Enum definition snippet"
-    },
-    "Function-Advanced": {
-        "prefix": [
-            "function-advanced",
-            "cmdlet"
-        ],
-        "body": [
-            "function ${1:Verb-Noun} {",
-            "\t[CmdletBinding()]",
-            "\tparam (",
-            "\t\t$0",
-            "\t)",
-            "\t",
-            "\tbegin {",
-            "\t\t",
-            "\t}",
-            "\t",
-            "\tprocess {",
-            "\t\t$TM_SELECTED_TEXT",
-            "\t}",
-            "\t",
-            "\tend {",
-            "\t\t",
-            "\t}",
-            "}"
-        ],
-        "description": "Script advanced function definition snippet"
-    },
-    "Comment-Help": {
-        "prefix": "comment-help",
-        "body": [
-            "<#",
-            ".SYNOPSIS",
-            "\tShort description",
-            ".DESCRIPTION",
-            "\tLong description",
-            ".EXAMPLE",
-            "\tPS C:\\> <example usage>",
-            "\tExplanation of what the example does",
-            ".INPUTS",
-            "\tInputs (if any)",
-            ".OUTPUTS",
-            "\tOutput (if any)",
-            ".NOTES",
-            "\tGeneral notes",
-            "#>"
-        ],
-        "description": "Comment-based help for an advanced function snippet"
-    },
-    "Parameter": {
-        "prefix": "parameter",
-        "body": [
-            "# ${1:Parameter help description}",
-            "[Parameter(${2:AttributeValues})]",
-            "[${3:ParameterType}]",
-            "$${0:ParameterName}"
-        ],
-        "description": "Parameter declaration snippet"
-    },
-    "Parameter_Block" : {
-        "prefix": "param-block",
-        "body": ["[CmdletBinding()]",
-            "param (",
-            "    [Parameter()]",
-            "    [${1:TypeName}]",
-            "    $${2:ParameterName}$0",
-            ")"
-	],
-        "description": "A Parameter block to get you started."
-    },
-    "Parameter-Path": {
-        "prefix": "parameter-path",
-        "body": [
-            "# Specifies a path to one or more locations.",
-            "[Parameter(Mandatory=\\$true,",
-            "           Position=${1:0},",
-            "           ParameterSetName=\"${2:ParameterSetName}\",",
-            "           ValueFromPipeline=\\$true,",
-            "           ValueFromPipelineByPropertyName=\\$true,",
-            "           HelpMessage=\"Path to one or more locations.\")]",
-            "[Alias(\"PSPath\")]",
-            "[ValidateNotNullOrEmpty()]",
-            "[string[]]",
-            "$${3:ParameterName}$0"
-        ],
-        "description": "Parameter declaration snippet for Path parameter that does not accept wildcards. Do not use with parameter-literalpath."
-    },
-    "Parameter-Path-Wildcards": {
-        "prefix": "parameter-path-wildcards",
-        "body": [
-            "# Specifies a path to one or more locations. Wildcards are permitted.",
-            "[Parameter(Mandatory=\\$true,",
-            "           Position=${1:Position},",
-            "           ParameterSetName=\"${2:ParameterSetName}\",",
-            "           ValueFromPipeline=\\$true,",
-            "           ValueFromPipelineByPropertyName=\\$true,",
-            "           HelpMessage=\"Path to one or more locations.\")]",
-            "[ValidateNotNullOrEmpty()]",
-            "[SupportsWildcards()]",
-            "[string[]]",
-            "$${3:ParameterName}$0"
-        ],
-        "description": "Parameter declaration snippet for Path parameter that accepts wildcards. Add parameter-literalpath to handle paths with embedded wildcard chars."
-    },
-    "Parameter-LiteralPath": {
-        "prefix": "parameter-literalpath",
-        "body": [
-            "# Specifies a path to one or more locations. Unlike the Path parameter, the value of the LiteralPath parameter is",
-            "# used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters,",
-            "# enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any",
-            "# characters as escape sequences.",
-            "[Parameter(Mandatory=\\$true,",
-            "           Position=${1:0},",
-            "           ParameterSetName=\"${2:LiteralPath}\",",
-            "           ValueFromPipelineByPropertyName=\\$true,",
-            "           HelpMessage=\"Literal path to one or more locations.\")]",
-            "[Alias(\"PSPath\")]",
-            "[ValidateNotNullOrEmpty()]",
-            "[string[]]",
-            "$${2:LiteralPath}$0"
-        ],
-        "description": "Parameter declaration snippet for a LiteralPath parameter"
-    },
-    "DSC Ensure Enum": {
-        "prefix": "DSC Ensure enum",
-        "body": [
-            "enum Ensure {",
-            "\tAbsent",
-            "\tPresent",
-            "}"
-        ],
-        "description": "DSC Ensure enum definition snippet"
-    },
-    "DSC Resource Provider (class-based)": {
-        "prefix": "DSC resource provider (class-based)",
-        "body": [
-            "[DscResource()]",
-            "class ${ResourceName:NameOfResource} {",
-            "\t[DscProperty(Key)]",
-            "\t[string] $${PropertyName:KeyName}",
-            "\t",
-            "\t# Gets the resource's current state.",
-            "\t[${ResourceName:NameOfResource}] Get() {",
-            "\t\t${0:$TM_SELECTED_TEXT}",
-            "\t\treturn \\$this",
-            "\t}",
-            "\t",
-            "\t# Sets the desired state of the resource.",
-            "\t[void] Set() {",
-            "\t\t",
-            "\t}",
-            "\t",
-            "\t# Tests if the resource is in the desired state.",
-            "\t[bool] Test() {",
-            "\t\t",
-            "\t}",
-            "}"
-        ],
-        "description": "Class-based DSC resource provider snippet"
-    },
-    "DSC Resource Provider (function-based)": {
-        "prefix": "DSC resource provider (function-based)",
-        "body": [
-            "function Get-TargetResource {",
-            "\tparam (",
-            "\t)",
-            "\t",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}",
-            "function Set-TargetResource {",
-            "\tparam (",
-            "\t)",
-            "\t",
-            "}",
-            "function Test-TargetResource {",
-            "\tparam (",
-            "\t)",
-            "\t",
-            "}"
-        ],
-        "description": "Function-based DSC resource provider snippet"
-    },
-    "comment block": {
-        "prefix": "comment",
-        "body": [
-            "<#",
-            " # ${0:$TM_SELECTED_TEXT}",
-            " #>"
-        ],
-        "description": "Comment block snippet"
-    },
-    "do-until": {
-        "prefix": "do-until",
-        "body": [
-            "do {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "} until (${1:condition})"
-        ],
-        "description": "do-until loop snippet"
-    },
-    "do-while": {
-        "prefix": "do-while",
-        "body": [
-            "do {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "} while (${1:condition})"
-        ],
-        "description": "do-while loop snippet"
-    },
-    "while": {
-        "prefix": "while",
-        "body": [
-            "while (${1:condition}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "while loop snippet"
-    },
-    "for": {
-        "prefix": "for",
-        "body": [
-            "for ($${1:i} = 0; $${1:i} -lt $${2:array}.Count; $${1:i}++) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "for loop snippet"
-    },
-    "for-reversed": {
-        "prefix": "forr",
-        "body": [
-            "for ($${1:i} = $${2:array}.Count - 1; $${1:i} -ge 0 ; $${1:i}--) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "reversed for loop snippet"
-    },
-    "foreach": {
-        "prefix": "foreach",
-        "body": [
-            "foreach ($${1:item} in $${2:collection}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "foreach loop snippet"
-    },
-    "function": {
-        "prefix": "function",
-        "body": [
-            "function ${1:FunctionName} {",
-            "\tparam (",
-            "\t\t${2:OptionalParameters}",
-            "\t)",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Function definition snippet that contains a param block"
-    },
-    "Function-Inline": {
-        "prefix": "Function-Inline",
-        "body": [
-            "function ${1:FunctionName} (${2:OptionalParameters}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Function definition snippet that does not contain a param block, but defines parameters inline. This syntax is commonly used in other languages"
-    },
-    "if": {
-        "prefix": "if",
-        "body": [
-            "if (${1:condition}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "if statement snippet"
-    },
-    "elseif": {
-        "prefix": "elseif",
-        "body": [
-            "elseif (${1:condition}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "elseif statement snippet"
-    },
-    "else": {
-        "prefix": "else",
-        "body": [
-            "else {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "else statement snippet"
-    },
-    "switch": {
-        "prefix": "switch",
-        "body": [
-            "switch (${1:\\$x}) {",
-            "\t${2:condition} { ${0:$TM_SELECTED_TEXT} }",
-            "\tDefault {}",
-            "}"
-        ],
-        "description": "switch statement snippet"
-    },
-    "try-catch": {
-        "prefix": "try",
-        "body": [
-            "try {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}",
-            "catch {",
-            "\t",
-            "}"
-        ],
-        "description": "try-catch snippet"
-    },
-    "try-catch-finally": {
-        "prefix": "trycf",
-        "body": [
-            "try {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}",
-            "catch {",
-            "\t",
-            "}",
-            "finally {",
-            "\t",
-            "}"
-        ],
-        "description": "try-catch-finally snippet"
-    },
-    "try-finally": {
-        "prefix": "tryf",
-        "body": [
-            "try {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}",
-            "finally {",
-            "\t",
-            "}"
-        ],
-        "description": "try-finally snippet"
-    },
-    "Workflow": {
-        "prefix": "workflow",
-        "body": [
-            "workflow ${name:Verb-Noun} {",
-            "\tparam (",
-            "\t)",
-            "",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "workflow snippet"
-    },
-    "Workflow ForEachParallel": {
-        "prefix": "workflow foreach-parallel",
-        "body": [
-            "foreach -parallel ($${variable:item} in $${collection:collection}) {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "foreach-parallel snippet (for use inside a workflow)"
-    },
-    "Workflow InlineScript": {
-        "prefix": "workflow inlinescript",
-        "body": [
-            "inlineScript {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "inlinescript snippet (for use inside a workflow)"
-    },
-    "Workflow Parallel": {
-        "prefix": "workflow parallel",
-        "body": [
-            "parallel {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "parallel snippet (for use inside a workflow)"
-    },
-    "Workflow Sequence": {
-        "prefix": "workflow sequence",
-        "body": [
-            "sequence {",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "sequence snippet (for use inside a workflow)"
-    },
-    "Suppress PSScriptAnalyzer Rule": {
-		"prefix": "suppress-message-rule",
-		"description": "Suppress a built-in PSScriptAnalyzer rule using the SuppressMessageAttribute",
-		"body": [
-			"[Diagnostics.CodeAnalysis.SuppressMessageAttribute('${1:PSUseDeclaredVarsMoreThanAssignments}', '')]"
-		]
-	},
-    "Suppress PSScriptAnalyzer Rule on Parameter": {
-		"prefix": "suppress-message-rule-for-parameter",
-		"description": "Suppress a built-in PSScriptAnalyzer rule on a parameter using the SuppressMessageAttribute",
-		"body": [
-			"[Diagnostics.CodeAnalysis.SuppressMessageAttribute('${1:PSUseDeclaredVarsMoreThanAssignments}', '${2:ParamName}')]"
-		]
-	},
-	"Suppress PSScriptAnalyzer Rule in Scope": {
-		"prefix": "suppress-message-rule-for-scope",
-		"description": "Suppress a built-in PSScriptAnalyzer rule for functions or classes in a specific scope using the SuppressMessageAttribute",
-		"body": [
-			"[Diagnostics.CodeAnalysis.SuppressMessageAttribute('${1:PSProvideDefaultParameterValue}', '', Scope='Function', Target='${2:*}')]"
-		]
-    },
-    "PSCustomObject": {
-        "prefix": "[PSCustomObject]",
-        "body": [
-            "[PSCustomObject]@{",
-            "\t${1:Name} = ${2:Value}",
-            "}"
-        ],
-        "description": "Creates a PSCustomObject"
-    },
-    "Hashtable": {
-        "prefix": "Hashtable",
-        "body": [
-            "\\$${1:Var} = @{",
-            "\t${2:Name} = ${3:Value}",
-            "}"
-        ],
-        "description": "Creates a Hashtable"
-    },
-    "Region Block": {
-        "prefix": "#region",
-        "body": [
-            "#region ${1}",
-            "${0:$TM_SELECTED_TEXT}",
-            "#endregion"
-        ],
-        "description": "Region Block for organizing and folding of your code"
-    },
-    "IfShouldProcess": {
-        "prefix": "IfShouldProcess",
-        "body": [
-            "if (\\$PSCmdlet.ShouldProcess(\"${1:Target}\", \"${2:Operation}\")) {",
-                "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Creates ShouldProcess block"
-    },
-    "CalculatedProperty": {
-        "prefix": "Calculated-Property",
-        "body": [
-            "@{name='${1:PropertyName}';expression={${2:${TM_SELECTED_TEXT:\\$_.PropertyValue}}}}$0"
-        ],
-        "description": "Creates a Calculated Property typically used with Select-Object."
-    },
-    "PesterDescribeContextIt": {
-        "prefix": "Describe-Context-It-Pester",
-        "body": [
-            "Describe \"${1:DescribeName}\" {",
-                "\tContext \"${2:ContextName}\" {",
-                    "\t\tIt \"${3:ItName}\" {",
-                        "\t\t\t${4:${TM_SELECTED_TEXT:Assertion}}",
-                    "\t\t}$0",
-                "\t}",
-            "}"
-        ],
-        "description": "Pester Describe block with nested Context & It blocks"
-    },
-    "PesterDescribeBlock": {
-        "prefix": "Describe-Pester",
-        "body": [
-            "Describe \"${1:DescribeName}\" {",
-                "\t${0:TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Pester Describe block"
-    },
-    "PesterContextIt": {
-        "prefix": "Context-It-Pester",
-        "body": [
-            "Context \"${1:ContextName}\" {",
-                "\tIt \"${2:ItName}\" {",
-                    "\t\t${3:${TM_SELECTED_TEXT:Assertion}}",
-                "\t}$0",
-            "}"
-        ],
-        "description": "Pester - Context block with nested It block"
-    },
-    "PesterContext": {
-        "prefix": "Context-Pester",
-        "body": [
-            "Context \"${1:ContextName}\" {",
-                "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "Pester - Context block"
-    },
-    "PesterIt": {
-        "prefix": "It-Pester",
-        "body": [
-            "It \"${1:ItName}\" {",
-                "\t${2:${TM_SELECTED_TEXT:Assertion}}",
-            "}$0"
-        ],
-        "description": "Pester - It block"
-    },
-    "ArgumentCompleterAttribute with ScriptBlock": {
-        "prefix": "completer-attribute",
-        "body": [
-            "[ArgumentCompleter({",
-            "\t[OutputType([System.Management.Automation.CompletionResult])]  # zero to many",
-            "\tparam(",
-            "\t\t[string] \\$CommandName,",
-            "\t\t[string] \\$ParameterName,",
-            "\t\t[string] \\$WordToComplete,",
-            "\t\t[System.Management.Automation.Language.CommandAst] \\$CommandAst,",
-            "\t\t[System.Collections.IDictionary] \\$FakeBoundParameters",
-            "\t)",
-            "\t",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "})]"
-        ],
-        "description": "ArgumentCompleter parameter attribute with script block definition"
-    },
-    "ArgumentCompleterAttribute ScriptBlock": {
-        "prefix": "completer-scriptblock",
-        "body": [
-            "{",
-            "\t[OutputType([System.Management.Automation.CompletionResult])]  # zero to many",
-            "\tparam(",
-            "\t\t[string] \\$CommandName,",
-            "\t\t[string] \\$ParameterName,",
-            "\t\t[string] \\$WordToComplete,",
-            "\t\t[System.Management.Automation.Language.CommandAst] \\$CommandAst,",
-            "\t\t[System.Collections.IDictionary] \\$FakeBoundParameters",
-            "\t)",
-            "\t",
-            "\t${0:$TM_SELECTED_TEXT}",
-            "}"
-        ],
-        "description": "ArgumentCompleter parameter attribute script block definition"
-    },
-    "IArgumentCompleter Class": {
-        "prefix": "completer-class",
-        "body": [
-            "class ${1:ArgumentCompleter} : System.Management.Automation.IArgumentCompleter {",
-            "\t[System.Collections.Generic.IEnumerable[System.Management.Automation.CompletionResult]] CompleteArgument(",
-            "\t\t[string] \\$CommandName,",
-            "\t\t[string] \\$ParameterName,",
-            "\t\t[string] \\$WordToComplete,",
-            "\t\t[System.Management.Automation.Language.CommandAst] \\$CommandAst,",
-            "\t\t[System.Collections.IDictionary] \\$FakeBoundParameters",
-            "\t) {",
-            "\t\t\\$CompletionResults = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new()",
-            "\t\t",
-            "\t\t${0:$TM_SELECTED_TEXT}",
-            "\t\t",
-            "\t\treturn \\$CompletionResults",
-            "\t}",
-            "}"
-        ],
-        "description": "IArgumentCompleter implementation class definition"
-    },
-    "Requires Assembly": {
-        "prefix": "requires-assembly",
-        "body": "#Requires -Assembly '${1:${TM_SELECTED_TEXT:fully-qualified-name}}'",
-        "description": "Requires an assembly (by name) in order to execute the containing script file."
-    },
-    "Requires Assembly Path": {
-        "prefix": "requires-assembly-path",
-        "body": "#Requires -Assembly ${0:${TM_SELECTED_TEXT:path/to/assembly.dll}}",
-        "description": "Requires an assembly (by relative or absolute path) in order to execute the containing script file."
-    },
-    "Requires Assembly Version": {
-        "prefix": "requires-assembly-version",
-        "body": "#Requires -Assembly '${1:${TM_SELECTED_TEXT:fully-qualified-name}}, Version=${2:1.0.0.0}'",
-        "description": "Requires an assembly (by name and minimum version) in order to execute the containing script file."
-    },
-    "Requires Module": {
-        "prefix": "requires-module",
-        "body": "#Requires -Module ${0:${TM_SELECTED_TEXT:fully-qualified-name}}",
-        "description": "Requires a module (by name) in order to execute the containing script file."
-    },
-    "Requires Module RequiredVersion": {
-        "prefix": "requires-module-required-version",
-        "body": "#Requires -Module @{ ModuleName = '${1:${TM_SELECTED_TEXT:fully-qualified-name}}'; RequiredVersion = '${2:exact-required-version}' }",
-        "description": "Requires a module (by name and exact version) in order to execute the containing script file."
-    },
-    "Requires Module Version": {
-        "prefix": "requires-module-version",
-        "body": "#Requires -Module @{ ModuleName = '${1:${TM_SELECTED_TEXT:fully-qualified-name}}'; ModuleVersion = '${2:minimum-acceptable-version}' }",
-        "description": "Requires a module (by name and minimum version) in order to execute the containing script file."
-    },
-    "Requires PSEdition": {
-        "prefix": "requires-ps-edition",
-        "body": "#Requires -PSEdition ${1|Core,Desktop|}",
-        "description": "Requires a specific edition of PowerShell in order to execute the containing script file."
-    },
-    "Requires PSSnapin": {
-        "prefix": "requires-ps-snapin",
-        "body": "#Requires -PSSnapin ${0:${TM_SELECTED_TEXT:fully-qualified-name}}",
-        "description": "Requires a PowerShell snap-in (by name) in order to execute the containing script file."
-    },
-    "Requires PSSnapin Version": {
-        "prefix": "requires-ps-snapin-version",
-        "body": "#Requires -PSSnapin ${1:${TM_SELECTED_TEXT:fully-qualified-name}} -Version ${2:minimum-acceptable-version}",
-        "description": "Requires a PowerShell snap-in (by name and minimum version) in order to execute the containing script file."
-    },
-    "Requires RunAsAdministrator": {
-        "prefix": "requires-run-as-administrator",
-        "body": "#Requires -RunAsAdministrator",
-        "description": "Requires elevated user rights in order to execute the containing script file. Ignored on non-Windows systems. On Windows systems, it requires that the PowerShell session in which the containing script file is run must have been started with elevated user rights (\"Run as Administrator\")."
-    },
-    "Requires ShellId": {
-        "prefix": "requires-shell-id",
-        "body": "#Requires -ShellId ${0:${TM_SELECTED_TEXT:shell-id}}",
-        "description": "Requires a specific shell id in order to execute the containing script file. The current shell id may be determined by querying the $ShellId automatic variable."
-    },
-    "Requires Version": {
-        "prefix": "requires-version",
-        "body": "#Requires -Version ${0:${TM_SELECTED_TEXT:minimum-acceptable-version}}",
-        "description": "Requires a minimum version of PowerShell in order to execute the containing script file."
-    }
+  "ArgumentCompleterAttribute": {
+    "prefix": "argument-completer",
+    "description": "Allows you to add tab completion values to a specific parameter by writing a script block that generates zero or more CompletionResult objects. More: Get-Help about_Functions_Argument_Completion",
+    "body": [
+      "[ArgumentCompleter({",
+      "\t[OutputType([System.Management.Automation.CompletionResult])]",
+      "\tparam(",
+      "\t\t[string] \\$CommandName,",
+      "\t\t[string] \\$ParameterName,",
+      "\t\t[string] \\$WordToComplete,",
+      "\t\t[System.Management.Automation.Language.CommandAst] \\$CommandAst,",
+      "\t\t[System.Collections.IDictionary] \\$FakeBoundParameters",
+      "\t)",
+      "\t",
+      "\t\\$CompletionResults = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new()",
+      "\t",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "\t",
+      "\treturn \\$CompletionResults",
+      "})]"
+    ]
+  },
+  "Calculated Property": {
+    "prefix": "calculated-property",
+    "description": "Typically used with Select-Object or Sort-Object. More: Get-Help about_Calculated_Properties",
+    "body": [
+      "@{Name='${1:PropertyName}';Expression={${2:${TM_SELECTED_TEXT:<# Desired result. You can reference this object via \\$_ and \\$PSItem #>}}}}$0"
+    ]
+  },
+  "Class": {
+    "prefix": "class",
+    "description": "A blueprint used to create instances of objects at run time. More: Get-Help about_Classes",
+    "body": [
+      "class ${1:ClassName} {",
+      "\t${0:${TM_SELECTED_TEXT:<# Define the class. Try constructors, properties, or methods. #>}}",
+      "}"
+    ]
+  },
+  "Class Constructor": {
+    "prefix": ["ctor-class", "class-constructor"],
+    "description": "Set default values and validate object logic at the moment of creating the instance of the class. Constructors have the same name as the class. Constructors might have arguments, to initialize the data members of the new object. More: Get-Help about_Classes",
+    "body": [
+      "${1:ClassName}(${2:<#OptionalParameters#>}) {",
+      "\t${0:${TM_SELECTED_TEXT:<# Initialize the class. Use \\$this to reference the properties of the instance you are creating #>}}",
+      "}"
+    ]
+  },
+  "Class Method": {
+    "prefix": "class-method",
+    "description": "Defines the actions that a class can perform. Methods may take parameters that provide input data. Methods can return output. Data returned by a method can be any defined data type. More: Get-Help about_Classes",
+    "body": [
+      "[${1:void}] ${2:MethodName}($${3:OptionalParameters}) {",
+      "\t${0:${TM_SELECTED_TEXT:<# Action to perform. You can use $$this to reference the current instance of this class #>}}",
+      "}"
+    ]
+  },
+  "Class Property": {
+    "prefix": "class-property",
+    "description": "Properties are variables declared at class scope. A property may be of any built-in type or an instance of another class. Classes have no restriction in the number of properties they have. More: Get-Help about_Classes",
+    "body": ["[${1:propertyType}] $${0:PropertyName}"]
+  },
+  "Comment Block": {
+    "prefix": ["block-comment"],
+    "description": "A multi-line comment.",
+    "body": [
+      "$BLOCK_COMMENT_START",
+      " # ${0:{$TM_SELECTED_TEXT:Enter a comment or description}}",
+      "$BLOCK_COMMENT_END"
+    ]
+  },
+  "do-until": {
+    "prefix": "do-until",
+    "description": "Runs a statement list repeatedly until a condition is met More: Get-Help about_Do",
+    "body": [
+      "do {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "} until (",
+      "\t${1:<# Condition that stops the loop if it returns true #>}",
+      ")"
+    ]
+  },
+  "do-while": {
+    "prefix": "do-while",
+    "description": "Runs a statement list repeatedly as long as a condition is met. More: Get-Help about_Do",
+    "body": [
+      "do {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "} while (",
+      "\t${1:<# Condition that stops the loop if it returns false #>}",
+      ")"
+    ]
+  },
+  "else": {
+    "prefix": "else",
+    "description": "else defines what is done when all if and elseif conditions are false. More: Get-Help about_If",
+    "body": [
+      "else {",
+      "\t${0:${TM_SELECTED_TEXT:<# Action when all if and elseif conditions are false #>}}",
+      "}"
+    ]
+  },
+  "elseif": {
+    "prefix": "elseif",
+    "description": "elseif provides an alternative path when an if condition is false. More: Get-Help about_If",
+    "body": [
+      "elseif (${1:<#condition#>}) {",
+      "\t${0:${TM_SELECTED_TEXT:<# Action when this condition is true #>}}",
+      "}"
+    ]
+  },
+  "Enum": {
+    "prefix": "enum",
+    "description": "An enumeration is a distinct type that consists of a set of named labels called the enumerator list. More: Get-Help about_Enum",
+    "body": [
+      "enum ${1:<#EnumName#>} {",
+      "\t${0:${TM_SELECTED_TEXT:<# Specify a list of distinct values #>}}",
+      "}"
+    ]
+  },
+  "for": {
+    "prefix": "for",
+    "description": "Creates a loop that runs commands in a command block while a specified condition evaluates to $true. A typical use of the for loop is to iterate an array of values and to operate on a subset of these values. More: Get-Help about_For",
+    "body": [
+      "for ($${1:i} = 0; $${1:i} -lt $${2:array}.Count; $${1:i}++) {",
+      "\t${0:${TM_SELECTED_TEXT:<# Action that will repeat until the condition is met #>}}",
+      "}"
+    ]
+  },
+  "for-reversed": {
+    "prefix": "forr",
+    "description": "reversed for loop snippet",
+    "body": [
+      "for ($${1:i} = $${2:array}.Count - 1; $${1:i} -ge 0 ; $${1:i}--) {",
+      "\t${0:${$TM_SELECTED_TEXT}}",
+      "}"
+    ]
+  },
+  "foreach": {
+    "prefix": "foreach",
+    "description": "Iterate through a collection, assigning a variable to the current item on each loop rather than using the automatic variable $PSItem. More: Get-Help about_Foreach",
+    "body": [
+      "foreach ($${1:currentItemName} in $${2:collection}) {",
+      "\t${0:${TM_SELECTED_TEXT:<# $${1} is the current item #>}}",
+      "}"
+    ]
+  },
+  "foreach-item": {
+    "prefix": "foreach-item",
+    "description": "Quicker definition of foreach, just highlight the variable name of the collection you want to use and type 'item' then enter then tab. More: Get-Help about_Foreach",
+    "body": [
+      "foreach (${1/(.*)/$1Item/} in ${1:${TM_SELECTED_TEXT:collection}}) {",
+      "\t${0:${1/(.*)/$1Item/}}",
+      "}"
+    ]
+  },
+  "Foreach with Progress": {
+    "prefix": "foreach-progress",
+    "description": "Insert a foreach loop with Write-Progress initialized",
+    "body": [
+      "\\$total = \\$${1:array}.count",
+      "\\$${4:i} = 1",
+      "\\$progPercent = \"{0:n2}\" -f ([math]::round(\\$${4:i}/\\$total,4) * 100)",
+      "Write-Progress -Activity \"${3:activityName}\" -Status \"\\$${4:i} of \\$total - \\$progPercent% Complete:\" -PercentComplete \\$progPercent",
+      "foreach ($${2:item} in $${1:array}) {",
+      "    \\$progPercent = \"{0:n2}\" -f ([math]::round(\\$${4:i}/\\$total,4) * 100)",
+      "    Write-Progress -Activity \"${3:activityName}\" -Status \"\\$${4:i} of \\$total - \\$progPercent% Complete:\" -PercentComplete \\$progPercent",
+      "    # Insert Code Here",
+      "    ${0}",
+      "    ",
+      "    \\$${4:i}++",
+      "}",
+      ""
+    ]
+  },
+  "ForEach-Object -Parallel": {
+    "prefix": "foreach-parallel",
+    "description": "[PS 7+] Process multiple objects in parallel using runspaces. This has some limitations compared to a regular ForEach-Object. More: Get-Help ForEach-Object",
+    "body": [
+      "${1:\\$collection} | Foreach-Object -ThrottleLimit ${2:5} -Parallel {",
+      "  ${0:${TM_SELECTED_TEXT:#Action that will run in Parallel. Reference the current object via \\$PSItem and bring in outside variables with \\$USING:varname}}",
+      "}"
+    ]
+  },
+  "function": {
+    "prefix": "function",
+    "description": "A simple function with a parameter block to specify function arguments. More: Get-Help about_Functions",
+    "body": [
+      "function ${1:FunctionName} {",
+      "\tparam (",
+      "\t\t${2:OptionalParameters}",
+      "\t)",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}"
+    ]
+  },
+  "Function Help": {
+    "prefix": ["help-function", "comment-help"],
+    "description": "Comment-based help for an advanced function. More: Get-Help about_Comment_Based_Help",
+    "body": [
+      "<#",
+      ".SYNOPSIS",
+      "\t${1:A short one-line action-based description, e.g. 'Tests if a function is valid'}",
+      ".DESCRIPTION",
+      "\t${2:A longer description of the function, its purpose, common use cases, etc.}",
+      ".NOTES",
+      "\t${3:Information or caveats about the function e.g. 'This function is not supported in Linux'}",
+      ".LINK",
+      "\t${4:Specify a URI to a help page, this will show when Get-Help -Online is used.}",
+      ".EXAMPLE",
+      "\t${5:Test-MyTestFunction -Verbose}",
+      "\t${6:Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines}",
+      "#>",
+      "",
+      "${0:$TM_SELECTED_TEXT}"
+    ]
+  },
+  "Function-Advanced": {
+    "prefix": ["function-advanced", "cmdlet"],
+    "description": "Script advanced function definition snippet. More: Get-Help about_Functions_Advanced",
+    "body": [
+      "function ${1:Verb-Noun} {",
+      "\t[CmdletBinding()]",
+      "\tparam (",
+      "\t\t$0",
+      "\t)",
+      "\t",
+      "\tbegin {",
+      "\t\t",
+      "\t}",
+      "\t",
+      "\tprocess {",
+      "\t\t$TM_SELECTED_TEXT",
+      "\t}",
+      "\t",
+      "\tend {",
+      "\t\t",
+      "\t}",
+      "}"
+    ]
+  },
+  "Function-Advanced-Doc-Full-Example-From-ISE": {
+    "prefix": ["function-advanced-doc-fromISE", "cmdlet-doc-fromISE"],
+    "description": "Script advanced function definition with full comment-based help and parameter attributes.",
+    "body": [
+      "function ${1:Verb-Noun} {",
+      "\t<#",
+      "\t.SYNOPSIS",
+      "\t${2:Short description}",
+      "\t.DESCRIPTION",
+      "\t${3:Long description}",
+      "\t.EXAMPLE",
+      "\t${4:Example of how to use this cmdlet}",
+      "\t.EXAMPLE",
+      "\t${5:Another example of how to use this cmdlet}",
+      "\t.INPUTS",
+      "\t${6:Inputs to this cmdlet (if any)}",
+      "\t.OUTPUTS",
+      "\t${7:Output from this cmdlet (if any)}",
+      "\t.NOTES",
+      "\t${8:General notes}",
+      "\t.COMPONENT",
+      "\t${9:The component this cmdlet belongs to}",
+      "\t.ROLE",
+      "\t${10:The role this cmdlet belongs to}",
+      "\t.FUNCTIONALITY",
+      "\t${11:The functionality that best describes this cmdlet}",
+      "\t#>",
+      "\t[CmdletBinding(DefaultParameterSetName = '${12:ParameterSet1}',",
+      "\t\tSupportsShouldProcess,",
+      "\t\tPositionalBinding,",
+      "\t\tHelpUri = '${13:http://yourwebsiteforhelp.here}',",
+      "\t\tConfirmImpact = 'Medium')]",
+      "\t[Alias('${14:Be-lazyWithThis}','${15:lzy}','${16:Use-OldFunctionName}')]",
+      "\t[OutputType([${17:String}])]",
+      "\tparam (",
+      "\t\t# ${18:Param1} help description",
+      "\t\t[Parameter(Mandatory,",
+      "\t\t\tValueFromPipeline,",
+      "\t\t\tValueFromPipelineByPropertyName,",
+      "\t\t\tValueFromRemainingArguments,",
+      "\t\t\tPosition = 0,",
+      "\t\t\tParameterSetName = '${12:ParameterSet1}')]",
+      "\t\t[ValidateNotNull()]",
+      "\t\t[ValidateNotNullOrEmpty()]",
+      "\t\t[ValidateCount(0, 5)]",
+      "\t\t[ValidateSet(\"${19:sun}\", \"${20:moon}\", \"${21:earth}\")]",
+      "\t\t[Alias(\"${22:p1}\")]",
+      "\t\t$${18:Param1},",
+      "",
+      "\t\t# ${24:Param2} help description",
+      "\t\t[Parameter(ParameterSetName = '${12:ParameterSet1}')]",
+      "\t\t[AllowNull()]",
+      "\t\t[AllowEmptyCollection()]",
+      "\t\t[AllowEmptyString()]",
+      "\t\t[ValidateScript({ ${25:true} })]",
+      "\t\t[ValidateRange(0, 5)]",
+      "\t\t[${26:int}]",
+      "\t\t$${24:Param2},",
+      "",
+      "\t\t# ${28:Param3} help description",
+      "\t\t[Parameter(ParameterSetName = '${29:Another Parameter Set}')]",
+      "\t\t[ValidatePattern(\"${30:[a-z]*}\")]",
+      "\t\t[ValidateLength(0, 15)]",
+      "\t\t[${31:String}]",
+      "\t\t$${28:Param3},",
+      "",
+      "\t\t# ${33:Param4} help description",
+      "\t\t# Checkout the docs https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_argument_completion?view=powershell-7.5#argumentcompletions-attribute on different ways to provide Argument Completion",
+      "\t\t[Parameter(ParameterSetName = '${34:Yet Another Parameter Set}')]",
+      "\t\t[ArgumentCompleter({'${35:add completer script}'})]",
+      "\t\t[ValidateLength(0, 15)]",
+      "\t\t[${36:String}]",
+      "\t\t$${33:Param4}",
+      "\t)",
+      "",
+      "\tbegin {",
+      "\t\t${38:#BeginCodeHere}",
+      "\t}",
+      "",
+      "\tprocess {",
+      "\t\tif (\\$pscmdlet.ShouldProcess(\"${39:Target}\", \"${40:Operation}\")) {",
+      "\t\t\t${41:#ProcessCodeHere}",
+      "\t\t}",
+      "\t}",
+      "",
+      "\tend {",
+      "\t\t${42:#EndCodeHere}",
+      "\t}",
+      "",
+      "\tclean {",
+      "\t\t${43:#CleanCodeHere} - Added in 7.3 for more information see https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_methods?view=powershell-7.5#clean",
+      "\t}",
+      "}"
+    ]
+  },
+  "Function-Inline": {
+    "prefix": "function-inline",
+    "description": "Function definition snippet that does not contain a param block, but defines parameters inline. This syntax is commonly used in other languages. More: Get-Help about_Functions",
+    "body": [
+      "function ${1:FunctionName} (${2:OptionalParameters}) {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}"
+    ]
+  },
+  "Function: Suppress PSScriptAnalyzer Rule": {
+    "prefix": ["suppress-message-rule-function", "[SuppressMessageAttribute]"],
+    "description": "Suppress a PSScriptAnalyzer rule for a function. More: https://docs.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules#suppressing-rules",
+    "body": [
+      "[Diagnostics.CodeAnalysis.SuppressMessageAttribute(",
+      "\t<#Category#>'${1:PSProvideDefaultParameterValue}', <#CheckId#>\\$null,",
+      "\tScope='Function',",
+      "\tJustification='${0:${TM_SELECTED_TEXT:Reason for suppressing}}'",
+      ")]"
+    ]
+  },
+  "Hashtable": {
+    "prefix": "hashtable",
+    "description": "A key/value store that are very efficient for finding and retrieving data. More: Get-Help about_Hash_Tables",
+    "body": ["\\$${1:Var} = @{", "\t${2:Name} = ${3:Value}", "}"]
+  },
+  "Here-String": {
+    "prefix": ["hs", "here-string"],
+    "description": "Escape all text but evaluate variables. More: Get-Help about_Quoting_Rules",
+    "body": ["@\"", "${0:TM_SELECTED_TEXT}", "\"@", ""]
+  },
+  "Here-String (Literal)": {
+    "prefix": ["hsl", "literal-here-string"],
+    "description": "Escape all text literally. More: Get-Help about_Quoting_Rules",
+    "body": ["@'", "${0:TM_SELECTED_TEXT}", "'@", ""]
+  },
+  "Hidden Property": {
+    "prefix": "class-proph-hidden",
+    "description": "Useful for creating internal properties and methods within a class that are hidden from users. More: Get-Help about_Hidden",
+    "body": ["hidden [${1:string}] $${0:PropertyName}"]
+  },
+  "IArgumentCompleter Class": {
+    "prefix": "iargument-completer",
+    "description": "Implementation of the IArgumentCompleter interface that can be directly attached to parameters (e.g. [MyCustomArgumentCompleter]). More: Get-Help about_Functions_Argument_Completion",
+    "body": [
+      "class ${1:ArgumentCompleter} : System.Management.Automation.IArgumentCompleter {",
+      "\t[System.Collections.Generic.IEnumerable[System.Management.Automation.CompletionResult]] CompleteArgument(",
+      "\t\t[string] \\$CommandName,",
+      "\t\t[string] \\$ParameterName,",
+      "\t\t[string] \\$WordToComplete,",
+      "\t\t[System.Management.Automation.Language.CommandAst] \\$CommandAst,",
+      "\t\t[System.Collections.IDictionary] \\$FakeBoundParameters",
+      "\t) {",
+      "\t\t\\$CompletionResults = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new()",
+      "\t\t",
+      "\t\t${0:$TM_SELECTED_TEXT}",
+      "\t\t",
+      "\t\treturn \\$CompletionResults",
+      "\t}",
+      "}"
+    ]
+  },
+  "if": {
+    "prefix": "if",
+    "description": "Run code blocks if a specified conditional test evaluates to true. More: Get-Help about_If",
+    "body": [
+      "if (${1:condition}) {",
+      "\t${0:${TM_SELECTED_TEXT:<# Action to perform if the condition is true #>}}",
+      "}"
+    ]
+  },
+  "IfShouldProcess": {
+    "prefix": "if-should-process",
+    "description": "Defines a condition that only executes if -WhatIf is not set, and returns a message otherwise. More: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-shouldprocess",
+    "body": [
+      "if (\\$PSCmdlet.ShouldProcess(\"${1:Target}\", \"${2:Operation}\")) {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}"
+    ]
+  },
+  "ModuleManifest": {
+    "prefix": "manifest",
+    "description": "Basic skeleton for a PowerShell module manifest, complete with PowerShell Gallery metadata. More: https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest",
+    "body": [
+      "@{",
+      "\t# If authoring a script module, the RootModule is the name of your .psm1 file",
+      "\tRootModule = '${module:MyModule}.psm1'",
+      "",
+      "\tAuthor = '${author:Cool Person <coolperson@email.local>}'",
+      "",
+      "\tCompanyName = '${company:Contoso Inc.}'",
+      "",
+      "\tModuleVersion = '${ModuleVersion:0.1}'",
+      "",
+      "\t# Use the New-Guid command to generate a GUID, and copy/paste into the next line",
+      "\tGUID = '<pasteNewGUIDhere>'",
+      "",
+      "\tCopyright = '2017 ${company:Copyright Holder}'",
+      "",
+      "\tDescription = '${Description:What does this module do?}'",
+      "",
+      "\t# Minimum PowerShell version supported by this module (optional, recommended)",
+      "\t# PowerShellVersion = ''",
+      "",
+      "\t# Which PowerShell Editions does this module work with? (Core, Desktop)",
+      "\tCompatiblePSEditions = @('Desktop', 'Core')",
+      "",
+      "\t# Which PowerShell functions are exported from your module? (eg. Get-CoolObject)",
+      "\tFunctionsToExport = @('')",
+      "",
+      "\t# Which PowerShell aliases are exported from your module? (eg. gco)",
+      "\tAliasesToExport = @('')",
+      "",
+      "\t# Which PowerShell variables are exported from your module? (eg. Fruits, Vegetables)",
+      "\tVariablesToExport = @('')",
+      "",
+      "\t# PowerShell Gallery: Define your module's metadata",
+      "\tPrivateData = @{",
+      "\t\tPSData = @{",
+      "\t\t\t# What keywords represent your PowerShell module? (eg. cloud, tools, framework, vendor)",
+      "\t\t\tTags = @('${tag1:cooltag1}', '${tag2:cooltag2}')",
+      "",
+      "\t\t\t# What software license is your code being released under? (see https://opensource.org/licenses)",
+      "\t\t\tLicenseUri = ''",
+      "",
+      "\t\t\t# What is the URL to your project's website?",
+      "\t\t\tProjectUri = ''",
+      "",
+      "\t\t\t# What is the URI to a custom icon file for your project? (optional)",
+      "\t\t\tIconUri = ''",
+      "",
+      "\t\t\t# What new features, bug fixes, or deprecated features, are part of this release?",
+      "\t\t\tReleaseNotes = @'",
+      "'@",
+      "\t\t}",
+      "\t}",
+      "",
+      "\t# If your module supports updatable help, what is the URI to the help archive? (optional)",
+      "\t# HelpInfoURI = ''",
+      "}"
+    ]
+  },
+  "Parallel Pipeline Function": {
+    "prefix": "function-parallel-pipeline",
+    "description": "Collects everything in the process block and does work in the end block. Useful when making a 'fan out' function that acts on multiple items simultaneously because the pipeline only does one item at a time in the process block. More: Get-Help about_Functions_Advanced",
+    "body": [
+      "function $1 {",
+      "  [CmdletBinding()]",
+      "  param(",
+      "    [parameter(ValueFromPipeline)]$$2",
+      "  )",
+      "",
+      "  begin {",
+      "    [Collections.ArrayList]\\$inputObjects = @()",
+      "  }",
+      "  process {",
+      "    [void]\\$inputObjects.Add($$2)",
+      "  }",
+      "  end {",
+      "    \\$inputObjects | Foreach -Parallel {",
+      "      $0",
+      "    }",
+      "  }",
+      "}"
+    ]
+  },
+  "Parameter": {
+    "prefix": "parameter",
+    "description": "A parameter definition for a method or function. More: Get-Help about_Functions",
+    "body": [
+      "# ${1:Parameter help description}",
+      "[Parameter(${2:AttributeValues})]",
+      "[${3:ParameterType}]",
+      "$${0:ParameterName}"
+    ]
+  },
+  "Parameter_Block": {
+    "prefix": "param-block-advanced-function",
+    "description": "A parameter block for an advanced function. More: Get-Help about_Functions_Advanced",
+    "body": [
+      "[CmdletBinding()]",
+      "param (",
+      "    [Parameter()]",
+      "    [${1:TypeName}]",
+      "    $${2:ParameterName}$0",
+      ")"
+    ]
+  },
+  "Parameter-LiteralPath": {
+    "prefix": "parameter-literalpath",
+    "description": "Parameter declaration snippet for a LiteralPath parameter",
+    "body": [
+      "# Specifies a path to one or more locations. Unlike the Path parameter, the value of the LiteralPath parameter is",
+      "# used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters,",
+      "# enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any",
+      "# characters as escape sequences.",
+      "[Parameter(Mandatory=\\$true,",
+      "           Position=${1:0},",
+      "           ParameterSetName=\"${2:LiteralPath}\",",
+      "           ValueFromPipelineByPropertyName=\\$true,",
+      "           HelpMessage=\"Literal path to one or more locations.\")]",
+      "[Alias(\"PSPath\")]",
+      "[ValidateNotNullOrEmpty()]",
+      "[string[]]",
+      "$${2:LiteralPath}$0"
+    ]
+  },
+  "Parameter-Path": {
+    "prefix": "parameter-path",
+    "description": "Parameter declaration snippet for Path parameter that does not accept wildcards. Do not use with parameter-literalpath.",
+    "body": [
+      "# Specifies a path to one or more locations.",
+      "[Parameter(Mandatory=\\$true,",
+      "           Position=${1:0},",
+      "           ParameterSetName=\"${2:ParameterSetName}\",",
+      "           ValueFromPipeline=\\$true,",
+      "           ValueFromPipelineByPropertyName=\\$true,",
+      "           HelpMessage=\"Path to one or more locations.\")]",
+      "[Alias(\"PSPath\")]",
+      "[ValidateNotNullOrEmpty()]",
+      "[string[]]",
+      "$${3:ParameterName}$0"
+    ]
+  },
+  "Parameter-Path-Wildcards": {
+    "prefix": "parameter-path-wildcards",
+    "description": "Parameter declaration snippet for Path parameter that accepts wildcards. Add parameter-literalpath to handle paths with embedded wildcard chars.",
+    "body": [
+      "# Specifies a path to one or more locations. Wildcards are permitted.",
+      "[Parameter(Mandatory=\\$true,",
+      "           Position=${1:Position},",
+      "           ParameterSetName=\"${2:ParameterSetName}\",",
+      "           ValueFromPipeline=\\$true,",
+      "           ValueFromPipelineByPropertyName=\\$true,",
+      "           HelpMessage=\"Path to one or more locations.\")]",
+      "[ValidateNotNullOrEmpty()]",
+      "[SupportsWildcards()]",
+      "[string[]]",
+      "$${3:ParameterName}$0"
+    ]
+  },
+  "Parameter: Suppress PSScriptAnalyzer Rule": {
+    "prefix": ["suppress-message-rule-parameter", "[SuppressMessageAttribute]"],
+    "description": "Suppress a PSScriptAnalyzer rule on a parameter. More: https://docs.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules#suppressing-rules",
+    "body": [
+      "[Diagnostics.CodeAnalysis.SuppressMessageAttribute(",
+      "\t<#Category#>'${1:PSUseDeclaredVarsMoreThanAssignments}',",
+      "\t<#ParameterName#>'${2:${TM_SELECTED_TEXT:ParamName}}',",
+      "\tJustification='${0:Reason for suppressing}'",
+      ")]"
+    ]
+  },
+  "Pipeline Function": {
+    "prefix": "function-pipeline",
+    "description": "Basic function that accepts pipeline input. More: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipelines",
+    "body": [
+      "function $1 {",
+      "  [CmdletBinding()]",
+      "  param(",
+      "    [parameter(ValueFromPipeline)]$2",
+      "  )",
+      "",
+      "  process {",
+      "    $0",
+      "  }",
+      "}"
+    ]
+  },
+  "PSCustomObject": {
+    "prefix": ["pscustomobject", "[PSCustomObject]"],
+    "description": "Create a custom object from a hashtable of properties. More: Get-Help about_PSCustomObject",
+    "body": ["[PSCustomObject]@{", "\t${1:Name} = ${2:Value}", "}"]
+  },
+  "Region Block": {
+    "prefix": "region",
+    "description": "Region block for organizing and folding of your code",
+    "body": ["#region ${1}", "${0:$TM_SELECTED_TEXT}", "#endregion"]
+  },
+  "Scope: Suppress PSScriptAnalyzer Rule": {
+    "prefix": ["suppress-message-rule-scope", "[SuppressMessageAttribute]"],
+    "description": "Suppress a PSScriptAnalyzer rule based on a function/parameter/class/variable/object's name by setting the SuppressMessageAttribute's Target property to a regular expression or a glob pattern. More: https://docs.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules#suppressing-rules",
+    "body": [
+      "[Diagnostics.CodeAnalysis.SuppressMessageAttribute(",
+      "\t<#Category#>'${1:PSUseDeclaredVarsMoreThanAssignments}', <#CheckId#>\\$null,",
+      "\tScope='${2|Function,Parameter,Class,Variable,Object|}',",
+      "\tTarget='${3:${TM_SELECTED_TEXT:RegexOrGlobPatternToMatchName}}',",
+      "\tJustification='${0:Reason for suppressing}'",
+      ")]"
+    ]
+  },
+  "splat": {
+    "prefix": "splat",
+    "description": "Use a hashtable to capture the parameters of a function and then pass them to a function in a concise way. More: Get-Help about_Splatting",
+    "body": [
+      "$${1/[^\\w]/_/}Params = @{",
+      "\t${2:Parameter} = ${0:Value}",
+      "}",
+      "${1:${TM_SELECTED_TEXT}} @${1/[^\\w]/_/}Params"
+    ]
+  },
+  "Suppress PSScriptAnalyzer Rule": {
+    "prefix": ["suppress-message-rule", "[SuppressMessageAttribute]"],
+    "description": "Suppress a PSScriptAnalyzer rule. More: https://docs.microsoft.com/en-us/powershell/utility-modules/psscriptanalyzer/overview?view=ps-modules#suppressing-rules",
+    "body": [
+      "[Diagnostics.CodeAnalysis.SuppressMessageAttribute(",
+      "\t<#Category#>'${1:PSUseDeclaredVarsMoreThanAssignments}',<#CheckId#>\\$null,",
+      "\tJustification = '${0:${TM_SELECTED_TEXT:Reason for suppressing}}'",
+      ")]"
+    ]
+  },
+  "switch": {
+    "prefix": "switch",
+    "description": "Equivalent to a series of if statements, but it is simpler. The switch statement lists each condition and an optional action. If a condition obtains, the action is performed. More: Get-Help about_Switch",
+    "body": [
+      "switch (${1:\\$x}) {",
+      "\t${2:condition} { ${0:$TM_SELECTED_TEXT} }",
+      "\tDefault {}",
+      "}"
+    ]
+  },
+  "Ternary Operator": {
+    "prefix": "ternary",
+    "description": "[PS 7+] Simplified version of if-else popular in other languages that works in Powershell. More: Get-Help about_If",
+    "body": [
+      "(${1:${TM_SELECTED_TEXT:condition}}) ? $(${2:<#Action if True#>}) : $(${0:<#Action If False#>})"
+    ]
+  },
+  "try-catch": {
+    "prefix": "try-catch",
+    "description": "Attempt a block of code and if a terminating exception occurs, perform another block of code rather than terminate the program More: Get-Help about_Try_Catch_Finally",
+    "body": [
+      "try {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}",
+      "catch {",
+      "\t${1:<#Do this if a terminating exception happens#>}",
+      "}"
+    ]
+  },
+  "try-catch-finally": {
+    "prefix": "try-catch-finally",
+    "description": "Attempt a block of code and if a terminating exception occurs, perform another block of code, finally performing a final block of code regardless of the outcome. More: Get-Help about_Try_Catch_Finally",
+    "body": [
+      "try {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}",
+      "catch {",
+      "\t${1:<#Do this if a terminating exception happens#>}",
+      "}",
+      "finally {",
+      "\t${2:<#Do this after the try block regardless of whether an exception occurred or not#>}",
+      "}"
+    ]
+  },
+  "try-finally": {
+    "prefix": "try-finally",
+    "description": "Attempt a block of code and perform an action regardless of the outcome. Useful for cleanup or gracefully disconnecting active sessions even if there was a terminating error. More: Get-Help about_Try_Catch_Finally",
+    "body": [
+      "try {",
+      "\t${0:$TM_SELECTED_TEXT}",
+      "}",
+      "finally {",
+      "\t${2:<#Do this after the try block regardless of whether an exception occurred or not#>}",
+      "}"
+    ]
+  },
+  "while": {
+    "prefix": "while",
+    "description": "Repeatedly perform an action after verifying a condition is true first. More: Get-Help about_While",
+    "body": ["while (${1:condition}) {", "\t${0:$TM_SELECTED_TEXT}", "}"]
+  }
 }
diff --git a/src/controls/animatedStatusBar.ts b/src/controls/animatedStatusBar.ts
deleted file mode 100644
index 6ee33df61f..0000000000
--- a/src/controls/animatedStatusBar.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import {
-    Disposable,
-    StatusBarAlignment,
-    StatusBarItem,
-    ThemeColor,
-    window,
-    Command} from "vscode";
-
-export function showAnimatedStatusBarMessage(text: string, hideWhenDone: Thenable<any>): Disposable {
-    const animatedStatusBarItem: AnimatedStatusBarItem = new AnimatedStatusBarItem(text);
-    animatedStatusBarItem.show(hideWhenDone);
-    return animatedStatusBarItem;
-}
-
-class AnimatedStatusBarItem implements StatusBarItem {
-    private readonly animationRate: number;
-    private statusBarItem: StatusBarItem;
-    private maxCount: number;
-    private counter: number;
-    private baseText: string;
-    private timerInterval: number;
-    private elapsedTime: number;
-    private intervalId: NodeJS.Timer;
-    private suffixStates: string[];
-
-    public get alignment(): StatusBarAlignment {
-        return this.statusBarItem.alignment;
-    }
-
-    public get priority(): number {
-        return this.statusBarItem.priority;
-    }
-
-    public get text(): string {
-        return this.statusBarItem.text;
-    }
-
-    public set text(value: string) {
-        this.statusBarItem.text = value;
-    }
-
-    public get tooltip(): string {
-        return this.statusBarItem.tooltip;
-    }
-
-    public set tooltip(value: string) {
-        this.statusBarItem.tooltip = value;
-    }
-
-    public get color(): string | ThemeColor {
-        return this.statusBarItem.color;
-    }
-
-    public set color(value: string | ThemeColor) {
-        this.statusBarItem.color = value;
-    }
-
-    public get backgroundColor(): string | ThemeColor {
-        return this.statusBarItem.backgroundColor;
-    }
-
-    public set backgroundColor(value: string | ThemeColor) {
-        this.statusBarItem.backgroundColor = value;
-    }
-
-    public get command(): string | Command {
-        return this.statusBarItem.command;
-    }
-
-    public set command(value: string | Command) {
-        this.statusBarItem.command = value;
-    }
-
-    constructor(baseText: string, alignment?: StatusBarAlignment, priority?: number) {
-        this.animationRate = 1;
-        this.statusBarItem = window.createStatusBarItem(alignment, priority);
-        this.baseText = baseText;
-        this.counter = 0;
-        this.suffixStates = ["  ", ".  ", ".. ", "..."];
-        this.maxCount = this.suffixStates.length;
-        this.timerInterval = ((1 / this.maxCount) * 1000) / this.animationRate;
-        this.elapsedTime = 0;
-    }
-
-    public show(hideWhenDone?: Thenable<any>): void {
-        this.statusBarItem.show();
-        this.start();
-        if (hideWhenDone !== undefined) {
-            hideWhenDone.then(() => this.hide());
-        }
-    }
-
-    public hide(): void {
-        this.stop();
-        this.statusBarItem.hide();
-    }
-
-    public dispose(): void {
-        this.statusBarItem.dispose();
-    }
-
-    private updateCounter(): void {
-        this.counter = (this.counter + 1) % this.maxCount;
-        this.elapsedTime = this.elapsedTime + this.timerInterval;
-    }
-
-    private updateText(): void {
-        this.text = this.baseText + this.suffixStates[this.counter];
-    }
-
-    private update(): void {
-        this.updateCounter();
-        this.updateText();
-    }
-
-    private reset(): void {
-        this.counter = 0;
-        this.updateText();
-    }
-
-    private  start(): void {
-        this.reset();
-        this.intervalId = setInterval(() => this.update(), this.timerInterval);
-    }
-
-    private stop(): void {
-        clearInterval(this.intervalId);
-    }
-}
diff --git a/src/controls/checkboxQuickPick.ts b/src/controls/checkboxQuickPick.ts
index 0a462671c1..2c8bf72c07 100644
--- a/src/controls/checkboxQuickPick.ts
+++ b/src/controls/checkboxQuickPick.ts
@@ -3,10 +3,11 @@
 
 import vscode = require("vscode");
 
-const confirmItemLabel: string = "$(checklist) Confirm";
-const checkedPrefix: string = "[ $(check) ]";
-const uncheckedPrefix: string = "[     ]";
-const defaultPlaceHolder: string = "Select 'Confirm' to confirm or press 'Esc' key to cancel";
+const confirmItemLabel = "$(checklist) Confirm";
+const checkedPrefix = "[ $(check) ]";
+const uncheckedPrefix = "[     ]";
+const defaultPlaceHolder =
+    "Select 'Confirm' to confirm or press 'Esc' key to cancel";
 
 export interface ICheckboxQuickPickItem {
     label: string;
@@ -18,73 +19,72 @@ export interface ICheckboxQuickPickOptions {
     confirmPlaceHolder: string;
 }
 
-const defaultOptions: ICheckboxQuickPickOptions = { confirmPlaceHolder: defaultPlaceHolder};
+const defaultOptions: ICheckboxQuickPickOptions = {
+    confirmPlaceHolder: defaultPlaceHolder,
+};
 
-export function showCheckboxQuickPick(
+export async function showCheckboxQuickPick(
     items: ICheckboxQuickPickItem[],
-    options: ICheckboxQuickPickOptions = defaultOptions): Thenable<ICheckboxQuickPickItem[]> {
-
-    return showInner(items, options).then(
-        (selectedItem) => {
-            // We're mutating the original item list so just return it for now.
-            // If 'selectedItem' is undefined it means the user cancelled the
-            // inner showQuickPick UI so pass the undefined along.
-            return selectedItem !== undefined ? items : undefined;
-        });
+    options: ICheckboxQuickPickOptions = defaultOptions,
+): Promise<ICheckboxQuickPickItem[] | undefined> {
+    const selectedItem = await showInner(items, options);
+    return selectedItem !== undefined ? items : undefined;
 }
 
-function getQuickPickItems(items: ICheckboxQuickPickItem[]): vscode.QuickPickItem[] {
-
+function getQuickPickItems(
+    items: ICheckboxQuickPickItem[],
+): vscode.QuickPickItem[] {
     const quickPickItems: vscode.QuickPickItem[] = [];
     quickPickItems.push({ label: confirmItemLabel, description: "" });
 
-    items.forEach((item) =>
+    for (const item of items) {
         quickPickItems.push({
-                label: convertToCheckBox(item),
-                description: item.description,
-        }));
+            label: convertToCheckBox(item),
+            description: item.description,
+        });
+    }
 
     return quickPickItems;
 }
 
-function showInner(
+async function showInner(
     items: ICheckboxQuickPickItem[],
-    options: ICheckboxQuickPickOptions): Thenable<vscode.QuickPickItem> {
-
-    const quickPickThenable: Thenable<vscode.QuickPickItem> =
-        vscode.window.showQuickPick(
-            getQuickPickItems(items),
-            {
-                ignoreFocusOut: true,
-                matchOnDescription: true,
-                placeHolder: options.confirmPlaceHolder,
-            });
-
-    return quickPickThenable.then(
-        (selection) => {
-            if (!selection) {
-                return Promise.resolve<vscode.QuickPickItem>(undefined);
-            }
-
-            if (selection.label === confirmItemLabel) {
-                return selection;
-            }
-
-            const index: number = getItemIndex(items, selection.label);
-
-            if (index >= 0) {
-                toggleSelection(items[index]);
-            } else {
-                // tslint:disable-next-line:no-console
-                console.log(`Couldn't find CheckboxQuickPickItem for label '${selection.label}'`);
-            }
-
-            return showInner(items, options);
-        });
+    options: ICheckboxQuickPickOptions,
+): Promise<vscode.QuickPickItem | undefined> {
+    const selection = await vscode.window.showQuickPick(
+        getQuickPickItems(items),
+        {
+            ignoreFocusOut: true,
+            matchOnDescription: true,
+            placeHolder: options.confirmPlaceHolder,
+        },
+    );
+
+    if (selection === undefined) {
+        return undefined;
+    }
+
+    if (selection.label === confirmItemLabel) {
+        return selection;
+    }
+
+    const index: number = getItemIndex(items, selection.label);
+    if (index >= 0) {
+        toggleSelection(items[index]);
+    } else {
+        console.log(
+            `Couldn't find CheckboxQuickPickItem for label '${selection.label}'`,
+        );
+    }
+
+    return showInner(items, options);
 }
 
-function getItemIndex(items: ICheckboxQuickPickItem[], itemLabel: string): number {
-    const trimmedLabel = itemLabel.substr(itemLabel.indexOf("]") + 2);
+function getItemIndex(
+    items: ICheckboxQuickPickItem[],
+    itemLabel: string,
+): number {
+    const trimmedLabel = itemLabel.substring(itemLabel.indexOf("]") + 2);
     return items.findIndex((item) => item.label === trimmedLabel);
 }
 
diff --git a/src/debugAdapter.ts b/src/debugAdapter.ts
deleted file mode 100644
index 260d42ddfd..0000000000
--- a/src/debugAdapter.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import { connect, Socket } from "net";
-import { DebugAdapter, Event, DebugProtocolMessage, EventEmitter } from "vscode";
-import { Logger } from "./logging";
-
-export class NamedPipeDebugAdapter implements DebugAdapter {
-    private static readonly TWO_CRLF = '\r\n\r\n';
-    private static readonly HEADER_LINESEPARATOR = /\r?\n/;    // allow for non-RFC 2822 conforming line separators
-    private static readonly HEADER_FIELDSEPARATOR = /: */;
-
-    private readonly _logger: Logger;
-    private readonly _namedPipe: string;
-
-    private _rawData = Buffer.allocUnsafe(0);
-    private _contentLength = -1;
-    private _isConnected: boolean = false;
-    private _debugMessageQueue: DebugProtocolMessage[] = [];
-
-    private _debugServiceSocket: Socket;
-
-    // The event that VS Code-proper will listen for.
-    private _sendMessage: EventEmitter<DebugProtocolMessage> = new EventEmitter<DebugProtocolMessage>();
-    onDidSendMessage: Event<DebugProtocolMessage> = this._sendMessage.event;
-
-    constructor(namedPipe: string, logger: Logger) {
-        this._namedPipe = namedPipe;
-        this._logger = logger;
-    }
-
-    public start(): void {
-        this._debugServiceSocket = connect(this._namedPipe);
-
-        this._debugServiceSocket.on("error", (e) => {
-            this._logger.writeError("Error on Debug Adapter: " + e);
-            this.dispose();
-        });
-
-        // Route any output from the socket through to VS Code.
-        this._debugServiceSocket.on("data", (data: Buffer) => this.handleData(data));
-
-        // Wait for the connection to complete.
-        this._debugServiceSocket.on("connect", () => {
-            while(this._debugMessageQueue.length) {
-                this.writeMessageToDebugAdapter(this._debugMessageQueue.shift());
-            }
-
-            this._isConnected = true;
-            this._logger.writeVerbose("Connected to socket!");
-        });
-
-        // When the socket closes, end the session.
-        this._debugServiceSocket.on("close", () => { this.dispose(); });
-        this._debugServiceSocket.on("end", () => { this.dispose(); });
-    }
-
-    public handleMessage(message: DebugProtocolMessage): void {
-        if (!this._isConnected) {
-            this._debugMessageQueue.push(message);
-            return;
-        }
-
-        this.writeMessageToDebugAdapter(message);
-    }
-
-    public dispose() {
-        this._debugServiceSocket.destroy();
-        this._sendMessage.fire({ type: 'event', event: 'terminated' });
-        this._sendMessage.dispose();
-    }
-
-    private writeMessageToDebugAdapter(message: DebugProtocolMessage): void {
-        const msg = JSON.stringify(message);
-        const messageWrapped = `Content-Length: ${Buffer.byteLength(msg, "utf8")}${NamedPipeDebugAdapter.TWO_CRLF}${msg}`;
-        this._logger.writeDiagnostic(`SENDING TO DEBUG ADAPTER: ${messageWrapped}`);
-        this._debugServiceSocket.write(messageWrapped, "utf8");
-    }
-
-    // Shamelessly stolen from VS Code's implementation with slight modification by using public types and our logger:
-    // https://github.com/microsoft/vscode/blob/ff1b513fbca1acad4467dfd768997e9e0b9c5735/src/vs/workbench/contrib/debug/node/debugAdapter.ts#L55-L92
-    private handleData(data: Buffer): void {
-        this._rawData = Buffer.concat([this._rawData, data]);
-
-        while (true) {
-            if (this._contentLength >= 0) {
-                if (this._rawData.length >= this._contentLength) {
-                    const message = this._rawData.toString('utf8', 0, this._contentLength);
-                    this._rawData = this._rawData.slice(this._contentLength);
-                    this._contentLength = -1;
-                    if (message.length > 0) {
-                        try {
-                            this._logger.writeDiagnostic(`RECEIVED FROM DEBUG ADAPTER: ${message}`);
-                            this._sendMessage.fire(JSON.parse(message) as DebugProtocolMessage);
-                        } catch (e) {
-                             this._logger.writeError("Error firing event in VS Code: ", (e.message || e), message);
-                        }
-                    }
-                    continue; // there may be more complete messages to process
-                }
-            } else {
-                const idx = this._rawData.indexOf(NamedPipeDebugAdapter.TWO_CRLF);
-                if (idx !== -1) {
-                    const header = this._rawData.toString('utf8', 0, idx);
-                    const lines = header.split(NamedPipeDebugAdapter.HEADER_LINESEPARATOR);
-                    for (const h of lines) {
-                        const kvPair = h.split(NamedPipeDebugAdapter.HEADER_FIELDSEPARATOR);
-                        if (kvPair[0] === 'Content-Length') {
-                            this._contentLength = Number(kvPair[1]);
-                        }
-                    }
-                    this._rawData = this._rawData.slice(idx + NamedPipeDebugAdapter.TWO_CRLF.length);
-                    continue;
-                }
-            }
-            break;
-        }
-    }
-}
diff --git a/src/extension.ts b/src/extension.ts
new file mode 100644
index 0000000000..d89708440f
--- /dev/null
+++ b/src/extension.ts
@@ -0,0 +1,298 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import vscode = require("vscode");
+import TelemetryReporter from "@vscode/extension-telemetry";
+import { DocumentSelector } from "vscode-languageclient";
+import { CodeActionsFeature } from "./features/CodeActions";
+import { ConsoleFeature } from "./features/Console";
+import {
+    DebugSessionFeature,
+    SpecifyScriptArgsFeature,
+} from "./features/DebugSession";
+import { ExamplesFeature } from "./features/Examples";
+import { ExpandAliasFeature } from "./features/ExpandAlias";
+import { ExtensionCommandsFeature } from "./features/ExtensionCommands";
+import {
+    ExternalApiFeature,
+    type IPowerShellExtensionClient,
+} from "./features/ExternalApi";
+import { GenerateBugReportFeature } from "./features/GenerateBugReport";
+import { GetCommandsFeature } from "./features/GetCommands";
+import { HelpCompletionFeature } from "./features/HelpCompletion";
+import { ISECompatibilityFeature } from "./features/ISECompatibility";
+import { OpenInISEFeature } from "./features/OpenInISE";
+import { PesterTestsFeature } from "./features/PesterTests";
+import { RemoteFilesFeature } from "./features/RemoteFiles";
+import { ShowHelpFeature } from "./features/ShowHelp";
+import { LanguageClientConsumer } from "./languageClientConsumer";
+import { Logger } from "./logging";
+import { SessionManager } from "./session";
+import { getSettings } from "./settings";
+import { PowerShellLanguageId, sleep } from "./utils";
+// The 1DS telemetry key, which is just shared among all Microsoft extensions
+// (and isn't sensitive).
+const TELEMETRY_KEY =
+    "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255";
+
+let languageConfigurationDisposable: vscode.Disposable;
+let logger: Logger;
+let sessionManager: SessionManager;
+let languageClientConsumers: LanguageClientConsumer[] = [];
+let commandRegistrations: vscode.Disposable[] = [];
+let telemetryReporter: TelemetryReporter;
+
+const documentSelector: DocumentSelector = [
+    { language: "powershell", scheme: "file" },
+    { language: "powershell", scheme: "untitled" },
+];
+
+export async function activate(
+    context: vscode.ExtensionContext,
+): Promise<IPowerShellExtensionClient> {
+    logger = new Logger();
+    if (context.extensionMode === vscode.ExtensionMode.Development) {
+        restartOnExtensionFileChanges(context);
+    }
+
+    telemetryReporter = new TelemetryReporter(TELEMETRY_KEY);
+
+    const settings = getSettings();
+    logger.writeDebug(
+        `Loaded settings:\n${JSON.stringify(settings, undefined, 2)}`,
+    );
+
+    languageConfigurationDisposable = vscode.languages.setLanguageConfiguration(
+        PowerShellLanguageId,
+        {
+            // TODO: Remove the useless escapes
+            wordPattern:
+                // eslint-disable-next-line no-useless-escape
+                /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\'\"\,\.\<\>\/\?\s]+)/g,
+
+            indentationRules: {
+                // ^(.*\*/)?\s*\}.*$
+                decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/,
+                // ^.*\{[^}"']*$
+                increaseIndentPattern: /^.*\{[^}"']*$/,
+            },
+
+            comments: {
+                lineComment: "#",
+                blockComment: ["<#", "#>"],
+            },
+
+            brackets: [
+                ["{", "}"],
+                ["[", "]"],
+                ["(", ")"],
+            ],
+
+            onEnterRules: [
+                {
+                    // e.g. /** | */
+                    // eslint-disable-next-line no-useless-escape
+                    beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
+                    afterText: /^\s*\*\/$/,
+                    action: {
+                        indentAction: vscode.IndentAction.IndentOutdent,
+                        appendText: " * ",
+                    },
+                },
+                {
+                    // e.g. /** ...|
+                    // eslint-disable-next-line no-useless-escape
+                    beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
+                    action: {
+                        indentAction: vscode.IndentAction.None,
+                        appendText: " * ",
+                    },
+                },
+                {
+                    // e.g.  * ...|
+                    // eslint-disable-next-line no-useless-escape
+                    beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
+                    action: {
+                        indentAction: vscode.IndentAction.None,
+                        appendText: "* ",
+                    },
+                },
+                {
+                    // e.g.  */|
+                    // eslint-disable-next-line no-useless-escape
+                    beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
+                    action: {
+                        indentAction: vscode.IndentAction.None,
+                        removeText: 1,
+                    },
+                },
+                {
+                    // e.g.  *-----*/|
+                    // eslint-disable-next-line no-useless-escape
+                    beforeText: /^(\t|(\ \ ))*\ \*[^/]*\*\/\s*$/,
+                    action: {
+                        indentAction: vscode.IndentAction.None,
+                        removeText: 1,
+                    },
+                },
+            ],
+        },
+    );
+
+    interface IPackageInfo {
+        name: string;
+        displayName: string;
+        version: string;
+        publisher: string;
+    }
+    const packageInfo: IPackageInfo = context.extension.packageJSON;
+
+    sessionManager = new SessionManager(
+        context,
+        settings,
+        logger,
+        documentSelector,
+        packageInfo.name,
+        packageInfo.displayName,
+        packageInfo.version,
+        packageInfo.publisher,
+        telemetryReporter,
+    );
+
+    // Register commands that do not require Language client
+    commandRegistrations = [
+        new ExamplesFeature(),
+        new GenerateBugReportFeature(sessionManager),
+        new ISECompatibilityFeature(),
+        new OpenInISEFeature(),
+        new PesterTestsFeature(sessionManager, logger),
+        new CodeActionsFeature(logger),
+        new SpecifyScriptArgsFeature(context),
+
+        vscode.commands.registerCommand(
+            "PowerShell.OpenLogFolder",
+            async () => {
+                await vscode.commands.executeCommand(
+                    "vscode.openFolder",
+                    context.logUri,
+                    { forceNewWindow: true },
+                );
+            },
+        ),
+        vscode.commands.registerCommand("PowerShell.ShowLogs", () => {
+            logger.showLogPanel();
+        }),
+        vscode.commands.registerCommand(
+            "GetVsCodeSessionId",
+            () => vscode.env.sessionId,
+        ),
+        // Register a command that waits for the Extension Terminal to be active. Can be used by .NET Attach Tasks.
+        registerWaitForPsesActivationCommand(context),
+    ];
+
+    const externalApi = new ExternalApiFeature(context, sessionManager, logger);
+
+    // Features and command registrations that require language client
+    languageClientConsumers = [
+        new ConsoleFeature(logger),
+        new ExpandAliasFeature(),
+        new GetCommandsFeature(),
+        new ShowHelpFeature(),
+        new ExtensionCommandsFeature(logger),
+        new RemoteFilesFeature(),
+        new DebugSessionFeature(context, sessionManager, logger),
+        new HelpCompletionFeature(),
+    ];
+
+    sessionManager.setLanguageClientConsumers(languageClientConsumers);
+
+    if (settings.startAutomatically) {
+        await sessionManager.start();
+    }
+
+    return {
+        registerExternalExtension: (id: string, apiVersion = "v1") =>
+            externalApi.registerExternalExtension(id, apiVersion),
+        unregisterExternalExtension: (uuid) =>
+            externalApi.unregisterExternalExtension(uuid),
+        getPowerShellVersionDetails: (uuid) =>
+            externalApi.getPowerShellVersionDetails(uuid),
+        waitUntilStarted: (uuid) => externalApi.waitUntilStarted(uuid),
+        getStorageUri: () => externalApi.getStorageUri(),
+        getLogUri: () => externalApi.getLogUri(),
+    };
+}
+
+/** Registers a command that waits for PSES Activation and returns the PID, used to auto-attach the PSES debugger */
+function registerWaitForPsesActivationCommand(
+    context: vscode.ExtensionContext,
+): vscode.Disposable {
+    return vscode.commands.registerCommand(
+        "PowerShell.WaitForPsesActivationAndReturnProcessId",
+        async () => {
+            const pidFileName = `PSES-${vscode.env.sessionId}.pid`;
+            const pidFile = vscode.Uri.joinPath(
+                context.globalStorageUri,
+                "sessions",
+                pidFileName,
+            );
+            const fs = vscode.workspace.fs;
+            // Wait for the file to be created
+            // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+            while (true) {
+                try {
+                    const pidContent = await fs.readFile(pidFile);
+                    const pid = parseInt(pidContent.toString(), 10);
+                    try {
+                        // Check if the process is still alive, delete the PID file if not and continue waiting.
+                        // https://nodejs.org/api/process.html#process_process_kill_pid_signal
+                        // "As a special case, a signal of 0 can be used to test for the existence of a process. "
+                        const NODE_TEST_PROCESS_EXISTENCE = 0;
+                        process.kill(pid, NODE_TEST_PROCESS_EXISTENCE);
+                    } catch {
+                        await fs.delete(pidFile);
+                        continue;
+                    }
+                    // VSCode command returns for launch configurations *must* be string type explicitly, will error on number or otherwise.
+                    return pidContent.toString();
+                } catch {
+                    // File doesn't exist yet, wait and try again
+                    await sleep(200);
+                }
+            }
+        },
+    );
+}
+
+/** Restarts the extension host when extension file changes are detected. Useful for development. */
+function restartOnExtensionFileChanges(context: vscode.ExtensionContext): void {
+    const watcher = vscode.workspace.createFileSystemWatcher(
+        new vscode.RelativePattern(context.extensionPath, "dist/*.js"),
+    );
+
+    context.subscriptions.push(watcher);
+    watcher.onDidChange(({ fsPath }) => {
+        vscode.window.showInformationMessage(
+            `${fsPath.split(context.extensionPath, 2)[1]} changed. Reloading Extension Host...`,
+        );
+        vscode.commands.executeCommand("workbench.action.restartExtensionHost");
+    });
+}
+
+export async function deactivate(): Promise<void> {
+    // Clean up all extension features
+    for (const commandRegistration of commandRegistrations) {
+        commandRegistration.dispose();
+    }
+
+    // Dispose of the current session
+    await sessionManager.dispose();
+
+    // Dispose of the logger
+    logger.dispose();
+
+    // Dispose of telemetry reporter
+    await telemetryReporter.dispose();
+
+    languageConfigurationDisposable.dispose();
+}
diff --git a/src/features/CodeActions.ts b/src/features/CodeActions.ts
index c1cc7646e1..825b7941a9 100644
--- a/src/features/CodeActions.ts
+++ b/src/features/CodeActions.ts
@@ -2,49 +2,47 @@
 // Licensed under the MIT License.
 
 import vscode = require("vscode");
-import Window = vscode.window;
-import { ILogger } from "../logging";
+import type { ILogger } from "../logging";
 
 export class CodeActionsFeature implements vscode.Disposable {
-    private applyEditsCommand: vscode.Disposable;
-    private showDocumentationCommand: vscode.Disposable;
+    private command: vscode.Disposable;
 
     constructor(private log: ILogger) {
-        this.applyEditsCommand = vscode.commands.registerCommand("PowerShell.ApplyCodeActionEdits", (edit: any) => {
-            Window.activeTextEditor.edit((editBuilder) => {
-                editBuilder.replace(
-                    new vscode.Range(
-                        edit.StartLineNumber - 1,
-                        edit.StartColumnNumber - 1,
-                        edit.EndLineNumber - 1,
-                        edit.EndColumnNumber - 1),
-                    edit.Text);
-            });
-        });
-
-        this.showDocumentationCommand =
-            vscode.commands.registerCommand("PowerShell.ShowCodeActionDocumentation", (ruleName: any) => {
-                this.showRuleDocumentation(ruleName);
-            });
+        // NOTE: While not exposed to the user via package.json, this is
+        // required as the server's code action sends across a command name.
+        //
+        // TODO: In the far future with LSP 3.19 the server can just set a URL
+        // and this can go away. See https://github.com/microsoft/language-server-protocol/issues/1548
+        this.command = vscode.commands.registerCommand(
+            "PowerShell.ShowCodeActionDocumentation",
+            async (ruleName: string) => {
+                await this.showRuleDocumentation(ruleName);
+            },
+        );
     }
 
-    public dispose() {
-        this.applyEditsCommand.dispose();
-        this.showDocumentationCommand.dispose();
+    public dispose(): void {
+        this.command.dispose();
     }
 
-    public showRuleDocumentation(ruleId: string) {
-        const pssaDocBaseURL = "https://docs.microsoft.com/powershell/utility-modules/psscriptanalyzer/rules/";
+    private async showRuleDocumentation(ruleId: string): Promise<void> {
+        const pssaDocBaseURL =
+            "https://docs.microsoft.com/powershell/utility-modules/psscriptanalyzer/rules/";
 
         if (!ruleId) {
-            this.log.writeWarning("Cannot show documentation for code action, no ruleName was supplied.");
+            this.log.writeWarning(
+                "Cannot show documentation for code action, no ruleName was supplied.",
+            );
             return;
         }
 
         if (ruleId.startsWith("PS")) {
-            ruleId = ruleId.substr(2);
+            ruleId = ruleId.substring(2);
         }
 
-        vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(pssaDocBaseURL + `${ruleId}`));
+        await vscode.commands.executeCommand(
+            "vscode.open",
+            vscode.Uri.parse(pssaDocBaseURL + ruleId),
+        );
     }
 }
diff --git a/src/features/Console.ts b/src/features/Console.ts
index 63d003c601..f7038f5ec1 100644
--- a/src/features/Console.ts
+++ b/src/features/Console.ts
@@ -4,23 +4,33 @@
 import vscode = require("vscode");
 import { NotificationType, RequestType } from "vscode-languageclient";
 import { LanguageClient } from "vscode-languageclient/node";
-import { ICheckboxQuickPickItem, showCheckboxQuickPick } from "../controls/checkboxQuickPick";
-import { Logger } from "../logging";
-import Settings = require("../settings");
+import {
+    type ICheckboxQuickPickItem,
+    showCheckboxQuickPick,
+} from "../controls/checkboxQuickPick";
 import { LanguageClientConsumer } from "../languageClientConsumer";
-
-export const EvaluateRequestType = new RequestType<IEvaluateRequestArguments, void, void>("evaluate");
-export const OutputNotificationType = new NotificationType<IOutputNotificationBody>("output");
-export const ExecutionStatusChangedNotificationType =
-    new NotificationType<IExecutionStatusDetails>("powerShell/executionStatusChanged");
-
-export const ShowChoicePromptRequestType =
-    new RequestType<IShowChoicePromptRequestArgs,
-                    IShowChoicePromptResponseBody, string>("powerShell/showChoicePrompt");
-
-export const ShowInputPromptRequestType =
-    new RequestType<IShowInputPromptRequestArgs,
-                    IShowInputPromptResponseBody, string>("powerShell/showInputPrompt");
+import type { ILogger } from "../logging";
+import { getSettings } from "../settings";
+
+export const EvaluateRequestType = new RequestType<
+    IEvaluateRequestArguments,
+    void,
+    void
+>("evaluate");
+export const OutputNotificationType =
+    new NotificationType<IOutputNotificationBody>("output");
+
+export const ShowChoicePromptRequestType = new RequestType<
+    IShowChoicePromptRequestArgs,
+    IShowChoicePromptResponseBody,
+    string
+>("powerShell/showChoicePrompt");
+
+export const ShowInputPromptRequestType = new RequestType<
+    IShowInputPromptRequestArgs,
+    IShowInputPromptResponseBody,
+    string
+>("powerShell/showInputPrompt");
 
 export interface IEvaluateRequestArguments {
     expression: string;
@@ -31,12 +41,6 @@ export interface IOutputNotificationBody {
     output: string;
 }
 
-interface IExecutionStatusDetails {
-    executionOptions: IExecutionOptions;
-    executionStatus: ExecutionStatus;
-    hadErrors: boolean;
-}
-
 interface IChoiceDetails {
     label: string;
     helpMessage: string;
@@ -56,52 +60,38 @@ interface IShowChoicePromptRequestArgs {
 }
 
 interface IShowChoicePromptResponseBody {
-    responseText: string;
+    responseText: string | undefined;
     promptCancelled: boolean;
 }
 
 interface IShowInputPromptResponseBody {
-    responseText: string;
+    responseText: string | undefined;
     promptCancelled: boolean;
 }
 
-enum ExecutionStatus {
-    Pending,
-    Running,
-    Failed,
-    Aborted,
-    Completed,
-}
-
-interface IExecutionOptions {
-    writeOutputToHost: boolean;
-    writeErrorsToHost: boolean;
-    addToHistory: boolean;
-    interruptCommandPrompt: boolean;
-}
-
 function showChoicePrompt(
     promptDetails: IShowChoicePromptRequestArgs,
-    client: LanguageClient): Thenable<IShowChoicePromptResponseBody> {
-
+): Thenable<IShowChoicePromptResponseBody> {
     let resultThenable: Thenable<IShowChoicePromptResponseBody>;
 
     if (!promptDetails.isMultiChoice) {
-        let quickPickItems =
-            promptDetails.choices.map<vscode.QuickPickItem>((choice) => {
+        let quickPickItems = promptDetails.choices.map<vscode.QuickPickItem>(
+            (choice) => {
                 return {
                     label: choice.label,
                     description: choice.helpMessage,
                 };
-            });
+            },
+        );
 
-        if (promptDetails.defaultChoices && promptDetails.defaultChoices.length > 0) {
+        if (promptDetails.defaultChoices.length > 0) {
             // Shift the default items to the front of the
             // array so that the user can select it easily
             const defaultChoice = promptDetails.defaultChoices[0];
-            if (defaultChoice > -1 &&
-                defaultChoice < promptDetails.choices.length) {
-
+            if (
+                defaultChoice > -1 &&
+                defaultChoice < promptDetails.choices.length
+            ) {
                 const defaultChoiceItem = quickPickItems[defaultChoice];
                 quickPickItems.splice(defaultChoice, 1);
 
@@ -110,12 +100,11 @@ function showChoicePrompt(
             }
         }
 
-        resultThenable =
-            vscode.window
-                .showQuickPick(
-                    quickPickItems,
-                    { placeHolder: promptDetails.message })
-                .then(onItemSelected);
+        resultThenable = vscode.window
+            .showQuickPick(quickPickItems, {
+                placeHolder: promptDetails.message,
+            })
+            .then(onItemSelected);
     } else {
         const checkboxQuickPickItems =
             promptDetails.choices.map<ICheckboxQuickPickItem>((choice) => {
@@ -127,37 +116,37 @@ function showChoicePrompt(
             });
 
         // Select the defaults
-        promptDetails.defaultChoices.forEach((choiceIndex) => {
-            checkboxQuickPickItems[choiceIndex].isSelected = true;
-        });
-
-        resultThenable =
-            showCheckboxQuickPick(
-                    checkboxQuickPickItems,
-                    { confirmPlaceHolder: promptDetails.message })
-                .then(onItemsSelected);
+        for (const choice of promptDetails.defaultChoices) {
+            checkboxQuickPickItems[choice].isSelected = true;
+        }
+
+        resultThenable = showCheckboxQuickPick(checkboxQuickPickItems, {
+            confirmPlaceHolder: promptDetails.message,
+        }).then(onItemsSelected);
     }
 
     return resultThenable;
 }
 
-function showInputPrompt(
+async function showInputPrompt(
     promptDetails: IShowInputPromptRequestArgs,
-    client: LanguageClient): Thenable<IShowInputPromptResponseBody> {
-
-    const resultThenable =
-        vscode.window.showInputBox({
-            placeHolder: promptDetails.name + ": ",
-        }).then(onInputEntered);
-
-    return resultThenable;
+): Promise<IShowInputPromptResponseBody> {
+    const responseText = await vscode.window.showInputBox({
+        placeHolder: promptDetails.name + ": ",
+    });
+    return onInputEntered(responseText);
 }
 
-function onItemsSelected(chosenItems: ICheckboxQuickPickItem[]): IShowChoicePromptResponseBody {
+function onItemsSelected(
+    chosenItems: ICheckboxQuickPickItem[] | undefined,
+): IShowChoicePromptResponseBody {
     if (chosenItems !== undefined) {
         return {
             promptCancelled: false,
-            responseText: chosenItems.filter((item) => item.isSelected).map((item) => item.label).join(", "),
+            responseText: chosenItems
+                .filter((item) => item.isSelected)
+                .map((item) => item.label)
+                .join(", "),
         };
     } else {
         // User cancelled the prompt, send the cancellation
@@ -168,7 +157,9 @@ function onItemsSelected(chosenItems: ICheckboxQuickPickItem[]): IShowChoiceProm
     }
 }
 
-function onItemSelected(chosenItem: vscode.QuickPickItem): IShowChoicePromptResponseBody {
+function onItemSelected(
+    chosenItem: vscode.QuickPickItem | undefined,
+): IShowChoicePromptResponseBody {
     if (chosenItem !== undefined) {
         return {
             promptCancelled: false,
@@ -183,7 +174,9 @@ function onItemSelected(chosenItem: vscode.QuickPickItem): IShowChoicePromptResp
     }
 }
 
-function onInputEntered(responseText: string): IShowInputPromptResponseBody {
+function onInputEntered(
+    responseText: string | undefined,
+): IShowInputPromptResponseBody {
     if (responseText !== undefined) {
         return {
             promptCancelled: false,
@@ -199,104 +192,98 @@ function onInputEntered(responseText: string): IShowInputPromptResponseBody {
 
 export class ConsoleFeature extends LanguageClientConsumer {
     private commands: vscode.Disposable[];
-    private resolveStatusBarPromise: (value?: {} | PromiseLike<{}>) => void;
+    private handlers: vscode.Disposable[] = [];
 
-    constructor(private log: Logger) {
+    constructor(private logger: ILogger) {
         super();
         this.commands = [
-            vscode.commands.registerCommand("PowerShell.RunSelection", async () => {
-
-                if (vscode.window.activeTerminal &&
-                    vscode.window.activeTerminal.name !== "PowerShell Integrated Console") {
-                    this.log.write("PSIC is not active terminal. Running in active terminal using 'runSelectedText'");
-                    await vscode.commands.executeCommand("workbench.action.terminal.runSelectedText");
-
-                    // We need to honor the focusConsoleOnExecute setting here too. However, the boolean that `show`
-                    // takes is called `preserveFocus` which when `true` the terminal will not take focus.
-                    // This is the inverse of focusConsoleOnExecute so we have to inverse the boolean.
-                    vscode.window.activeTerminal.show(!Settings.load().integratedConsole.focusConsoleOnExecute);
-                    await vscode.commands.executeCommand("workbench.action.terminal.scrollToBottom");
-
-                    return;
-                }
-
-                const editor = vscode.window.activeTextEditor;
-                let selectionRange: vscode.Range;
-
-                if (!editor.selection.isEmpty) {
-                    selectionRange =
-                        new vscode.Range(
+            vscode.commands.registerCommand(
+                "PowerShell.RunSelection",
+                async () => {
+                    if (
+                        vscode.window.activeTerminal &&
+                        vscode.window.activeTerminal.name !==
+                            "PowerShell Extension"
+                    ) {
+                        this.logger.write(
+                            "PowerShell Extension Terminal is not active! Running in current terminal using 'runSelectedText'.",
+                        );
+                        await vscode.commands.executeCommand(
+                            "workbench.action.terminal.runSelectedText",
+                        );
+
+                        // We need to honor the focusConsoleOnExecute setting here too. However, the boolean that `show`
+                        // takes is called `preserveFocus` which when `true` the terminal will not take focus.
+                        // This is the inverse of focusConsoleOnExecute so we have to inverse the boolean.
+                        vscode.window.activeTerminal.show(
+                            !getSettings().integratedConsole
+                                .focusConsoleOnExecute,
+                        );
+                        await vscode.commands.executeCommand(
+                            "workbench.action.terminal.scrollToBottom",
+                        );
+
+                        return;
+                    }
+
+                    const editor = vscode.window.activeTextEditor;
+                    if (editor === undefined) {
+                        return;
+                    }
+
+                    let selectionRange: vscode.Range;
+
+                    if (!editor.selection.isEmpty) {
+                        selectionRange = new vscode.Range(
                             editor.selection.start,
-                            editor.selection.end);
-                } else {
-                    selectionRange = editor.document.lineAt(editor.selection.start.line).range;
-                }
-
-                this.languageClient.sendRequest(EvaluateRequestType, {
-                    expression: editor.document.getText(selectionRange),
-                });
-
-                // Show the integrated console if it isn't already visible and
-                // scroll terminal to bottom so new output is visible
-                await vscode.commands.executeCommand("PowerShell.ShowSessionConsole", true);
-                await vscode.commands.executeCommand("workbench.action.terminal.scrollToBottom");
-            }),
+                            editor.selection.end,
+                        );
+                    } else {
+                        selectionRange = editor.document.lineAt(
+                            editor.selection.start.line,
+                        ).range;
+                    }
+                    const client =
+                        await LanguageClientConsumer.getLanguageClient();
+                    await client.sendRequest(EvaluateRequestType, {
+                        expression: editor.document.getText(selectionRange),
+                    });
+
+                    // Show the Extension Terminal if it isn't already visible and
+                    // scroll terminal to bottom so new output is visible
+                    await vscode.commands.executeCommand(
+                        "PowerShell.ShowSessionConsole",
+                        true,
+                    );
+                    await vscode.commands.executeCommand(
+                        "workbench.action.terminal.scrollToBottom",
+                    );
+                },
+            ),
         ];
     }
 
-    public dispose() {
-        // Make sure we cancel any status bar
-        this.clearStatusBar();
-        this.commands.forEach((command) => command.dispose());
-    }
-
-    public setLanguageClient(languageClient: LanguageClient) {
-        this.languageClient = languageClient;
-        this.languageClient.onRequest(
-            ShowChoicePromptRequestType,
-            (promptDetails) => showChoicePrompt(promptDetails, this.languageClient));
-
-        this.languageClient.onRequest(
-            ShowInputPromptRequestType,
-            (promptDetails) => showInputPrompt(promptDetails, this.languageClient));
-
-        // Set up status bar alerts for when PowerShell is executing a script
-        this.languageClient.onNotification(
-            ExecutionStatusChangedNotificationType,
-            (executionStatusDetails) => {
-                switch (executionStatusDetails.executionStatus) {
-                    // If execution has changed to running, make a notification
-                    case ExecutionStatus.Running:
-                        this.showExecutionStatus("PowerShell");
-                        break;
-
-                    // If the execution has stopped, destroy the previous notification
-                    case ExecutionStatus.Completed:
-                    case ExecutionStatus.Aborted:
-                    case ExecutionStatus.Failed:
-                        this.clearStatusBar();
-                        break;
-                }
-            });
-
-    }
-
-    private showExecutionStatus(message: string) {
-        vscode.window.withProgress({
-                location: vscode.ProgressLocation.Window,
-            }, (progress) => {
-                return new Promise((resolve, reject) => {
-                    this.clearStatusBar();
+    public dispose(): void {
+        for (const command of this.commands) {
+            command.dispose();
+        }
 
-                    this.resolveStatusBarPromise = resolve;
-                    progress.report({ message });
-                });
-            });
+        for (const handler of this.handlers) {
+            handler.dispose();
+        }
     }
 
-    private clearStatusBar() {
-        if (this.resolveStatusBarPromise) {
-            this.resolveStatusBarPromise();
-        }
+    public override onLanguageClientSet(languageClient: LanguageClient): void {
+        this.handlers = [
+            languageClient.onRequest(
+                ShowChoicePromptRequestType,
+                (promptDetails) => showChoicePrompt(promptDetails),
+            ),
+
+            languageClient.onRequest(
+                ShowInputPromptRequestType,
+                (promptDetails) => showInputPrompt(promptDetails),
+            ),
+        ];
     }
 }
diff --git a/src/features/CustomViews.ts b/src/features/CustomViews.ts
deleted file mode 100644
index 0e36d602f4..0000000000
--- a/src/features/CustomViews.ts
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import * as path from "path";
-import * as vscode from "vscode";
-import { RequestType } from "vscode-languageclient";
-import { LanguageClient } from "vscode-languageclient/node";
-import { LanguageClientConsumer } from "../languageClientConsumer";
-
-export class CustomViewsFeature extends LanguageClientConsumer {
-
-    private commands: vscode.Disposable[] = [];
-    private contentProvider: PowerShellContentProvider;
-
-    constructor() {
-        super();
-        this.contentProvider = new PowerShellContentProvider();
-        this.commands.push(
-            vscode.workspace.registerTextDocumentContentProvider(
-                "powershell",
-                this.contentProvider));
-    }
-
-    public dispose() {
-        this.commands.forEach((d) => d.dispose());
-    }
-
-    public setLanguageClient(languageClient: LanguageClient) {
-
-        languageClient.onRequest(
-            NewCustomViewRequestType,
-            (args) => {
-                this.contentProvider.createView(
-                    args.id,
-                    args.title,
-                    args.viewType);
-            });
-
-        languageClient.onRequest(
-            ShowCustomViewRequestType,
-            (args) => {
-                this.contentProvider.showView(
-                    args.id,
-                    args.viewColumn);
-            });
-
-        languageClient.onRequest(
-            CloseCustomViewRequestType,
-            (args) => {
-                this.contentProvider.closeView(args.id);
-            });
-
-        languageClient.onRequest(
-            SetHtmlContentViewRequestType,
-            (args) => {
-                this.contentProvider.setHtmlContentView(
-                    args.id,
-                    args.htmlContent);
-            });
-
-        languageClient.onRequest(
-            AppendHtmlOutputViewRequestType,
-            (args) => {
-                this.contentProvider.appendHtmlOutputView(
-                    args.id,
-                    args.appendedHtmlBodyContent);
-            });
-    }
-}
-
-class PowerShellContentProvider implements vscode.TextDocumentContentProvider {
-
-    private count: number = 1;
-    private viewIndex: { [id: string]: CustomView } = {};
-    private didChangeEvent: vscode.EventEmitter<vscode.Uri> = new vscode.EventEmitter<vscode.Uri>();
-
-    // tslint:disable-next-line:member-ordering
-    public onDidChange: vscode.Event<vscode.Uri> = this.didChangeEvent.event;
-
-    public provideTextDocumentContent(uri: vscode.Uri): string {
-        return this.viewIndex[uri.toString()].getContent();
-    }
-
-    public createView(id: string, title: string, viewType: CustomViewType) {
-        let view;
-        switch (viewType) {
-            case CustomViewType.HtmlContent:
-                view = new HtmlContentView(id, title);
-        }
-
-        this.viewIndex[this.getUri(view.id)] = view;
-    }
-
-    public showView(id: string, viewColumn: vscode.ViewColumn) {
-        const uriString = this.getUri(id);
-        (this.viewIndex[uriString] as HtmlContentView).showContent(viewColumn);
-    }
-
-    public closeView(id: string) {
-        const uriString = this.getUri(id);
-        const view: CustomView = this.viewIndex[uriString];
-
-        vscode.workspace.textDocuments.some((doc) => {
-            if (doc.uri.toString() === uriString) {
-                vscode.window
-                    .showTextDocument(doc)
-                    .then((editor) => vscode.commands.executeCommand("workbench.action.closeActiveEditor"));
-
-                return true;
-            }
-
-            return false;
-        });
-    }
-
-    public setHtmlContentView(id: string, content: IHtmlContent) {
-        const uriString = this.getUri(id);
-        const view: CustomView = this.viewIndex[uriString];
-
-        if (view.viewType === CustomViewType.HtmlContent) {
-            (view as HtmlContentView).setContent(content);
-            this.didChangeEvent.fire(vscode.Uri.parse(uriString));
-        }
-    }
-
-    public appendHtmlOutputView(id: string, content: string) {
-        const uriString = this.getUri(id);
-        const view: CustomView = this.viewIndex[uriString];
-
-        if (view.viewType === CustomViewType.HtmlContent) {
-            (view as HtmlContentView).appendContent(content);
-            this.didChangeEvent.fire(vscode.Uri.parse(uriString));
-        }
-    }
-
-    private getUri(id: string) {
-        return `powershell://views/${id}`;
-    }
-}
-
-abstract class CustomView {
-
-    constructor(
-        public id: string,
-        public title: string,
-        public viewType: CustomViewType) {
-    }
-
-    public abstract getContent(): string;
-}
-
-class HtmlContentView extends CustomView {
-
-    private htmlContent: IHtmlContent = {
-        bodyContent: "",
-        javaScriptPaths: [],
-        styleSheetPaths: [],
-    };
-
-    private webviewPanel: vscode.WebviewPanel;
-
-    constructor(
-        id: string,
-        title: string) {
-        super(id, title, CustomViewType.HtmlContent);
-    }
-
-    public setContent(htmlContent: IHtmlContent) {
-        this.htmlContent = htmlContent;
-    }
-
-    public appendContent(content: string) {
-        this.htmlContent.bodyContent += content;
-    }
-
-    public getContent(): string {
-        let styleTags = "";
-        if (this.htmlContent.styleSheetPaths &&
-            this.htmlContent.styleSheetPaths.length > 0) {
-            this.htmlContent.styleSheetPaths.forEach(
-                (styleSheetPath) => {
-                    styleTags += `<link rel="stylesheet" href="${
-                        styleSheetPath.toString().replace("file://", "vscode-resource://")
-                    }">\n`;
-                });
-        }
-
-        let scriptTags = "";
-        if (this.htmlContent.javaScriptPaths &&
-            this.htmlContent.javaScriptPaths.length > 0) {
-            this.htmlContent.javaScriptPaths.forEach(
-                (javaScriptPath) => {
-                    scriptTags += `<script src="${
-                        javaScriptPath.toString().replace("file://", "vscode-resource://")
-                    }"></script>\n`;
-                });
-        }
-
-        // Return an HTML page with the specified content
-        return `<html><head>${styleTags}</head><body>\n${this.htmlContent.bodyContent}\n${scriptTags}</body></html>`;
-    }
-
-    public showContent(viewColumn: vscode.ViewColumn): void {
-        if (this.webviewPanel) {
-            this.webviewPanel.dispose();
-        }
-
-        let localResourceRoots: vscode.Uri[] = [];
-        if (this.htmlContent.javaScriptPaths) {
-            localResourceRoots = localResourceRoots.concat(this.htmlContent.javaScriptPaths.map((p) => {
-                return vscode.Uri.parse(path.dirname(p));
-            }));
-        }
-
-        if (this.htmlContent.styleSheetPaths) {
-            localResourceRoots = localResourceRoots.concat(this.htmlContent.styleSheetPaths.map((p) => {
-                return vscode.Uri.parse(path.dirname(p));
-            }));
-        }
-
-        this.webviewPanel = vscode.window.createWebviewPanel(
-            this.id,
-            this.title,
-            viewColumn,
-            {
-                enableScripts: true,
-                enableFindWidget: true,
-                enableCommandUris: true,
-                retainContextWhenHidden: true,
-                localResourceRoots,
-            });
-        this.webviewPanel.webview.html = this.getContent();
-        this.webviewPanel.reveal(viewColumn);
-    }
-}
-
-enum CustomViewType {
-    HtmlContent = 1,
-}
-
-export const NewCustomViewRequestType =
-    new RequestType<INewCustomViewRequestArguments, void, void>(
-        "powerShell/newCustomView");
-
-interface INewCustomViewRequestArguments {
-    id: string;
-    title: string;
-    viewType: CustomViewType;
-}
-
-export const ShowCustomViewRequestType =
-    new RequestType<IShowCustomViewRequestArguments, void, void>(
-        "powerShell/showCustomView");
-
-interface IShowCustomViewRequestArguments {
-    id: string;
-    viewColumn: vscode.ViewColumn;
-}
-
-export const CloseCustomViewRequestType =
-    new RequestType<ICloseCustomViewRequestArguments, void, void>(
-        "powerShell/closeCustomView");
-
-interface ICloseCustomViewRequestArguments {
-    id: string;
-}
-
-export const SetHtmlContentViewRequestType =
-    new RequestType<ISetHtmlContentViewRequestArguments, void, void>(
-        "powerShell/setHtmlViewContent");
-
-interface IHtmlContent {
-    bodyContent: string;
-    javaScriptPaths: string[];
-    styleSheetPaths: string[];
-}
-
-interface ISetHtmlContentViewRequestArguments {
-    id: string;
-    htmlContent: IHtmlContent;
-}
-
-export const AppendHtmlOutputViewRequestType =
-    new RequestType<IAppendHtmlOutputViewRequestArguments, void, void>(
-        "powerShell/appendHtmlViewContent");
-
-interface IAppendHtmlOutputViewRequestArguments {
-    id: string;
-    appendedHtmlBodyContent: string;
-}
diff --git a/src/features/DebugSession.ts b/src/features/DebugSession.ts
index ce1951802f..3128db3b46 100644
--- a/src/features/DebugSession.ts
+++ b/src/features/DebugSession.ts
@@ -1,96 +1,246 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import vscode = require("vscode");
-import { CancellationToken, DebugConfiguration, DebugConfigurationProvider,
-    ExtensionContext, WorkspaceFolder } from "vscode";
+import type { DebugProtocol } from "@vscode/debugprotocol";
+import path from "path";
+import {
+    CancellationTokenSource,
+    DebugAdapterExecutable,
+    DebugAdapterNamedPipeServer,
+    DebugConfigurationProviderTriggerKind,
+    Disposable,
+    commands,
+    debug,
+    extensions,
+    window,
+    workspace,
+    type CancellationToken,
+    type DebugAdapterDescriptor,
+    type DebugAdapterDescriptorFactory,
+    type DebugAdapterTracker,
+    type DebugAdapterTrackerFactory,
+    type DebugConfiguration,
+    type DebugConfigurationProvider,
+    type DebugSession,
+    type ExtensionContext,
+    type InputBoxOptions,
+    type LogOutputChannel,
+    type QuickPickItem,
+    type QuickPickOptions,
+    type WorkspaceFolder,
+} from "vscode";
 import { NotificationType, RequestType } from "vscode-languageclient";
 import { LanguageClient } from "vscode-languageclient/node";
-import { getPlatformDetails, OperatingSystem } from "../platform";
-import { PowerShellProcess} from "../process";
-import { SessionManager, SessionStatus } from "../session";
-import Settings = require("../settings");
-import utils = require("../utils");
-import { NamedPipeDebugAdapter } from "../debugAdapter";
-import { Logger } from "../logging";
 import { LanguageClientConsumer } from "../languageClientConsumer";
+import type { ILogger } from "../logging";
+import { OperatingSystem, getPlatformDetails } from "../platform";
+import { PowerShellProcess } from "../process";
+import { SessionManager, type IEditorServicesSessionDetails } from "../session";
+import { getSettings } from "../settings";
+import { checkIfFileExists } from "../utils";
+
+export const StartDebuggerNotificationType = new NotificationType<void>(
+    "powerShell/startDebugger",
+);
+
+export const StopDebuggerNotificationType = new NotificationType<void>(
+    "powerShell/stopDebugger",
+);
+
+export enum DebugConfig {
+    LaunchCurrentFile,
+    LaunchScript,
+    InteractiveSession,
+    AttachHostProcess,
+    RunPester,
+    ModuleInteractiveSession,
+    BinaryModule,
+    BinaryModulePester,
+    WindowsPowerShell,
+}
 
-export const StartDebuggerNotificationType =
-    new NotificationType<void>("powerShell/startDebugger");
-
-export const StopDebuggerNotificationType =
-    new NotificationType<void>("powerShell/stopDebugger");
-
-export class DebugSessionFeature extends LanguageClientConsumer
-    implements DebugConfigurationProvider, vscode.DebugAdapterDescriptorFactory {
+/** Make the implicit behavior of undefined and null in the debug api more explicit  */
+type PREVENT_DEBUG_START = undefined;
+type PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG = null;
+type ResolveDebugConfigurationResult =
+    | DebugConfiguration
+    | PREVENT_DEBUG_START
+    | PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
+
+const PREVENT_DEBUG_START = undefined;
+const PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG = null;
+
+/** Represents the various built-in debug configurations that will be advertised to the user if they choose "Add Config" from the launch debug config window */
+// NOTE: These are duplicated with what is in package.json until https://github.com/microsoft/vscode/issues/150663#issuecomment-1506134754 is resolved.
+export const DebugConfigurations: Record<DebugConfig, DebugConfiguration> = {
+    [DebugConfig.LaunchCurrentFile]: {
+        name: "PowerShell: Launch Current File",
+        type: "PowerShell",
+        request: "launch",
+        script: "${file}",
+        args: [],
+    },
+    [DebugConfig.LaunchScript]: {
+        name: "PowerShell: Launch Script",
+        type: "PowerShell",
+        request: "launch",
+        script: 'Enter path or command to execute, for example: "${workspaceFolder}/src/foo.ps1" or "Invoke-Pester"',
+        args: [],
+    },
+    [DebugConfig.InteractiveSession]: {
+        name: "PowerShell: Interactive Session",
+        type: "PowerShell",
+        request: "launch",
+    },
+    [DebugConfig.AttachHostProcess]: {
+        name: "PowerShell: Attach to PowerShell Host Process",
+        type: "PowerShell",
+        request: "attach",
+    },
+    [DebugConfig.RunPester]: {
+        name: "PowerShell: Run Pester Tests",
+        type: "PowerShell",
+        request: "launch",
+        script: "Invoke-Pester",
+        createTemporaryIntegratedConsole: true,
+        attachDotnetDebugger: true,
+    },
+    [DebugConfig.ModuleInteractiveSession]: {
+        name: "PowerShell: Module Interactive Session",
+        type: "PowerShell",
+        request: "launch",
+        script: 'Enter command to import your binary module, for example: "Import-Module -Force ${workspaceFolder}/path/to/module.psd1|dll"',
+    },
+    [DebugConfig.BinaryModule]: {
+        name: "PowerShell: Binary Module Interactive",
+        type: "PowerShell",
+        request: "launch",
+        script: 'Enter command to import your binary module, for example: "Import-Module -Force ${workspaceFolder}/path/to/module.psd1|dll"',
+        createTemporaryIntegratedConsole: true,
+        attachDotnetDebugger: true,
+    },
+    [DebugConfig.BinaryModulePester]: {
+        name: "PowerShell: Binary Module Pester Tests",
+        type: "PowerShell",
+        request: "launch",
+        script: "Invoke-Pester",
+        createTemporaryIntegratedConsole: true,
+        attachDotnetDebugger: true,
+    },
+    [DebugConfig.WindowsPowerShell]: {
+        name: "PowerShell: Windows PowerShell",
+        type: "PowerShell",
+        request: "launch",
+        sessionName: "Windows PowerShell (x64)",
+    },
+};
+
+export class DebugSessionFeature
+    extends LanguageClientConsumer
+    implements DebugConfigurationProvider, DebugAdapterDescriptorFactory
+{
+    private tempDebugProcess: PowerShellProcess | undefined;
+    private tempSessionDetails: IEditorServicesSessionDetails | undefined;
+    private commands: Disposable[] = [];
+    private handlers: Disposable[] = [];
+    private adapterName = "PowerShell";
+
+    constructor(
+        context: ExtensionContext,
+        private sessionManager: SessionManager,
+        private logger: ILogger,
+    ) {
+        super();
 
-    private sessionCount: number = 1;
-    private tempDebugProcess: PowerShellProcess;
-    private tempSessionDetails: utils.IEditorServicesSessionDetails;
+        this.activateDebugAdaptor(context);
+
+        // NOTE: While process and runspace IDs are numbers, command
+        // substitutions in VS Code debug configurations are required to return
+        // strings. Hence to the `toString()` on these.
+        this.commands = [
+            commands.registerCommand(
+                "PowerShell.PickPSHostProcess",
+                async () => {
+                    const processId = await this.pickPSHostProcess();
+                    return processId?.toString();
+                },
+            ),
 
-    constructor(context: ExtensionContext, private sessionManager: SessionManager, private logger: Logger) {
-        super();
-        // Register a debug configuration provider
-        context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("PowerShell", this));
-        context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory("PowerShell", this))
+            commands.registerCommand(
+                "PowerShell.PickRunspace",
+                async (processId) => {
+                    const runspace = await this.pickRunspace(processId);
+                    return runspace?.toString();
+                },
+                this,
+            ),
+        ];
     }
 
-    createDebugAdapterDescriptor(
-        session: vscode.DebugSession,
-        _executable: vscode.DebugAdapterExecutable): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
-
-        const sessionDetails = session.configuration.createTemporaryIntegratedConsole
-            ? this.tempSessionDetails
-            : this.sessionManager.getSessionDetails();
+    public dispose(): void {
+        for (const command of this.commands) {
+            command.dispose();
+        }
 
-        // Establish connection before setting up the session
-        this.logger.writeVerbose(`Connecting to pipe: ${sessionDetails.debugServicePipeName}`);
-        this.logger.writeVerbose(`Debug configuration: ${JSON.stringify(session.configuration)}`);
+        for (const handler of this.handlers) {
+            handler.dispose();
+        }
+    }
 
-        const debugAdapter = new NamedPipeDebugAdapter(sessionDetails.debugServicePipeName, this.logger);
-        debugAdapter.start();
+    // This "activates" the debug adapter. You can only do this once.
+    public activateDebugAdaptor(context: ExtensionContext): void {
+        const triggers = [
+            DebugConfigurationProviderTriggerKind.Initial,
+            DebugConfigurationProviderTriggerKind.Dynamic,
+        ];
 
-        return new vscode.DebugAdapterInlineImplementation(debugAdapter);
-    }
+        for (const triggerKind of triggers) {
+            context.subscriptions.push(
+                debug.registerDebugConfigurationProvider(
+                    this.adapterName,
+                    this,
+                    triggerKind,
+                ),
+            );
+        }
 
-    // tslint:disable-next-line:no-empty
-    public dispose() {
+        context.subscriptions.push(
+            debug.registerDebugAdapterTrackerFactory(
+                this.adapterName,
+                new PowerShellDebugAdapterTrackerFactory(this.adapterName),
+            ),
+            debug.registerDebugAdapterDescriptorFactory(this.adapterName, this),
+        );
     }
 
-    public setLanguageClient(languageClient: LanguageClient) {
-        languageClient.onNotification(
-            StartDebuggerNotificationType,
-            () =>
-                // TODO: Use a named debug configuration.
-                vscode.debug.startDebugging(undefined, {
-                    request: "launch",
-                    type: "PowerShell",
-                    name: "PowerShell: Interactive Session",
-        }));
-
-        languageClient.onNotification(
-            StopDebuggerNotificationType,
-            () =>
-                vscode.debug.stopDebugging(undefined)
-        );
+    public override onLanguageClientSet(languageClient: LanguageClient): void {
+        this.handlers = [
+            languageClient.onNotification(
+                StartDebuggerNotificationType,
+                () =>
+                    void debug.startDebugging(
+                        undefined,
+                        DebugConfigurations[DebugConfig.InteractiveSession],
+                    ),
+            ),
+
+            languageClient.onNotification(
+                StopDebuggerNotificationType,
+                () => void debug.stopDebugging(undefined),
+            ),
+        ];
     }
 
     public async provideDebugConfigurations(
-        folder: WorkspaceFolder | undefined,
-        token?: CancellationToken): Promise<DebugConfiguration[]> {
-
-        enum DebugConfig {
-            LaunchCurrentFile,
-            LaunchScript,
-            InteractiveSession,
-            AttachHostProcess,
-        }
-
+        _folder: WorkspaceFolder | undefined,
+        _token?: CancellationToken,
+    ): Promise<DebugConfiguration[]> {
         const debugConfigPickItems = [
             {
                 id: DebugConfig.LaunchCurrentFile,
                 label: "Launch Current File",
-                description: "Launch and debug the file in the currently active editor window",
+                description:
+                    "Launch and debug the file in the currently active editor window",
             },
             {
                 id: DebugConfig.LaunchScript,
@@ -100,525 +250,692 @@ export class DebugSessionFeature extends LanguageClientConsumer
             {
                 id: DebugConfig.InteractiveSession,
                 label: "Interactive Session",
-                description: "Debug commands executed from the Integrated Console",
+                description:
+                    "Debug commands executed from the PowerShell Extension Terminal",
             },
             {
                 id: DebugConfig.AttachHostProcess,
                 label: "Attach",
-                description: "Attach the debugger to a running PowerShell Host Process",
+                description:
+                    "Attach the debugger to a running PowerShell Host Process",
+            },
+            {
+                id: DebugConfig.RunPester,
+                label: "Run Pester Tests",
+                description:
+                    "Debug Pester Tests detected in your current directory (runs Invoke-Pester)",
+            },
+            {
+                id: DebugConfig.ModuleInteractiveSession,
+                label: "Interactive Session (Module)",
+                description:
+                    "Debug commands executed from the PowerShell Extension Terminal after auto-loading your module",
+            },
+            {
+                id: DebugConfig.BinaryModule,
+                label: "Interactive Session (Binary Module)",
+                description:
+                    "Debug a .NET binary or hybrid module loaded into a PowerShell session. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
+            },
+            {
+                id: DebugConfig.BinaryModulePester,
+                label: "Run Pester Tests (Binary Module)",
+                description:
+                    "Debug a .NET binary or hybrid module by running Pester tests. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
             },
         ];
 
-        const launchSelection =
-            await vscode.window.showQuickPick(
-                debugConfigPickItems,
-                { placeHolder: "Select a PowerShell debug configuration" });
-
-        // TODO: Make these available in a dictionary and share them.
-        switch (launchSelection.id) {
-            case DebugConfig.LaunchCurrentFile:
-                return [
-                    {
-                        name: "PowerShell: Launch Current File",
-                        type: "PowerShell",
-                        request: "launch",
-                        script: "${file}",
-                        cwd: "${file}",
-                    },
-                ];
-            case DebugConfig.LaunchScript:
-                return [
-                    {
-                        name: "PowerShell: Launch Script",
-                        type: "PowerShell",
-                        request: "launch",
-                        script: "enter path or command to execute e.g.: ${workspaceFolder}/src/foo.ps1 or Invoke-Pester",
-                        cwd: "${workspaceFolder}",
-                    },
-                ];
-            case DebugConfig.InteractiveSession:
-                return [
-                    {
-                        name: "PowerShell: Interactive Session",
-                        type: "PowerShell",
-                        request: "launch",
-                        cwd: "",
-                    },
-                ];
-            case DebugConfig.AttachHostProcess:
-                return [
-                    {
-                        name: "PowerShell: Attach to PowerShell Host Process",
-                        type: "PowerShell",
-                        request: "attach",
-                        runspaceId: 1,
-                    },
-                ];
+        // Only show the Windows PowerShell option if the platform is Windows
+        const platformDetails = getPlatformDetails();
+        if (platformDetails.operatingSystem === OperatingSystem.Windows) {
+            debugConfigPickItems.push({
+                id: DebugConfig.WindowsPowerShell,
+                label: "Windows PowerShell",
+                description:
+                    "Launch Windows PowerShell in a temporary integrated console for debugging",
+            });
+        }
+
+        const launchSelection = await window.showQuickPick(
+            debugConfigPickItems,
+            { placeHolder: "Select a PowerShell debug configuration" },
+        );
+
+        if (launchSelection) {
+            return [DebugConfigurations[launchSelection.id]];
         }
+
+        return [DebugConfigurations[DebugConfig.LaunchCurrentFile]];
     }
 
-    // DebugConfigurationProvider method
+    // We don't use await here but we are returning a promise and the return syntax is easier in an async function
+    // eslint-disable-next-line @typescript-eslint/require-await
     public async resolveDebugConfiguration(
         _folder: WorkspaceFolder | undefined,
         config: DebugConfiguration,
-        _token?: CancellationToken): Promise<DebugConfiguration> {
-        // Make sure there is a session running before attempting to debug/run a program
-        // TODO: Perhaps this should just wait until it's running or aborted.
-        if (this.sessionManager.getSessionStatus() !== SessionStatus.Running) {
-            const msg = "Cannot debug or run a PowerShell script until the PowerShell session has started. " +
-                "Wait for the PowerShell session to finish starting and try again.";
-            vscode.window.showWarningMessage(msg);
-            return undefined;
+        _token?: CancellationToken,
+    ): Promise<ResolveDebugConfigurationResult> {
+        // NOTE: We intentionally do not touch the `cwd` setting of the config.
+
+        if (!config.request) {
+            // No launch.json, create the default configuration for both unsaved
+            // (Untitled) and saved documents.
+            const LaunchCurrentFileConfig =
+                DebugConfigurations[DebugConfig.LaunchCurrentFile];
+            config = { ...config, ...LaunchCurrentFileConfig };
+            config.current_document = true;
         }
 
-        // Starting a debug session can be done when there is no document open e.g. attach to PS host process
-        const currentDocument = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document : undefined;
-        const debugCurrentScript = (config.script === "${file}") || !config.request;
-        const generateLaunchConfig = !config.request;
-
-        const settings = Settings.load();
-
-        // If the createTemporaryIntegratedConsole field is not specified in the launch config, set the field using
-        // the value from the corresponding setting. Otherwise, the launch config value overrides the setting.
-        config.createTemporaryIntegratedConsole =
-            config.createTemporaryIntegratedConsole ??
-            settings.debugging.createTemporaryIntegratedConsole;
-
-        if (config.request === "attach") {
-            const platformDetails = getPlatformDetails();
-            const versionDetails = this.sessionManager.getPowerShellVersionDetails();
-
-            // Cross-platform attach to process was added in 6.2.0-preview.4
-            if (versionDetails.version < "6.2.0" && platformDetails.operatingSystem !== OperatingSystem.Windows) {
-                const msg = `Attaching to a PowerShell Host Process on ${
-                    OperatingSystem[platformDetails.operatingSystem] } requires PowerShell 6.2 or higher.`;
-                return vscode.window.showErrorMessage(msg).then((_) => {
-                    return undefined;
-                });
+        if (
+            config.script === "${file}" ||
+            config.script === "${relativeFile}"
+        ) {
+            if (window.activeTextEditor === undefined) {
+                void this.logger.writeAndShowError(
+                    "To debug the 'Current File', you must first open a PowerShell script file in the editor.",
+                );
+                return PREVENT_DEBUG_START;
+            }
+            config.current_document = true;
+            // Special case using the URI for untitled documents.
+            const currentDocument = window.activeTextEditor.document;
+            if (currentDocument.isUntitled) {
+                config.untitled_document = true;
+                config.script = currentDocument.uri.toString();
             }
+        }
 
-            // if nothing is set, prompt for the processId
-            if (!config.customPipeName && !config.processId) {
-                config.processId = await vscode.commands.executeCommand("PowerShell.PickPSHostProcess");
+        return config;
+    }
 
-                // No process selected. Cancel attach.
-                if (!config.processId) {
-                    return null;
-                }
-            }
+    public async resolveDebugConfigurationWithSubstitutedVariables(
+        _folder: WorkspaceFolder | undefined,
+        config: DebugConfiguration,
+        _token?: CancellationToken,
+    ): Promise<ResolveDebugConfigurationResult> {
+        let resolvedConfig: ResolveDebugConfigurationResult;
 
-            if (!config.runspaceId && !config.runspaceName) {
-                config.runspaceId = await vscode.commands.executeCommand("PowerShell.PickRunspace", config.processId);
+        // Prevent the Debug Console from opening
+        config.internalConsoleOptions = "neverOpen";
 
-                // No runspace selected. Cancel attach.
-                if (!config.runspaceId) {
-                    return null;
-                }
-            }
+        const settings = getSettings();
+        config.createTemporaryIntegratedConsole ??=
+            settings.debugging.createTemporaryIntegratedConsole;
+        config.executeMode ??= settings.debugging.executeMode;
+        if (config.request === "attach") {
+            resolvedConfig = await this.resolveAttachDebugConfiguration(config);
+        } else if (config.request === "launch") {
+            resolvedConfig = await this.resolveLaunchDebugConfiguration(config);
+        } else {
+            void this.logger.writeAndShowError(
+                `PowerShell debug configuration's request type was invalid: '${config.request}'.`,
+            );
+            return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
         }
 
-        // TODO: Use a named debug configuration.
-        if (generateLaunchConfig) {
-            // No launch.json, create the default configuration for both unsaved (Untitled) and saved documents.
-            config.type = "PowerShell";
-            config.name = "PowerShell: Launch Current File";
-            config.request = "launch";
-            config.args = [];
-
-            config.script =
-                currentDocument.isUntitled
-                    ? currentDocument.uri.toString()
-                    : currentDocument.fileName;
-
-            if (config.createTemporaryIntegratedConsole) {
-                // For a folder-less workspace, vscode.workspace.rootPath will be undefined.
-                // PSES will convert that undefined to a reasonable working dir.
-                config.cwd =
-                    currentDocument.isUntitled
-                        ? vscode.workspace.rootPath
-                        : currentDocument.fileName;
-
-            } else {
-                // If the non-temp integrated console is being used, default to the current working dir.
-                config.cwd = "";
-            }
-        }
+        return resolvedConfig;
+    }
 
-        if (config.request === "launch") {
-            // For debug launch of "current script" (saved or unsaved), warn before starting the debugger if either
-            // A) there is not an active document
-            // B) the unsaved document's language type is not PowerShell
-            // C) the saved document's extension is a type that PowerShell can't debug.
-            if (debugCurrentScript) {
-
-                if (currentDocument === undefined) {
-                    const msg = "To debug the \"Current File\", you must first open a " +
-                                "PowerShell script file in the editor.";
-                    vscode.window.showErrorMessage(msg);
-                    return;
-                }
+    // This is our factory entrypoint hook to when a debug session starts, and
+    // where we will lazy initialize everything needed to do the debugging such
+    // as a temporary console if required.
+    //
+    // NOTE: A Promise meets the shape of a ProviderResult, which allows us to
+    // make this method async.
+    public async createDebugAdapterDescriptor(
+        session: DebugSession,
+        _executable: DebugAdapterExecutable | undefined,
+    ): Promise<DebugAdapterDescriptor | undefined> {
+        await this.sessionManager.start();
+
+        const sessionDetails = session.configuration
+            .createTemporaryIntegratedConsole
+            ? await this.createTemporaryIntegratedConsole(session)
+            : this.sessionManager.getSessionDetails();
 
-                if (currentDocument.isUntitled) {
-                    if (config.createTemporaryIntegratedConsole) {
-                        const msg = "Debugging Untitled files in a temporary console is currently not supported.";
-                        vscode.window.showErrorMessage(msg);
-                        return;
-                    }
+        if (sessionDetails === undefined) {
+            return undefined;
+        }
 
-                    if (currentDocument.languageId === "powershell") {
-                        if (!generateLaunchConfig) {
-                            // Cover the case of existing launch.json but unsaved (Untitled) document.
-                            // In this case, vscode.workspace.rootPath will not be undefined.
-                            config.script = currentDocument.uri.toString();
-                            config.cwd = vscode.workspace.rootPath;
-                        }
-                    } else {
-                        const msg = "To debug '" + currentDocument.fileName + "', change the document's " +
-                                    "language mode to PowerShell or save the file with a PowerShell extension.";
-                        vscode.window.showErrorMessage(msg);
-                        return;
-                    }
-                } else {
-                    let isValidExtension = false;
-                    const extIndex = currentDocument.fileName.lastIndexOf(".");
-                    if (extIndex !== -1) {
-                        const ext = currentDocument.fileName.substr(extIndex + 1).toUpperCase();
-                        isValidExtension = (ext === "PS1" || ext === "PSM1");
-                    }
+        // Create or show the debug terminal (either temporary or session).
+        this.sessionManager.showDebugTerminal(true);
 
-                    if ((currentDocument.languageId !== "powershell") || !isValidExtension) {
-                        let docPath = currentDocument.fileName;
-                        const workspaceRootPath = vscode.workspace.rootPath;
-                        if (currentDocument.fileName.startsWith(workspaceRootPath)) {
-                            docPath = currentDocument.fileName.substring(vscode.workspace.rootPath.length + 1);
-                        }
+        this.logger.writeDebug(
+            `Connecting to pipe: ${sessionDetails.debugServicePipeName}`,
+        );
+        this.logger.writeDebug(
+            `Debug configuration: ${JSON.stringify(session.configuration, undefined, 2)}`,
+        );
 
-                        const msg = "PowerShell does not support debugging this file type: '" + docPath + "'.";
-                        vscode.window.showErrorMessage(msg);
-                        return;
-                    }
+        return new DebugAdapterNamedPipeServer(
+            sessionDetails.debugServicePipeName,
+        );
+    }
 
-                    if (config.script === "${file}") {
-                        config.script = currentDocument.fileName;
-                    }
-                }
+    private async resolveLaunchDebugConfiguration(
+        config: DebugConfiguration,
+    ): Promise<ResolveDebugConfigurationResult> {
+        // Check the languageId and file extension only for current documents
+        // (which includes untitled documents). This prevents accidentally
+        // running the debugger for an open non-PowerShell file.
+        if (config.current_document) {
+            const currentDocument = window.activeTextEditor?.document;
+            if (currentDocument?.languageId !== "powershell") {
+                void this.logger.writeAndShowError(
+                    `PowerShell does not support debugging this language mode: '${currentDocument?.languageId}'.`,
+                );
+                return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
             }
 
-            // NOTE: There is a tight coupling to a weird setting in
-            // `package.json` for the Launch Current File configuration where
-            // the default cwd is set to ${file}.
-            if ((currentDocument !== undefined) && (config.cwd === "${file}")) {
-                config.cwd = currentDocument.fileName;
+            if (await checkIfFileExists(config.script)) {
+                const ext = path.extname(config.script).toLowerCase();
+                if (!(ext === ".ps1" || ext === ".psm1")) {
+                    void this.logger.writeAndShowError(
+                        `PowerShell does not support debugging this file type: '${path.basename(config.script)}'.`,
+                    );
+                    return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
+                }
             }
         }
 
-        // Prevent the Debug Console from opening
-        config.internalConsoleOptions = "neverOpen";
+        if (
+            config.untitled_document &&
+            config.createTemporaryIntegratedConsole
+        ) {
+            void this.logger.writeAndShowError(
+                "PowerShell does not support debugging untitled files in a temporary console.",
+            );
+            return PREVENT_DEBUG_START;
+        }
+
+        if (
+            !config.createTemporaryIntegratedConsole &&
+            config.attachDotnetDebugger
+        ) {
+            void this.logger.writeAndShowError(
+                "dotnet debugging without using a temporary console is currently not supported. Please updated your launch config to include createTemporaryIntegratedConsole: true.",
+            );
+            return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
+        }
 
-        // Create or show the interactive console
-        vscode.commands.executeCommand("PowerShell.ShowSessionConsole", true);
+        if (config.sessionName) {
+            config.createTemporaryIntegratedConsole = true;
+        }
 
-        const sessionFilePath = utils.getDebugSessionFilePath();
+        if (config.attachDotnetDebugger) {
+            return this.resolveAttachDotnetDebugConfiguration(config);
+        }
 
-        if (config.createTemporaryIntegratedConsole) {
-            if (this.tempDebugProcess) {
-                this.tempDebugProcess.dispose();
-            }
+        return config;
+    }
 
-            this.tempDebugProcess =
-                this.sessionManager.createDebugSessionProcess(
-                    sessionFilePath,
-                    settings);
+    private resolveAttachDotnetDebugConfiguration(
+        config: DebugConfiguration,
+    ): ResolveDebugConfigurationResult {
+        if (!extensions.getExtension("ms-dotnettools.csharp")) {
+            void this.logger.writeAndShowError(
+                "You specified attachDotnetDebugger in your PowerShell Launch configuration but the C# extension is not installed. Please install the C# extension and try again.",
+            );
+            return PREVENT_DEBUG_START;
+        }
 
-            this.tempSessionDetails = await this.tempDebugProcess.start(`DebugSession-${this.sessionCount++}`);
-            utils.writeSessionFile(sessionFilePath, this.tempSessionDetails);
+        const dotnetDebuggerConfig = this.getDotnetNamedConfigOrDefault(
+            config.dotnetDebuggerConfigName,
+        );
 
-        } else {
-            utils.writeSessionFile(sessionFilePath, this.sessionManager.getSessionDetails());
+        if (dotnetDebuggerConfig === undefined) {
+            void this.logger.writeAndShowError(
+                `You specified dotnetDebuggerConfigName in your PowerShell Launch configuration but a matching launch config was not found. Please ensure you have a coreclr attach config with the name ${config.dotnetDebuggerConfigName} in your launch.json file or remove dotnetDebuggerConfigName from your PowerShell Launch configuration to use the defaults`,
+            );
+            return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
         }
 
+        config.dotnetAttachConfig = dotnetDebuggerConfig;
         return config;
     }
-}
 
-export class SpecifyScriptArgsFeature implements vscode.Disposable {
+    private async createTemporaryIntegratedConsole(
+        session: DebugSession,
+    ): Promise<IEditorServicesSessionDetails | undefined> {
+        const settings = getSettings();
+        this.tempDebugProcess =
+            await this.sessionManager.createDebugSessionProcess(
+                settings,
+                session.configuration.sessionName,
+            );
+        // TODO: Maybe set a timeout on the cancellation token?
+        const cancellationTokenSource = new CancellationTokenSource();
+        this.tempSessionDetails = await this.tempDebugProcess.start(
+            cancellationTokenSource.token,
+        );
 
-    private command: vscode.Disposable;
-    private context: vscode.ExtensionContext;
+        // NOTE: Dotnet attach debugging is only currently supported if a temporary debug terminal is used, otherwise we get lots of lock conflicts from loading the assemblies.
+        if (session.configuration.attachDotnetDebugger) {
+            const dotnetAttachConfig = session.configuration.dotnetAttachConfig;
+
+            // Will wait until the process is started and available before attaching
+            const pid = await this.tempDebugProcess.getPid();
+            if (pid === undefined) {
+                void this.logger.writeAndShowError(
+                    "Attach Dotnet Debugger was specified but the PowerShell temporary debug session failed to start. This is probably a bug.",
+                );
+                return PREVENT_DEBUG_START;
+            }
+            dotnetAttachConfig.processId = pid;
+
+            // Ensure the .NET session stops before the PowerShell session so that the .NET debug session doesn't emit an error about the process unexpectedly terminating.
+            let tempConsoleDotnetAttachSession: DebugSession;
+            const startDebugEvent = debug.onDidStartDebugSession(
+                (dotnetAttachSession) => {
+                    if (
+                        dotnetAttachSession.configuration.name !=
+                        dotnetAttachConfig.name
+                    ) {
+                        return;
+                    }
 
-    constructor(context: vscode.ExtensionContext) {
-        this.context = context;
+                    // Makes the event one-time
+                    // HACK: This seems like you would be calling a method on a variable not assigned yet, but it does work in the flow.
+                    // The dispose shorthand demonry for making an event one-time courtesy of: https://github.com/OmniSharp/omnisharp-vscode/blob/b8b07bb12557b4400198895f82a94895cb90c461/test/integrationTests/launchConfiguration.integration.test.ts#L41-L45
+                    startDebugEvent.dispose();
 
-        this.command =
-            vscode.commands.registerCommand("PowerShell.SpecifyScriptArgs", () => {
-                return this.specifyScriptArguments();
-            });
-    }
+                    this.logger.writeDebug(
+                        `Debugger session detected: ${dotnetAttachSession.name} (${dotnetAttachSession.id})`,
+                    );
 
-    public dispose() {
-        this.command.dispose();
-    }
+                    tempConsoleDotnetAttachSession = dotnetAttachSession;
 
-    private async specifyScriptArguments(): Promise<string> {
-        const powerShellDbgScriptArgsKey = "powerShellDebugScriptArgs";
+                    const stopDebugEvent = debug.onDidTerminateDebugSession(
+                        async (tempConsoleSession) => {
+                            if (
+                                tempConsoleDotnetAttachSession.parentSession
+                                    ?.id !== tempConsoleSession.id
+                            ) {
+                                return;
+                            }
 
-        const options: vscode.InputBoxOptions = {
-            ignoreFocusOut: true,
-            placeHolder: "Enter script arguments or leave empty to pass no args",
-        };
+                            // Makes the event one-time
+                            stopDebugEvent.dispose();
+
+                            this.logger.writeDebug(
+                                `Debugger session terminated: ${tempConsoleSession.name} (${tempConsoleSession.id})`,
+                            );
+
+                            // HACK: As of 2023-08-17, there is no vscode debug API to request the C# debugger to detach, so we send it a custom DAP request instead.
+                            const disconnectRequest: DebugProtocol.DisconnectRequest =
+                                {
+                                    command: "disconnect",
+                                    seq: 0,
+                                    type: "request",
+                                    arguments: {
+                                        restart: false,
+                                        terminateDebuggee: false,
+                                        suspendDebuggee: false,
+                                    },
+                                };
+
+                            try {
+                                await dotnetAttachSession.customRequest(
+                                    disconnectRequest.command,
+                                    disconnectRequest.arguments,
+                                );
+                            } catch (err) {
+                                this.logger.writeWarning(
+                                    `Disconnect request to dotnet debugger failed: ${err}`,
+                                );
+                            }
+                        },
+                    );
+                },
+            );
 
-        const prevArgs = this.context.workspaceState.get(powerShellDbgScriptArgsKey, "");
-        if (prevArgs.length > 0) {
-            options.value = prevArgs;
+            // Start a child debug session to attach the dotnet debugger
+            // TODO: Accommodate multi-folder workspaces if the C# code is in a different workspace folder
+            await debug.startDebugging(undefined, dotnetAttachConfig, session);
+            this.logger.writeDebug(
+                `Dotnet attach debug configuration: ${JSON.stringify(dotnetAttachConfig, undefined, 2)}`,
+            );
+            this.logger.writeDebug(
+                `Attached dotnet debugger to process: ${pid}`,
+            );
         }
 
-        const text = await vscode.window.showInputBox(options);
-        // When user cancel's the input box (by pressing Esc), the text value is undefined.
-        // Let's not blow away the previous settting.
-        if (text !== undefined) {
-            this.context.workspaceState.update(powerShellDbgScriptArgsKey, text);
+        return this.tempSessionDetails;
+    }
+
+    private getDotnetNamedConfigOrDefault(
+        configName?: string,
+    ): ResolveDebugConfigurationResult {
+        if (configName) {
+            const debugConfigs = this.getLaunchConfigurations();
+            return debugConfigs.find(
+                ({ type, request, name }) =>
+                    type === "coreclr" &&
+                    request === "attach" &&
+                    name === configName,
+            );
         }
-        return text;
+
+        // Default debugger config if none provided
+        // TODO: Type this appropriately from the C# extension?
+        return {
+            name: "Dotnet Debugger: Temporary Extension Terminal",
+            type: "coreclr",
+            request: "attach",
+            processId: undefined,
+            logging: {
+                moduleLoad: false,
+            },
+        };
     }
-}
 
-interface IProcessItem extends vscode.QuickPickItem {
-    pid: string;    // payload for the QuickPick UI
-}
+    /** Fetches all available vscode launch configurations. This is abstracted out for easier testing. */
+    private getLaunchConfigurations(): DebugConfiguration[] {
+        return (
+            workspace
+                .getConfiguration("launch")
+                .get<DebugConfiguration[]>("configurations") ?? []
+        );
+    }
 
-interface IPSHostProcessInfo {
-    processName: string;
-    processId: string;
-    appDomainName: string;
-    mainWindowTitle: string;
-}
+    private async resolveAttachDebugConfiguration(
+        config: DebugConfiguration,
+    ): Promise<ResolveDebugConfigurationResult> {
+        const platformDetails = getPlatformDetails();
+        const versionDetails =
+            this.sessionManager.getPowerShellVersionDetails();
+        if (versionDetails === undefined) {
+            void this.logger.writeAndShowError(
+                `PowerShell session version details were not found for '${config.name}'.`,
+            );
+            return PREVENT_DEBUG_START;
+        }
 
-export const GetPSHostProcessesRequestType =
-    new RequestType<any, IGetPSHostProcessesResponseBody, string>("powerShell/getPSHostProcesses");
+        // Cross-platform attach to process was added in 6.2.0-preview.4.
+        if (
+            versionDetails.version < "7.0.0" &&
+            platformDetails.operatingSystem !== OperatingSystem.Windows
+        ) {
+            void this.logger.writeAndShowError(
+                `Attaching to a PowerShell Host Process on ${OperatingSystem[platformDetails.operatingSystem]} requires PowerShell 7.0 or higher (Current Version: ${versionDetails.version}).`,
+            );
+            return PREVENT_DEBUG_START;
+        }
 
-interface IGetPSHostProcessesResponseBody {
-    hostProcesses: IPSHostProcessInfo[];
-}
+        // If nothing is set, prompt for the processId.
+        if (!config.customPipeName && !config.processId) {
+            config.processId = await this.pickPSHostProcess();
+            // No process selected. Cancel attach.
+            if (!config.processId) {
+                return PREVENT_DEBUG_START;
+            }
+        }
 
-export class PickPSHostProcessFeature extends LanguageClientConsumer {
+        // If we were given a stringified int from the user, or from the picker
+        // command, we need to parse it here.
+        if (
+            typeof config.processId === "string" &&
+            config.processId != "current"
+        ) {
+            config.processId = parseInt(config.processId);
+        }
 
-    private command: vscode.Disposable;
-    private waitingForClientToken: vscode.CancellationTokenSource;
-    private getLanguageClientResolve: (value?: LanguageClient | Promise<LanguageClient>) => void;
+        // NOTE: We don't support attaching to the Extension Terminal, even
+        // though in the past it looked like we did. The implementation was
+        // half-baked and left things unusable.
+        if (
+            config.processId === "current" ||
+            config.processId ===
+                (await this.sessionManager.getLanguageServerPid())
+        ) {
+            // TODO: When (if ever) it's supported, we need to convert 0 and the
+            // old notion of "current" to the actual process ID, like this:
+            // config.processId = await this.sessionManager.getLanguageServerPid();
+            void this.logger.writeAndShowError(
+                "Attaching to the PowerShell Extension terminal is not supported. Please use the 'PowerShell: Interactive Session' debug configuration instead.",
+            );
+            return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
+        }
 
-    constructor() {
-        super();
+        if (!config.runspaceId && !config.runspaceName) {
+            config.runspaceId = await this.pickRunspace(config.processId);
+            // No runspace selected. Cancel attach.
+            if (!config.runspaceId) {
+                return PREVENT_DEBUG_START;
+            }
+        }
 
-        this.command =
-            vscode.commands.registerCommand("PowerShell.PickPSHostProcess", () => {
-                return this.getLanguageClient()
-                           .then((_) => this.pickPSHostProcess(), (_) => undefined);
-            });
+        return config;
     }
 
-    public setLanguageClient(languageClient: LanguageClient) {
-        this.languageClient = languageClient;
+    private async pickPSHostProcess(): Promise<number | undefined> {
+        const client = await LanguageClientConsumer.getLanguageClient();
+        const response = await client.sendRequest(
+            GetPSHostProcessesRequestType,
+            {},
+        );
+        const items: IProcessItem[] = [];
+        for (const process of response) {
+            let windowTitle = "";
+            if (process.mainWindowTitle) {
+                windowTitle = `, ${process.mainWindowTitle}`;
+            }
 
-        if (this.waitingForClientToken) {
-            this.getLanguageClientResolve(this.languageClient);
-            this.clearWaitingToken();
+            items.push({
+                label: process.processName,
+                description: `PID: ${process.processId.toString()}${windowTitle}`,
+                processId: process.processId,
+            });
         }
-    }
-
-    public dispose() {
-        this.command.dispose();
-    }
 
-    private getLanguageClient(): Promise<LanguageClient> {
-        if (this.languageClient) {
-            return Promise.resolve(this.languageClient);
-        } else {
-            // If PowerShell isn't finished loading yet, show a loading message
-            // until the LanguageClient is passed on to us
-            this.waitingForClientToken = new vscode.CancellationTokenSource();
-
-            return new Promise<LanguageClient>(
-                (resolve, reject) => {
-                    this.getLanguageClientResolve = resolve;
-
-                    vscode.window
-                        .showQuickPick(
-                            ["Cancel"],
-                            { placeHolder: "Attach to PowerShell host process: Please wait, starting PowerShell..." },
-                            this.waitingForClientToken.token)
-                        .then((response) => {
-                            if (response === "Cancel") {
-                                this.clearWaitingToken();
-                                reject();
-                            }
-                        });
-
-                    // Cancel the loading prompt after 60 seconds
-                    setTimeout(() => {
-                        if (this.waitingForClientToken) {
-                            this.clearWaitingToken();
-                            reject();
-
-                            vscode.window.showErrorMessage(
-                                "Attach to PowerShell host process: PowerShell session took too long to start.");
-                        }
-                    }, 60000);
-                },
+        if (items.length === 0) {
+            return Promise.reject(
+                new Error("There are no PowerShell host processes to attach."),
             );
         }
-    }
 
-    private async pickPSHostProcess(): Promise<string> {
-        const hostProcesses = await this.languageClient.sendRequest(GetPSHostProcessesRequestType, {});
-        // Start with the current PowerShell process in the list.
-        const items: IProcessItem[] = [{
-            label: "Current",
-            description: "The current PowerShell Integrated Console process.",
-            pid: "current",
-        }];
-        for (const p in hostProcesses) {
-            if (hostProcesses.hasOwnProperty(p)) {
-                let windowTitle = "";
-                if (hostProcesses[p].mainWindowTitle) {
-                    windowTitle = `, Title: ${hostProcesses[p].mainWindowTitle}`;
-                }
+        const options: QuickPickOptions = {
+            placeHolder: "Select a PowerShell host process to attach.",
+            matchOnDescription: true,
+            matchOnDetail: true,
+        };
 
-                items.push({
-                    label: hostProcesses[p].processName,
-                    description: `PID: ${hostProcesses[p].processId.toString()}${windowTitle}`,
-                    pid: hostProcesses[p].processId,
-                });
-            }
-        }
-        if (items.length === 0) {
-            return Promise.reject("There are no PowerShell host processes to attach to.");
+        const item = await window.showQuickPick(items, options);
+
+        return item?.processId ?? undefined;
+    }
+
+    private async pickRunspace(processId: number): Promise<number | undefined> {
+        const client = await LanguageClientConsumer.getLanguageClient();
+        const response = await client.sendRequest(GetRunspaceRequestType, {
+            processId,
+        });
+        const items: IRunspaceItem[] = [];
+        for (const runspace of response) {
+            items.push({
+                label: runspace.name,
+                description: `ID: ${runspace.id} - ${runspace.availability}`,
+                id: runspace.id,
+            });
         }
-        const options: vscode.QuickPickOptions = {
-            placeHolder: "Select a PowerShell host process to attach to",
+
+        const options: QuickPickOptions = {
+            placeHolder: "Select PowerShell runspace to debug",
             matchOnDescription: true,
             matchOnDetail: true,
         };
-        const item = await vscode.window.showQuickPick(items, options);
-        return item ? `${item.pid}` : undefined;
+
+        const item = await window.showQuickPick(items, options);
+
+        return item?.id ?? undefined;
     }
+}
 
-    private clearWaitingToken() {
-        if (this.waitingForClientToken) {
-            this.waitingForClientToken.dispose();
-            this.waitingForClientToken = undefined;
+class PowerShellDebugAdapterTrackerFactory
+    implements DebugAdapterTrackerFactory, Disposable
+{
+    disposables: Disposable[] = [];
+    constructor(private adapterName = "PowerShell") {}
+
+    _log: LogOutputChannel | undefined;
+    /** Lazily creates a {@link LogOutputChannel} for debug tracing, and presents it only when DAP logging is enabled.
+     *
+     * We want to use a shared output log for separate debug sessions as usually only one is running at a time and we
+     * dont need an output window for every debug session. We also want to leave it active so user can copy and paste
+     * even on run end. When user changes the setting and disables it getter will return undefined, which will result
+     * in a noop for the logging activities, effectively pausing logging but not disposing the output channel. If the
+     * user re-enables, then logging resumes.
+     */
+    get log(): LogOutputChannel | undefined {
+        if (
+            workspace
+                .getConfiguration("powershell.developer")
+                .get<boolean>("traceDap") &&
+            this._log === undefined
+        ) {
+            this._log = window.createOutputChannel(
+                `${this.adapterName}: Trace DAP`,
+                { log: true },
+            );
+            this.disposables.push(this._log);
         }
+        return this._log;
     }
-}
 
-interface IRunspaceItem extends vscode.QuickPickItem {
-    id: string;    // payload for the QuickPick UI
-}
+    // This tracker effectively implements the logging for the debug adapter to a LogOutputChannel
+    createDebugAdapterTracker(session: DebugSession): DebugAdapterTracker {
+        const sessionInfo = `${this.adapterName} Debug Session: ${session.name} [${session.id}]`;
+        return {
+            onWillStartSession: () =>
+                this.log?.info(
+                    `Starting ${sessionInfo}. Set log level to trace to see DAP messages beyond errors`,
+                ),
+            onWillStopSession: () => this.log?.info(`Stopping ${sessionInfo}`),
+            onExit: (code) =>
+                this.log?.info(`${sessionInfo} exited with code ${code}`),
+            onWillReceiveMessage: (m): void => {
+                this.log?.debug(`➡️${m.seq} ${m.type}: ${m.command}`);
+                if (
+                    m.arguments &&
+                    (Array.isArray(m.arguments)
+                        ? m.arguments.length > 0
+                        : Object.keys(m.arguments).length > 0)
+                ) {
+                    this.log?.trace(
+                        `${m.seq}: ` +
+                            JSON.stringify(m.arguments, undefined, 2),
+                    );
+                }
+            },
+            onDidSendMessage: (m): void => {
+                const responseSummary =
+                    m.request_seq !== undefined
+                        ? `${m.success ? "✅" : "❌"}${m.request_seq} ${m.type}(${m.seq}): ${m.command}`
+                        : `⬅️${m.seq} ${m.type}: ${m.event ?? m.command}`;
+                this.log?.debug(responseSummary);
+                if (
+                    m.body &&
+                    (Array.isArray(m.body)
+                        ? m.body.length > 0
+                        : Object.keys(m.body).length > 0)
+                ) {
+                    this.log?.trace(
+                        `${m.seq}: ` + JSON.stringify(m.body, undefined, 2),
+                    );
+                }
+            },
+            onError: (e) => this.log?.error(e),
+        };
+    }
 
-interface IRunspace {
-    id: number;
-    name: string;
-    availability: string;
+    dispose(): void {
+        this.disposables.forEach((d) => d.dispose());
+    }
 }
 
-export const GetRunspaceRequestType =
-    new RequestType<any, IRunspace[], string>("powerShell/getRunspace");
+export class SpecifyScriptArgsFeature implements Disposable {
+    private command: Disposable;
+    private context: ExtensionContext;
 
-export class PickRunspaceFeature extends LanguageClientConsumer {
+    constructor(context: ExtensionContext) {
+        this.context = context;
 
-    private command: vscode.Disposable;
-    private waitingForClientToken: vscode.CancellationTokenSource;
-    private getLanguageClientResolve: (value?: LanguageClient | Promise<LanguageClient>) => void;
+        this.command = commands.registerCommand(
+            "PowerShell.SpecifyScriptArgs",
+            () => {
+                return this.specifyScriptArguments();
+            },
+        );
+    }
 
-    constructor() {
-        super();
-        this.command =
-            vscode.commands.registerCommand("PowerShell.PickRunspace", (processId) => {
-                return this.getLanguageClient()
-                           .then((_) => this.pickRunspace(processId), (_) => undefined);
-            }, this);
+    public dispose(): void {
+        this.command.dispose();
     }
 
-    public setLanguageClient(languageClient: LanguageClient) {
-        this.languageClient = languageClient;
+    private async specifyScriptArguments(): Promise<string | undefined> {
+        const powerShellDbgScriptArgsKey = "powerShellDebugScriptArgs";
 
-        if (this.waitingForClientToken) {
-            this.getLanguageClientResolve(this.languageClient);
-            this.clearWaitingToken();
-        }
-    }
+        const options: InputBoxOptions = {
+            ignoreFocusOut: true,
+            placeHolder:
+                "Enter script arguments or leave empty to pass no args",
+        };
 
-    public dispose() {
-        this.command.dispose();
-    }
+        const prevArgs = this.context.workspaceState.get(
+            powerShellDbgScriptArgsKey,
+            "",
+        );
+        if (prevArgs.length > 0) {
+            options.value = prevArgs;
+        }
 
-    private getLanguageClient(): Promise<LanguageClient> {
-        if (this.languageClient) {
-            return Promise.resolve(this.languageClient);
-        } else {
-            // If PowerShell isn't finished loading yet, show a loading message
-            // until the LanguageClient is passed on to us
-            this.waitingForClientToken = new vscode.CancellationTokenSource();
-
-            return new Promise<LanguageClient>(
-                (resolve, reject) => {
-                    this.getLanguageClientResolve = resolve;
-
-                    vscode.window
-                        .showQuickPick(
-                            ["Cancel"],
-                            { placeHolder: "Attach to PowerShell host process: Please wait, starting PowerShell..." },
-                            this.waitingForClientToken.token)
-                        .then((response) => {
-                            if (response === "Cancel") {
-                                this.clearWaitingToken();
-                                reject();
-                            }
-                        });
-
-                    // Cancel the loading prompt after 60 seconds
-                    setTimeout(() => {
-                        if (this.waitingForClientToken) {
-                            this.clearWaitingToken();
-                            reject();
-
-                            vscode.window.showErrorMessage(
-                                "Attach to PowerShell host process: PowerShell session took too long to start.");
-                        }
-                    }, 60000);
-                },
+        const text = await window.showInputBox(options);
+        // When user cancel's the input box (by pressing Esc), the text value is undefined.
+        // Let's not blow away the previous setting.
+        if (text !== undefined) {
+            await this.context.workspaceState.update(
+                powerShellDbgScriptArgsKey,
+                text,
             );
         }
+
+        return text;
     }
+}
 
-    private async pickRunspace(processId: string): Promise<string> {
-        const response = await this.languageClient.sendRequest(GetRunspaceRequestType, { processId });
-        const items: IRunspaceItem[] = [];
-        for (const runspace of response) {
-            // Skip default runspace
-            if ((runspace.id === 1 || runspace.name === "PSAttachRunspace")
-                && processId === "current") {
-                continue;
-            }
+interface IProcessItem extends QuickPickItem {
+    processId: number; // payload for the QuickPick UI
+}
 
-            items.push({
-                label: runspace.name,
-                description: `ID: ${runspace.id} - ${runspace.availability}`,
-                id: runspace.id.toString(),
-            });
-        }
-        const options: vscode.QuickPickOptions = {
-            placeHolder: "Select PowerShell runspace to debug",
-            matchOnDescription: true,
-            matchOnDetail: true,
-        };
-        const item = await vscode.window.showQuickPick(items, options);
-        return item ? `${item.id}` : undefined;
-    }
+interface IGetPSHostProcessesArguments {}
 
-    private clearWaitingToken() {
-        if (this.waitingForClientToken) {
-            this.waitingForClientToken.dispose();
-            this.waitingForClientToken = undefined;
-        }
-    }
+interface IPSHostProcessInfo {
+    processName: string;
+    processId: number;
+    appDomainName: string;
+    mainWindowTitle: string;
+}
+
+export const GetPSHostProcessesRequestType = new RequestType<
+    IGetPSHostProcessesArguments,
+    IPSHostProcessInfo[],
+    string
+>("powerShell/getPSHostProcesses");
+
+interface IRunspaceItem extends QuickPickItem {
+    id: number; // payload for the QuickPick UI
 }
+
+interface IGetRunspaceRequestArguments {}
+
+interface IRunspace {
+    id: number;
+    name: string;
+    availability: string;
+}
+
+export const GetRunspaceRequestType = new RequestType<
+    IGetRunspaceRequestArguments,
+    IRunspace[],
+    string
+>("powerShell/getRunspace");
diff --git a/src/features/Examples.ts b/src/features/Examples.ts
index 96861ac9f5..d3c0b0da56 100644
--- a/src/features/Examples.ts
+++ b/src/features/Examples.ts
@@ -2,7 +2,7 @@
 // Licensed under the MIT License.
 
 import path = require("path");
-import utils = require("../utils")
+import utils = require("../utils");
 import vscode = require("vscode");
 
 export class ExamplesFeature implements vscode.Disposable {
@@ -10,16 +10,25 @@ export class ExamplesFeature implements vscode.Disposable {
     private examplesPath: vscode.Uri;
 
     constructor() {
-        this.examplesPath = vscode.Uri.file(path.resolve(__dirname, "../examples"));
-        this.command = vscode.commands.registerCommand("PowerShell.OpenExamplesFolder", () => {
-            vscode.commands.executeCommand("vscode.openFolder", this.examplesPath, true);
-            // Return existence of the path for testing. The `vscode.openFolder`
-            // command should do this, but doesn't (yet).
-            return utils.fileExists(this.examplesPath);
-        });
+        this.examplesPath = vscode.Uri.file(
+            path.resolve(__dirname, "../examples"),
+        );
+        this.command = vscode.commands.registerCommand(
+            "PowerShell.OpenExamplesFolder",
+            async () => {
+                await vscode.commands.executeCommand(
+                    "vscode.openFolder",
+                    this.examplesPath,
+                    true,
+                );
+                // Return existence of the path for testing. The `vscode.openFolder`
+                // command should do this, but doesn't (yet).
+                return utils.checkIfFileExists(this.examplesPath);
+            },
+        );
     }
 
-    public dispose() {
+    public dispose(): void {
         this.command.dispose();
     }
 }
diff --git a/src/features/ExpandAlias.ts b/src/features/ExpandAlias.ts
index 5030dd5e33..45e86be7e1 100644
--- a/src/features/ExpandAlias.ts
+++ b/src/features/ExpandAlias.ts
@@ -2,46 +2,79 @@
 // Licensed under the MIT License.
 
 import vscode = require("vscode");
-import Window = vscode.window;
 import { RequestType } from "vscode-languageclient";
-import { Logger } from "../logging";
+import type { LanguageClient } from "vscode-languageclient/node";
 import { LanguageClientConsumer } from "../languageClientConsumer";
 
-export const ExpandAliasRequestType = new RequestType<any, any, void>("powerShell/expandAlias");
+interface IExpandAliasRequestArguments {}
+
+interface IExpandAliasRequestResponse {
+    text: string;
+}
+
+export const ExpandAliasRequestType = new RequestType<
+    IExpandAliasRequestArguments,
+    IExpandAliasRequestResponse,
+    void
+>("powerShell/expandAlias");
 
 export class ExpandAliasFeature extends LanguageClientConsumer {
     private command: vscode.Disposable;
 
-    constructor(private log: Logger) {
+    constructor() {
         super();
-        this.command = vscode.commands.registerCommand("PowerShell.ExpandAlias", () => {
-
-            const editor = Window.activeTextEditor;
-            const document = editor.document;
-            const selection = editor.selection;
-            const sls = selection.start;
-            const sle = selection.end;
-
-            let text;
-            let range;
-
-            if ((sls.character === sle.character) && (sls.line === sle.line)) {
-                text = document.getText();
-                range = new vscode.Range(0, 0, document.lineCount, text.length);
-            } else {
-                text = document.getText(selection);
-                range = new vscode.Range(sls.line, sls.character, sle.line, sle.character);
-            }
-
-            this.languageClient.sendRequest(ExpandAliasRequestType, { text }).then((result) => {
-                editor.edit((editBuilder) => {
+        this.command = vscode.commands.registerCommand(
+            "PowerShell.ExpandAlias",
+            async () => {
+                const editor = vscode.window.activeTextEditor;
+                if (editor === undefined) {
+                    return;
+                }
+
+                const document = editor.document;
+                const selection = editor.selection;
+                const sls = selection.start;
+                const sle = selection.end;
+
+                let text: string;
+                let range: vscode.Range | vscode.Position;
+
+                if (sls.character === sle.character && sls.line === sle.line) {
+                    text = document.getText();
+                    range = new vscode.Range(
+                        0,
+                        0,
+                        document.lineCount,
+                        text.length,
+                    );
+                } else {
+                    text = document.getText(selection);
+                    range = new vscode.Range(
+                        sls.line,
+                        sls.character,
+                        sle.line,
+                        sle.character,
+                    );
+                }
+
+                const client = await LanguageClientConsumer.getLanguageClient();
+                const result = await client.sendRequest(
+                    ExpandAliasRequestType,
+                    { text },
+                );
+                await editor.edit((editBuilder) => {
                     editBuilder.replace(range, result.text);
                 });
-            });
-        });
+            },
+        );
     }
 
-    public dispose() {
+    public override onLanguageClientSet(
+        _languageClient: LanguageClient,
+        // eslint-disable-next-line @typescript-eslint/no-empty-function
+    ): void {}
+
+    public dispose(): void {
         this.command.dispose();
     }
 }
diff --git a/src/features/ExtensionCommands.ts b/src/features/ExtensionCommands.ts
index fc23bf9cdc..c4ca7203b0 100644
--- a/src/features/ExtensionCommands.ts
+++ b/src/features/ExtensionCommands.ts
@@ -1,16 +1,20 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import * as fs from "fs";
-import * as os from "os";
 import * as path from "path";
 import * as vscode from "vscode";
-import { NotificationType, NotificationType0,
-    Position, Range, RequestType } from "vscode-languageclient";
+import {
+    NotificationType,
+    NotificationType0,
+    Position,
+    Range,
+    RequestType,
+} from "vscode-languageclient";
 import { LanguageClient } from "vscode-languageclient/node";
-import { Logger } from "../logging";
-import Settings = require("../settings");
 import { LanguageClientConsumer } from "../languageClientConsumer";
+import type { ILogger } from "../logging";
+import { getSettings, validateCwdSetting } from "../settings";
+import { DebugConfig, DebugConfigurations } from "./DebugSession";
 
 export interface IExtensionCommand {
     name: string;
@@ -21,16 +25,18 @@ export interface IExtensionCommandQuickPickItem extends vscode.QuickPickItem {
     command: IExtensionCommand;
 }
 
-export const InvokeExtensionCommandRequestType =
-    new RequestType<IInvokeExtensionCommandRequestArguments, void, void>(
-        "powerShell/invokeExtensionCommand");
+export const InvokeExtensionCommandRequestType = new RequestType<
+    IInvokeExtensionCommandRequestArguments,
+    void,
+    void
+>("powerShell/invokeExtensionCommand");
 
 export interface IEditorContext {
     currentFileContent: string;
     currentFileLanguage: string;
     currentFilePath: string;
-    cursorPosition: Position;
-    selectionRange: Range;
+    cursorPosition: Position | undefined | null;
+    selectionRange: Range | undefined | null;
 }
 
 export interface IInvokeExtensionCommandRequestArguments {
@@ -40,71 +46,46 @@ export interface IInvokeExtensionCommandRequestArguments {
 
 export const ExtensionCommandAddedNotificationType =
     new NotificationType<IExtensionCommandAddedNotificationBody>(
-        "powerShell/extensionCommandAdded");
+        "powerShell/extensionCommandAdded",
+    );
 
 export interface IExtensionCommandAddedNotificationBody {
     name: string;
     displayName: string;
 }
 
-// ---------- Editor Operations ----------
-
 function asRange(value: vscode.Range): Range {
-
-    if (value === undefined) {
-        return undefined;
-    } else if (value === null) {
-        return null;
-    }
     return { start: asPosition(value.start), end: asPosition(value.end) };
 }
 
 function asPosition(value: vscode.Position): Position {
-
-    if (value === undefined) {
-        return undefined;
-    } else if (value === null) {
-        return null;
-    }
     return { line: value.line, character: value.character };
 }
 
-function asCodeRange(value: Range): vscode.Range {
-
-    if (value === undefined) {
-        return undefined;
-    } else if (value === null) {
-        return null;
-    }
-    return new vscode.Range(asCodePosition(value.start), asCodePosition(value.end));
-}
-
 function asCodePosition(value: Position): vscode.Position {
-
-    if (value === undefined) {
-        return undefined;
-    } else if (value === null) {
-        return null;
-    }
     return new vscode.Position(value.line, value.character);
 }
 
-export const GetEditorContextRequestType =
-    new RequestType<IGetEditorContextRequestArguments, IEditorContext, void>(
-        "editor/getEditorContext");
+export const GetEditorContextRequestType = new RequestType<
+    IGetEditorContextRequestArguments,
+    IEditorContext,
+    void
+>("editor/getEditorContext");
 
-// tslint:disable-next-line:no-empty-interface
-export interface IGetEditorContextRequestArguments {
-}
+export interface IGetEditorContextRequestArguments {}
 
+// NOTE: The server at least now expects this response, but it's not used in any
+// way. In the future we could actually communicate an error to the user.
 enum EditorOperationResponse {
-    Unsupported = 0,
     Completed,
+    Failed,
 }
 
-export const InsertTextRequestType =
-    new RequestType<IInsertTextRequestArguments, EditorOperationResponse, void>(
-        "editor/insertText");
+export const InsertTextRequestType = new RequestType<
+    IInsertTextRequestArguments,
+    EditorOperationResponse,
+    void
+>("editor/insertText");
 
 export interface IInsertTextRequestArguments {
     filePath: string;
@@ -112,53 +93,72 @@ export interface IInsertTextRequestArguments {
     insertRange: Range;
 }
 
-export const SetSelectionRequestType =
-    new RequestType<ISetSelectionRequestArguments, EditorOperationResponse, void>(
-        "editor/setSelection");
+export const SetSelectionRequestType = new RequestType<
+    ISetSelectionRequestArguments,
+    EditorOperationResponse,
+    void
+>("editor/setSelection");
 
 export interface ISetSelectionRequestArguments {
     selectionRange: Range;
 }
 
-export const OpenFileRequestType =
-    new RequestType<IOpenFileDetails, EditorOperationResponse, void>(
-        "editor/openFile");
+export const OpenFileRequestType = new RequestType<
+    IOpenFileDetails,
+    EditorOperationResponse,
+    void
+>("editor/openFile");
 
 export interface IOpenFileDetails {
     filePath: string;
     preview: boolean;
 }
 
-export const NewFileRequestType =
-    new RequestType<string, EditorOperationResponse, void>(
-        "editor/newFile");
-
-export const CloseFileRequestType =
-    new RequestType<string, EditorOperationResponse, void>(
-        "editor/closeFile");
-
-export const SaveFileRequestType =
-    new RequestType<ISaveFileDetails, EditorOperationResponse, void>(
-        "editor/saveFile");
-
-export const ShowErrorMessageRequestType =
-    new RequestType<string, EditorOperationResponse, void>(
-        "editor/showErrorMessage");
-
-export const ShowWarningMessageRequestType =
-    new RequestType<string, EditorOperationResponse, void>(
-        "editor/showWarningMessage");
-
-export const ShowInformationMessageRequestType =
-    new RequestType<string, EditorOperationResponse, void>(
-        "editor/showInformationMessage");
-
-export const SetStatusBarMessageRequestType =
-    new RequestType<IStatusBarMessageDetails, EditorOperationResponse, void>(
-        "editor/setStatusBarMessage");
-
-export const ClearTerminalNotificationType =
-        new NotificationType0("editor/clearTerminal");
+export const NewFileRequestType = new RequestType<
+    string,
+    EditorOperationResponse,
+    void
+>("editor/newFile");
+
+export const CloseFileRequestType = new RequestType<
+    string,
+    EditorOperationResponse,
+    void
+>("editor/closeFile");
+
+export const SaveFileRequestType = new RequestType<
+    ISaveFileDetails,
+    EditorOperationResponse,
+    void
+>("editor/saveFile");
+
+export const ShowErrorMessageRequestType = new RequestType<
+    string,
+    EditorOperationResponse,
+    void
+>("editor/showErrorMessage");
+
+export const ShowWarningMessageRequestType = new RequestType<
+    string,
+    EditorOperationResponse,
+    void
+>("editor/showWarningMessage");
+
+export const ShowInformationMessageRequestType = new RequestType<
+    string,
+    EditorOperationResponse,
+    void
+>("editor/showInformationMessage");
+
+export const SetStatusBarMessageRequestType = new RequestType<
+    IStatusBarMessageDetails,
+    EditorOperationResponse,
+    void
+>("editor/setStatusBarMessage");
+
+export const ClearTerminalNotificationType = new NotificationType0(
+    "editor/clearTerminal",
+);
 
 export interface ISaveFileDetails {
     filePath: string;
@@ -169,151 +169,174 @@ export interface IStatusBarMessageDetails {
     message: string;
     timeout?: number;
 }
+
 interface IInvokeRegisteredEditorCommandParameter {
     commandName: string;
 }
 
 export class ExtensionCommandsFeature extends LanguageClientConsumer {
-
-    private command: vscode.Disposable;
-    private command2: vscode.Disposable;
-    private command3: vscode.Disposable;
-    private command4: vscode.Disposable;
-    private command5: vscode.Disposable;
-    private command6: vscode.Disposable;
-    // TODO: Make a list of commands instead.
+    private commands: vscode.Disposable[];
+    private handlers: vscode.Disposable[] = [];
+    private statusBarMessages: vscode.Disposable[] = [];
     private extensionCommands: IExtensionCommand[] = [];
 
-    constructor(private log: Logger) {
+    constructor(private logger: ILogger) {
         super();
-        this.command = vscode.commands.registerCommand("PowerShell.ShowAdditionalCommands", () => {
-
-            const editor = vscode.window.activeTextEditor;
-            let start = editor.selection.start;
-            const end = editor.selection.end;
-            if (editor.selection.isEmpty) {
-                start = new vscode.Position(start.line, 0);
-            }
-
-            this.showExtensionCommands(this.languageClient);
-        });
-
-        this.command2 = vscode.commands.registerCommand("PowerShell.InvokeRegisteredEditorCommand",
-                                                        (param: IInvokeRegisteredEditorCommandParameter) => {
-            if (this.extensionCommands.length === 0) {
-                return;
-            }
-
-            const commandToExecute = this.extensionCommands.find((x) => x.name === param.commandName);
-
-            if (commandToExecute) {
-                this.languageClient.sendRequest(
-                    InvokeExtensionCommandRequestType,
-                    { name: commandToExecute.name,
-                    context: this.getEditorContext() });
-            }
-        });
-
-        this.command3 = vscode.commands.registerCommand('PowerShell.ClosePanel',
-            () => { vscode.commands.executeCommand('workbench.action.closePanel'); }),
-
-        this.command4 = vscode.commands.registerCommand('PowerShell.PositionPanelLeft',
-            () => { vscode.commands.executeCommand('workbench.action.positionPanelLeft'); }),
-
-        this.command5 = vscode.commands.registerCommand('PowerShell.PositionPanelBottom',
-            () => { vscode.commands.executeCommand('workbench.action.positionPanelBottom'); }),
-
-        this.command6 = vscode.commands.registerCommand('PowerShell.Debug.Start',
-            () => {
-                // TODO: Use a named debug configuration.
-                vscode.debug.startDebugging(undefined, {
-                    name: "PowerShell: Launch Current File",
-                    type: "PowerShell",
-                    request: "launch",
-                    script: "${file}",
-                    cwd: "${file}",
-                })
-            })
+        this.commands = [
+            vscode.commands.registerCommand(
+                "PowerShell.ShowAdditionalCommands",
+                async () => {
+                    await this.showExtensionCommands();
+                },
+            ),
+
+            vscode.commands.registerCommand(
+                "PowerShell.InvokeRegisteredEditorCommand",
+                async (param: IInvokeRegisteredEditorCommandParameter) => {
+                    const commandToExecute = this.extensionCommands.find(
+                        (x) => x.name === param.commandName,
+                    );
+
+                    if (commandToExecute) {
+                        const client =
+                            await LanguageClientConsumer.getLanguageClient();
+                        await client.sendRequest(
+                            InvokeExtensionCommandRequestType,
+                            {
+                                name: commandToExecute.name,
+                                context: this.getEditorContext(),
+                            },
+                        );
+                    }
+                },
+            ),
+
+            vscode.commands.registerCommand(
+                "PowerShell.ClosePanel",
+                async () => {
+                    await vscode.commands.executeCommand(
+                        "workbench.action.togglePanel",
+                    );
+                },
+            ),
+
+            vscode.commands.registerCommand(
+                "PowerShell.PositionPanelLeft",
+                async () => {
+                    await vscode.commands.executeCommand(
+                        "workbench.action.positionPanelLeft",
+                    );
+                },
+            ),
+
+            vscode.commands.registerCommand(
+                "PowerShell.PositionPanelBottom",
+                async () => {
+                    await vscode.commands.executeCommand(
+                        "workbench.action.positionPanelBottom",
+                    );
+                },
+            ),
+
+            vscode.commands.registerCommand(
+                "PowerShell.Debug.Start",
+                async () => {
+                    await vscode.debug.startDebugging(
+                        undefined,
+                        DebugConfigurations[DebugConfig.LaunchCurrentFile],
+                    );
+                },
+            ),
+        ];
     }
 
-    public setLanguageClient(languageclient: LanguageClient) {
+    public override onLanguageClientSet(languageClient: LanguageClient): void {
         // Clear the current list of extension commands since they were
         // only relevant to the previous session
         this.extensionCommands = [];
-
-        this.languageClient = languageclient;
-        if (this.languageClient !== undefined) {
-            this.languageClient.onNotification(
+        this.handlers = [
+            languageClient.onNotification(
                 ExtensionCommandAddedNotificationType,
-                (command) => this.addExtensionCommand(command));
+                (command) => {
+                    this.addExtensionCommand(command);
+                },
+            ),
 
-            this.languageClient.onRequest(
-                GetEditorContextRequestType,
-                (details) => this.getEditorContext());
+            languageClient.onRequest(GetEditorContextRequestType, (_details) =>
+                this.getEditorContext(),
+            ),
 
-            this.languageClient.onRequest(
-                InsertTextRequestType,
-                (details) => this.insertText(details));
+            languageClient.onRequest(InsertTextRequestType, (details) =>
+                this.insertText(details),
+            ),
 
-            this.languageClient.onRequest(
-                SetSelectionRequestType,
-                (details) => this.setSelection(details));
+            languageClient.onRequest(SetSelectionRequestType, (details) =>
+                this.setSelection(details),
+            ),
 
-            this.languageClient.onRequest(
-                NewFileRequestType,
-                (filePath) => this.newFile());
+            languageClient.onRequest(NewFileRequestType, (_content) =>
+                this.newFile(_content),
+            ),
 
-            this.languageClient.onRequest(
-                OpenFileRequestType,
-                (filePath) => this.openFile(filePath));
+            languageClient.onRequest(OpenFileRequestType, (filePath) =>
+                this.openFile(filePath),
+            ),
 
-            this.languageClient.onRequest(
-                CloseFileRequestType,
-                (filePath) => this.closeFile(filePath));
+            languageClient.onRequest(CloseFileRequestType, (filePath) =>
+                this.closeFile(filePath),
+            ),
 
-            this.languageClient.onRequest(
-                SaveFileRequestType,
-                (saveFileDetails) => this.saveFile(saveFileDetails));
+            languageClient.onRequest(SaveFileRequestType, (saveFileDetails) =>
+                this.saveFile(saveFileDetails),
+            ),
 
-            this.languageClient.onRequest(
+            languageClient.onRequest(
                 ShowInformationMessageRequestType,
-                (message) => this.showInformationMessage(message));
+                (message) => this.showInformationMessage(message),
+            ),
 
-            this.languageClient.onRequest(
-                ShowErrorMessageRequestType,
-                (message) => this.showErrorMessage(message));
+            languageClient.onRequest(ShowErrorMessageRequestType, (message) =>
+                this.showErrorMessage(message),
+            ),
 
-            this.languageClient.onRequest(
-                ShowWarningMessageRequestType,
-                (message) => this.showWarningMessage(message));
+            languageClient.onRequest(ShowWarningMessageRequestType, (message) =>
+                this.showWarningMessage(message),
+            ),
 
-            this.languageClient.onRequest(
+            languageClient.onRequest(
                 SetStatusBarMessageRequestType,
-                (messageDetails) => this.setStatusBarMessage(messageDetails));
-
-            this.languageClient.onNotification(
-                ClearTerminalNotificationType,
-                () => {
-                    // We check to see if they have TrueClear on. If not, no-op because the
-                    // overriden Clear-Host already calls [System.Console]::Clear()
-                    if (Settings.load().integratedConsole.forceClearScrollbackBuffer) {
-                        vscode.commands.executeCommand("workbench.action.terminal.clear");
-                    }
-                });
-        }
+                (messageDetails) => this.setStatusBarMessage(messageDetails),
+            ),
+
+            languageClient.onNotification(ClearTerminalNotificationType, () => {
+                // We check to see if they have TrueClear on. If not, no-op because the
+                // overriden Clear-Host already calls [System.Console]::Clear()
+                if (
+                    getSettings().integratedConsole.forceClearScrollbackBuffer
+                ) {
+                    void vscode.commands.executeCommand(
+                        "workbench.action.terminal.clear",
+                    );
+                }
+            }),
+        ];
     }
 
-    public dispose() {
-        this.command.dispose();
-        this.command2.dispose();
-        this.command3.dispose();
-        this.command4.dispose();
-        this.command5.dispose();
-        this.command6.dispose();
+    public dispose(): void {
+        for (const command of this.commands) {
+            command.dispose();
+        }
+        for (const handler of this.handlers) {
+            handler.dispose();
+        }
+        for (const statusBarMessage of this.statusBarMessages) {
+            statusBarMessage.dispose();
+        }
     }
 
-    private addExtensionCommand(command: IExtensionCommandAddedNotificationBody) {
-
+    private addExtensionCommand(
+        command: IExtensionCommandAddedNotificationBody,
+    ): void {
         this.extensionCommands.push({
             name: command.name,
             displayName: command.displayName,
@@ -321,322 +344,301 @@ export class ExtensionCommandsFeature extends LanguageClientConsumer {
 
         this.extensionCommands.sort(
             (a: IExtensionCommand, b: IExtensionCommand) =>
-                a.name.localeCompare(b.name));
+                a.name.localeCompare(b.name),
+        );
     }
 
-    private showExtensionCommands(client: LanguageClient): Thenable<IInvokeExtensionCommandRequestArguments> {
-
+    private async showExtensionCommands(): Promise<void> {
         // If no extension commands are available, show a message
         if (this.extensionCommands.length === 0) {
-            vscode.window.showInformationMessage(
-                "No extension commands have been loaded into the current session.");
-
+            void this.logger.writeAndShowInformation(
+                "No extension commands have been loaded into the current session.",
+            );
             return;
         }
 
         const quickPickItems =
-            this.extensionCommands.map<IExtensionCommandQuickPickItem>((command) => {
-                return {
-                    label: command.displayName,
-                    description: command.name,
-                    command,
-                };
-            });
+            this.extensionCommands.map<IExtensionCommandQuickPickItem>(
+                (command) => {
+                    return {
+                        label: command.displayName,
+                        description: command.name,
+                        command,
+                    };
+                },
+            );
+
+        const selectedCommand = await vscode.window.showQuickPick(
+            quickPickItems,
+            { placeHolder: "Select a command..." },
+        );
 
-        vscode.window
-            .showQuickPick(
-                quickPickItems,
-                { placeHolder: "Select a command" })
-            .then((command) => this.onCommandSelected(command, client));
+        return this.onCommandSelected(selectedCommand);
     }
 
-    private onCommandSelected(
-        chosenItem: IExtensionCommandQuickPickItem,
-        client: LanguageClient) {
-
+    private async onCommandSelected(
+        chosenItem?: IExtensionCommandQuickPickItem,
+    ): Promise<void> {
         if (chosenItem !== undefined) {
-            client.sendRequest(
-                InvokeExtensionCommandRequestType,
-                { name: chosenItem.command.name,
-                context: this.getEditorContext() });
+            const client = await LanguageClientConsumer.getLanguageClient();
+            await client.sendRequest(InvokeExtensionCommandRequestType, {
+                name: chosenItem.command.name,
+                context: this.getEditorContext(),
+            });
         }
     }
 
-    private insertText(details: IInsertTextRequestArguments): EditorOperationResponse {
+    private async insertText(
+        details: IInsertTextRequestArguments,
+    ): Promise<EditorOperationResponse> {
         const edit = new vscode.WorkspaceEdit();
 
-        edit.set(
-            vscode.Uri.parse(details.filePath),
-            [
-                new vscode.TextEdit(
-                    new vscode.Range(
-                        details.insertRange.start.line,
-                        details.insertRange.start.character,
-                        details.insertRange.end.line,
-                        details.insertRange.end.character),
-                        details.insertText),
-            ],
-        );
+        edit.set(vscode.Uri.parse(details.filePath), [
+            new vscode.TextEdit(
+                new vscode.Range(
+                    details.insertRange.start.line,
+                    details.insertRange.start.character,
+                    details.insertRange.end.line,
+                    details.insertRange.end.character,
+                ),
+                details.insertText,
+            ),
+        ]);
 
-        vscode.workspace.applyEdit(edit);
+        await vscode.workspace.applyEdit(edit);
 
         return EditorOperationResponse.Completed;
     }
 
-    private getEditorContext(): IEditorContext {
+    private getEditorContext(): IEditorContext | undefined {
+        if (vscode.window.activeTextEditor === undefined) {
+            return undefined;
+        }
+
         return {
-            currentFileContent: vscode.window.activeTextEditor.document.getText(),
-            currentFileLanguage: vscode.window.activeTextEditor.document.languageId,
-            currentFilePath: vscode.window.activeTextEditor.document.uri.toString(),
-            cursorPosition: asPosition(vscode.window.activeTextEditor.selection.active),
-            selectionRange:
-                asRange(
-                    new vscode.Range(
-                        vscode.window.activeTextEditor.selection.start,
-                        vscode.window.activeTextEditor.selection.end)),
+            currentFileContent:
+                vscode.window.activeTextEditor.document.getText(),
+            currentFileLanguage:
+                vscode.window.activeTextEditor.document.languageId,
+            currentFilePath:
+                vscode.window.activeTextEditor.document.uri.toString(),
+            cursorPosition: asPosition(
+                vscode.window.activeTextEditor.selection.active,
+            ),
+            selectionRange: asRange(
+                new vscode.Range(
+                    vscode.window.activeTextEditor.selection.start,
+                    vscode.window.activeTextEditor.selection.end,
+                ),
+            ),
         };
     }
 
-    private newFile(): Thenable<EditorOperationResponse> {
-        return vscode.workspace.openTextDocument({ content: ""})
-                     .then((doc) => vscode.window.showTextDocument(doc))
-                     .then((_) => EditorOperationResponse.Completed);
+    private async newFile(content: string): Promise<EditorOperationResponse> {
+        const doc = await vscode.workspace.openTextDocument({
+            language: "powershell",
+            content: content,
+        });
+        await vscode.window.showTextDocument(doc);
+        return EditorOperationResponse.Completed;
     }
 
-    private openFile(openFileDetails: IOpenFileDetails): Thenable<EditorOperationResponse> {
-
-        const filePath = this.normalizeFilePath(openFileDetails.filePath);
-
-        const promise =
-            vscode.workspace.openTextDocument(filePath)
-                .then((doc) => vscode.window.showTextDocument(
-                    doc,
-                    { preview: openFileDetails.preview }))
-                .then((_) => EditorOperationResponse.Completed);
-
-        return promise;
+    private async openFile(
+        openFileDetails: IOpenFileDetails,
+    ): Promise<EditorOperationResponse> {
+        const filePath = await this.resolveFilePathWithCwd(
+            openFileDetails.filePath,
+        );
+        try {
+            const doc = await vscode.workspace.openTextDocument(filePath);
+            await vscode.window.showTextDocument(doc, {
+                preview: openFileDetails.preview,
+            });
+        } catch {
+            void this.logger.writeAndShowWarning(
+                `File to open not found: ${filePath}`,
+            );
+            return EditorOperationResponse.Failed;
+        }
+        return EditorOperationResponse.Completed;
     }
 
-    private closeFile(filePath: string): Thenable<EditorOperationResponse> {
-
-        let promise: Thenable<EditorOperationResponse>;
-        if (this.findTextDocument(this.normalizeFilePath(filePath))) {
-            promise =
-                vscode.workspace.openTextDocument(filePath)
-                    .then((doc) => vscode.window.showTextDocument(doc))
-                    .then((editor) => vscode.commands.executeCommand("workbench.action.closeActiveEditor"))
-                    .then((_) => EditorOperationResponse.Completed);
-        } else {
-            promise = Promise.resolve(EditorOperationResponse.Completed);
+    private async closeFile(
+        filePath: string,
+    ): Promise<EditorOperationResponse> {
+        filePath = await this.resolveFilePathWithCwd(filePath);
+        const doc = vscode.workspace.textDocuments.find(
+            (x) => x.uri.fsPath === filePath,
+        );
+        if (doc != undefined && !doc.isClosed) {
+            await vscode.window.showTextDocument(doc);
+            await vscode.commands.executeCommand(
+                "workbench.action.closeActiveEditor",
+            );
+            return EditorOperationResponse.Completed;
         }
-
-        return promise;
+        void this.logger.writeAndShowWarning(
+            `File to close not found or already closed: ${filePath}`,
+        );
+        return EditorOperationResponse.Failed;
     }
 
     /**
      * Save a file, possibly to a new path. If the save is not possible, return a completed response
      * @param saveFileDetails the object detailing the path of the file to save and optionally its new path to save to
      */
-    private async saveFile(saveFileDetails: ISaveFileDetails): Promise<EditorOperationResponse> {
-        // Try to interpret the filepath as a URI, defaulting to "file://" if we don't succeed
+    private async saveFile(
+        saveFileDetails: ISaveFileDetails,
+    ): Promise<EditorOperationResponse> {
+        // Try to interpret the filePath as a URI, defaulting to "file://" if we don't succeed
         let currentFileUri: vscode.Uri;
-        if (saveFileDetails.filePath.startsWith("untitled") || saveFileDetails.filePath.startsWith("file")) {
+        if (
+            saveFileDetails.filePath.startsWith("untitled") ||
+            saveFileDetails.filePath.startsWith("file")
+        ) {
             currentFileUri = vscode.Uri.parse(saveFileDetails.filePath);
         } else {
-            currentFileUri = vscode.Uri.file(saveFileDetails.filePath);
+            const filePath = await this.resolveFilePathWithCwd(
+                saveFileDetails.filePath,
+            );
+            currentFileUri = vscode.Uri.file(filePath);
         }
 
-        let newFileAbsolutePath: string;
-        switch (currentFileUri.scheme) {
-            case "file":
-                // If the file to save can't be found, just complete the request
-                if (!this.findTextDocument(this.normalizeFilePath(currentFileUri.fsPath))) {
-                    this.log.writeAndShowError(`File to save not found: ${currentFileUri.fsPath}.`);
-                    return EditorOperationResponse.Completed;
-                }
-
-                // If no newFile is given, just save the current file
-                if (!saveFileDetails.newPath) {
-                    const doc = await vscode.workspace.openTextDocument(currentFileUri.fsPath);
-                    if (doc.isDirty) {
-                        await doc.save();
-                    }
-                    return EditorOperationResponse.Completed;
-                }
+        const doc = vscode.workspace.textDocuments.find(
+            (x) => x.uri.fsPath === currentFileUri.fsPath,
+        );
+        if (doc === undefined) {
+            void this.logger.writeAndShowWarning(
+                `File to save not found: ${currentFileUri.fsPath}`,
+            );
+            return EditorOperationResponse.Failed;
+        }
 
-                // Make sure we have an absolute path
-                if (path.isAbsolute(saveFileDetails.newPath)) {
-                    newFileAbsolutePath = saveFileDetails.newPath;
-                } else {
-                    // If not, interpret the path as relative to the current file
-                    newFileAbsolutePath = path.join(path.dirname(currentFileUri.fsPath), saveFileDetails.newPath);
-                }
-                break;
-
-            case "untitled":
-                // We need a new name to save an untitled file
-                if (!saveFileDetails.newPath) {
-                    // TODO: Create a class handle vscode warnings and errors so we can warn easily
-                    //       without logging
-                    this.log.writeAndShowWarning(
-                        "Cannot save untitled file. Try SaveAs(\"path/to/file.ps1\") instead.");
-                    return EditorOperationResponse.Completed;
+        let newFilePath = saveFileDetails.newPath ?? undefined; // Otherwise it's null.
+        if (currentFileUri.scheme === "file") {
+            // If no newFile is given, just save the current file
+            if (newFilePath === undefined) {
+                if (doc.isDirty) {
+                    await doc.save();
                 }
+                return EditorOperationResponse.Completed;
+            }
 
-                // Make sure we have an absolute path
-                if (path.isAbsolute(saveFileDetails.newPath)) {
-                    newFileAbsolutePath = saveFileDetails.newPath;
-                } else {
-                    // In fresh contexts, workspaceFolders is not defined...
-                    if (!vscode.workspace.workspaceFolders || vscode.workspace.workspaceFolders.length === 0) {
-                        this.log.writeAndShowWarning("Cannot save file to relative path: no workspaces are open. " +
-                            "Try saving to an absolute path, or open a workspace.");
-                        return EditorOperationResponse.Completed;
-                    }
+            // Special case where we interpret a path as relative to the current
+            // file, not the CWD!
+            if (!path.isAbsolute(newFilePath)) {
+                newFilePath = path.join(
+                    path.dirname(currentFileUri.fsPath),
+                    newFilePath,
+                );
+            }
+        } else if (currentFileUri.scheme === "untitled") {
+            // We need a new name to save an untitled file
+            if (newFilePath === undefined) {
+                void this.logger.writeAndShowWarning(
+                    'Cannot save untitled file! Try SaveAs("path/to/file.ps1") instead.',
+                );
+                return EditorOperationResponse.Failed;
+            }
 
-                    // If not, interpret the path as relative to the workspace root
-                    const workspaceRootUri = vscode.workspace.workspaceFolders[0].uri;
-                    // We don't support saving to a non-file URI-schemed workspace
-                    if (workspaceRootUri.scheme !== "file") {
-                        this.log.writeAndShowWarning(
-                            "Cannot save untitled file to a relative path in an untitled workspace. " +
-                            "Try saving to an absolute path or opening a workspace folder.");
-                        return EditorOperationResponse.Completed;
-                    }
-                    newFileAbsolutePath = path.join(workspaceRootUri.fsPath, saveFileDetails.newPath);
-                }
-                break;
-
-            default:
-                // Other URI schemes are not supported
-                const msg = JSON.stringify(saveFileDetails);
-                this.log.writeVerbose(
-                    `<${ExtensionCommandsFeature.name}>: Saving a document with scheme '${currentFileUri.scheme}' ` +
-                    `is currently unsupported. Message: '${msg}'`);
-                return EditorOperationResponse.Completed;
+            newFilePath = await this.resolveFilePathWithCwd(newFilePath);
+        } else {
+            // Other URI schemes are not supported
+            const msg = JSON.stringify(saveFileDetails, undefined, 2);
+            void this.logger.writeAndShowWarning(
+                `<${ExtensionCommandsFeature.name}>: Saving a document with scheme '${currentFileUri.scheme}' ` +
+                    `is currently unsupported. Message: '${msg}'`,
+            );
+            return EditorOperationResponse.Failed;
         }
 
-        await this.saveDocumentContentToAbsolutePath(currentFileUri, newFileAbsolutePath);
-        return EditorOperationResponse.Completed;
-
+        return await this.saveFileAs(doc, newFilePath);
     }
 
     /**
      * Take a document available to vscode at the given URI and save it to the given absolute path
      * @param documentUri the URI of the vscode document to save
-     * @param destinationAbsolutePath the absolute path to save the document contents to
+     * @param filePath the absolute path to save the document contents to
      */
-    private async saveDocumentContentToAbsolutePath(
-        documentUri: vscode.Uri,
-        destinationAbsolutePath: string): Promise<void> {
-            // Retrieve the text out of the current document
-            const oldDocument = await vscode.workspace.openTextDocument(documentUri);
-
-            // Write it to the new document path
-            try {
-                // TODO: Change this to be asyncronous
-                await new Promise<void>((resolve, reject) => {
-                    fs.writeFile(destinationAbsolutePath, oldDocument.getText(), (err) => {
-                        if (err) {
-                            return reject(err);
-                        }
-                        return resolve();
-                    });
-                });
-            } catch (e) {
-                this.log.writeAndShowWarning(`<${ExtensionCommandsFeature.name}>: ` +
-                    `Unable to save file to path '${destinationAbsolutePath}': ${e}`);
-                return;
-            }
+    private async saveFileAs(
+        doc: vscode.TextDocument,
+        filePath: string,
+    ): Promise<EditorOperationResponse> {
+        // Write the old document's contents to the new document path
+        const newFileUri = vscode.Uri.file(filePath);
+        try {
+            await vscode.workspace.fs.writeFile(
+                newFileUri,
+                Buffer.from(doc.getText()),
+            );
+        } catch (err) {
+            void this.logger.writeAndShowWarning(
+                `<${ExtensionCommandsFeature.name}>: ` +
+                    `Unable to save file to path '${filePath}': ${err}`,
+            );
+            return EditorOperationResponse.Failed;
+        }
 
-            // Finally open the new document
-            const newFileUri = vscode.Uri.file(destinationAbsolutePath);
-            const newFile = await vscode.workspace.openTextDocument(newFileUri);
-            vscode.window.showTextDocument(newFile, { preview: true });
+        // Finally open the new document
+        const newFile = await vscode.workspace.openTextDocument(newFileUri);
+        await vscode.window.showTextDocument(newFile, { preview: true });
+        return EditorOperationResponse.Completed;
     }
 
-    private normalizeFilePath(filePath: string): string {
-        const platform = os.platform();
-        if (platform === "win32") {
-            // Make sure the file path is absolute
-            if (!path.win32.isAbsolute(filePath)) {
-                filePath = path.win32.resolve(
-                    vscode.workspace.rootPath,
-                    filePath);
-            }
-
-            // Normalize file path case for comparison for Windows
-            return filePath.toLowerCase();
-        } else {
-            // Make sure the file path is absolute
-            if (!path.isAbsolute(filePath)) {
-                filePath = path.resolve(
-                    vscode.workspace.rootPath,
-                    filePath);
-            }
-
-            // macOS is case-insensitive
-            if (platform === "darwin") {
-                filePath = filePath.toLowerCase();
-            }
-
-            return  filePath;
+    // Resolve file path against user's CWD setting
+    private async resolveFilePathWithCwd(filePath: string): Promise<string> {
+        if (!path.isAbsolute(filePath)) {
+            const cwd = await validateCwdSetting(this.logger);
+            return path.resolve(cwd, filePath);
         }
+        return filePath;
     }
 
-    private findTextDocument(filePath: string): boolean {
-        // since Windows and macOS are case-insensitive, we need to normalize them differently
-        const canFind = vscode.workspace.textDocuments.find((doc) => {
-            let docPath;
-            const platform = os.platform();
-            if (platform === "win32" || platform === "darwin") {
-                // for Windows and macOS paths, they are normalized to be lowercase
-                docPath = doc.fileName.toLowerCase();
-            } else {
-                docPath = doc.fileName;
-            }
-            return docPath === filePath;
-        });
-
-        return canFind != null;
+    private setSelection(
+        details: ISetSelectionRequestArguments,
+    ): EditorOperationResponse {
+        if (vscode.window.activeTextEditor !== undefined) {
+            vscode.window.activeTextEditor.selections = [
+                new vscode.Selection(
+                    asCodePosition(details.selectionRange.start),
+                    asCodePosition(details.selectionRange.end),
+                ),
+            ];
+            return EditorOperationResponse.Completed;
+        }
+        return EditorOperationResponse.Failed;
     }
 
-    private setSelection(details: ISetSelectionRequestArguments): EditorOperationResponse {
-        vscode.window.activeTextEditor.selections = [
-            new vscode.Selection(
-                asCodePosition(details.selectionRange.start),
-                asCodePosition(details.selectionRange.end)),
-        ];
-
+    private showInformationMessage(message: string): EditorOperationResponse {
+        void this.logger.writeAndShowInformation(message);
         return EditorOperationResponse.Completed;
     }
 
-    private showInformationMessage(message: string): Thenable<EditorOperationResponse> {
-        return vscode.window
-                     .showInformationMessage(message)
-                     .then((_) => EditorOperationResponse.Completed);
-    }
-
-    private showErrorMessage(message: string): Thenable<EditorOperationResponse> {
-        return vscode.window
-                     .showErrorMessage(message)
-                     .then((_) => EditorOperationResponse.Completed);
+    private showErrorMessage(message: string): EditorOperationResponse {
+        void this.logger.writeAndShowError(message);
+        return EditorOperationResponse.Completed;
     }
 
-    private showWarningMessage(message: string): Thenable<EditorOperationResponse> {
-        return vscode.window
-                     .showWarningMessage(message)
-                     .then((_) => EditorOperationResponse.Completed);
+    private showWarningMessage(message: string): EditorOperationResponse {
+        void this.logger.writeAndShowWarning(message);
+        return EditorOperationResponse.Completed;
     }
 
-    private setStatusBarMessage(messageDetails: IStatusBarMessageDetails): EditorOperationResponse {
-
+    private setStatusBarMessage(
+        messageDetails: IStatusBarMessageDetails,
+    ): EditorOperationResponse {
         if (messageDetails.timeout) {
-            vscode.window.setStatusBarMessage(messageDetails.message, messageDetails.timeout);
+            this.statusBarMessages.push(
+                vscode.window.setStatusBarMessage(
+                    messageDetails.message,
+                    messageDetails.timeout,
+                ),
+            );
         } else {
-            vscode.window.setStatusBarMessage(messageDetails.message);
+            this.statusBarMessages.push(
+                vscode.window.setStatusBarMessage(messageDetails.message),
+            );
         }
-
         return EditorOperationResponse.Completed;
     }
 }
diff --git a/src/features/ExternalApi.ts b/src/features/ExternalApi.ts
index f83c45680c..cafd856c26 100644
--- a/src/features/ExternalApi.ts
+++ b/src/features/ExternalApi.ts
@@ -1,10 +1,9 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
+import { v4 as uuidv4 } from "uuid";
 import * as vscode from "vscode";
-import { v4 as uuidv4 } from 'uuid';
-import { LanguageClientConsumer } from "../languageClientConsumer";
-import { Logger } from "../logging";
+import type { ILogger } from "../logging";
 import { SessionManager } from "../session";
 
 export interface IExternalPowerShellDetails {
@@ -17,8 +16,12 @@ export interface IExternalPowerShellDetails {
 export interface IPowerShellExtensionClient {
     registerExternalExtension(id: string, apiVersion?: string): string;
     unregisterExternalExtension(uuid: string): boolean;
-    getPowerShellVersionDetails(uuid: string): Promise<IExternalPowerShellDetails>;
+    getPowerShellVersionDetails(
+        uuid: string,
+    ): Promise<IExternalPowerShellDetails>;
     waitUntilStarted(uuid: string): Promise<void>;
+    getStorageUri(): vscode.Uri;
+    getLogUri(): vscode.Uri;
 }
 
 /*
@@ -32,12 +35,17 @@ NOTE: At some point, we should release a helper npm package that wraps the API a
 * Manages session id for you
 
 */
-export class ExternalApiFeature extends LanguageClientConsumer implements IPowerShellExtensionClient {
-    private static readonly registeredExternalExtension: Map<string, IExternalExtension> = new Map<string, IExternalExtension>();
-
-    constructor(private sessionManager: SessionManager, private log: Logger) {
-        super();
-    }
+export class ExternalApiFeature implements IPowerShellExtensionClient {
+    private static readonly registeredExternalExtension: Map<
+        string,
+        IExternalExtension
+    > = new Map<string, IExternalExtension>();
+
+    constructor(
+        private extensionContext: vscode.ExtensionContext,
+        private sessionManager: SessionManager,
+        private logger: ILogger,
+    ) {}
 
     /*
     DESCRIPTION:
@@ -52,30 +60,42 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
     RETURNS:
         string session uuid
     */
-    public registerExternalExtension(id: string, apiVersion: string = 'v1'): string {
-        this.log.writeDiagnostic(`Registering extension '${id}' for use with API version '${apiVersion}'.`);
-
-        for (const [_, externalExtension] of ExternalApiFeature.registeredExternalExtension) {
+    public registerExternalExtension(id: string, apiVersion = "v1"): string {
+        this.logger.writeDebug(
+            `Registering extension '${id}' for use with API version '${apiVersion}'.`,
+        );
+
+        for (const [
+            _name,
+            externalExtension,
+        ] of ExternalApiFeature.registeredExternalExtension) {
             if (externalExtension.id === id) {
                 const message = `The extension '${id}' is already registered.`;
-                this.log.writeWarning(message);
+                this.logger.writeWarning(message);
                 throw new Error(message);
             }
         }
 
-        if (!vscode.extensions.all.some(ext => ext.id === id)) {
-            throw new Error(`No extension installed with id '${id}'. You must use a valid extension id.`);
+        if (!vscode.extensions.all.some((ext) => ext.id === id)) {
+            throw new Error(
+                `No extension installed with id '${id}'. You must use a valid extension id.`,
+            );
         }
 
-        // If we're in development mode, we allow these to be used for testing purposes.
-        if (!this.sessionManager.InDevelopmentMode && (id === "ms-vscode.PowerShell" || id === "ms-vscode.PowerShell-Preview")) {
-            throw new Error("You can't use the PowerShell extension's id in this registration.");
+        // Our ID is only only allowed to be used in our unit tests.
+        if (
+            id === "ms-vscode.powershell" &&
+            !(this.extensionContext.extensionMode === vscode.ExtensionMode.Test)
+        ) {
+            throw new Error(
+                "You can't use the PowerShell extension's id in this registration.",
+            );
         }
 
         const uuid = uuidv4();
         ExternalApiFeature.registeredExternalExtension.set(uuid, {
             id,
-            apiVersion
+            apiVersion,
         });
         return uuid;
     }
@@ -92,22 +112,27 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
     RETURNS:
         true if it worked, otherwise throws an error.
     */
-    public unregisterExternalExtension(uuid: string = ""): boolean {
-        this.log.writeDiagnostic(`Unregistering extension with session UUID: ${uuid}`);
+    public unregisterExternalExtension(uuid = ""): boolean {
+        this.logger.writeDebug(
+            `Unregistering extension with session UUID: ${uuid}`,
+        );
         if (!ExternalApiFeature.registeredExternalExtension.delete(uuid)) {
-            throw new Error(`No extension registered with session UUID: ${uuid}`);
+            throw new Error(
+                `No extension registered with session UUID: ${uuid}`,
+            );
         }
         return true;
     }
 
-    private getRegisteredExtension(uuid: string = ""): IExternalExtension {
+    private getRegisteredExtension(uuid = ""): IExternalExtension {
         if (!ExternalApiFeature.registeredExternalExtension.has(uuid)) {
             throw new Error(
-                "UUID provided was invalid, make sure you ran the 'powershellExtensionClient.registerExternalExtension(extensionId)' method and pass in the UUID that it returns to subsequent methods.");
+                "UUID provided was invalid, make sure you ran the 'powershellExtensionClient.registerExternalExtension(extensionId)' method and pass in the UUID that it returns to subsequent methods.",
+            );
         }
 
         // TODO: When we have more than one API version, make sure to include a check here.
-        return ExternalApiFeature.registeredExternalExtension.get(uuid);
+        return ExternalApiFeature.registeredExternalExtension.get(uuid)!;
     }
 
     /*
@@ -128,18 +153,26 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
             architecture: string;
         }
     */
-    public async getPowerShellVersionDetails(uuid: string = ""): Promise<IExternalPowerShellDetails> {
+    public async getPowerShellVersionDetails(
+        uuid = "",
+    ): Promise<IExternalPowerShellDetails> {
         const extension = this.getRegisteredExtension(uuid);
-        this.log.writeDiagnostic(`Extension '${extension.id}' called 'getPowerShellVersionDetails'`);
+        this.logger.writeDebug(
+            `Extension '${extension.id}' called 'getPowerShellVersionDetails'.`,
+        );
 
         await this.sessionManager.waitUntilStarted();
-        const versionDetails = this.sessionManager.getPowerShellVersionDetails();
+        const versionDetails =
+            this.sessionManager.getPowerShellVersionDetails();
 
         return {
-            exePath: this.sessionManager.PowerShellExeDetails.exePath,
-            version: versionDetails.version,
-            displayName: this.sessionManager.PowerShellExeDetails.displayName, // comes from the Session Menu
-            architecture: versionDetails.architecture
+            exePath:
+                this.sessionManager.PowerShellExeDetails?.exePath ?? "unknown",
+            version: versionDetails?.version ?? "unknown",
+            displayName:
+                this.sessionManager.PowerShellExeDetails?.displayName ??
+                "unknown", // comes from the Session Menu
+            architecture: versionDetails?.architecture ?? "unknown",
         };
     }
     /*
@@ -156,13 +189,25 @@ export class ExternalApiFeature extends LanguageClientConsumer implements IPower
         If the extension is not started by some mechanism
         then this will wait indefinitely.
     */
-    public async waitUntilStarted(uuid: string = ""): Promise<void> {
+    public async waitUntilStarted(uuid = ""): Promise<void> {
         const extension = this.getRegisteredExtension(uuid);
-        this.log.writeDiagnostic(`Extension '${extension.id}' called 'waitUntilStarted'`);
-        return this.sessionManager.waitUntilStarted();
+        this.logger.writeDebug(
+            `Extension '${extension.id}' called 'waitUntilStarted'.`,
+        );
+        await this.sessionManager.waitUntilStarted();
+    }
+
+    public getStorageUri(): vscode.Uri {
+        // We have to override the scheme because it defaults to
+        // 'vscode-userdata' which breaks UNC paths.
+        return this.extensionContext.globalStorageUri.with({ scheme: "file" });
+    }
+
+    public getLogUri(): vscode.Uri {
+        return this.extensionContext.logUri.with({ scheme: "file" });
     }
 
-    public dispose() {
+    public dispose(): void {
         // Nothing to dispose.
     }
 }
diff --git a/src/features/FindModule.ts b/src/features/FindModule.ts
deleted file mode 100644
index 1a50580ffd..0000000000
--- a/src/features/FindModule.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import vscode = require("vscode");
-import { RequestType } from "vscode-languageclient";
-import QuickPickItem = vscode.QuickPickItem;
-import { LanguageClientConsumer } from "../languageClientConsumer";
-
-export const FindModuleRequestType =
-    new RequestType<any, any, void>("powerShell/findModule");
-
-export const InstallModuleRequestType =
-    new RequestType<string, void, void>("powerShell/installModule");
-
-export class FindModuleFeature extends LanguageClientConsumer {
-
-    private command: vscode.Disposable;
-    private cancelFindToken: vscode.CancellationTokenSource;
-
-    constructor() {
-        super();
-        this.command = vscode.commands.registerCommand("PowerShell.PowerShellFindModule", () => {
-            // It takes a while to get the list of PowerShell modules, display some UI to let user know
-            this.cancelFindToken = new vscode.CancellationTokenSource();
-            vscode.window
-                .showQuickPick(
-                ["Cancel"],
-                { placeHolder: "Please wait, retrieving list of PowerShell modules. This can take some time..." },
-                this.cancelFindToken.token)
-                .then((response) => {
-                    if (response === "Cancel") { this.clearCancelFindToken(); }
-                });
-
-            // Cancel the loading prompt after 60 seconds
-            setTimeout(() => {
-                if (this.cancelFindToken) {
-                    this.clearCancelFindToken();
-
-                    vscode.window.showErrorMessage(
-                        "The online source for PowerShell modules is not responding. " +
-                        "Cancelling Find/Install PowerShell command.");
-                }
-            }, 60000);
-
-            this.pickPowerShellModule().then((moduleName) => {
-                if (moduleName) {
-                    // vscode.window.setStatusBarMessage("Installing PowerShell Module " + moduleName, 1500);
-                    this.languageClient.sendRequest(InstallModuleRequestType, moduleName);
-                }
-            });
-        });
-    }
-
-    public dispose() {
-        this.command.dispose();
-    }
-
-    private pickPowerShellModule(): Thenable<string> {
-        return this.languageClient.sendRequest(FindModuleRequestType, null).then((modules) => {
-            const items: QuickPickItem[] = [];
-
-            // We've got the modules info, let's cancel the timeout unless it's already been cancelled
-            if (this.cancelFindToken) {
-                this.clearCancelFindToken();
-            } else {
-                // Already timed out, would be weird to dislay modules after we said it timed out.
-                return Promise.resolve("");
-            }
-
-            for (const item in modules) {
-                if (modules.hasOwnProperty(item)) {
-                    items.push({ label: modules[item].name, description: modules[item].description });
-                }
-            }
-
-            if (items.length === 0) {
-                return Promise.reject("No PowerShell modules were found.");
-            }
-
-            const options: vscode.QuickPickOptions = {
-                placeHolder: "Select a PowerShell module to install",
-                matchOnDescription: true,
-                matchOnDetail: true,
-            };
-
-            return vscode.window.showQuickPick(items, options).then((item) => {
-                return item ? item.label : "";
-            });
-        });
-    }
-
-    private clearCancelFindToken() {
-        if (this.cancelFindToken) {
-            this.cancelFindToken.dispose();
-            this.cancelFindToken = undefined;
-        }
-    }
-}
diff --git a/src/features/GenerateBugReport.ts b/src/features/GenerateBugReport.ts
index c9c1d4d2c3..6539f978d9 100644
--- a/src/features/GenerateBugReport.ts
+++ b/src/features/GenerateBugReport.ts
@@ -1,120 +1,57 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import os = require("os");
 import vscode = require("vscode");
+import child_process = require("child_process");
 import { SessionManager } from "../session";
-import Settings = require("../settings");
 
-const queryStringPrefix: string = "?";
-
-const settings = Settings.load();
-const project = settings.bugReporting.project;
-const issuesUrl: string = `${project}/issues/new`;
-
-const extensions =
-    vscode.extensions.all.filter((element) => element.packageJSON.isBuiltin === false)
-        .sort((leftside, rightside): number => {
-            if (leftside.packageJSON.name.toLowerCase() < rightside.packageJSON.name.toLowerCase()) {
-                return -1;
-            }
-            if (leftside.packageJSON.name.toLowerCase() > rightside.packageJSON.name.toLowerCase()) {
-                return 1;
-            }
-            return 0;
-        });
+const issuesUrl = "https://github.com/PowerShell/vscode-powershell/issues/new?";
 
 export class GenerateBugReportFeature implements vscode.Disposable {
-
     private command: vscode.Disposable;
 
     constructor(private sessionManager: SessionManager) {
-        this.command = vscode.commands.registerCommand("PowerShell.GenerateBugReport", () => {
-
-            const body = `Issue Description
-=====
-
-I am experiencing a problem with...
-
-Attached Logs
-=====
-
-Follow the instructions in the [README](https://github.com/PowerShell/vscode-powershell/blob/master/docs/troubleshooting.md) about
-capturing and sending logs.
-
-Environment Information
-=====
-
-Visual Studio Code
------
-
-| Name | Version |
-| --- | --- |
-| Operating System | ${os.type()} ${os.arch()} ${os.release()} |
-| VSCode | ${vscode.version}|
-| PowerShell Extension Version | ${sessionManager.HostVersion} |
-
-PowerShell Information
------
-
-${this.getRuntimeInfo()}
-
-Visual Studio Code Extensions
------
-
-<details><summary>Visual Studio Code Extensions(Click to Expand)</summary>
-
-${this.generateExtensionTable(extensions)}
-</details>
-
-`;
-
-            const encodedBody = encodeURIComponent(body);
-            const fullUrl = `${issuesUrl}${queryStringPrefix}body=${encodedBody}`;
-            vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(fullUrl));
-        });
+        this.command = vscode.commands.registerCommand(
+            "PowerShell.GenerateBugReport",
+            async () => {
+                const params = [
+                    "labels=Issue-Bug",
+                    "template=bug-report.yml",
+                    "powershell-version=" + this.getRuntimeInfo(),
+                    "vscode-version=" + vscode.version + "\n" + process.arch,
+                    "extension-version=" +
+                        sessionManager.Publisher +
+                        "." +
+                        sessionManager.HostName +
+                        "@" +
+                        sessionManager.HostVersion,
+                ];
+                const url = vscode.Uri.parse(
+                    issuesUrl + encodeURIComponent(params.join("&")),
+                );
+                await vscode.env.openExternal(url);
+            },
+        );
     }
 
-    public dispose() {
+    public dispose(): void {
         this.command.dispose();
     }
 
-    private generateExtensionTable(installedExtensions): string {
-        if (!installedExtensions.length) {
-            return "none";
+    private getRuntimeInfo(): string {
+        if (this.sessionManager.PowerShellExeDetails === undefined) {
+            return "Session's PowerShell details are unknown!";
         }
-
-        const tableHeader = `|Extension|Author|Version|\n|---|---|---|`;
-        const table = installedExtensions.map((e) => {
-            if (e.packageJSON.isBuiltin === false) {
-                return `|${e.packageJSON.name}|${e.packageJSON.publisher}|${e.packageJSON.version}|`;
-            }
-        }).join("\n");
-
-        const extensionTable = `
-${tableHeader}\n${table};
-`;
-        // 2000 chars is browsers de-facto limit for URLs, 400 chars are allowed for other string parts of the issue URL
-        // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
-        // if (encodeURIComponent(extensionTable).length > 1600) {
-        //     return 'the listing length exceeds browsers\' URL characters limit';
-        // }
-
-        return extensionTable;
-    }
-
-    private getRuntimeInfo() {
-
-        const powerShellExePath = this.sessionManager.PowerShellExeDetails.exePath;
-        const powerShellArgs = [
-            "-NoProfile",
-            "-Command",
-            '$PSVersionString = "|Name|Value|\n"; $PSVersionString += "|---|---|\n"; $PSVersionTable.keys | ' +
-            'ForEach-Object { $PSVersionString += "|$_|$($PSVersionTable.Item($_))|\n" }; $PSVersionString',
-        ];
-
-        const spawn = require("child_process").spawnSync;
-        const child = spawn(powerShellExePath, powerShellArgs);
-        return child.stdout.toString().replace(";", ",");
+        const child = child_process.spawnSync(
+            this.sessionManager.PowerShellExeDetails.exePath,
+            [
+                "-NoProfile",
+                "-NoLogo",
+                "-Command",
+                "$PSVersionTable | Out-String",
+            ],
+        );
+        // Replace semicolons as they'll cause the URI component to truncate
+        return child.stdout.toString().trim().replace(";", ",");
     }
 }
diff --git a/src/features/GetCommands.ts b/src/features/GetCommands.ts
index c97ce92a1b..52d007532e 100644
--- a/src/features/GetCommands.ts
+++ b/src/features/GetCommands.ts
@@ -4,8 +4,8 @@
 import * as vscode from "vscode";
 import { RequestType0 } from "vscode-languageclient";
 import { LanguageClient } from "vscode-languageclient/node";
-import { Logger } from "../logging";
 import { LanguageClientConsumer } from "../languageClientConsumer";
+import { getSettings } from "../settings";
 
 interface ICommand {
     name: string;
@@ -19,66 +19,94 @@ interface ICommand {
  * RequestType sent over to PSES.
  * Expects: ICommand to be returned
  */
-export const GetCommandRequestType = new RequestType0<ICommand[], void>("powerShell/getCommand");
+export const GetCommandRequestType = new RequestType0<ICommand[], void>(
+    "powerShell/getCommand",
+);
 
 /**
  * A PowerShell Command listing feature. Implements a treeview control.
  */
 export class GetCommandsFeature extends LanguageClientConsumer {
-    private command: vscode.Disposable;
+    private commands: vscode.Disposable[];
     private commandsExplorerProvider: CommandsExplorerProvider;
     private commandsExplorerTreeView: vscode.TreeView<Command>;
 
-    constructor(private log: Logger) {
+    constructor() {
         super();
-        this.command = vscode.commands.registerCommand("PowerShell.RefreshCommandsExplorer",
-            () => this.CommandExplorerRefresh());
+        this.commands = [
+            vscode.commands.registerCommand(
+                "PowerShell.RefreshCommandsExplorer",
+                async () => {
+                    await this.CommandExplorerRefresh();
+                },
+            ),
+            vscode.commands.registerCommand(
+                "PowerShell.InsertCommand",
+                async (item) => {
+                    await this.InsertCommand(item);
+                },
+            ),
+        ];
         this.commandsExplorerProvider = new CommandsExplorerProvider();
 
-        this.commandsExplorerTreeView = vscode.window.createTreeView<Command>("PowerShellCommands",
-            { treeDataProvider: this.commandsExplorerProvider });
+        this.commandsExplorerTreeView = vscode.window.createTreeView<Command>(
+            "PowerShellCommands",
+            { treeDataProvider: this.commandsExplorerProvider },
+        );
 
         // Refresh the command explorer when the view is visible
-        this.commandsExplorerTreeView.onDidChangeVisibility( (e) => {
+        this.commandsExplorerTreeView.onDidChangeVisibility(async (e) => {
             if (e.visible) {
-                this.CommandExplorerRefresh();
+                await this.CommandExplorerRefresh();
             }
         });
-
-        vscode.commands.registerCommand("PowerShell.InsertCommand", (item) => this.InsertCommand(item));
     }
 
-    public dispose() {
-        this.command.dispose();
+    public dispose(): void {
+        for (const command of this.commands) {
+            command.dispose();
+        }
     }
 
-    public setLanguageClient(languageclient: LanguageClient) {
-        this.languageClient = languageclient;
+    public override onLanguageClientSet(_languageClient: LanguageClient): void {
         if (this.commandsExplorerTreeView.visible) {
-            vscode.commands.executeCommand("PowerShell.RefreshCommandsExplorer");
+            void vscode.commands.executeCommand(
+                "PowerShell.RefreshCommandsExplorer",
+            );
         }
     }
 
-    private CommandExplorerRefresh() {
-        if (this.languageClient === undefined) {
-            this.log.writeVerbose(`<${GetCommandsFeature.name}>: Unable to send getCommand request`);
-            return;
-        }
-        this.languageClient.sendRequest(GetCommandRequestType).then((result) => {
-            const SidebarConfig = vscode.workspace.getConfiguration("powershell.sideBar");
-            const excludeFilter = (SidebarConfig.CommandExplorerExcludeFilter).map((filter) => filter.toLowerCase());
-            result = result.filter((command) => (excludeFilter.indexOf(command.moduleName.toLowerCase()) === -1));
-            this.commandsExplorerProvider.powerShellCommands = result.map(toCommand);
-            this.commandsExplorerProvider.refresh();
-        });
+    private async CommandExplorerRefresh(): Promise<void> {
+        const client = await LanguageClientConsumer.getLanguageClient();
+        const result = await client.sendRequest(GetCommandRequestType);
+        const exclusions = getSettings().sideBar.CommandExplorerExcludeFilter;
+        const excludeFilter = exclusions.map((filter: string) =>
+            filter.toLowerCase(),
+        );
+        const filteredResult = result.filter(
+            (command) =>
+                !excludeFilter.includes(command.moduleName.toLowerCase()),
+        );
+        this.commandsExplorerProvider.powerShellCommands =
+            filteredResult.map(toCommand);
+        this.commandsExplorerProvider.refresh();
     }
 
-    private InsertCommand(item) {
+    private async InsertCommand(item: { Name: string }): Promise<void> {
         const editor = vscode.window.activeTextEditor;
+        if (editor === undefined) {
+            return;
+        }
+
         const sls = editor.selection.start;
         const sle = editor.selection.end;
-        const range = new vscode.Range(sls.line, sls.character, sle.line, sle.character);
-        editor.edit((editBuilder) => {
+        const range = new vscode.Range(
+            sls.line,
+            sls.character,
+            sle.line,
+            sle.character,
+        );
+        await editor.edit((editBuilder) => {
             editBuilder.replace(range, item.Name);
         });
     }
@@ -86,8 +114,9 @@ export class GetCommandsFeature extends LanguageClientConsumer {
 
 class CommandsExplorerProvider implements vscode.TreeDataProvider<Command> {
     public readonly onDidChangeTreeData: vscode.Event<Command | undefined>;
-    public powerShellCommands: Command[];
-    private didChangeTreeData: vscode.EventEmitter<Command | undefined> = new vscode.EventEmitter<Command>();
+    public powerShellCommands: Command[] = [];
+    private didChangeTreeData: vscode.EventEmitter<Command | undefined> =
+        new vscode.EventEmitter<Command>();
 
     constructor() {
         this.onDidChangeTreeData = this.didChangeTreeData.event;
@@ -101,8 +130,8 @@ class CommandsExplorerProvider implements vscode.TreeDataProvider<Command> {
         return element;
     }
 
-    public getChildren(element?: Command): Thenable<Command[]> {
-        return Promise.resolve(this.powerShellCommands || []);
+    public getChildren(_element?: Command): Thenable<Command[]> {
+        return Promise.resolve(this.powerShellCommands);
     }
 }
 
@@ -123,7 +152,8 @@ class Command extends vscode.TreeItem {
         public readonly defaultParameterSet: string,
         public readonly ParameterSets: object,
         public readonly Parameters: object,
-        public readonly collapsibleState = vscode.TreeItemCollapsibleState.None,
+        public override readonly collapsibleState = vscode
+            .TreeItemCollapsibleState.None,
     ) {
         super(Name, collapsibleState);
     }
@@ -135,9 +165,9 @@ class Command extends vscode.TreeItem {
         };
     }
 
-    public async getChildren(element?): Promise<Command[]> {
-        return [];
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/require-await
+    public async getChildren(_element?: any): Promise<Command[]> {
         // Returning an empty array because we need to return something.
+        return [];
     }
-
 }
diff --git a/src/features/HelpCompletion.ts b/src/features/HelpCompletion.ts
index 14263d10b1..bf439748d2 100644
--- a/src/features/HelpCompletion.ts
+++ b/src/features/HelpCompletion.ts
@@ -1,57 +1,65 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import { Disposable, EndOfLine, Position, Range, SnippetString,
-    TextDocument, TextDocumentChangeEvent, window, workspace } from "vscode";
+import {
+    Disposable,
+    EndOfLine,
+    Range,
+    SnippetString,
+    type TextDocument,
+    type TextDocumentChangeEvent,
+    window,
+    workspace,
+} from "vscode";
 import { RequestType } from "vscode-languageclient";
 import { LanguageClient } from "vscode-languageclient/node";
-import { Logger } from "../logging";
-import Settings = require("../settings");
 import { LanguageClientConsumer } from "../languageClientConsumer";
+import { CommentType, getSettings, Settings } from "../settings";
 
-export const CommentHelpRequestType =
-    new RequestType<any, any, void>("powerShell/getCommentHelp");
+interface ICommentHelpRequestArguments {}
 
-interface ICommentHelpRequestParams {
-    documentUri: string;
-    triggerPosition: Position;
-    blockComment: boolean;
-}
-
-interface ICommentHelpRequestResult {
+interface ICommentHelpRequestResponse {
     content: string[];
 }
 
-enum SearchState { Searching, Locked, Found }
+export const CommentHelpRequestType = new RequestType<
+    ICommentHelpRequestArguments,
+    ICommentHelpRequestResponse,
+    void
+>("powerShell/getCommentHelp");
+
+enum SearchState {
+    Searching,
+    Locked,
+    Found,
+}
 
 export class HelpCompletionFeature extends LanguageClientConsumer {
-    private helpCompletionProvider: HelpCompletionProvider;
-    private disposable: Disposable;
-    private settings: Settings.ISettings;
+    private helpCompletionProvider: HelpCompletionProvider | undefined;
+    private disposable: Disposable | undefined;
+    private settings: Settings;
 
-    constructor(private log: Logger) {
+    constructor() {
         super();
-        this.settings = Settings.load();
+        this.settings = getSettings();
 
-        if (this.settings.helpCompletion !== Settings.CommentType.Disabled) {
+        if (this.settings.helpCompletion !== CommentType.Disabled) {
             this.helpCompletionProvider = new HelpCompletionProvider();
-            const subscriptions = [];
-            workspace.onDidChangeTextDocument(this.onEvent, this, subscriptions);
-            this.disposable = Disposable.from(...subscriptions);
+            this.disposable = workspace.onDidChangeTextDocument(async (e) => {
+                await this.onEvent(e);
+            });
         }
     }
 
-    public dispose() {
-        if (this.disposable) {
-            this.disposable.dispose();
-        }
+    public dispose(): void {
+        this.disposable?.dispose();
     }
 
-    public setLanguageClient(languageClient: LanguageClient) {
-        this.languageClient = languageClient;
-        if (this.helpCompletionProvider) {
-            this.helpCompletionProvider.languageClient = languageClient;
-        }
+    public override onLanguageClientSet(languageClient: LanguageClient): void {
+        // Our helper class isn't in the session's list of language client
+        // consumers since we optionally create it, so we have to set it
+        // manually.
+        this.helpCompletionProvider?.onLanguageClientSet(languageClient);
     }
 
     public async onEvent(changeEvent: TextDocumentChangeEvent): Promise<void> {
@@ -60,22 +68,17 @@ export class HelpCompletionFeature extends LanguageClientConsumer {
             return;
         }
 
-        if (!(changeEvent && changeEvent.contentChanges)) {
-            this.log.writeWarning(`<${HelpCompletionFeature.name}>: ` +
-                `Bad TextDocumentChangeEvent message: ${JSON.stringify(changeEvent)}`);
-            return;
-        }
-
         if (changeEvent.contentChanges.length > 0) {
-            this.helpCompletionProvider.updateState(
+            this.helpCompletionProvider?.updateState(
                 changeEvent.document,
                 changeEvent.contentChanges[0].text,
-                changeEvent.contentChanges[0].range);
+                changeEvent.contentChanges[0].range,
+            );
 
-            // todo raise an event when trigger is found, and attach complete() to the event.
-            if (this.helpCompletionProvider.triggerFound) {
+            // TODO: Raise an event when trigger is found, and attach complete() to the event.
+            if (this.helpCompletionProvider?.triggerFound) {
                 await this.helpCompletionProvider.complete();
-                await this.helpCompletionProvider.reset();
+                this.helpCompletionProvider.reset();
             }
         }
     }
@@ -83,7 +86,7 @@ export class HelpCompletionFeature extends LanguageClientConsumer {
 
 class TriggerFinder {
     private state: SearchState;
-    private document: TextDocument;
+    private document: TextDocument | undefined;
     private count: number;
 
     constructor(private triggerCharacters: string) {
@@ -98,7 +101,11 @@ class TriggerFinder {
     public updateState(document: TextDocument, changeText: string): void {
         switch (this.state) {
             case SearchState.Searching:
-                if (changeText.length === 1 && changeText[0] === this.triggerCharacters[this.count]) {
+                if (
+                    changeText.length === 1 &&
+                    // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
+                    changeText[0] === this.triggerCharacters[this.count]
+                ) {
                     this.state = SearchState.Locked;
                     this.document = document;
                     this.count++;
@@ -106,9 +113,12 @@ class TriggerFinder {
                 break;
 
             case SearchState.Locked:
-                if (document === this.document &&
-                        changeText.length === 1 &&
-                        changeText[0] === this.triggerCharacters[this.count]) {
+                if (
+                    document === this.document &&
+                    changeText.length === 1 &&
+                    // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with
+                    changeText[0] === this.triggerCharacters[this.count]
+                ) {
                     this.count++;
                     if (this.count === this.triggerCharacters.length) {
                         this.state = SearchState.Found;
@@ -130,27 +140,32 @@ class TriggerFinder {
     }
 }
 
-class HelpCompletionProvider {
+class HelpCompletionProvider extends LanguageClientConsumer {
     private triggerFinderHelpComment: TriggerFinder;
-    private lastChangeRange: Range;
-    private lastDocument: TextDocument;
-    private langClient: LanguageClient;
-    private settings: Settings.ISettings;
+    private lastChangeRange: Range | undefined;
+    private lastDocument: TextDocument | undefined;
+    private settings: Settings;
 
     constructor() {
+        super();
         this.triggerFinderHelpComment = new TriggerFinder("##");
-        this.settings = Settings.load();
+        this.settings = getSettings();
     }
 
     public get triggerFound(): boolean {
         return this.triggerFinderHelpComment.found;
     }
 
-    public set languageClient(value: LanguageClient) {
-        this.langClient = value;
-    }
+    public override onLanguageClientSet(
+        _languageClient: LanguageClient,
+        // eslint-disable-next-line @typescript-eslint/no-empty-function
+    ): void {}
 
-    public updateState(document: TextDocument, changeText: string, changeRange: Range): void {
+    public updateState(
+        document: TextDocument,
+        changeText: string,
+        changeRange: Range,
+    ): void {
         this.lastDocument = document;
         this.lastChangeRange = changeRange;
         this.triggerFinderHelpComment.updateState(document, changeText);
@@ -161,36 +176,45 @@ class HelpCompletionProvider {
     }
 
     public async complete(): Promise<void> {
-        if (this.langClient === undefined) {
+        if (
+            this.lastChangeRange === undefined ||
+            this.lastDocument === undefined
+        ) {
             return;
         }
 
         const triggerStartPos = this.lastChangeRange.start;
         const doc = this.lastDocument;
 
-        const result = await this.langClient.sendRequest(CommentHelpRequestType, {
+        const client = await LanguageClientConsumer.getLanguageClient();
+        const result = await client.sendRequest(CommentHelpRequestType, {
             documentUri: doc.uri.toString(),
             triggerPosition: triggerStartPos,
-            blockComment: this.settings.helpCompletion === Settings.CommentType.BlockComment,
+            blockComment:
+                this.settings.helpCompletion === CommentType.BlockComment,
         });
 
-        if (!(result && result.content)) {
+        if (result.content.length === 0) {
             return;
         }
 
-        const replaceRange = new Range(triggerStartPos.translate(0, -1), triggerStartPos.translate(0, 1));
+        const replaceRange = new Range(
+            triggerStartPos.translate(0, -1),
+            triggerStartPos.translate(0, 1),
+        );
 
-        // TODO add indentation level to the help content
+        // TODO: add indentation level to the help content
         // Trim leading whitespace (used by the rule for indentation) as VSCode takes care of the indentation.
         // Trim the last empty line and join the strings.
         const lines: string[] = result.content;
-        const text = lines
-            .map((x) => (x as any).trimLeft())
-            .join(this.getEOL(doc.eol));
+        const text = lines.map((x) => x.trimStart()).join(this.getEOL(doc.eol));
 
         const snippetString = new SnippetString(text);
 
-        window.activeTextEditor.insertSnippet(snippetString, replaceRange);
+        await window.activeTextEditor?.insertSnippet(
+            snippetString,
+            replaceRange,
+        );
     }
 
     private getEOL(eol: EndOfLine): string {
diff --git a/src/features/ISECompatibility.ts b/src/features/ISECompatibility.ts
index d48b999c81..747bb4f6f4 100644
--- a/src/features/ISECompatibility.ts
+++ b/src/features/ISECompatibility.ts
@@ -2,7 +2,6 @@
 // Licensed under the MIT License.
 
 import * as vscode from "vscode";
-import * as Settings from "../settings";
 
 interface ISetting {
     path: string;
@@ -16,34 +15,84 @@ interface ISetting {
 export class ISECompatibilityFeature implements vscode.Disposable {
     // Marking settings as public so we can use it within the tests without needing to duplicate the list of settings.
     public static settings: ISetting[] = [
-        { path: "workbench.activityBar", name: "visible", value: false },
         { path: "debug", name: "openDebug", value: "neverOpen" },
         { path: "editor", name: "tabCompletion", value: "on" },
-        { path: "powershell.integratedConsole", name: "focusConsoleOnExecute", value: false },
+        {
+            path: "powershell.integratedConsole",
+            name: "focusConsoleOnExecute",
+            value: false,
+        },
         { path: "files", name: "defaultLanguage", value: "powershell" },
         { path: "workbench", name: "colorTheme", value: "PowerShell ISE" },
-        { path: "editor", name: "wordSeparators", value: "`~!@#%^&*()-=+[{]}\\|;:'\",.<>/?" },
-        { path: "powershell.buttons", name: "showPanelMovementButtons", value: true }
+        {
+            path: "editor",
+            name: "wordSeparators",
+            value: "`~!@#%^&*()-=+[{]}\\|;:'\",.<>/?",
+        },
+        {
+            path: "powershell.buttons",
+            name: "showPanelMovementButtons",
+            value: true,
+        },
+        { path: "powershell.codeFolding", name: "showLastLine", value: false },
+        {
+            path: "powershell.sideBar",
+            name: "CommandExplorerVisibility",
+            value: true,
+        },
     ];
-    private iseCommandRegistration: vscode.Disposable;
-    private defaultCommandRegistration: vscode.Disposable;
+
+    private commands: vscode.Disposable[] = [];
+    private iseModeEnabled: boolean;
+    private originalSettings: Record<string, boolean | string | undefined> = {};
 
     constructor() {
-        this.iseCommandRegistration = vscode.commands.registerCommand(
-            "PowerShell.EnableISEMode", this.EnableISEMode);
-        this.defaultCommandRegistration = vscode.commands.registerCommand(
-            "PowerShell.DisableISEMode", this.DisableISEMode);
+        const testSetting =
+            ISECompatibilityFeature.settings[
+                ISECompatibilityFeature.settings.length - 1
+            ];
+        this.iseModeEnabled =
+            vscode.workspace
+                .getConfiguration(testSetting.path)
+                .get(testSetting.name) === testSetting.value;
+        this.commands = [
+            vscode.commands.registerCommand(
+                "PowerShell.EnableISEMode",
+                async () => {
+                    await this.EnableISEMode();
+                },
+            ),
+            vscode.commands.registerCommand(
+                "PowerShell.DisableISEMode",
+                async () => {
+                    await this.DisableISEMode();
+                },
+            ),
+            vscode.commands.registerCommand(
+                "PowerShell.ToggleISEMode",
+                async () => {
+                    await this.ToggleISEMode();
+                },
+            ),
+        ];
     }
 
-    public dispose() {
-        this.iseCommandRegistration.dispose();
-        this.defaultCommandRegistration.dispose();
+    public dispose(): void {
+        for (const command of this.commands) {
+            command.dispose();
+        }
     }
 
-    private async EnableISEMode() {
+    private async EnableISEMode(): Promise<void> {
+        this.iseModeEnabled = true;
         for (const iseSetting of ISECompatibilityFeature.settings) {
             try {
-                await vscode.workspace.getConfiguration(iseSetting.path).update(iseSetting.name, iseSetting.value, true);
+                const config = vscode.workspace.getConfiguration(
+                    iseSetting.path,
+                );
+                this.originalSettings[iseSetting.path + iseSetting.name] =
+                    config.get(iseSetting.name);
+                await config.update(iseSetting.name, iseSetting.value, true);
             } catch {
                 // The `update` call can fail if the setting doesn't exist. This
                 // happens when the extension runs in Azure Data Studio, which
@@ -53,21 +102,32 @@ export class ISECompatibilityFeature implements vscode.Disposable {
             }
         }
 
-        // Show the PowerShell Command Explorer
-        await vscode.commands.executeCommand("workbench.view.extension.PowerShellCommandExplorer");
-
-        if (!Settings.load().sideBar.CommandExplorerVisibility) {
-            // Hide the explorer if the setting says so.
-            await vscode.commands.executeCommand("workbench.action.toggleSidebarVisibility");
-        }
+        // Show the PowerShell view container which has the Command Explorer view
+        await vscode.commands.executeCommand(
+            "workbench.view.extension.PowerShell",
+        );
     }
 
-    private async DisableISEMode() {
+    private async DisableISEMode(): Promise<void> {
+        this.iseModeEnabled = false;
         for (const iseSetting of ISECompatibilityFeature.settings) {
-            const currently = vscode.workspace.getConfiguration(iseSetting.path).get<string | boolean>(iseSetting.name);
+            const config = vscode.workspace.getConfiguration(iseSetting.path);
+            const currently = config.get(iseSetting.name);
             if (currently === iseSetting.value) {
-                await vscode.workspace.getConfiguration(iseSetting.path).update(iseSetting.name, undefined, true);
+                await config.update(
+                    iseSetting.name,
+                    this.originalSettings[iseSetting.path + iseSetting.name],
+                    true,
+                );
             }
         }
     }
+
+    private async ToggleISEMode(): Promise<void> {
+        if (this.iseModeEnabled) {
+            await this.DisableISEMode();
+        } else {
+            await this.EnableISEMode();
+        }
+    }
 }
diff --git a/src/features/NewFileOrProject.ts b/src/features/NewFileOrProject.ts
deleted file mode 100644
index 77ebe0ae6d..0000000000
--- a/src/features/NewFileOrProject.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import vscode = require("vscode");
-import { RequestType } from "vscode-languageclient";
-import { LanguageClient } from "vscode-languageclient/node";
-import { LanguageClientConsumer } from "../languageClientConsumer";
-
-export class NewFileOrProjectFeature extends LanguageClientConsumer {
-
-    private readonly loadIcon = "  $(sync)  ";
-    private command: vscode.Disposable;
-    private waitingForClientToken: vscode.CancellationTokenSource;
-
-    constructor() {
-        super();
-        this.command =
-            vscode.commands.registerCommand("PowerShell.NewProjectFromTemplate", () => {
-
-                if (!this.languageClient && !this.waitingForClientToken) {
-
-                    // If PowerShell isn't finished loading yet, show a loading message
-                    // until the LanguageClient is passed on to us
-                    this.waitingForClientToken = new vscode.CancellationTokenSource();
-                    vscode.window
-                        .showQuickPick(
-                            ["Cancel"],
-                            { placeHolder: "New Project: Please wait, starting PowerShell..." },
-                            this.waitingForClientToken.token)
-                        .then((response) => {
-                            if (response === "Cancel") {
-                                this.clearWaitingToken();
-                            }
-                        });
-
-                    // Cancel the loading prompt after 60 seconds
-                    setTimeout(() => {
-                            if (this.waitingForClientToken) {
-                                this.clearWaitingToken();
-
-                                vscode.window.showErrorMessage(
-                                    "New Project: PowerShell session took too long to start.");
-                            }
-                        }, 60000);
-                } else {
-                    this.showProjectTemplates();
-                }
-            });
-    }
-
-    public dispose() {
-        this.command.dispose();
-    }
-
-    public setLanguageClient(languageClient: LanguageClient) {
-        this.languageClient = languageClient;
-
-        if (this.waitingForClientToken) {
-            this.clearWaitingToken();
-            this.showProjectTemplates();
-        }
-    }
-
-    private showProjectTemplates(includeInstalledModules: boolean = false): void {
-        vscode.window
-            .showQuickPick(
-                this.getProjectTemplates(includeInstalledModules),
-                { placeHolder: "Choose a template to create a new project",
-                  ignoreFocusOut: true })
-            .then((template) => {
-                if (template.label.startsWith(this.loadIcon)) {
-                    this.showProjectTemplates(true);
-                } else {
-                    this.createProjectFromTemplate(template.template);
-                }
-            });
-    }
-
-    private getProjectTemplates(includeInstalledModules: boolean): Thenable<ITemplateQuickPickItem[]> {
-        return this.languageClient
-            .sendRequest(GetProjectTemplatesRequestType, { includeInstalledModules })
-            .then((response) => {
-                if (response.needsModuleInstall) {
-                    // TODO: Offer to install Plaster
-                    vscode.window.showErrorMessage("Plaster is not installed!");
-                    return Promise.reject<ITemplateQuickPickItem[]>("Plaster needs to be installed");
-                } else {
-                    let templates = response.templates.map<ITemplateQuickPickItem>(
-                        (template) => {
-                            return {
-                                label: template.title,
-                                description: `v${template.version} by ${template.author}, tags: ${template.tags}`,
-                                detail: template.description,
-                                template,
-                            };
-                        });
-
-                    if (!includeInstalledModules) {
-                        templates =
-                            [({
-                                label: this.loadIcon,
-                                description: "Load additional templates from installed modules",
-                                template: undefined,
-                            } as ITemplateQuickPickItem)]
-                            .concat(templates);
-                    } else {
-                        templates =
-                            [({
-                                label: this.loadIcon,
-                                description: "Refresh template list",
-                                template: undefined,
-                            }  as ITemplateQuickPickItem)]
-                            .concat(templates);
-                    }
-
-                    return templates;
-                }
-            });
-    }
-
-    private createProjectFromTemplate(template: ITemplateDetails): void {
-        vscode.window
-            .showInputBox(
-                { placeHolder: "Enter an absolute path to the folder where the project should be created",
-                  ignoreFocusOut: true })
-            .then((destinationPath) => {
-
-                if (destinationPath) {
-                    // Show the PowerShell session output in case an error occurred
-                    vscode.commands.executeCommand("PowerShell.ShowSessionOutput");
-
-                    this.languageClient
-                        .sendRequest(
-                            NewProjectFromTemplateRequestType,
-                            { templatePath: template.templatePath, destinationPath })
-                        .then((result) => {
-                            if (result.creationSuccessful) {
-                                this.openWorkspacePath(destinationPath);
-                            } else {
-                                vscode.window.showErrorMessage(
-                                    "Project creation failed, read the Output window for more details.");
-                            }
-                        });
-                } else {
-                    vscode.window
-                        .showErrorMessage(
-                            "New Project: You must enter an absolute folder path to continue.  Try again?",
-                            "Yes", "No")
-                        .then((response) => {
-                            if (response === "Yes") {
-                                this.createProjectFromTemplate(template);
-                            }
-                        });
-                }
-            });
-    }
-
-    private openWorkspacePath(workspacePath: string) {
-        // Open the created project in a new window
-        vscode.commands.executeCommand(
-            "vscode.openFolder",
-            vscode.Uri.file(workspacePath),
-            true);
-    }
-
-    private clearWaitingToken() {
-        if (this.waitingForClientToken) {
-            this.waitingForClientToken.dispose();
-            this.waitingForClientToken = undefined;
-        }
-    }
-}
-
-interface ITemplateQuickPickItem extends vscode.QuickPickItem {
-    template: ITemplateDetails;
-}
-
-interface ITemplateDetails {
-    title: string;
-    version: string;
-    author: string;
-    description: string;
-    tags: string;
-    templatePath: string;
-}
-
-export const GetProjectTemplatesRequestType =
-    new RequestType<IGetProjectTemplatesRequestArgs, IGetProjectTemplatesResponseBody, string>(
-        "powerShell/getProjectTemplates");
-
-interface IGetProjectTemplatesRequestArgs {
-    includeInstalledModules: boolean;
-}
-
-interface IGetProjectTemplatesResponseBody {
-    needsModuleInstall: boolean;
-    templates: ITemplateDetails[];
-}
-
-export const NewProjectFromTemplateRequestType =
-    new RequestType<any, INewProjectFromTemplateResponseBody, string>(
-        "powerShell/newProjectFromTemplate");
-
-interface INewProjectFromTemplateRequestArgs {
-    destinationPath: string;
-    templatePath: string;
-}
-
-interface INewProjectFromTemplateResponseBody {
-    creationSuccessful: boolean;
-}
diff --git a/src/features/OpenInISE.ts b/src/features/OpenInISE.ts
index 13199bbe30..808ee59db7 100644
--- a/src/features/OpenInISE.ts
+++ b/src/features/OpenInISE.ts
@@ -8,27 +8,32 @@ export class OpenInISEFeature implements vscode.Disposable {
     private command: vscode.Disposable;
 
     constructor() {
-        this.command = vscode.commands.registerCommand("PowerShell.OpenInISE", () => {
-
-            const editor = vscode.window.activeTextEditor;
-            const document = editor.document;
-            const uri = document.uri;
-
-            let ISEPath = process.env.windir;
-
-            if (process.env.hasOwnProperty("PROCESSOR_ARCHITEW6432")) {
-                ISEPath += "\\Sysnative";
-            } else {
-                ISEPath += "\\System32";
-            }
-
-            ISEPath += "\\WindowsPowerShell\\v1.0\\powershell_ise.exe";
-
-            ChildProcess.exec(ISEPath + ` -File "${uri.fsPath}"`).unref();
-        });
+        this.command = vscode.commands.registerCommand(
+            "PowerShell.OpenInISE",
+            () => {
+                const editor = vscode.window.activeTextEditor;
+                if (editor === undefined) {
+                    return;
+                }
+
+                const document = editor.document;
+                const uri = document.uri;
+                let ISEPath = process.env.windir ?? "C:\\Windows";
+
+                if (process.env.PROCESSOR_ARCHITEW6432 !== undefined) {
+                    ISEPath += "\\Sysnative";
+                } else {
+                    ISEPath += "\\System32";
+                }
+
+                ISEPath += "\\WindowsPowerShell\\v1.0\\powershell_ise.exe";
+
+                ChildProcess.exec(`${ISEPath} -File "${uri.fsPath}"`).unref();
+            },
+        );
     }
 
-    public dispose() {
+    public dispose(): void {
         this.command.dispose();
     }
 }
diff --git a/src/features/PesterTests.ts b/src/features/PesterTests.ts
index 32cc795a0b..486bcd8aab 100644
--- a/src/features/PesterTests.ts
+++ b/src/features/PesterTests.ts
@@ -2,9 +2,10 @@
 // Licensed under the MIT License.
 
 import * as path from "path";
-import vscode = require("vscode");
+import type { ILogger } from "../logging";
 import { SessionManager } from "../session";
-import Settings = require("../settings");
+import { getChosenWorkspace, getSettings } from "../settings";
+import vscode = require("vscode");
 import utils = require("../utils");
 
 enum LaunchType {
@@ -13,96 +14,130 @@ enum LaunchType {
 }
 
 export class PesterTestsFeature implements vscode.Disposable {
-
-    private command: vscode.Disposable;
+    private commands: vscode.Disposable[];
     private invokePesterStubScriptPath: string;
 
-    constructor(private sessionManager: SessionManager) {
-        this.invokePesterStubScriptPath = path.resolve(__dirname, "../modules/PowerShellEditorServices/InvokePesterStub.ps1");
-
-        // File context-menu command - Run Pester Tests
-        this.command = vscode.commands.registerCommand(
-            "PowerShell.RunPesterTestsFromFile",
-            (fileUri) => {
-                return this.launchAllTestsInActiveEditor(LaunchType.Run, fileUri);
-            });
-        // File context-menu command - Debug Pester Tests
-        this.command = vscode.commands.registerCommand(
-            "PowerShell.DebugPesterTestsFromFile",
-            (fileUri) => {
-                return this.launchAllTestsInActiveEditor(LaunchType.Debug, fileUri);
-            });
-        // This command is provided for usage by PowerShellEditorServices (PSES) only
-        this.command = vscode.commands.registerCommand(
-            "PowerShell.RunPesterTests",
-            (uriString, runInDebugger, describeBlockName?, describeBlockLineNumber?, outputPath?) => {
-                return this.launchTests(uriString, runInDebugger, describeBlockName, describeBlockLineNumber, outputPath);
-            });
+    constructor(
+        private sessionManager: SessionManager,
+        private logger: ILogger,
+    ) {
+        this.invokePesterStubScriptPath = path.resolve(
+            __dirname,
+            "../modules/PowerShellEditorServices/InvokePesterStub.ps1",
+        );
+        this.commands = [
+            // File context-menu command - Run Pester Tests
+            vscode.commands.registerCommand(
+                "PowerShell.RunPesterTestsFromFile",
+                (fileUri?) => {
+                    return this.launchAllTestsInActiveEditor(
+                        LaunchType.Run,
+                        fileUri,
+                    );
+                },
+            ),
+
+            // File context-menu command - Debug Pester Tests
+            vscode.commands.registerCommand(
+                "PowerShell.DebugPesterTestsFromFile",
+                (fileUri?) => {
+                    return this.launchAllTestsInActiveEditor(
+                        LaunchType.Debug,
+                        fileUri,
+                    );
+                },
+            ),
+
+            // This command is provided for usage by PowerShellEditorServices (PSES) only
+            vscode.commands.registerCommand(
+                "PowerShell.RunPesterTests",
+                (
+                    uriString,
+                    runInDebugger,
+                    describeBlockName?,
+                    describeBlockLineNumber?,
+                    outputPath?,
+                ) => {
+                    return this.launchTests(
+                        vscode.Uri.parse(uriString),
+                        runInDebugger,
+                        describeBlockName,
+                        describeBlockLineNumber,
+                        outputPath,
+                    );
+                },
+            ),
+        ];
     }
 
-    public dispose() {
-        this.command.dispose();
+    public dispose(): void {
+        for (const command of this.commands) {
+            command.dispose();
+        }
     }
 
     private async launchAllTestsInActiveEditor(
         launchType: LaunchType,
-        fileUri: vscode.Uri): Promise<boolean> {
+        fileUri?: vscode.Uri,
+    ): Promise<boolean> {
+        fileUri ??= vscode.window.activeTextEditor?.document.uri;
 
-        const uriString = (fileUri || vscode.window.activeTextEditor.document.uri).toString();
-        const launchConfig = this.createLaunchConfig(uriString, launchType);
+        if (fileUri === undefined) {
+            return false;
+        }
+
+        const launchConfig = this.createLaunchConfig(fileUri, launchType);
         return this.launch(launchConfig);
     }
 
     private async launchTests(
-        uriString: string,
+        fileUri: vscode.Uri,
         runInDebugger: boolean,
         describeBlockName?: string,
         describeBlockLineNumber?: number,
-        outputPath?: string): Promise<boolean> {
-
+        outputPath?: string,
+    ): Promise<boolean> {
         const launchType = runInDebugger ? LaunchType.Debug : LaunchType.Run;
-        const launchConfig = this.createLaunchConfig(uriString, launchType, describeBlockName, describeBlockLineNumber, outputPath);
+        const launchConfig = this.createLaunchConfig(
+            fileUri,
+            launchType,
+            describeBlockName,
+            describeBlockLineNumber,
+            outputPath,
+        );
         return this.launch(launchConfig);
     }
 
     private createLaunchConfig(
-        uriString: string,
+        fileUri: vscode.Uri,
         launchType: LaunchType,
         testName?: string,
         lineNum?: number,
-        outputPath?: string) {
-
-        const uri = vscode.Uri.parse(uriString);
-        const currentDocument = vscode.window.activeTextEditor.document;
-        const settings = Settings.load();
-
-        // Since we pass the script path to PSES in single quotes to avoid issues with PowerShell
-        // special chars like & $ @ () [], we do have to double up the interior single quotes.
-        const scriptPath = uri.fsPath.replace(/'/g, "''");
-
+        outputPath?: string,
+    ): vscode.DebugConfiguration {
+        const settings = getSettings();
         const launchConfig = {
             request: "launch",
             type: "PowerShell",
-            name: "PowerShell Launch Pester Tests",
+            name: "PowerShell: Launch Pester Tests",
             script: this.invokePesterStubScriptPath,
             args: [
                 "-ScriptPath",
-                `'${scriptPath}'`,
+                `'${utils.escapeSingleQuotes(fileUri.fsPath)}'`,
             ],
             internalConsoleOptions: "neverOpen",
-            noDebug: (launchType === LaunchType.Run),
-            createTemporaryIntegratedConsole: settings.debugging.createTemporaryIntegratedConsole
+            noDebug: launchType === LaunchType.Run,
+            createTemporaryIntegratedConsole:
+                settings.debugging.createTemporaryIntegratedConsole,
         };
 
         if (lineNum) {
             launchConfig.args.push("-LineNumber", `${lineNum}`);
         } else if (testName) {
-            // Escape single quotes inside double quotes by doubling them up
-            if (testName.includes("'")) {
-                testName = testName.replace(/'/g, "''");
-            }
-
-            launchConfig.args.push("-TestName", `'${testName}'`);
+            launchConfig.args.push(
+                "-TestName",
+                `'${utils.escapeSingleQuotes(testName)}'`,
+            );
         } else {
             launchConfig.args.push("-All");
         }
@@ -112,10 +147,15 @@ export class PesterTestsFeature implements vscode.Disposable {
         }
 
         if (launchType === LaunchType.Debug) {
-            launchConfig.args.push("-Output", `'${settings.pester.debugOutputVerbosity}'`);
-        }
-        else {
-            launchConfig.args.push("-Output", `'${settings.pester.outputVerbosity}'`);
+            launchConfig.args.push(
+                "-Output",
+                `'${settings.pester.debugOutputVerbosity}'`,
+            );
+        } else {
+            launchConfig.args.push(
+                "-Output",
+                `'${settings.pester.outputVerbosity}'`,
+            );
         }
 
         if (outputPath) {
@@ -125,21 +165,21 @@ export class PesterTestsFeature implements vscode.Disposable {
         return launchConfig;
     }
 
-    private async launch(launchConfig): Promise<boolean> {
+    private async launch(
+        launchConfig: vscode.DebugConfiguration,
+    ): Promise<boolean> {
         // Create or show the interactive console
         // TODO: #367 Check if "newSession" mode is configured
-        vscode.commands.executeCommand("PowerShell.ShowSessionConsole", true);
-
-        // Write out temporary debug session file
-        utils.writeSessionFile(
-            utils.getDebugSessionFilePath(),
-            this.sessionManager.getSessionDetails());
+        this.sessionManager.showDebugTerminal(true);
 
-        // TODO: Update to handle multiple root workspaces.
-        //
         // Ensure the necessary script exists (for testing). The debugger will
         // start regardless, but we also pass its success along.
-        return utils.fileExists(this.invokePesterStubScriptPath)
-            && vscode.debug.startDebugging(vscode.workspace.workspaceFolders?.[0], launchConfig);
+        return (
+            (await utils.checkIfFileExists(this.invokePesterStubScriptPath)) &&
+            vscode.debug.startDebugging(
+                await getChosenWorkspace(this.logger),
+                launchConfig,
+            )
+        );
     }
 }
diff --git a/src/features/RemoteFiles.ts b/src/features/RemoteFiles.ts
index ef2c5af3c9..46164b5de4 100644
--- a/src/features/RemoteFiles.ts
+++ b/src/features/RemoteFiles.ts
@@ -4,7 +4,11 @@
 import os = require("os");
 import path = require("path");
 import vscode = require("vscode");
-import { NotificationType, TextDocumentIdentifier } from "vscode-languageclient";
+import {
+    NotificationType,
+    TextDocumentIdentifier,
+} from "vscode-languageclient";
+import type { LanguageClient } from "vscode-languageclient/node";
 import { LanguageClientConsumer } from "../languageClientConsumer";
 
 // NOTE: The following two DidSaveTextDocument* types will
@@ -18,59 +22,73 @@ export interface IDidSaveTextDocumentParams {
 }
 
 export const DidSaveTextDocumentNotificationType =
-    new NotificationType<IDidSaveTextDocumentParams>(
-        "textDocument/didSave");
+    new NotificationType<IDidSaveTextDocumentParams>("textDocument/didSave");
 
 export class RemoteFilesFeature extends LanguageClientConsumer {
-
+    private command: vscode.Disposable;
     private tempSessionPathPrefix: string;
 
     constructor() {
         super();
         // Get the common PowerShell Editor Services temporary file path
         // so that remote files from previous sessions can be closed.
-        this.tempSessionPathPrefix =
-            path.join(os.tmpdir(), "PSES-")
-                .toLowerCase();
+        this.tempSessionPathPrefix = path
+            .join(os.tmpdir(), "PSES-")
+            .toLowerCase();
 
         // At startup, close any lingering temporary remote files
         this.closeRemoteFiles();
 
-        vscode.workspace.onDidSaveTextDocument((doc) => {
-            if (this.isDocumentRemote(doc) && this.languageClient) {
-                this.languageClient.sendNotification(
+        this.command = vscode.workspace.onDidSaveTextDocument(async (doc) => {
+            if (this.isDocumentRemote(doc)) {
+                const client = await LanguageClientConsumer.getLanguageClient();
+                await client.sendNotification(
                     DidSaveTextDocumentNotificationType,
                     {
-                        textDocument: TextDocumentIdentifier.create(doc.uri.toString()),
-                    });
+                        textDocument: TextDocumentIdentifier.create(
+                            doc.uri.toString(),
+                        ),
+                    },
+                );
             }
         });
     }
 
-    public dispose() {
+    public override onLanguageClientSet(
+        _languageClient: LanguageClient,
+        // eslint-disable-next-line @typescript-eslint/no-empty-function
+    ): void {}
+
+    public dispose(): void {
+        this.command.dispose();
         // Close any leftover remote files before exiting
         this.closeRemoteFiles();
     }
 
-    private isDocumentRemote(doc: vscode.TextDocument) {
-        return doc.fileName.toLowerCase().startsWith(this.tempSessionPathPrefix);
+    private isDocumentRemote(doc: vscode.TextDocument): boolean {
+        return doc.fileName
+            .toLowerCase()
+            .startsWith(this.tempSessionPathPrefix);
     }
 
-    private closeRemoteFiles() {
-        const remoteDocuments =
-            vscode.workspace.textDocuments.filter((doc) => this.isDocumentRemote(doc));
+    private closeRemoteFiles(): void {
+        const remoteDocuments = vscode.workspace.textDocuments.filter((doc) =>
+            this.isDocumentRemote(doc),
+        );
 
-        function innerCloseFiles(): Thenable<{}> {
-            if (remoteDocuments.length > 0) {
-                const doc = remoteDocuments.pop();
-
-                return vscode.window
-                    .showTextDocument(doc)
-                    .then((editor) => vscode.commands.executeCommand("workbench.action.closeActiveEditor"))
-                    .then((_) => innerCloseFiles());
+        async function innerCloseFiles(): Promise<void> {
+            const doc = remoteDocuments.pop();
+            if (doc === undefined) {
+                return;
             }
+
+            await vscode.window.showTextDocument(doc);
+            await vscode.commands.executeCommand(
+                "workbench.action.closeActiveEditor",
+            );
+            await innerCloseFiles();
         }
 
-        innerCloseFiles();
+        void innerCloseFiles();
     }
 }
diff --git a/src/features/RunCode.ts b/src/features/RunCode.ts
deleted file mode 100644
index 288a7b1295..0000000000
--- a/src/features/RunCode.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import * as path from "path";
-import vscode = require("vscode");
-import { SessionManager } from "../session";
-import Settings = require("../settings");
-import utils = require("../utils");
-
-enum LaunchType {
-    Debug,
-    Run,
-}
-
-export class RunCodeFeature implements vscode.Disposable {
-
-    private command: vscode.Disposable;
-
-    constructor(private sessionManager: SessionManager) {
-        this.command = vscode.commands.registerCommand(
-            "PowerShell.RunCode",
-            (runInDebugger: boolean, scriptToRun: string, args: string[]) => {
-                this.launchTask(runInDebugger, scriptToRun, args);
-            });
-    }
-
-    public dispose() {
-        this.command.dispose();
-    }
-
-    private async launchTask(
-        runInDebugger: boolean,
-        scriptToRun: string,
-        args: string[]) {
-
-        const launchType = runInDebugger ? LaunchType.Debug : LaunchType.Run;
-        const launchConfig = createLaunchConfig(launchType, scriptToRun, args);
-        this.launch(launchConfig);
-    }
-
-    private launch(launchConfig) {
-        // Create or show the interactive console
-        // TODO #367: Check if "newSession" mode is configured
-        vscode.commands.executeCommand("PowerShell.ShowSessionConsole", true);
-
-        // Write out temporary debug session file
-        utils.writeSessionFile(
-            utils.getDebugSessionFilePath(),
-            this.sessionManager.getSessionDetails());
-
-        // TODO: Update to handle multiple root workspaces.
-        vscode.debug.startDebugging(vscode.workspace.workspaceFolders?.[0], launchConfig);
-    }
-}
-
-function createLaunchConfig(launchType: LaunchType, commandToRun: string, args: string[]) {
-    const settings = Settings.load();
-
-    let cwd: string = vscode.workspace.rootPath;
-    if (vscode.window.activeTextEditor
-        && vscode.window.activeTextEditor.document
-        && !vscode.window.activeTextEditor.document.isUntitled) {
-        cwd = path.dirname(vscode.window.activeTextEditor.document.fileName);
-    }
-
-    const launchConfig = {
-        request: "launch",
-        type: "PowerShell",
-        name: "PowerShell Run Code",
-        internalConsoleOptions: "neverOpen",
-        noDebug: (launchType === LaunchType.Run),
-        createTemporaryIntegratedConsole: settings.debugging.createTemporaryIntegratedConsole,
-        script: commandToRun,
-        args,
-        cwd,
-    };
-
-    return launchConfig;
-}
diff --git a/src/features/ShowHelp.ts b/src/features/ShowHelp.ts
index ebb6662732..6af843e53b 100644
--- a/src/features/ShowHelp.ts
+++ b/src/features/ShowHelp.ts
@@ -3,36 +3,55 @@
 
 import vscode = require("vscode");
 import { NotificationType } from "vscode-languageclient";
-import { Logger } from "../logging";
+import type { LanguageClient } from "vscode-languageclient/node";
 import { LanguageClientConsumer } from "../languageClientConsumer";
 
+interface IShowHelpNotificationArguments {}
+
 export const ShowHelpNotificationType =
-    new NotificationType<any>("powerShell/showHelp");
+    new NotificationType<IShowHelpNotificationArguments>("powerShell/showHelp");
 
 export class ShowHelpFeature extends LanguageClientConsumer {
     private command: vscode.Disposable;
 
-    constructor(private log: Logger) {
+    constructor() {
         super();
-        this.command = vscode.commands.registerCommand("PowerShell.ShowHelp", (item?) => {
-            if (!item || !item.Name) {
-
-                const editor = vscode.window.activeTextEditor;
-
-                const selection = editor.selection;
-                const doc = editor.document;
-                const cwr = doc.getWordRangeAtPosition(selection.active);
-                const text = doc.getText(cwr);
-
-                this.languageClient.sendNotification(ShowHelpNotificationType, { text });
-            } else {
-                this.languageClient.sendNotification(ShowHelpNotificationType, { text: item.Name } );
-            }
-        });
+        this.command = vscode.commands.registerCommand(
+            "PowerShell.ShowHelp",
+            async (item?) => {
+                if (!item?.Name) {
+                    const editor = vscode.window.activeTextEditor;
+                    if (editor === undefined) {
+                        return;
+                    }
+
+                    const selection = editor.selection;
+                    const doc = editor.document;
+                    const cwr = doc.getWordRangeAtPosition(selection.active);
+                    const text = doc.getText(cwr);
+
+                    const client =
+                        await LanguageClientConsumer.getLanguageClient();
+                    await client.sendNotification(ShowHelpNotificationType, {
+                        text,
+                    });
+                } else {
+                    const client =
+                        await LanguageClientConsumer.getLanguageClient();
+                    await client.sendNotification(ShowHelpNotificationType, {
+                        text: item.Name,
+                    });
+                }
+            },
+        );
     }
 
-    public dispose() {
+    public override onLanguageClientSet(
+        _languageClient: LanguageClient,
+        // eslint-disable-next-line @typescript-eslint/no-empty-function
+    ): void {}
+
+    public dispose(): void {
         this.command.dispose();
     }
-
 }
diff --git a/src/features/UpdatePowerShell.ts b/src/features/UpdatePowerShell.ts
index e8ff0680de..17edea4770 100644
--- a/src/features/UpdatePowerShell.ts
+++ b/src/features/UpdatePowerShell.ts
@@ -1,88 +1,28 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import { spawn } from "child_process";
-import * as fs from "fs";
-import fetch, { RequestInit } from "node-fetch";
-import * as os from "os";
-import * as path from "path";
-import * as semver from "semver";
-import * as stream from "stream";
-import * as util from "util";
-import { MessageItem, ProgressLocation, window } from "vscode";
-
-import { LanguageClient } from "vscode-languageclient/node";
-import { SessionManager } from "../session";
-import * as Settings from "../settings";
-import { isMacOS, isWindows } from "../utils";
-import { EvaluateRequestType } from "./Console";
-
-const streamPipeline = util.promisify(stream.pipeline);
-
-const PowerShellGitHubReleasesUrl =
-        "https://api.github.com/repos/PowerShell/PowerShell/releases/latest";
-const PowerShellGitHubPrereleasesUrl =
-    "https://api.github.com/repos/PowerShell/PowerShell/releases";
-
-export class GitHubReleaseInformation {
-    public static async FetchLatestRelease(preview: boolean): Promise<GitHubReleaseInformation> {
-        const requestConfig: RequestInit = {};
-
-        // For CI. This prevents GitHub from rate limiting us.
-        if (process.env.PS_TEST_GITHUB_API_USERNAME && process.env.PS_TEST_GITHUB_API_PAT) {
-            const authHeaderValue = Buffer
-                .from(`${process.env.PS_TEST_GITHUB_API_USERNAME}:${process.env.PS_TEST_GITHUB_API_PAT}`)
-                .toString("base64");
-            requestConfig.headers = {
-                Authorization: `Basic ${authHeaderValue}`,
-            };
-        }
-
-        // Fetch the latest PowerShell releases from GitHub.
-        const response = await fetch(
-            preview ? PowerShellGitHubPrereleasesUrl : PowerShellGitHubReleasesUrl,
-            requestConfig);
-
-        if (!response.ok) {
-            const json = await response.json();
-            throw new Error(json.message || json || "response was not ok.");
-        }
-
-        // For preview, we grab all the releases and then grab the first prerelease.
-        const releaseJson = preview
-            ? (await response.json()).find((release: any) => release.prerelease)
-            : await response.json();
+import { SemVer } from "semver";
+import vscode = require("vscode");
 
-        return new GitHubReleaseInformation(
-            releaseJson.tag_name, releaseJson.assets);
-    }
-
-    public version: semver.SemVer;
-    public isPreview: boolean = false;
-    public assets: any[];
-
-    public constructor(version: string | semver.SemVer, assets: any[] = []) {
-        this.version = semver.parse(version);
+import type { ILogger } from "../logging";
+import type { IPowerShellVersionDetails } from "../session";
+import { changeSetting, Settings } from "../settings";
 
-        if (semver.prerelease(this.version)) {
-            this.isPreview = true;
-        }
-
-        this.assets = assets;
-    }
-}
-
-interface IUpdateMessageItem extends MessageItem {
+interface IUpdateMessageItem extends vscode.MessageItem {
     id: number;
 }
 
-export async function InvokePowerShellUpdateCheck(
-    sessionManager: SessionManager,
-    languageServerClient: LanguageClient,
-    localVersion: semver.SemVer,
-    arch: string,
-    release: GitHubReleaseInformation) {
-    const options: IUpdateMessageItem[] = [
+// This attempts to mirror PowerShell's `UpdatesNotification.cs` logic as much as
+// possibly, documented at:
+// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_update_notifications
+export class UpdatePowerShell {
+    private static LTSBuildInfoURL = "https://aka.ms/pwsh-buildinfo-lts";
+    private static StableBuildInfoURL = "https://aka.ms/pwsh-buildinfo-stable";
+    private static PreviewBuildInfoURL =
+        "https://aka.ms/pwsh-buildinfo-preview";
+    private static GitHubWebReleaseURL =
+        "https://github.com/PowerShell/PowerShell/releases/tag/";
+    private static promptOptions: IUpdateMessageItem[] = [
         {
             id: 0,
             title: "Yes",
@@ -96,97 +36,203 @@ export async function InvokePowerShellUpdateCheck(
             title: "Don't Show Again",
         },
     ];
-
-    // If our local version is up-to-date, we can return early.
-    if (semver.compare(localVersion, release.version) >= 0) {
-        return;
+    private localVersion: SemVer;
+
+    constructor(
+        private sessionSettings: Settings,
+        private logger: ILogger,
+        versionDetails: IPowerShellVersionDetails,
+    ) {
+        // We use the commit field as it's like
+        // '7.3.0-preview.3-508-g07175ae0ff8eb7306fe0b0fc7d...' which translates
+        // to SemVer. The version handler in PSES handles Windows PowerShell and
+        // just returns the first three fields like '5.1.22621'.
+        this.localVersion = new SemVer(versionDetails.commit);
     }
 
-    const commonText: string = `You have an old version of PowerShell (${
-        localVersion.raw
-    }). The current latest release is ${
-        release.version.raw
-    }.`;
+    private shouldCheckForUpdate(): boolean {
+        // Respect user setting.
+        if (!this.sessionSettings.promptToUpdatePowerShell) {
+            this.logger.writeDebug(
+                "Setting 'promptToUpdatePowerShell' was false.",
+            );
+            return false;
+        }
+
+        // Respect environment configuration.
+        if (process.env.POWERSHELL_UPDATECHECK?.toLowerCase() === "off") {
+            this.logger.writeDebug(
+                "Environment variable 'POWERSHELL_UPDATECHECK' was 'Off'.",
+            );
+            return false;
+        }
+
+        // Skip prompting when using Windows PowerShell for now.
+        if (this.localVersion.compare("6.0.0") === -1) {
+            // TODO: Maybe we should announce PowerShell Core?
+            this.logger.writeDebug(
+                "Not prompting to update Windows PowerShell.",
+            );
+            return false;
+        }
+
+        if (this.localVersion.prerelease.length > 1) {
+            // Daily builds look like '7.3.0-daily20221206.1' which split to
+            // ['daily20221206', '1'] and development builds look like
+            // '7.3.0-preview.3-508-g07175...' which splits to ['preview',
+            // '3-508-g0717...']. The ellipsis is hiding a 40 char hash.
+            const daily = this.localVersion.prerelease[0].toString();
+            const commit = this.localVersion.prerelease[1].toString();
+
+            // Skip if PowerShell is self-built, that is, this contains a commit hash.
+            if (commit.length >= 40) {
+                this.logger.writeDebug(
+                    "Not prompting to update development build.",
+                );
+                return false;
+            }
+
+            // Skip if preview is a daily build.
+            if (daily.toLowerCase().startsWith("daily")) {
+                this.logger.writeDebug("Not prompting to update daily build.");
+                return false;
+            }
+        }
 
-    if (process.platform === "linux") {
-        await window.showInformationMessage(
-            `${commonText} We recommend updating to the latest version.`);
-        return;
+        // TODO: Check if network is available?
+        // TODO: Only check once a week.
+        return true;
     }
 
-    const result = await window.showInformationMessage(
-        `${commonText} Would you like to update the version? ${
-            isMacOS ? "(Homebrew is required on macOS)"
-                : "(This will close ALL pwsh terminals running in this Visual Studio Code session)"
-        }`, ...options);
-
-    // If the user cancels the notification.
-    if (!result) { return; }
-
-    // Yes choice.
-    switch (result.id) {
-        // Yes choice.
-        case 0:
-            if (isWindows) {
-                const msiMatcher = arch === "x86" ?
-                    "win-x86.msi" : "win-x64.msi";
-
-                const asset = release.assets.filter((a: any) => a.name.indexOf(msiMatcher) >= 0)[0];
-                const msiDownloadPath = path.join(os.tmpdir(), asset.name);
-
-                const res = await fetch(asset.browser_download_url);
-                if (!res.ok) {
-                    throw new Error("unable to fetch MSI");
-                }
+    private async getRemoteVersion(url: string): Promise<string | undefined> {
+        const response = await fetch(url);
+        if (!response.ok) {
+            return undefined;
+        }
+        // Looks like:
+        // {
+        //     "ReleaseDate": "2022-10-20T22:01:38Z",
+        //     "BlobName": "v7-2-7",
+        //     "ReleaseTag": "v7.2.7"
+        // }
+        const data = await response.json();
+        this.logger.writeDebug(
+            `Received from '${url}':\n${JSON.stringify(data, undefined, 2)}`,
+        );
+        return data.ReleaseTag;
+    }
 
-                await window.withProgress({
-                    title: "Downloading PowerShell Installer...",
-                    location: ProgressLocation.Notification,
-                    cancellable: false,
-                },
-                async () => {
-                    // Streams the body of the request to a file.
-                    await streamPipeline(res.body, fs.createWriteStream(msiDownloadPath));
-                });
-
-                // Stop the Integrated Console session because Windows likes to hold on to files.
-                sessionManager.stop();
-
-                // Close all terminals with the name "pwsh" in the current VS Code session.
-                // This will encourage folks to not close the instance of VS Code that spawned
-                // the MSI process.
-                for (const terminal of window.terminals) {
-                    if (terminal.name === "pwsh") {
-                        terminal.dispose();
-                    }
-                }
+    private async maybeGetNewRelease(): Promise<string | undefined> {
+        if (!this.shouldCheckForUpdate()) {
+            return undefined;
+        }
 
-                // Invoke the MSI via cmd.
-                const msi = spawn("msiexec", ["/i", msiDownloadPath]);
+        this.logger.writeDebug("Checking for PowerShell update...");
+        const tags: string[] = [];
+        if (process.env.POWERSHELL_UPDATECHECK?.toLowerCase() === "lts") {
+            // Only check for update to LTS.
+            this.logger.writeDebug("Checking for LTS update...");
+            const tag = await this.getRemoteVersion(
+                UpdatePowerShell.LTSBuildInfoURL,
+            );
+            if (tag != undefined) {
+                tags.push(tag);
+            }
+        } else {
+            // Check for update to stable.
+            this.logger.writeDebug("Checking for stable update...");
+            const tag = await this.getRemoteVersion(
+                UpdatePowerShell.StableBuildInfoURL,
+            );
+            if (tag != undefined) {
+                tags.push(tag);
+            }
 
-                msi.on("close", (code) => {
-                    // Now that the MSI is finished, start the Integrated Console session.
-                    sessionManager.start();
-                    fs.unlinkSync(msiDownloadPath);
-                });
+            // Also check for a preview update.
+            if (this.localVersion.prerelease.length > 0) {
+                this.logger.writeDebug("Checking for preview update...");
+                const tag = await this.getRemoteVersion(
+                    UpdatePowerShell.PreviewBuildInfoURL,
+                );
+                if (tag != undefined) {
+                    tags.push(tag);
+                }
+            }
+        }
+
+        for (const tag of tags) {
+            if (this.localVersion.compare(tag) === -1) {
+                return tag;
+            }
+        }
 
-            } else if (isMacOS) {
-                const script = release.isPreview
-                    ? "brew upgrade --cask powershell-preview"
-                    : "brew upgrade --cask powershell";
+        this.logger.write("PowerShell is up-to-date.");
+        return undefined;
+    }
 
-                await languageServerClient.sendRequest(EvaluateRequestType, {
-                    expression: script,
-                });
+    public async checkForUpdate(): Promise<void> {
+        try {
+            const tag = await this.maybeGetNewRelease();
+            if (tag) {
+                await this.promptToUpdate(tag);
+                return;
             }
+        } catch (err) {
+            // Best effort. This probably failed to fetch the data from GitHub.
+            this.logger.writeWarning(
+                err instanceof Error ? err.message : "unknown",
+            );
+        }
+    }
 
-            break;
+    private async openReleaseInBrowser(tag: string): Promise<void> {
+        const url = vscode.Uri.parse(
+            UpdatePowerShell.GitHubWebReleaseURL + tag,
+        );
+        await vscode.env.openExternal(url);
+    }
 
-        // Never choice.
-        case 2:
-            await Settings.change("promptToUpdatePowerShell", false, true);
-            break;
-        default:
-            break;
+    private async promptToUpdate(tag: string): Promise<void> {
+        const releaseVersion = new SemVer(tag);
+        this.logger.write(
+            `Prompting to update PowerShell v${this.localVersion.version} to v${releaseVersion.version}.`,
+        );
+        const result = await vscode.window.showInformationMessage(
+            `PowerShell v${this.localVersion.version} is out-of-date.
+             The latest version is v${releaseVersion.version}.
+             Would you like to open the GitHub release in your browser?`,
+            ...UpdatePowerShell.promptOptions,
+        );
+
+        // If the user cancels the notification.
+        if (!result) {
+            this.logger.writeDebug("User canceled PowerShell update prompt.");
+            return;
+        }
+
+        this.logger.writeDebug(
+            `User said '${UpdatePowerShell.promptOptions[result.id].title}'.`,
+        );
+
+        switch (result.id) {
+            // Yes
+            case 0:
+                await this.openReleaseInBrowser(tag);
+                break;
+            // Not Now
+            case 1:
+                break;
+            // Don't Show Again
+            case 2:
+                await changeSetting(
+                    "promptToUpdatePowerShell",
+                    false,
+                    true,
+                    this.logger,
+                );
+                break;
+            default:
+                break;
+        }
     }
 }
diff --git a/src/languageClientConsumer.ts b/src/languageClientConsumer.ts
index b1cea31ac0..e161f5a34e 100644
--- a/src/languageClientConsumer.ts
+++ b/src/languageClientConsumer.ts
@@ -1,28 +1,76 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import { window } from "vscode";
+import { ProgressLocation, window } from "vscode";
 import { LanguageClient } from "vscode-languageclient/node";
 
 export abstract class LanguageClientConsumer {
+    private static languageClientPromise?: Promise<LanguageClient>;
+    private static getLanguageClientResolve?: (value: LanguageClient) => void;
 
-    private _languageClient: LanguageClient;
+    // Implementations of this class must override this method to register their
+    // handlers, as its called whenever the client is restarted / replaced.
+    public abstract onLanguageClientSet(languageClient: LanguageClient): void;
 
-    public setLanguageClient(languageClient: LanguageClient) {
-        this.languageClient = languageClient;
+    // This is called in the session manager when the client is started (so we
+    // can wait for that). It's what actually resolves the promise.
+    public static onLanguageClientStarted(
+        languageClient: LanguageClient,
+    ): void {
+        // It should have been created earlier, but if not, create and resolve it.
+        this.languageClientPromise ??= Promise.resolve(languageClient);
+        this.getLanguageClientResolve?.(languageClient);
     }
 
-    abstract dispose(): void;
+    // This is called in the session manager when the client exits so we can
+    // make a new promise.
+    public static onLanguageClientExited(): void {
+        this.languageClientPromise = undefined;
+        this.getLanguageClientResolve = undefined;
+    }
 
-    public get languageClient(): LanguageClient {
-        if (!this._languageClient) {
-            window.showInformationMessage(
-                "PowerShell extension has not finished starting up yet. Please try again in a few moments.");
-        }
-        return this._languageClient;
+    // We should have a promise as defined in resetLanguageClient, but if we
+    // don't, create it.
+    public static async getLanguageClient(): Promise<LanguageClient> {
+        // If it hasn't been created or was rejected, recreate it.
+        LanguageClientConsumer.languageClientPromise?.catch(() => {
+            LanguageClientConsumer.languageClientPromise = undefined;
+        });
+        LanguageClientConsumer.languageClientPromise ??=
+            LanguageClientConsumer.createLanguageClientPromise();
+        return LanguageClientConsumer.languageClientPromise;
     }
 
-    public set languageClient(value: LanguageClient) {
-        this._languageClient = value;
+    // This waits for the language client to start and shows a cancellable
+    // loading message. (It just wrap the static method below.)
+    private static async createLanguageClientPromise(): Promise<LanguageClient> {
+        return window.withProgress<LanguageClient>(
+            {
+                location: ProgressLocation.Notification,
+                title: "Please wait, starting PowerShell Extension Terminal...",
+                cancellable: true,
+            },
+            (_progress, token) => {
+                token.onCancellationRequested(() => {
+                    void window.showErrorMessage(
+                        "Cancelled PowerShell Extension Terminal start-up.",
+                    );
+                });
+
+                // The real promise!
+                return new Promise<LanguageClient>((resolve, reject) => {
+                    // Store the resolve function to be called in resetLanguageClient.
+                    LanguageClientConsumer.getLanguageClientResolve = resolve;
+                    // Reject the promise if the operation is cancelled.
+                    token.onCancellationRequested(() => {
+                        reject(
+                            new Error(
+                                "Cancelled PowerShell Extension Terminal start-up.",
+                            ),
+                        );
+                    });
+                });
+            },
+        );
     }
 }
diff --git a/src/logging.ts b/src/logging.ts
index 5faf23a3d2..4a9d9fa54d 100644
--- a/src/logging.ts
+++ b/src/logging.ts
@@ -1,134 +1,157 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import fs = require("fs");
-import os = require("os");
-import path = require("path");
-import vscode = require("vscode");
-import utils = require("./utils");
-
-export enum LogLevel {
-    Diagnostic,
-    Verbose,
-    Normal,
-    Warning,
-    Error,
-}
+import { LogLevel, window, type Event, type LogOutputChannel } from "vscode";
 
 /** Interface for logging operations. New features should use this interface for the "type" of logger.
  *  This will allow for easy mocking of the logger during unit tests.
  */
 export interface ILogger {
-    write(message: string, ...additionalMessages: string[]);
-    writeDiagnostic(message: string, ...additionalMessages: string[]);
-    writeVerbose(message: string, ...additionalMessages: string[]);
-    writeWarning(message: string, ...additionalMessages: string[]);
-    writeAndShowWarning(message: string, ...additionalMessages: string[]);
-    writeError(message: string, ...additionalMessages: string[]);
+    write(message: string, ...additionalMessages: string[]): void;
+    writeAndShowInformation(
+        message: string,
+        ...additionalMessages: string[]
+    ): Promise<void>;
+    writeTrace(message: string, ...additionalMessages: string[]): void;
+    writeDebug(message: string, ...additionalMessages: string[]): void;
+    writeWarning(message: string, ...additionalMessages: string[]): void;
+    writeAndShowWarning(
+        message: string,
+        ...additionalMessages: string[]
+    ): Promise<void>;
+    writeError(message: string, ...additionalMessages: string[]): void;
+    writeAndShowError(
+        message: string,
+        ...additionalMessages: string[]
+    ): Promise<void>;
+    writeAndShowErrorWithActions(
+        message: string,
+        actions: {
+            prompt: string;
+            action: (() => Promise<void>) | undefined;
+        }[],
+    ): Promise<void>;
 }
 
 export class Logger implements ILogger {
-
-    public logBasePath: string;
-    public logSessionPath: string;
-    public MinimumLogLevel: LogLevel = LogLevel.Normal;
-
-    private commands: vscode.Disposable[];
-    private logChannel: vscode.OutputChannel;
-    private logFilePath: string;
-
-    constructor() {
-        this.logChannel = vscode.window.createOutputChannel("PowerShell Extension Logs");
-
-        this.logBasePath = path.resolve(__dirname, "../logs");
-        utils.ensurePathExists(this.logBasePath);
-
-        this.commands = [
-            vscode.commands.registerCommand(
-                "PowerShell.ShowLogs",
-                () => { this.showLogPanel(); }),
-
-            vscode.commands.registerCommand(
-                "PowerShell.OpenLogFolder",
-                () => { this.openLogFolder(); }),
-        ];
+    // Log output channel handles all the verbosity management so we don't have to.
+    private logChannel: LogOutputChannel;
+    public get logLevel(): LogLevel {
+        return this.logChannel.logLevel;
     }
 
-    public dispose() {
-        this.commands.forEach((command) => { command.dispose(); });
-        this.logChannel.dispose();
+    constructor(logChannel?: LogOutputChannel) {
+        this.logChannel =
+            logChannel ??
+            window.createOutputChannel("PowerShell", { log: true });
     }
 
-    public getLogFilePath(baseName: string): string {
-        return path.resolve(this.logSessionPath, `${baseName}.log`);
+    public dispose(): void {
+        this.logChannel.dispose();
     }
 
-    public writeAtLevel(logLevel: LogLevel, message: string, ...additionalMessages: string[]) {
-        if (logLevel >= this.MinimumLogLevel) {
-            this.writeLine(message, logLevel);
+    private writeAtLevel(
+        logLevel: LogLevel,
+        message: string,
+        ...additionalMessages: string[]
+    ): void {
+        if (logLevel >= this.logLevel) {
+            void this.writeLine(message, logLevel);
 
-            additionalMessages.forEach((line) => {
-                this.writeLine(line, logLevel);
-            });
+            for (const additionalMessage of additionalMessages) {
+                void this.writeLine(additionalMessage, logLevel);
+            }
         }
     }
 
-    public write(message: string, ...additionalMessages: string[]) {
-        this.writeAtLevel(LogLevel.Normal, message, ...additionalMessages);
+    public write(message: string, ...additionalMessages: string[]): void {
+        this.writeAtLevel(LogLevel.Info, message, ...additionalMessages);
     }
 
-    public writeDiagnostic(message: string, ...additionalMessages: string[]) {
-        this.writeAtLevel(LogLevel.Diagnostic, message, ...additionalMessages);
+    public async writeAndShowInformation(
+        message: string,
+        ...additionalMessages: string[]
+    ): Promise<void> {
+        this.write(message, ...additionalMessages);
+
+        const selection = await window.showInformationMessage(
+            message,
+            "Show Logs",
+            "Okay",
+        );
+        if (selection === "Show Logs") {
+            this.showLogPanel();
+        }
+    }
+
+    public writeTrace(message: string, ...additionalMessages: string[]): void {
+        this.writeAtLevel(LogLevel.Trace, message, ...additionalMessages);
     }
 
-    public writeVerbose(message: string, ...additionalMessages: string[]) {
-        this.writeAtLevel(LogLevel.Verbose, message, ...additionalMessages);
+    public writeDebug(message: string, ...additionalMessages: string[]): void {
+        this.writeAtLevel(LogLevel.Debug, message, ...additionalMessages);
     }
 
-    public writeWarning(message: string, ...additionalMessages: string[]) {
+    public writeWarning(
+        message: string,
+        ...additionalMessages: string[]
+    ): void {
         this.writeAtLevel(LogLevel.Warning, message, ...additionalMessages);
     }
 
-    public writeAndShowWarning(message: string, ...additionalMessages: string[]) {
+    public async writeAndShowWarning(
+        message: string,
+        ...additionalMessages: string[]
+    ): Promise<void> {
         this.writeWarning(message, ...additionalMessages);
 
-        vscode.window.showWarningMessage(message, "Show Logs").then((selection) => {
-            if (selection !== undefined) {
-                this.showLogPanel();
-            }
-        });
+        const selection = await window.showWarningMessage(message, "Show Logs");
+        if (selection !== undefined) {
+            this.showLogPanel();
+        }
     }
 
-    public writeError(message: string, ...additionalMessages: string[]) {
+    public writeError(message: string, ...additionalMessages: string[]): void {
         this.writeAtLevel(LogLevel.Error, message, ...additionalMessages);
     }
 
-    public writeAndShowError(message: string, ...additionalMessages: string[]) {
+    public async writeAndShowError(
+        message: string,
+        ...additionalMessages: string[]
+    ): Promise<void> {
         this.writeError(message, ...additionalMessages);
 
-        vscode.window.showErrorMessage(message, "Show Logs").then((selection) => {
-            if (selection !== undefined) {
-                this.showLogPanel();
-            }
-        });
+        const choice = await window.showErrorMessage(message, "Show Logs");
+        if (choice !== undefined) {
+            this.showLogPanel();
+        }
     }
 
     public async writeAndShowErrorWithActions(
         message: string,
-        actions: { prompt: string; action: () => Promise<void> }[]) {
+        actions: {
+            prompt: string;
+            action: (() => Promise<void>) | undefined;
+        }[],
+    ): Promise<void> {
         this.writeError(message);
 
         const fullActions = [
             ...actions,
-            { prompt: "Show Logs", action: async () => { this.showLogPanel(); } },
+            {
+                prompt: "Show Logs",
+                action: (): void => {
+                    this.showLogPanel();
+                },
+            },
         ];
 
         const actionKeys: string[] = fullActions.map((action) => action.prompt);
 
-        const choice = await vscode.window.showErrorMessage(message, ...actionKeys);
+        const choice = await window.showErrorMessage(message, ...actionKeys);
         if (choice) {
             for (const action of fullActions) {
-                if (choice === action.prompt) {
+                if (choice === action.prompt && action.action !== undefined) {
                     await action.action();
                     return;
                 }
@@ -136,61 +159,208 @@ export class Logger implements ILogger {
         }
     }
 
-    public startNewLog(minimumLogLevel: string = "Normal") {
-        this.MinimumLogLevel = this.logLevelNameToValue(minimumLogLevel.trim());
+    public showLogPanel(): void {
+        this.logChannel.show();
+    }
 
-        this.logSessionPath =
-            path.resolve(
-                this.logBasePath,
-                `${Math.floor(Date.now() / 1000)}-${vscode.env.sessionId}`);
+    private async writeLine(
+        message: string,
+        level: LogLevel = LogLevel.Info,
+    ): Promise<void> {
+        return new Promise<void>((resolve) => {
+            switch (level) {
+                case LogLevel.Off:
+                    break;
+                case LogLevel.Trace:
+                    this.logChannel.trace(message);
+                    break;
+                case LogLevel.Debug:
+                    this.logChannel.debug(message);
+                    break;
+                case LogLevel.Info:
+                    this.logChannel.info(message);
+                    break;
+                case LogLevel.Warning:
+                    this.logChannel.warn(message);
+                    break;
+                case LogLevel.Error:
+                    this.logChannel.error(message);
+                    break;
+                default:
+                    this.logChannel.appendLine(message);
+                    break;
+            }
+            resolve();
+        });
+    }
+}
 
-        this.logFilePath = this.getLogFilePath("vscode-powershell");
+/** Parses logs received via the legacy OutputChannel to LogOutputChannel with proper severity.
+ *
+ * HACK: This is for legacy compatability and can be removed when https://github.com/microsoft/vscode-languageserver-node/issues/1116 is merged and replaced with a normal LogOutputChannel. We don't use a middleware here because any direct logging calls like client.warn() and server-initiated messages would not be captured by middleware.
+ */
+export class LanguageClientOutputChannelAdapter implements LogOutputChannel {
+    private _channel: LogOutputChannel | undefined;
+    private get channel(): LogOutputChannel {
+        this._channel ??= window.createOutputChannel(this.channelName, {
+            log: true,
+        });
+        return this._channel;
+    }
 
-        utils.ensurePathExists(this.logSessionPath);
+    /**
+     * Creates an instance of the logging class.
+     *
+     * @param channelName - The name of the output channel.
+     * @param parser - A function that parses a log message and returns a tuple containing the parsed message and its log level, or undefined if the log should be filtered.
+     */
+    constructor(
+        private channelName: string,
+        private parser: (
+            message: string,
+        ) =>
+            | [string, LogLevel]
+            | undefined = LanguageClientOutputChannelAdapter.omnisharpLspParser.bind(
+            this,
+        ),
+    ) {}
+
+    public appendLine(message: string): void {
+        this.append(message);
     }
 
-    private logLevelNameToValue(logLevelName: string): LogLevel {
-        switch (logLevelName.toLowerCase()) {
-            case "diagnostic": return LogLevel.Diagnostic;
-            case "verbose": return LogLevel.Verbose;
-            case "normal": return LogLevel.Normal;
-            case "warning": return LogLevel.Warning;
-            case "error": return LogLevel.Error;
-            default: return LogLevel.Normal;
+    public append(message: string): void {
+        const parseResult = this.parser(message);
+        if (parseResult !== undefined) {
+            this.sendLogMessage(...parseResult);
         }
     }
 
-    private showLogPanel() {
-        this.logChannel.show();
+    /** Converts from Omnisharp logs since middleware for LogMessage does not currently exist **/
+    public static omnisharpLspParser(message: string): [string, LogLevel] {
+        const logLevelMatch =
+            /^\[(?<level>Trace|Debug|Info|Warn|Error) +- \d+:\d+:\d+ [AP]M\] (?<message>.+)/.exec(
+                message,
+            );
+        const logLevel: LogLevel = logLevelMatch?.groups?.level
+            ? LogLevel[logLevelMatch.groups.level as keyof typeof LogLevel]
+            : LogLevel.Info;
+        const logMessage = logLevelMatch?.groups?.message ?? message;
+
+        return [logMessage, logLevel];
     }
 
-    private openLogFolder() {
-        if (this.logSessionPath) {
-            // Open the folder in VS Code since there isn't an easy way to
-            // open the folder in the platform's file browser
-            vscode.commands.executeCommand(
-                "vscode.openFolder",
-                vscode.Uri.file(this.logSessionPath),
-                true);
+    protected sendLogMessage(message: string, level: LogLevel): void {
+        switch (level) {
+            case LogLevel.Trace:
+                this.channel.trace(message);
+                break;
+            case LogLevel.Debug:
+                this.channel.debug(message);
+                break;
+            case LogLevel.Info:
+                this.channel.info(message);
+                break;
+            case LogLevel.Warning:
+                this.channel.warn(message);
+                break;
+            case LogLevel.Error:
+                this.channel.error(message);
+                break;
+            default:
+                this.channel.error("!UNKNOWN LOG LEVEL!: " + message);
+                break;
         }
     }
 
-    private writeLine(message: string, level: LogLevel = LogLevel.Normal) {
-        const now = new Date();
-        const timestampedMessage =
-            `${now.toLocaleDateString()} ${now.toLocaleTimeString()} [${LogLevel[level].toUpperCase()}] - ${message}`;
-
-        this.logChannel.appendLine(timestampedMessage);
-        if (this.logFilePath) {
-            fs.appendFile(
-                this.logFilePath,
-                timestampedMessage + os.EOL,
-                (err) => {
-                    if (err) {
-                        // tslint:disable-next-line:no-console
-                        console.log(`Error writing to vscode-powershell log file: ${err}`);
-                    }
-                });
-        }
+    // #region Passthru Implementation
+    public get name(): string {
+        // prevents the window from being created unless we get a log request
+        return this.channelName;
+    }
+    public get logLevel(): LogLevel {
+        return this.channel.logLevel;
+    }
+    replace(value: string): void {
+        this.channel.replace(value);
+    }
+    show(_column?: undefined, preserveFocus?: boolean): void {
+        this.channel.show(preserveFocus);
+    }
+    public get onDidChangeLogLevel(): Event<LogLevel> {
+        return this.channel.onDidChangeLogLevel;
+    }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    public trace(message: string, ...args: any[]): void {
+        this.channel.trace(message, ...args);
+    }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    public debug(message: string, ...args: any[]): void {
+        this.channel.debug(message, ...args);
+    }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    public info(message: string, ...args: any[]): void {
+        this.channel.info(message, ...args);
     }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    public warn(message: string, ...args: any[]): void {
+        this.channel.warn(message, ...args);
+    }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    public error(message: string, ...args: any[]): void {
+        this.channel.error(message, ...args);
+    }
+    public clear(): void {
+        this.channel.clear();
+    }
+    public hide(): void {
+        this.channel.hide();
+    }
+    public dispose(): void {
+        this.channel.dispose();
+    }
+    // #endregion
+}
+
+/** Special parsing for PowerShell Editor Services LSP messages since the LogLevel cannot be read due to vscode
+ * LanguageClient Limitations (https://github.com/microsoft/vscode-languageserver-node/issues/1116)
+ */
+export function PsesParser(message: string): [string, LogLevel] {
+    const logLevelMatch =
+        /^<(?<level>Trace|Debug|Info|Warning|Error)>(?<message>.+)/.exec(
+            message,
+        );
+    const logLevel: LogLevel = logLevelMatch?.groups?.level
+        ? LogLevel[logLevelMatch.groups.level as keyof typeof LogLevel]
+        : LogLevel.Info;
+    const logMessage = logLevelMatch?.groups?.message ?? message;
+
+    return ["[PSES] " + logMessage, logLevel];
+}
+
+/** Lsp Trace Parser that does some additional parsing and formatting to make it look nicer */
+export function LspTraceParser(message: string): [string, LogLevel] {
+    let [parsedMessage, level] =
+        LanguageClientOutputChannelAdapter.omnisharpLspParser(message);
+    if (parsedMessage.startsWith("Sending ")) {
+        parsedMessage = parsedMessage.replace("Sending", "➡️");
+        level = LogLevel.Debug;
+    }
+    if (parsedMessage.startsWith("Received ")) {
+        parsedMessage = parsedMessage.replace("Received", "⬅️");
+        level = LogLevel.Debug;
+    }
+    if (
+        parsedMessage.startsWith("Params:") ||
+        parsedMessage.startsWith("Result:")
+    ) {
+        level = LogLevel.Trace;
+    }
+
+    // These are PSES messages that get logged to the output channel anyways so we drop these to trace for easy noise filtering
+    if (parsedMessage.startsWith("⬅️ notification 'window/logMessage'")) {
+        level = LogLevel.Trace;
+    }
+
+    return [parsedMessage.trimEnd(), level];
 }
diff --git a/src/main.ts b/src/main.ts
deleted file mode 100644
index 9d0219d4d1..0000000000
--- a/src/main.ts
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-"use strict";
-
-import path = require("path");
-import vscode = require("vscode");
-import TelemetryReporter from "vscode-extension-telemetry";
-import { DocumentSelector } from "vscode-languageclient";
-import { CodeActionsFeature } from "./features/CodeActions";
-import { ConsoleFeature } from "./features/Console";
-import { CustomViewsFeature } from "./features/CustomViews";
-import { DebugSessionFeature } from "./features/DebugSession";
-import { ExamplesFeature } from "./features/Examples";
-import { ExpandAliasFeature } from "./features/ExpandAlias";
-import { ExtensionCommandsFeature } from "./features/ExtensionCommands";
-import { ExternalApiFeature, IPowerShellExtensionClient } from "./features/ExternalApi";
-import { FindModuleFeature } from "./features/FindModule";
-import { GenerateBugReportFeature } from "./features/GenerateBugReport";
-import { GetCommandsFeature } from "./features/GetCommands";
-import { HelpCompletionFeature } from "./features/HelpCompletion";
-import { ISECompatibilityFeature } from "./features/ISECompatibility";
-import { NewFileOrProjectFeature } from "./features/NewFileOrProject";
-import { OpenInISEFeature } from "./features/OpenInISE";
-import { PesterTestsFeature } from "./features/PesterTests";
-import { PickPSHostProcessFeature, PickRunspaceFeature } from "./features/DebugSession";
-import { RemoteFilesFeature } from "./features/RemoteFiles";
-import { RunCodeFeature } from "./features/RunCode";
-import { ShowHelpFeature } from "./features/ShowHelp";
-import { SpecifyScriptArgsFeature } from "./features/DebugSession";
-import { Logger, LogLevel } from "./logging";
-import { SessionManager } from "./session";
-import Settings = require("./settings");
-import { PowerShellLanguageId } from "./utils";
-import { LanguageClientConsumer } from "./languageClientConsumer";
-
-// The most reliable way to get the name and version of the current extension.
-// tslint:disable-next-line: no-var-requires
-const PackageJSON: any = require("../package.json");
-
-// the application insights key (also known as instrumentation key) used for telemetry.
-const AI_KEY: string = "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217";
-
-let logger: Logger;
-let sessionManager: SessionManager;
-let languageClientConsumers: LanguageClientConsumer[] = [];
-let commandRegistrations: vscode.Disposable[] = [];
-let telemetryReporter: TelemetryReporter;
-
-const documentSelector: DocumentSelector = [
-    { language: "powershell", scheme: "file" },
-    { language: "powershell", scheme: "untitled" },
-];
-
-export function activate(context: vscode.ExtensionContext): IPowerShellExtensionClient {
-    // create telemetry reporter on extension activation
-    telemetryReporter = new TelemetryReporter(PackageJSON.name, PackageJSON.version, AI_KEY);
-
-    // If both extensions are enabled, this will cause unexpected behavior since both register the same commands
-    if (PackageJSON.name.toLowerCase() === "powershell-preview"
-        && vscode.extensions.getExtension("ms-vscode.powershell")) {
-        vscode.window.showWarningMessage(
-            "'PowerShell' and 'PowerShell Preview' are both enabled. Please disable one for best performance.");
-    }
-
-    checkForUpdatedVersion(context, PackageJSON.version);
-
-    vscode.languages.setLanguageConfiguration(
-        PowerShellLanguageId,
-        {
-            wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\'\"\,\.\<\>\/\?\s]+)/g,
-
-            indentationRules: {
-                // ^(.*\*/)?\s*\}.*$
-                decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/,
-                // ^.*\{[^}"']*$
-                increaseIndentPattern: /^.*\{[^}"']*$/,
-            },
-
-            comments: {
-                lineComment: "#",
-                blockComment: ["<#", "#>"],
-            },
-
-            brackets: [
-                ["{", "}"],
-                ["[", "]"],
-                ["(", ")"],
-            ],
-
-            onEnterRules: [
-                {
-                    // e.g. /** | */
-                    beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
-                    afterText: /^\s*\*\/$/,
-                    action: { indentAction: vscode.IndentAction.IndentOutdent, appendText: " * " },
-                },
-                {
-                    // e.g. /** ...|
-                    beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
-                    action: { indentAction: vscode.IndentAction.None, appendText: " * " },
-                },
-                {
-                    // e.g.  * ...|
-                    beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
-                    action: { indentAction: vscode.IndentAction.None, appendText: "* " },
-                },
-                {
-                    // e.g.  */|
-                    beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
-                    action: { indentAction: vscode.IndentAction.None, removeText: 1 },
-                },
-                {
-                    // e.g.  *-----*/|
-                    beforeText: /^(\t|(\ \ ))*\ \*[^/]*\*\/\s*$/,
-                    action: { indentAction: vscode.IndentAction.None, removeText: 1 },
-                },
-            ],
-        });
-
-    // Create the logger
-    logger = new Logger();
-
-    // Set the log level
-    const extensionSettings = Settings.load();
-    logger.MinimumLogLevel = LogLevel[extensionSettings.developer.editorServicesLogLevel];
-
-    sessionManager =
-        new SessionManager(
-            logger,
-            documentSelector,
-            PackageJSON.displayName,
-            PackageJSON.version,
-            telemetryReporter);
-
-    // Register commands that do not require Language client
-    commandRegistrations = [
-        new ExamplesFeature(),
-        new GenerateBugReportFeature(sessionManager),
-        new ISECompatibilityFeature(),
-        new OpenInISEFeature(),
-        new PesterTestsFeature(sessionManager),
-        new RunCodeFeature(sessionManager),
-        new CodeActionsFeature(logger),
-        new SpecifyScriptArgsFeature(context),
-    ]
-
-    const externalApi = new ExternalApiFeature(sessionManager, logger);
-
-    // Features and command registrations that require language client
-    languageClientConsumers = [
-        new ConsoleFeature(logger),
-        new ExpandAliasFeature(logger),
-        new GetCommandsFeature(logger),
-        new ShowHelpFeature(logger),
-        new FindModuleFeature(),
-        new ExtensionCommandsFeature(logger),
-        new NewFileOrProjectFeature(),
-        new RemoteFilesFeature(),
-        new DebugSessionFeature(context, sessionManager, logger),
-        new PickPSHostProcessFeature(),
-        new HelpCompletionFeature(logger),
-        new CustomViewsFeature(),
-        new PickRunspaceFeature(),
-        externalApi
-    ];
-
-    sessionManager.setLanguageClientConsumers(languageClientConsumers);
-
-    if (extensionSettings.startAutomatically) {
-        sessionManager.start();
-    }
-
-    return {
-        registerExternalExtension: (id: string, apiVersion: string = 'v1') => externalApi.registerExternalExtension(id, apiVersion),
-        unregisterExternalExtension: uuid => externalApi.unregisterExternalExtension(uuid),
-        getPowerShellVersionDetails: uuid => externalApi.getPowerShellVersionDetails(uuid),
-        waitUntilStarted: uuid => externalApi.waitUntilStarted(uuid),
-    };
-}
-
-function checkForUpdatedVersion(context: vscode.ExtensionContext, version: string) {
-
-    const showReleaseNotes = "Show Release Notes";
-    const powerShellExtensionVersionKey = "powerShellExtensionVersion";
-
-    const storedVersion = context.globalState.get(powerShellExtensionVersionKey);
-
-    if (!storedVersion) {
-        // TODO: Prompt to show User Guide for first-time install
-    } else if (version !== storedVersion) {
-        vscode
-            .window
-            .showInformationMessage(
-                `The PowerShell extension has been updated to version ${version}!`,
-                showReleaseNotes)
-            .then((choice) => {
-                if (choice === showReleaseNotes) {
-                    vscode.commands.executeCommand(
-                        "markdown.showPreview",
-                        vscode.Uri.file(path.resolve(__dirname, "../CHANGELOG.md")));
-                }
-            });
-    }
-
-    context.globalState.update(
-        powerShellExtensionVersionKey,
-        version);
-}
-
-export function deactivate(): void {
-    // Clean up all extension features
-    languageClientConsumers.forEach((languageClientConsumer) => {
-        languageClientConsumer.dispose();
-    });
-
-    commandRegistrations.forEach((commandRegistration) => {
-        commandRegistration.dispose();
-    });
-
-    // Dispose of the current session
-    sessionManager.dispose();
-
-    // Dispose of the logger
-    logger.dispose();
-
-    // Dispose of telemetry reporter
-    telemetryReporter.dispose();
-}
diff --git a/src/platform.ts b/src/platform.ts
index 9aee1e5d1a..76ca5992ed 100644
--- a/src/platform.ts
+++ b/src/platform.ts
@@ -1,25 +1,36 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import * as child_process from "child_process";
-import * as fs from "fs";
 import * as os from "os";
 import * as path from "path";
 import * as process from "process";
-import { IPowerShellAdditionalExePathSettings } from "./settings";
+import untildify from "untildify";
+import { integer } from "vscode-languageserver-protocol";
+import type { ILogger } from "./logging";
+import {
+    changeSetting,
+    getSettings,
+    type PowerShellAdditionalExePathSettings,
+} from "./settings";
+import * as utils from "./utils";
+import vscode = require("vscode");
 
 const WindowsPowerShell64BitLabel = "Windows PowerShell (x64)";
 const WindowsPowerShell32BitLabel = "Windows PowerShell (x86)";
 
-const LinuxExePath        = "/usr/bin/pwsh";
+const LinuxExePath = "/usr/bin/pwsh";
 const LinuxPreviewExePath = "/usr/bin/pwsh-preview";
 
-const SnapExePath         = "/snap/bin/pwsh";
-const SnapPreviewExePath  = "/snap/bin/pwsh-preview";
+const SnapExePath = "/snap/bin/pwsh";
+const SnapPreviewExePath = "/snap/bin/pwsh-preview";
 
-const MacOSExePath        = "/usr/local/bin/pwsh";
+const MacOSExePath = "/usr/local/bin/pwsh";
 const MacOSPreviewExePath = "/usr/local/bin/pwsh-preview";
 
+const MacOSHomebrewExePath = "/opt/homebrew/bin/pwsh";
+const MacOSHomebrewLTSExePath = "/opt/homebrew/bin/pwsh-lts";
+const MacOSHomebrewPreviewExePath = "/opt/homebrew/bin/pwsh-preview";
+
 export enum OperatingSystem {
     Unknown,
     Windows,
@@ -36,6 +47,7 @@ export interface IPlatformDetails {
 export interface IPowerShellExeDetails {
     readonly displayName: string;
     readonly exePath: string;
+    readonly supportsProperArguments: boolean;
 }
 
 export function getPlatformDetails(): IPlatformDetails {
@@ -49,11 +61,12 @@ export function getPlatformDetails(): IPlatformDetails {
         operatingSystem = OperatingSystem.Linux;
     }
 
-    const isProcess64Bit = (process.arch === "x64" || process.arch === "arm64");
+    const isProcess64Bit = process.arch === "x64" || process.arch === "arm64";
 
     return {
         operatingSystem,
-        isOS64Bit: isProcess64Bit || process.env.hasOwnProperty("PROCESSOR_ARCHITEW6432"),
+        isOS64Bit:
+            isProcess64Bit || process.env.PROCESSOR_ARCHITEW6432 !== undefined,
         isProcess64Bit,
     };
 }
@@ -65,21 +78,11 @@ export function getPlatformDetails(): IPlatformDetails {
  */
 export class PowerShellExeFinder {
     // This is required, since parseInt("7-preview") will return 7.
-    private static IntRegex: RegExp = /^\d+$/;
-
-    private static PwshMsixRegex: RegExp = /^Microsoft.PowerShell_.*/;
-
-    private static PwshPreviewMsixRegex: RegExp = /^Microsoft.PowerShellPreview_.*/;
-
-    // The platform details descriptor for the platform we're on
-    private readonly platformDetails: IPlatformDetails;
-
-    // Additional configured PowerShells
-    private readonly additionalPSExeSettings: Iterable<IPowerShellAdditionalExePathSettings>;
-
-    private winPS: IPossiblePowerShellExe;
-
-    private alternateBitnessWinPS: IPossiblePowerShellExe;
+    private static IntRegex = /^\d+$/;
+    private static PwshMsixRegex = /^Microsoft.PowerShell_.*/;
+    private static PwshPreviewMsixRegex = /^Microsoft.PowerShellPreview_.*/;
+    private winPS: IPossiblePowerShellExe | undefined;
+    private alternateBitnessWinPS: IPossiblePowerShellExe | undefined;
 
     /**
      * Create a new PowerShellFinder object to discover PowerShell installations.
@@ -87,34 +90,45 @@ export class PowerShellExeFinder {
      * @param additionalPowerShellExes Additional PowerShell installations as configured in the settings.
      */
     constructor(
-        platformDetails?: IPlatformDetails,
-        additionalPowerShellExes?: Iterable<IPowerShellAdditionalExePathSettings>) {
-
-        this.platformDetails = platformDetails || getPlatformDetails();
-        this.additionalPSExeSettings = additionalPowerShellExes || [];
-    }
+        // The platform details descriptor for the platform we're on
+        private platformDetails: IPlatformDetails,
+        // Additional configured PowerShells
+        private additionalPowerShellExes: PowerShellAdditionalExePathSettings,
+        private logger?: ILogger,
+    ) {}
 
     /**
      * Returns the first available PowerShell executable found in the search order.
      */
-    public getFirstAvailablePowerShellInstallation(): IPowerShellExeDetails {
-        for (const pwsh of this.enumeratePowerShellInstallations()) {
+    public async getFirstAvailablePowerShellInstallation(): Promise<
+        IPowerShellExeDetails | undefined
+    > {
+        for await (const pwsh of this.enumeratePowerShellInstallations()) {
             return pwsh;
         }
+        return undefined;
     }
 
     /**
      * Get an array of all PowerShell executables found when searching for PowerShell installations.
      */
-    public getAllAvailablePowerShellInstallations(): IPowerShellExeDetails[] {
-        return Array.from(this.enumeratePowerShellInstallations());
+    public async getAllAvailablePowerShellInstallations(): Promise<
+        IPowerShellExeDetails[]
+    > {
+        const array: IPowerShellExeDetails[] = [];
+        for await (const pwsh of this.enumeratePowerShellInstallations()) {
+            array.push(pwsh);
+        }
+        return array;
     }
 
     /**
      * Fixes PowerShell paths when Windows PowerShell is set to the non-native bitness.
      * @param configuredPowerShellPath the PowerShell path configured by the user.
      */
-    public fixWindowsPowerShellPath(configuredPowerShellPath: string): string {
+    public fixWindowsPowerShellPath(
+        configuredPowerShellPath: string,
+    ): string | undefined {
         const altWinPS = this.findWinPS({ useAlternateBitness: true });
 
         if (!altWinPS) {
@@ -122,10 +136,11 @@ export class PowerShellExeFinder {
         }
 
         const lowerAltWinPSPath = altWinPS.exePath.toLocaleLowerCase();
-        const lowerConfiguredPath = configuredPowerShellPath.toLocaleLowerCase();
+        const lowerConfiguredPath =
+            configuredPowerShellPath.toLocaleLowerCase();
 
         if (lowerConfiguredPath === lowerAltWinPSPath) {
-            return this.findWinPS().exePath;
+            return this.findWinPS()?.exePath;
         }
 
         return configuredPowerShellPath;
@@ -137,19 +152,37 @@ export class PowerShellExeFinder {
      * PowerShell items returned by this object are verified
      * to exist on the filesystem.
      */
-    public *enumeratePowerShellInstallations(): Iterable<IPowerShellExeDetails> {
+    public async *enumeratePowerShellInstallations(): AsyncIterable<IPowerShellExeDetails> {
         // Get the default PowerShell installations first
-        for (const defaultPwsh of this.enumerateDefaultPowerShellInstallations()) {
-            if (defaultPwsh && defaultPwsh.exists()) {
+        for await (const defaultPwsh of this.enumerateDefaultPowerShellInstallations()) {
+            if (defaultPwsh && (await defaultPwsh.exists())) {
                 yield defaultPwsh;
             }
         }
 
         // Also show any additionally configured PowerShells
         // These may be duplicates of the default installations, but given a different name.
-        for (const additionalPwsh of this.enumerateAdditionalPowerShellInstallations()) {
-            if (additionalPwsh && additionalPwsh.exists()) {
+        for await (const additionalPwsh of this.enumerateAdditionalPowerShellInstallations()) {
+            if (await additionalPwsh.exists()) {
                 yield additionalPwsh;
+            } else if (!additionalPwsh.suppressWarning) {
+                const message = `Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`;
+                this.logger?.writeWarning(message);
+
+                if (!getSettings().suppressAdditionalExeNotFoundWarning) {
+                    const selection = await vscode.window.showWarningMessage(
+                        message,
+                        "Don't Show Again",
+                    );
+                    if (selection !== undefined) {
+                        await changeSetting(
+                            "suppressAdditionalExeNotFoundWarning",
+                            true,
+                            true,
+                            this.logger,
+                        );
+                    }
+                }
             }
         }
     }
@@ -158,8 +191,11 @@ export class PowerShellExeFinder {
      * Iterates through all the possible well-known PowerShell installations on a machine.
      * Returned values may not exist, but come with an .exists property
      * which will check whether the executable exists.
+     * TODO: We really need to define the order in which we search for stable/LTS/preview/daily
      */
-    private *enumerateDefaultPowerShellInstallations(): Iterable<IPossiblePowerShellExe> {
+    private async *enumerateDefaultPowerShellInstallations(): AsyncIterable<
+        IPossiblePowerShellExe | undefined
+    > {
         // Find PSCore stable first
         yield this.findPSCoreStable();
 
@@ -171,11 +207,17 @@ export class PowerShellExeFinder {
 
             case OperatingSystem.Windows:
                 // Windows may have a 32-bit pwsh.exe
-                yield this.findPSCoreWindowsInstallation({ useAlternateBitness: true });
-
+                yield this.findPSCoreWindowsInstallation({
+                    useAlternateBitness: true,
+                });
                 // Also look for the MSIX/UWP installation
-                yield this.findPSCoreMsix();
+                yield await this.findPSCoreMsix();
+                break;
 
+            case OperatingSystem.MacOS:
+                // On MacOS, find the Homebrew installations
+                yield this.findPSCoreHomebrewStable();
+                yield this.findPSCoreHomebrewLTS();
                 break;
         }
 
@@ -198,7 +240,10 @@ export class PowerShellExeFinder {
                 yield this.findPSCoreMsix({ findPreview: true });
 
                 // Look for pwsh-preview with the opposite bitness
-                yield this.findPSCoreWindowsInstallation({ useAlternateBitness: true, findPreview: true });
+                yield this.findPSCoreWindowsInstallation({
+                    useAlternateBitness: true,
+                    findPreview: true,
+                });
 
                 // Finally, get Windows PowerShell
 
@@ -209,20 +254,119 @@ export class PowerShellExeFinder {
                 yield this.findWinPS({ useAlternateBitness: true });
 
                 break;
+
+            case OperatingSystem.MacOS:
+                // On MacOS, find the Homebrew preview
+                yield this.findPSCoreHomebrewPreview();
+                break;
         }
+
+        // Look for PSCore daily
+        yield this.findPSCoreDaily();
     }
 
     /**
-     * Iterates through the configured additonal PowerShell executable locations,
+     * Iterates through the configured additional PowerShell executable locations,
      * without checking for their existence.
      */
-    private *enumerateAdditionalPowerShellInstallations(): Iterable<IPossiblePowerShellExe> {
-        for (const additionalPwshSetting of this.additionalPSExeSettings) {
-            yield new PossiblePowerShellExe(additionalPwshSetting.exePath, additionalPwshSetting.versionName);
+    public async *enumerateAdditionalPowerShellInstallations(): AsyncIterable<IPossiblePowerShellExe> {
+        for (const versionName in this.additionalPowerShellExes) {
+            if (
+                Object.prototype.hasOwnProperty.call(
+                    this.additionalPowerShellExes,
+                    versionName,
+                )
+            ) {
+                let exePath: string | undefined = utils.stripQuotePair(
+                    this.additionalPowerShellExes[versionName],
+                );
+                if (!exePath) {
+                    continue;
+                }
+
+                exePath = untildify(exePath);
+                const args: [string, undefined, boolean, boolean] =
+                    // Must be a tuple type and is suppressing the warning
+                    [versionName, undefined, true, true];
+
+                // Always search for what the user gave us first, but with the warning
+                // suppressed so we can display it after all possibilities are exhausted
+                let pwsh = new PossiblePowerShellExe(exePath, ...args);
+                if (await pwsh.exists()) {
+                    yield pwsh;
+                    continue;
+                }
+
+                // Also search for `pwsh[.exe]` and `powershell[.exe]` if missing
+                if (
+                    this.platformDetails.operatingSystem ===
+                    OperatingSystem.Windows
+                ) {
+                    // Handle Windows where '.exe' and 'powershell' are things
+                    if (
+                        !exePath.endsWith("pwsh.exe") &&
+                        !exePath.endsWith("powershell.exe")
+                    ) {
+                        if (
+                            exePath.endsWith("pwsh") ||
+                            exePath.endsWith("powershell")
+                        ) {
+                            // Add extension if that was missing
+                            pwsh = new PossiblePowerShellExe(
+                                exePath + ".exe",
+                                ...args,
+                            );
+                            if (await pwsh.exists()) {
+                                yield pwsh;
+                                continue;
+                            }
+                        }
+                        // Also add full exe names (this isn't an else just in case
+                        // the folder was named "pwsh" or "powershell")
+                        pwsh = new PossiblePowerShellExe(
+                            path.join(exePath, "pwsh.exe"),
+                            ...args,
+                        );
+                        if (await pwsh.exists()) {
+                            yield pwsh;
+                            continue;
+                        }
+                        pwsh = new PossiblePowerShellExe(
+                            path.join(exePath, "powershell.exe"),
+                            ...args,
+                        );
+                        if (await pwsh.exists()) {
+                            yield pwsh;
+                            continue;
+                        }
+                    }
+                } else if (!exePath.endsWith("pwsh")) {
+                    // Always just 'pwsh' on non-Windows
+                    pwsh = new PossiblePowerShellExe(
+                        path.join(exePath, "pwsh"),
+                        ...args,
+                    );
+                    if (await pwsh.exists()) {
+                        yield pwsh;
+                        continue;
+                    }
+                }
+
+                // If we're still being iterated over, no permutation of the given path existed so yield an object with the warning unsuppressed
+                yield new PossiblePowerShellExe(
+                    exePath,
+                    versionName,
+                    false,
+                    undefined,
+                    false,
+                );
+            }
         }
     }
 
-    private findPSCoreStable(): IPossiblePowerShellExe {
+    private async findPSCoreStable(): Promise<
+        IPossiblePowerShellExe | undefined
+    > {
         switch (this.platformDetails.operatingSystem) {
             case OperatingSystem.Linux:
                 return new PossiblePowerShellExe(LinuxExePath, "PowerShell");
@@ -231,104 +375,222 @@ export class PowerShellExeFinder {
                 return new PossiblePowerShellExe(MacOSExePath, "PowerShell");
 
             case OperatingSystem.Windows:
-                return this.findPSCoreWindowsInstallation();
+                return await this.findPSCoreWindowsInstallation();
+
+            case OperatingSystem.Unknown:
+                return undefined;
         }
     }
 
-    private findPSCorePreview(): IPossiblePowerShellExe {
+    private async findPSCorePreview(): Promise<
+        IPossiblePowerShellExe | undefined
+    > {
         switch (this.platformDetails.operatingSystem) {
             case OperatingSystem.Linux:
-                return new PossiblePowerShellExe(LinuxPreviewExePath, "PowerShell Preview");
+                return new PossiblePowerShellExe(
+                    LinuxPreviewExePath,
+                    "PowerShell Preview",
+                );
 
             case OperatingSystem.MacOS:
-                return new PossiblePowerShellExe(MacOSPreviewExePath, "PowerShell Preview");
+                return new PossiblePowerShellExe(
+                    MacOSPreviewExePath,
+                    "PowerShell Preview",
+                );
 
             case OperatingSystem.Windows:
-                return this.findPSCoreWindowsInstallation({ findPreview: true });
+                return await this.findPSCoreWindowsInstallation({
+                    findPreview: true,
+                });
+
+            case OperatingSystem.Unknown:
+                return undefined;
         }
     }
 
-    private findPSCoreDotnetGlobalTool(): IPossiblePowerShellExe {
-        const exeName: string = this.platformDetails.operatingSystem === OperatingSystem.Windows
-            ? "pwsh.exe"
-            : "pwsh";
+    /**
+     * If the daily was installed via 'https://aka.ms/install-powershell.ps1', then
+     * this is the default installation location:
+     *
+     * if ($IsWinEnv) {
+     *     $Destination = "$env:LOCALAPPDATA\Microsoft\powershell"
+     * } else {
+     *     $Destination = "~/.powershell"
+     * }
+     *
+     * if ($Daily) {
+     *     $Destination = "${Destination}-daily"
+     * }
+     *
+     * TODO: Remove this after the daily is officially no longer supported.
+     */
+    private findPSCoreDaily(): IPossiblePowerShellExe | undefined {
+        switch (this.platformDetails.operatingSystem) {
+            case OperatingSystem.Linux:
+            case OperatingSystem.MacOS: {
+                const exePath = path.join(
+                    os.homedir(),
+                    ".powershell-daily",
+                    "pwsh",
+                );
+                return new PossiblePowerShellExe(exePath, "PowerShell Daily");
+            }
+
+            case OperatingSystem.Windows: {
+                // We can't proceed if there's no LOCALAPPDATA path
+                if (!process.env.LOCALAPPDATA) {
+                    return undefined;
+                }
+                const exePath = path.join(
+                    process.env.LOCALAPPDATA,
+                    "Microsoft",
+                    "powershell-daily",
+                    "pwsh.exe",
+                );
+                return new PossiblePowerShellExe(exePath, "PowerShell Daily");
+            }
 
-        const dotnetGlobalToolExePath: string = path.join(os.homedir(), ".dotnet", "tools", exeName);
+            case OperatingSystem.Unknown:
+                return undefined;
+        }
+    }
+
+    // The Homebrew installations of PowerShell on Apple Silicon are no longer in the default PATH.
+    private findPSCoreHomebrewStable(): IPossiblePowerShellExe {
+        return new PossiblePowerShellExe(
+            MacOSHomebrewExePath,
+            "PowerShell (Homebrew)",
+        );
+    }
 
-        return new PossiblePowerShellExe(dotnetGlobalToolExePath, ".NET Core PowerShell Global Tool");
+    private findPSCoreHomebrewLTS(): IPossiblePowerShellExe {
+        return new PossiblePowerShellExe(
+            MacOSHomebrewLTSExePath,
+            "PowerShell LTS (Homebrew)",
+        );
     }
 
-    private findPSCoreMsix({ findPreview }: { findPreview?: boolean } = {}): IPossiblePowerShellExe {
+    private findPSCoreHomebrewPreview(): IPossiblePowerShellExe {
+        return new PossiblePowerShellExe(
+            MacOSHomebrewPreviewExePath,
+            "PowerShell Preview (Homebrew)",
+        );
+    }
+
+    private findPSCoreDotnetGlobalTool(): IPossiblePowerShellExe {
+        const exeName: string =
+            this.platformDetails.operatingSystem === OperatingSystem.Windows
+                ? "pwsh.exe"
+                : "pwsh";
+
+        const dotnetGlobalToolExePath: string = path.join(
+            os.homedir(),
+            ".dotnet",
+            "tools",
+            exeName,
+        );
+
+        // The dotnet installed version of PowerShell does not support proper argument parsing, and so it fails with our multi-line startup banner.
+        return new PossiblePowerShellExe(
+            dotnetGlobalToolExePath,
+            ".NET Core PowerShell Global Tool",
+            undefined,
+            false,
+        );
+    }
+
+    private async findPSCoreMsix({
+        findPreview,
+    }: { findPreview?: boolean } = {}): Promise<
+        IPossiblePowerShellExe | undefined
+    > {
         // We can't proceed if there's no LOCALAPPDATA path
         if (!process.env.LOCALAPPDATA) {
-            return null;
+            return undefined;
         }
 
         // Find the base directory for MSIX application exe shortcuts
-        const msixAppDir = path.join(process.env.LOCALAPPDATA, "Microsoft", "WindowsApps");
-
-        if (!fileExistsSync(msixAppDir)) {
-            return null;
+        const msixAppDir = path.join(
+            process.env.LOCALAPPDATA,
+            "Microsoft",
+            "WindowsApps",
+        );
+
+        if (!(await utils.checkIfDirectoryExists(msixAppDir))) {
+            return undefined;
         }
 
         // Define whether we're looking for the preview or the stable
         const { pwshMsixDirRegex, pwshMsixName } = findPreview
-            ? { pwshMsixDirRegex: PowerShellExeFinder.PwshPreviewMsixRegex, pwshMsixName: "PowerShell Preview (Store)" }
-            : { pwshMsixDirRegex: PowerShellExeFinder.PwshMsixRegex, pwshMsixName: "PowerShell (Store)" };
+            ? {
+                  pwshMsixDirRegex: PowerShellExeFinder.PwshPreviewMsixRegex,
+                  pwshMsixName: "PowerShell Preview (Store)",
+              }
+            : {
+                  pwshMsixDirRegex: PowerShellExeFinder.PwshMsixRegex,
+                  pwshMsixName: "PowerShell (Store)",
+              };
 
         // We should find only one such application, so return on the first one
-        for (const subdir of fs.readdirSync(msixAppDir)) {
-            if (pwshMsixDirRegex.test(subdir)) {
-                const pwshMsixPath = path.join(msixAppDir, subdir, "pwsh.exe");
-                return new PossiblePowerShellExe(pwshMsixPath, pwshMsixName);
+        for (const name of await utils.readDirectory(msixAppDir)) {
+            if (pwshMsixDirRegex.test(name)) {
+                return new PossiblePowerShellExe(
+                    path.join(msixAppDir, name, "pwsh.exe"),
+                    pwshMsixName,
+                );
             }
         }
 
-        // If we find nothing, return null
-        return null;
+        return undefined;
     }
 
+    // TODO: Are snaps still a thing?
     private findPSCoreStableSnap(): IPossiblePowerShellExe {
         return new PossiblePowerShellExe(SnapExePath, "PowerShell Snap");
     }
 
     private findPSCorePreviewSnap(): IPossiblePowerShellExe {
-        return new PossiblePowerShellExe(SnapPreviewExePath, "PowerShell Preview Snap");
+        return new PossiblePowerShellExe(
+            SnapPreviewExePath,
+            "PowerShell Preview Snap",
+        );
     }
 
-    private findPSCoreWindowsInstallation(
-        { useAlternateBitness = false, findPreview = false }:
-            { useAlternateBitness?: boolean; findPreview?: boolean } = {}): IPossiblePowerShellExe {
-
-        const programFilesPath: string = this.getProgramFilesPath({ useAlternateBitness });
+    private async findPSCoreWindowsInstallation({
+        useAlternateBitness = false,
+        findPreview = false,
+    }: { useAlternateBitness?: boolean; findPreview?: boolean } = {}): Promise<
+        IPossiblePowerShellExe | undefined
+    > {
+        const programFilesPath = this.getProgramFilesPath({
+            useAlternateBitness,
+        });
 
         if (!programFilesPath) {
-            return null;
+            return undefined;
         }
 
-        const powerShellInstallBaseDir = path.join(programFilesPath, "PowerShell");
+        const powerShellInstallBaseDir = path.join(
+            programFilesPath,
+            "PowerShell",
+        );
 
         // Ensure the base directory exists
-        try {
-            const powerShellInstallBaseDirLStat = fs.lstatSync(powerShellInstallBaseDir);
-            if (!powerShellInstallBaseDirLStat.isDirectory())
-            {
-                return null;
-            }
-        } catch {
-            return null;
+        if (!(await utils.checkIfDirectoryExists(powerShellInstallBaseDir))) {
+            return undefined;
         }
 
-        let highestSeenVersion: number = -1;
-        let pwshExePath: string = null;
-        for (const item of fs.readdirSync(powerShellInstallBaseDir)) {
-
-            let currentVersion: number = -1;
+        let highestSeenVersion = -1;
+        let pwshExePath: string | undefined;
+        for (const item of await utils.readDirectory(
+            powerShellInstallBaseDir,
+        )) {
+            let currentVersion = -1;
             if (findPreview) {
                 // We are looking for something like "7-preview"
 
                 // Preview dirs all have dashes in them
-                const dashIndex = item.indexOf("-");
+                const dashIndex: integer = item.indexOf("-");
                 if (dashIndex < 0) {
                     continue;
                 }
@@ -360,8 +622,12 @@ export class PowerShellExeFinder {
             }
 
             // Now look for the file
-            const exePath = path.join(powerShellInstallBaseDir, item, "pwsh.exe");
-            if (!fs.existsSync(exePath)) {
+            const exePath = path.join(
+                powerShellInstallBaseDir,
+                item,
+                "pwsh.exe",
+            );
+            if (!(await utils.checkIfFileExists(exePath))) {
                 continue;
             }
 
@@ -370,7 +636,7 @@ export class PowerShellExeFinder {
         }
 
         if (!pwshExePath) {
-            return null;
+            return undefined;
         }
 
         const bitness: string = programFilesPath.includes("x86")
@@ -379,21 +645,40 @@ export class PowerShellExeFinder {
 
         const preview: string = findPreview ? " Preview" : "";
 
-        return new PossiblePowerShellExe(pwshExePath, `PowerShell${preview} ${bitness}`);
+        return new PossiblePowerShellExe(
+            pwshExePath,
+            `PowerShell${preview} ${bitness}`,
+        );
     }
 
-    private findWinPS({ useAlternateBitness = false }: { useAlternateBitness?: boolean } = {}): IPossiblePowerShellExe {
-
+    private findWinPS({
+        useAlternateBitness = false,
+    }: { useAlternateBitness?: boolean } = {}):
+        | IPossiblePowerShellExe
+        | undefined {
         // 32-bit OSes only have one WinPS on them
         if (!this.platformDetails.isOS64Bit && useAlternateBitness) {
-            return null;
+            return undefined;
         }
 
-        let winPS = useAlternateBitness ? this.alternateBitnessWinPS : this.winPS;
+        let winPS = useAlternateBitness
+            ? this.alternateBitnessWinPS
+            : this.winPS;
         if (winPS === undefined) {
-            const systemFolderPath: string = this.getSystem32Path({ useAlternateBitness });
+            const systemFolderPath = this.getSystem32Path({
+                useAlternateBitness,
+            });
+
+            if (!systemFolderPath) {
+                return undefined;
+            }
 
-            const winPSPath = path.join(systemFolderPath, "WindowsPowerShell", "v1.0", "powershell.exe");
+            const winPSPath = path.join(
+                systemFolderPath,
+                "WindowsPowerShell",
+                "v1.0",
+                "powershell.exe",
+            );
 
             let displayName: string;
             if (this.platformDetails.isProcess64Bit) {
@@ -408,7 +693,7 @@ export class PowerShellExeFinder {
                 displayName = WindowsPowerShell32BitLabel;
             }
 
-            winPS = new PossiblePowerShellExe(winPSPath, displayName, { knownToExist: true });
+            winPS = new PossiblePowerShellExe(winPSPath, displayName, true);
 
             if (useAlternateBitness) {
                 this.alternateBitnessWinPS = winPS;
@@ -420,9 +705,9 @@ export class PowerShellExeFinder {
         return winPS;
     }
 
-    private getProgramFilesPath(
-        { useAlternateBitness = false }: { useAlternateBitness?: boolean } = {}): string | null {
-
+    private getProgramFilesPath({
+        useAlternateBitness = false,
+    }: { useAlternateBitness?: boolean } = {}): string | undefined {
         if (!useAlternateBitness) {
             // Just use the native system bitness
             return process.env.ProgramFiles;
@@ -439,11 +724,17 @@ export class PowerShellExeFinder {
         }
 
         // We're a 32-bit process on 32-bit Windows, there is no other Program Files dir
-        return null;
+        return undefined;
     }
 
-    private getSystem32Path({ useAlternateBitness = false }: { useAlternateBitness?: boolean } = {}): string | null {
-        const windir: string = process.env.windir;
+    private getSystem32Path({
+        useAlternateBitness = false,
+    }: { useAlternateBitness?: boolean } = {}): string | undefined {
+        const windir = process.env.windir;
+
+        if (!windir) {
+            return undefined;
+        }
 
         if (!useAlternateBitness) {
             // Just use the native system bitness
@@ -461,54 +752,41 @@ export class PowerShellExeFinder {
         }
 
         // We're on a 32-bit Windows, so no alternate bitness
-        return null;
+        return undefined;
     }
 }
 
-export function getWindowsSystemPowerShellPath(systemFolderName: string) {
-    return path.join(
-        process.env.windir,
-        systemFolderName,
-        "WindowsPowerShell",
-        "v1.0",
-        "powershell.exe");
-}
-
-function fileExistsSync(filePath: string): boolean {
-    try {
-        // This will throw if the path does not exist,
-        // and otherwise returns a value that we don't care about
-        fs.lstatSync(filePath);
-        return true;
-    } catch {
-        return false;
-    }
+export function getWindowsSystemPowerShellPath(
+    systemFolderName: string,
+): string | undefined {
+    if (process.env.windir === undefined) {
+        return undefined;
+    } else
+        return path.join(
+            process.env.windir,
+            systemFolderName,
+            "WindowsPowerShell",
+            "v1.0",
+            "powershell.exe",
+        );
 }
 
 interface IPossiblePowerShellExe extends IPowerShellExeDetails {
-    exists(): boolean;
+    exists(): Promise<boolean>;
+    readonly suppressWarning: boolean;
 }
 
 class PossiblePowerShellExe implements IPossiblePowerShellExe {
-    public readonly exePath: string;
-    public readonly displayName: string;
-
-    private knownToExist: boolean;
-
     constructor(
-        pathToExe: string,
-        installationName: string,
-        { knownToExist = false }: { knownToExist?: boolean } = {}) {
-
-        this.exePath = pathToExe;
-        this.displayName = installationName;
-        this.knownToExist = knownToExist || undefined;
-    }
-
-    public exists(): boolean {
-        if (this.knownToExist === undefined) {
-            this.knownToExist = fileExistsSync(this.exePath);
-        }
-        return this.knownToExist;
+        public readonly exePath: string,
+        public readonly displayName: string,
+        private knownToExist?: boolean,
+        public readonly supportsProperArguments = true,
+        public readonly suppressWarning = false,
+    ) {}
+
+    public async exists(): Promise<boolean> {
+        this.knownToExist ??= await utils.checkIfFileExists(this.exePath);
+        return this.knownToExist ?? false;
     }
 }
diff --git a/src/process.ts b/src/process.ts
index 507e195773..75314d882c 100644
--- a/src/process.ts
+++ b/src/process.ts
@@ -2,70 +2,73 @@
 // Licensed under the MIT License.
 
 import cp = require("child_process");
-import fs = require("fs");
-import net = require("net");
-import os = require("os");
 import path = require("path");
 import vscode = require("vscode");
-import { Logger } from "./logging";
-import Settings = require("./settings");
+import { promisify } from "util";
+import type { ILogger } from "./logging";
+import type { IEditorServicesSessionDetails } from "./session";
+import { Settings, validateCwdSetting } from "./settings";
 import utils = require("./utils");
 
 export class PowerShellProcess {
-    public static escapeSingleQuotes(pspath: string): string {
-        return pspath.replace(new RegExp("'", "g"), "''");
-    }
-
-    // This is used to warn the user that the extension is taking longer than expected to startup.
-    // After the 15th try we've hit 30 seconds and should warn.
-    private static warnUserThreshold = 15;
+    private static title = "PowerShell Extension";
 
     public onExited: vscode.Event<void>;
-    private onExitedEmitter = new vscode.EventEmitter<void>();
+    private onExitedEmitter?: vscode.EventEmitter<void>;
+
+    private consoleTerminal?: vscode.Terminal;
+    private consoleCloseSubscription?: vscode.Disposable;
 
-    private consoleTerminal: vscode.Terminal = undefined;
-    private consoleCloseSubscription: vscode.Disposable;
+    private pid?: number;
+    private pidUpdateEmitter?: vscode.EventEmitter<number | undefined>;
 
     constructor(
         public exePath: string,
         private bundledModulesPath: string,
-        private title: string,
-        private log: Logger,
+        private isTemp: boolean,
+        private shellIntegrationEnabled: boolean,
+        private logger: ILogger,
+        private logDirectoryPath: vscode.Uri,
         private startPsesArgs: string,
-        private sessionFilePath: string,
-        private sessionSettings: Settings.ISettings) {
-
+        private sessionFilePath: vscode.Uri,
+        private sessionSettings: Settings,
+        private devMode = false,
+    ) {
+        this.onExitedEmitter = new vscode.EventEmitter<void>();
         this.onExited = this.onExitedEmitter.event;
+        this.pidUpdateEmitter = new vscode.EventEmitter<number | undefined>();
     }
 
-    public async start(logFileName: string): Promise<utils.IEditorServicesSessionDetails> {
-        const editorServicesLogPath = this.log.getLogFilePath(logFileName);
-
-        const psesModulePath =
-            path.resolve(
-                __dirname,
-                this.bundledModulesPath,
-                "PowerShellEditorServices/PowerShellEditorServices.psd1");
+    public async start(
+        cancellationToken: vscode.CancellationToken,
+    ): Promise<IEditorServicesSessionDetails | undefined> {
+        const psesModulePath = path.resolve(
+            __dirname,
+            this.bundledModulesPath,
+            "PowerShellEditorServices/PowerShellEditorServices.psd1",
+        );
 
         const featureFlags =
-            this.sessionSettings.developer.featureFlags !== undefined
-                ? this.sessionSettings.developer.featureFlags.map((f) => `'${f}'`).join(", ")
+            this.sessionSettings.developer.featureFlags.length > 0
+                ? this.sessionSettings.developer.featureFlags
+                      .map((f) => `'${f}'`)
+                      .join(", ")
                 : "";
 
         this.startPsesArgs +=
-            `-LogPath '${PowerShellProcess.escapeSingleQuotes(editorServicesLogPath)}' ` +
-            `-SessionDetailsPath '${PowerShellProcess.escapeSingleQuotes(this.sessionFilePath)}' ` +
+            `-LogPath '${utils.escapeSingleQuotes(this.logDirectoryPath.fsPath)}' ` +
+            `-SessionDetailsPath '${utils.escapeSingleQuotes(this.sessionFilePath.fsPath)}' ` +
             `-FeatureFlags @(${featureFlags}) `;
 
         if (this.sessionSettings.integratedConsole.useLegacyReadLine) {
             this.startPsesArgs += "-UseLegacyReadLine";
         }
 
-        const powerShellArgs = [];
+        const powerShellArgs: string[] = [];
 
         const useLoginShell: boolean =
-            (utils.isMacOS && this.sessionSettings.startAsLoginShell.osx)
-            || (utils.isLinux && this.sessionSettings.startAsLoginShell.linux);
+            (utils.isMacOS && this.sessionSettings.startAsLoginShell.osx) ||
+            (utils.isLinux && this.sessionSettings.startAsLoginShell.linux);
 
         if (useLoginShell && this.isLoginShell(this.exePath)) {
             // This MUST be the first argument.
@@ -75,92 +78,165 @@ export class PowerShellProcess {
         powerShellArgs.push("-NoProfile");
 
         // Only add ExecutionPolicy param on Windows
-        if (utils.isWindows) {
+        if (
+            utils.isWindows &&
+            this.sessionSettings.developer.setExecutionPolicy
+        ) {
             powerShellArgs.push("-ExecutionPolicy", "Bypass");
         }
 
-        const startEditorServices = "Import-Module '" +
-            PowerShellProcess.escapeSingleQuotes(psesModulePath) +
-            "'; Start-EditorServices " + this.startPsesArgs;
+        const startEditorServices =
+            "Import-Module '" +
+            utils.escapeSingleQuotes(psesModulePath) +
+            "'; Start-EditorServices " +
+            this.startPsesArgs;
 
+        // On Windows we unfortunately can't Base64 encode the startup command
+        // because it annoys some poorly implemented anti-virus scanners.
         if (utils.isWindows) {
-            powerShellArgs.push(
-                "-Command",
-                startEditorServices);
+            powerShellArgs.push("-Command", startEditorServices);
         } else {
-            // Use -EncodedCommand for better quote support on non-Windows
+            // Otherwise use -EncodedCommand for better quote support.
+            this.logger.writeDebug(
+                "Using Base64 -EncodedCommand but logging as -Command equivalent.",
+            );
             powerShellArgs.push(
                 "-EncodedCommand",
-                Buffer.from(startEditorServices, "utf16le").toString("base64"));
+                Buffer.from(startEditorServices, "utf16le").toString("base64"),
+            );
         }
 
-        this.log.write(
-            "Language server starting --",
-            "    PowerShell executable: " + this.exePath,
-            "    PowerShell args: " + powerShellArgs.join(" "),
-            "    PowerShell Editor Services args: " + startEditorServices);
+        this.logger.writeDebug(
+            `Starting process: ${this.exePath} ${powerShellArgs.slice(0, -2).join(" ")} -Command ${startEditorServices}`,
+        );
 
         // Make sure no old session file exists
-        utils.deleteSessionFile(this.sessionFilePath);
+        await this.deleteSessionFile(this.sessionFilePath);
+
+        // When VS Code shell integration is enabled, the script expects certain
+        // variables to be added to the environment.
+        let envMixin = {};
+        if (this.shellIntegrationEnabled) {
+            envMixin = {
+                VSCODE_INJECTION: "1",
+                // There is no great way to check if we are running stable VS
+                // Code. Since this is used to disable experimental features, we
+                // default to stable unless we're definitely running Insiders.
+                VSCODE_STABLE: vscode.env.appName.includes("Insiders")
+                    ? "0"
+                    : "1",
+                // Maybe one day we can set VSCODE_NONCE...
+            };
+        }
+
+        // Enables Hot Reload in .NET for the attached process
+        // https://devblogs.microsoft.com/devops/net-enc-support-for-lambdas-and-other-improvements-in-visual-studio-2015/
+        if (this.devMode) {
+            (envMixin as Record<string, string>).COMPLUS_FORCEENC = "1";
+        }
 
         // Launch PowerShell in the integrated terminal
-        this.consoleTerminal =
-            vscode.window.createTerminal({
-                name: this.title,
-                shellPath: this.exePath,
-                shellArgs: powerShellArgs,
-                hideFromUser: !this.sessionSettings.integratedConsole.showOnStartup,
-                cwd: this.sessionSettings.cwd
-            });
-
-        const pwshName = path.basename(this.exePath);
-        this.log.write(`${pwshName} started.`);
-
-        if (this.sessionSettings.integratedConsole.showOnStartup) {
-            // We still need to run this to set the active terminal to the Integrated Console.
+        const terminalOptions: vscode.TerminalOptions = {
+            name: this.isTemp
+                ? `${PowerShellProcess.title} (TEMP)`
+                : PowerShellProcess.title,
+            shellPath: this.exePath,
+            shellArgs: powerShellArgs,
+            cwd: await validateCwdSetting(this.logger),
+            env: envMixin,
+            iconPath: new vscode.ThemeIcon("terminal-powershell"),
+            isTransient: true,
+            hideFromUser:
+                this.sessionSettings.integratedConsole.startInBackground,
+            location:
+                vscode.TerminalLocation[
+                    this.sessionSettings.integratedConsole.startLocation
+                ],
+        };
+
+        // Subscribe a log event for when the terminal closes (this fires for
+        // all terminals and the event itself checks if it's our terminal). This
+        // subscription should happen before we create the terminal so if it
+        // fails immediately, the event fires.
+        this.consoleCloseSubscription = vscode.window.onDidCloseTerminal(
+            (terminal) => {
+                this.onTerminalClose(terminal);
+            },
+        );
+        this.consoleTerminal = vscode.window.createTerminal(terminalOptions);
+        this.pid = await this.getPid();
+        this.logger.write(`PowerShell process started with PID: ${this.pid}`);
+        this.pidUpdateEmitter?.fire(this.pid);
+
+        if (
+            this.sessionSettings.integratedConsole.showOnStartup &&
+            !this.sessionSettings.integratedConsole.startInBackground
+        ) {
+            // We still need to run this to set the active terminal to the extension terminal.
             this.consoleTerminal.show(true);
         }
 
-        // Start the language client
-        this.log.write("Waiting for session file");
-        const sessionDetails = await this.waitForSessionFile();
+        return await this.waitForSessionFile(cancellationToken);
+    }
 
-        // Subscribe a log event for when the terminal closes
-        this.log.write("Registering terminal close callback");
-        this.consoleCloseSubscription = vscode.window.onDidCloseTerminal((terminal) => this.onTerminalClose(terminal));
+    // This function is used to clean-up stale PowerShell Extension terminals,
+    // which can happen with `restartExtensionHost` is called because we are
+    // unable to finish diposing before we're gone.
+    public static cleanUpTerminals(): void {
+        for (const terminal of vscode.window.terminals) {
+            if (terminal.name.startsWith(PowerShellProcess.title)) {
+                terminal.dispose();
+            }
+        }
+    }
 
-        // Log that the PowerShell terminal process has been started
-        this.log.write("Registering terminal PID log callback");
-        this.consoleTerminal.processId.then((pid) => this.logTerminalPid(pid, pwshName));
+    // This function should only be used after a failure has occurred because it is slow!
+    public async getVersionCli(): Promise<string> {
+        const exec = promisify(cp.execFile);
+        const { stdout } = await exec(this.exePath, [
+            "-NoProfile",
+            "-NoLogo",
+            "-Command",
+            "$PSVersionTable.PSVersion.ToString()",
+        ]);
+        return stdout.trim();
+    }
 
-        return sessionDetails;
+    // Returns the process Id of the consoleTerminal
+    public async getPid(): Promise<number | undefined> {
+        return await this.consoleTerminal?.processId;
     }
 
-    public showConsole(preserveFocus: boolean) {
-        if (this.consoleTerminal) {
-            this.consoleTerminal.show(preserveFocus);
-        }
+    public showTerminal(preserveFocus?: boolean): void {
+        this.consoleTerminal?.show(preserveFocus);
     }
 
-    public dispose() {
+    public dispose(): void {
+        this.logger.writeDebug(
+            `Disposing PowerShell process with PID: ${this.pid}`,
+        );
 
-        // Clean up the session file
-        utils.deleteSessionFile(this.sessionFilePath);
+        void this.deleteSessionFile(this.sessionFilePath);
 
-        if (this.consoleCloseSubscription) {
-            this.consoleCloseSubscription.dispose();
-            this.consoleCloseSubscription = undefined;
-        }
+        this.onExitedEmitter?.fire();
+        this.onExitedEmitter = undefined;
 
-        if (this.consoleTerminal) {
-            this.log.write("Terminating PowerShell process...");
-            this.consoleTerminal.dispose();
-            this.consoleTerminal = undefined;
-        }
+        this.consoleTerminal?.dispose();
+        this.consoleTerminal = undefined;
+
+        this.consoleCloseSubscription?.dispose();
+        this.consoleCloseSubscription = undefined;
+
+        this.pidUpdateEmitter?.dispose();
+        this.pidUpdateEmitter = undefined;
     }
 
-    private logTerminalPid(pid: number, exeName: string) {
-        this.log.write(`${exeName} PID: ${pid}`);
+    public sendKeyPress(): void {
+        // NOTE: This is a regular character instead of something like \0
+        // because non-printing characters can cause havoc with different
+        // languages and terminal settings. We discard the character server-side
+        // anyway, so it doesn't matter what we send.
+        this.consoleTerminal?.sendText("p", false);
     }
 
     private isLoginShell(pwshPath: string): boolean {
@@ -169,48 +245,88 @@ export class PowerShellProcess {
             // So we try to start PowerShell with -Login
             // If it exits successfully, we return true
             // If it exits unsuccessfully, node throws, we catch, and return false
-            cp.execFileSync(pwshPath, ["-Login", "-NoProfile", "-NoLogo", "-Command", "exit 0"]);
+            cp.execFileSync(pwshPath, [
+                "-Login",
+                "-NoProfile",
+                "-NoLogo",
+                "-Command",
+                "exit 0",
+            ]);
         } catch {
             return false;
         }
-
         return true;
     }
 
-    private async waitForSessionFile(): Promise<utils.IEditorServicesSessionDetails> {
-        // Determine how many tries by dividing by 2000 thus checking every 2 seconds.
-        const numOfTries = this.sessionSettings.developer.waitForSessionFileTimeoutSeconds / 2;
-        const warnAt = numOfTries - PowerShellProcess.warnUserThreshold;
+    private async readSessionFile(
+        sessionFilePath: vscode.Uri,
+    ): Promise<IEditorServicesSessionDetails> {
+        const fileContents =
+            await vscode.workspace.fs.readFile(sessionFilePath);
+        return JSON.parse(fileContents.toString());
+    }
+
+    private async deleteSessionFile(
+        sessionFilePath: vscode.Uri,
+    ): Promise<void> {
+        try {
+            await vscode.workspace.fs.delete(sessionFilePath);
+        } catch {
+            // We don't care about any reasons for it to fail.
+        }
+    }
 
-        // Check every 2 seconds
+    private async waitForSessionFile(
+        cancellationToken: vscode.CancellationToken,
+    ): Promise<IEditorServicesSessionDetails | undefined> {
+        const numOfTries = // We sleep for 1/5 of a second each try
+            5 * this.sessionSettings.developer.waitForSessionFileTimeoutSeconds;
+        const warnAt = numOfTries - 5 * 30; // Warn at 30 seconds
+
+        // Check every second.
+        this.logger.writeDebug(
+            `Waiting for session file: ${this.sessionFilePath}`,
+        );
         for (let i = numOfTries; i > 0; i--) {
-            if (utils.checkIfFileExists(this.sessionFilePath)) {
-                this.log.write("Session file found");
-                const sessionDetails = utils.readSessionFile(this.sessionFilePath);
-                utils.deleteSessionFile(this.sessionFilePath);
-                return sessionDetails;
+            if (cancellationToken.isCancellationRequested) {
+                this.logger.writeWarning(
+                    "Canceled while waiting for session file.",
+                );
+                return undefined;
+            }
+
+            if (this.consoleTerminal === undefined) {
+                this.logger.writeError("Extension Terminal is undefined.");
+                return undefined;
+            }
+
+            if (await utils.checkIfFileExists(this.sessionFilePath)) {
+                this.logger.writeDebug("Session file found.");
+                return await this.readSessionFile(this.sessionFilePath);
             }
 
             if (warnAt === i) {
-                vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected.
-    If you're using privilege enforcement software, this can affect start up performance.`);
+                void this.logger.writeAndShowWarning(
+                    "Loading the PowerShell extension is taking longer than expected. If you're using privilege enforcement software, this can affect start up performance.",
+                );
             }
 
-            // Wait a bit and try again
-            await utils.sleep(2000);
+            // Wait 1/5 of a second and try again
+            await utils.sleep(200);
         }
 
-        const err = "Timed out waiting for session file to appear.";
-        this.log.write(err);
-        throw new Error(err);
+        this.logger.writeError("Timed out waiting for session file!");
+        return undefined;
     }
 
-    private onTerminalClose(terminal: vscode.Terminal) {
+    private onTerminalClose(terminal: vscode.Terminal): void {
         if (terminal !== this.consoleTerminal) {
             return;
         }
 
-        this.log.write("powershell.exe terminated or terminal UI was closed");
-        this.onExitedEmitter.fire();
+        this.logger.writeWarning(
+            `PowerShell process terminated or Extension Terminal was closed, PID: ${this.pid}`,
+        );
+        this.dispose();
     }
 }
diff --git a/src/session.ts b/src/session.ts
index 81803deb98..df8fd9fbe9 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -1,89 +1,167 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import fs = require("fs");
 import net = require("net");
 import path = require("path");
-import * as semver from "semver";
 import vscode = require("vscode");
-import TelemetryReporter from "vscode-extension-telemetry";
+import TelemetryReporter, {
+    type TelemetryEventMeasurements,
+    type TelemetryEventProperties,
+} from "@vscode/extension-telemetry";
 import { Message } from "vscode-jsonrpc";
-import { Logger } from "./logging";
+import {
+    type ILogger,
+    LanguageClientOutputChannelAdapter,
+    LspTraceParser,
+    PsesParser,
+} from "./logging";
 import { PowerShellProcess } from "./process";
-import Settings = require("./settings");
-import utils = require("./utils");
-
 import {
-    CloseAction, DocumentSelector, ErrorAction, LanguageClientOptions,
-    Middleware, NotificationType, RequestType0,
-    ResolveCodeLensSignature, RevealOutputChannelOn } from "vscode-languageclient";
-import { LanguageClient, StreamInfo } from "vscode-languageclient/node";
+    Settings,
+    changeSetting,
+    getEffectiveConfigurationTarget,
+    getSettings,
+    validateCwdSetting,
+} from "./settings";
+import utils = require("./utils");
 
-import { GitHubReleaseInformation, InvokePowerShellUpdateCheck } from "./features/UpdatePowerShell";
 import {
-    getPlatformDetails, IPlatformDetails, IPowerShellExeDetails,
-    OperatingSystem, PowerShellExeFinder } from "./platform";
+    CloseAction,
+    type CloseHandlerResult,
+    DocumentSelector,
+    ErrorAction,
+    type ErrorHandlerResult,
+    type LanguageClientOptions,
+    type Middleware,
+    NotificationType,
+    RequestType0,
+    type ResolveCodeLensSignature,
+    RevealOutputChannelOn,
+} from "vscode-languageclient";
+import { LanguageClient, type StreamInfo } from "vscode-languageclient/node";
+
+import { SemVer, satisfies } from "semver";
+import { UpdatePowerShell } from "./features/UpdatePowerShell";
 import { LanguageClientConsumer } from "./languageClientConsumer";
+import {
+    type IPlatformDetails,
+    type IPowerShellExeDetails,
+    OperatingSystem,
+    PowerShellExeFinder,
+    getPlatformDetails,
+} from "./platform";
+
+enum SessionStatus {
+    NotStarted = "Not Started",
+    Starting = "Starting",
+    Running = "Running",
+    Busy = "Busy",
+    Stopping = "Stopping",
+    Failed = "Failed",
+}
+
+export enum RunspaceType {
+    Local,
+    Process,
+    Remote,
+}
+export interface IEditorServicesSessionDetails {
+    status: string;
+    reason: string;
+    powerShellVersion: string;
+    channel: string;
+    languageServicePort: number;
+    debugServicePort: number;
+    languageServicePipeName: string;
+    debugServicePipeName: string;
+}
 
-export enum SessionStatus {
-    NeverStarted,
-    NotStarted,
-    Initializing,
-    Running,
-    Stopping,
-    Failed,
+export interface IPowerShellVersionDetails {
+    version: string;
+    edition: string;
+    commit: string;
+    architecture: string;
 }
 
+export type IReadSessionFileCallback = (
+    details: IEditorServicesSessionDetails,
+) => void;
+
+export const SendKeyPressNotificationType = new NotificationType<void>(
+    "powerShell/sendKeyPress",
+);
+
+export const ExecutionBusyStatusNotificationType =
+    new NotificationType<boolean>("powerShell/executionBusyStatus");
+
+export const PowerShellVersionRequestType = new RequestType0<
+    IPowerShellVersionDetails,
+    void
+>("powerShell/getVersion");
+
 export class SessionManager implements Middleware {
     public HostName: string;
+    public DisplayName: string;
     public HostVersion: string;
-    public PowerShellExeDetails: IPowerShellExeDetails;
-    private ShowSessionMenuCommandName = "PowerShell.ShowSessionMenu";
-    private editorServicesArgs: string;
-    private sessionStatus: SessionStatus = SessionStatus.NeverStarted;
-    private suppressRestartPrompt: boolean;
-    private focusConsoleOnExecute: boolean;
-    private platformDetails: IPlatformDetails;
+    public Publisher: string;
+    public PowerShellExeDetails: IPowerShellExeDetails | undefined;
+    private readonly ShowSessionMenuCommandName = "PowerShell.ShowSessionMenu";
+    private debugEventHandler: vscode.Disposable | undefined;
+    private debugSessionProcess: PowerShellProcess | undefined;
+    private languageClient: LanguageClient | undefined;
     private languageClientConsumers: LanguageClientConsumer[] = [];
-    private statusBarItem: vscode.StatusBarItem;
-    private languageServerProcess: PowerShellProcess;
-    private debugSessionProcess: PowerShellProcess;
-    private versionDetails: IPowerShellVersionDetails;
+    private languageServerProcess: PowerShellProcess | undefined;
+    private languageStatusItem: vscode.LanguageStatusItem;
+    private platformDetails: IPlatformDetails;
     private registeredCommands: vscode.Disposable[] = [];
-    private languageServerClient: LanguageClient = undefined;
-    private sessionSettings: Settings.ISettings = undefined;
-    private sessionDetails: utils.IEditorServicesSessionDetails;
-    private bundledModulesPath: string;
-    private started: boolean = false;
-
-    // Initialized by the start() method, since this requires settings
-    private powershellExeFinder: PowerShellExeFinder;
-
-    // When in development mode, VS Code's session ID is a fake
-    // value of "someValue.machineId".  Use that to detect dev
-    // mode for now until Microsoft/vscode#10272 gets implemented.
-    public readonly InDevelopmentMode =
-        vscode.env.sessionId === "someValue.sessionId";
+    private registeredHandlers: vscode.Disposable[] = [];
+    private sessionDetails: IEditorServicesSessionDetails | undefined;
+    private sessionsFolder: vscode.Uri;
+    private sessionStatus: SessionStatus = SessionStatus.NotStarted;
+    private shellIntegrationEnabled = false;
+    private startCancellationTokenSource:
+        | vscode.CancellationTokenSource
+        | undefined;
+    private suppressRestartPrompt = false;
+    private versionDetails: IPowerShellVersionDetails | undefined;
+    private traceLogLevelHandler?: vscode.Disposable;
 
     constructor(
-        private log: Logger,
+        private extensionContext: vscode.ExtensionContext,
+        private sessionSettings: Settings,
+        private logger: ILogger,
         private documentSelector: DocumentSelector,
         hostName: string,
-        version: string,
-        private telemetryReporter: TelemetryReporter) {
+        displayName: string,
+        hostVersion: string,
+        publisher: string,
+        private telemetryReporter: TelemetryReporter,
+    ) {
+        // Create the language status item
+        this.languageStatusItem = this.createStatusBarItem();
+        // We have to override the scheme because it defaults to
+        // 'vscode-userdata' which breaks UNC paths.
+        this.sessionsFolder = vscode.Uri.joinPath(
+            extensionContext.globalStorageUri.with({ scheme: "file" }),
+            "sessions",
+        );
 
         this.platformDetails = getPlatformDetails();
-
         this.HostName = hostName;
-        this.HostVersion = version;
+        this.DisplayName = displayName;
+        this.HostVersion = hostVersion;
+        this.Publisher = publisher;
 
         const osBitness = this.platformDetails.isOS64Bit ? "64-bit" : "32-bit";
-        const procBitness = this.platformDetails.isProcess64Bit ? "64-bit" : "32-bit";
+        const procBitness = this.platformDetails.isProcess64Bit
+            ? "64-bit"
+            : "32-bit";
 
-        this.log.write(
-            `Visual Studio Code v${vscode.version} ${procBitness}`,
-            `${this.HostName} Extension v${this.HostVersion}`,
-            `Operating System: ${OperatingSystem[this.platformDetails.operatingSystem]} ${osBitness}`);
+        this.logger.write(
+            `Visual Studio Code: v${vscode.version} ${procBitness}` +
+                ` on ${OperatingSystem[this.platformDetails.operatingSystem]} ${osBitness}`,
+            `${this.DisplayName} Extension: v${this.HostVersion}`,
+        );
 
         // Fix the host version so that PowerShell can consume it.
         // This is needed when the extension uses a prerelease
@@ -93,733 +171,1271 @@ export class SessionManager implements Middleware {
         this.registerCommands();
     }
 
-    public dispose(): void {
-        // Stop the current session
-        this.stop();
+    public async dispose(): Promise<void> {
+        await this.stop(); // A whole lot of disposals.
 
-        // Dispose of all commands
-        this.registeredCommands.forEach((command) => { command.dispose(); });
-    }
+        this.languageStatusItem.dispose();
 
-    public setLanguageClientConsumers(languageClientConsumers: LanguageClientConsumer[]) {
-        this.languageClientConsumers = languageClientConsumers;
-    }
-
-    public start(exeNameOverride?: string) {
-        this.sessionSettings = Settings.load();
-        if (exeNameOverride) {
-            this.sessionSettings.powerShellDefaultVersion = exeNameOverride;
+        for (const handler of this.registeredHandlers) {
+            handler.dispose();
         }
 
-        this.log.startNewLog(this.sessionSettings.developer.editorServicesLogLevel);
+        for (const command of this.registeredCommands) {
+            command.dispose();
+        }
+    }
 
-        // Create the PowerShell executable finder now
-        this.powershellExeFinder = new PowerShellExeFinder(
-            this.platformDetails,
-            this.sessionSettings.powerShellAdditionalExePaths);
+    // The `exeNameOverride` is used by `restartSession` to override ANY other setting.
+    // We've made this function idempotent, so it can used to ensure the session has started.
+    public async start(): Promise<void> {
+        switch (this.sessionStatus) {
+            case SessionStatus.NotStarted:
+                // Go ahead and start.
+                break;
+            case SessionStatus.Starting:
+                // A simple lock because this function isn't re-entrant.
+                this.logger.writeWarning("Re-entered 'start' so waiting...");
+                await this.waitWhileStarting();
+                return;
+            case SessionStatus.Running:
+                // We're started, just return.
+                this.logger.writeDebug("Already started.");
+                return;
+            case SessionStatus.Busy:
+                // We're started but busy so notify and return.
+                // TODO: Make a proper notification for this and when IntelliSense is blocked.
+                this.logger.write(
+                    "The Extension Terminal is currently busy, please wait for your task to finish!",
+                );
+                return;
+            case SessionStatus.Stopping:
+                // Wait until done stopping, then start.
+                this.logger.writeDebug("Still stopping.");
+                await this.waitWhileStopping();
+                break;
+            case SessionStatus.Failed:
+                // Try to start again.
+                this.logger.writeDebug("Previously failed, starting again.");
+                break;
+        }
 
-        this.focusConsoleOnExecute = this.sessionSettings.integratedConsole.focusConsoleOnExecute;
+        // This status needs to be set immediately so the above check works
+        this.setSessionStatus("Starting...", SessionStatus.Starting);
 
-        this.createStatusBarItem();
+        this.startCancellationTokenSource =
+            new vscode.CancellationTokenSource();
+        const cancellationToken = this.startCancellationTokenSource.token;
 
-        this.promptPowerShellExeSettingsCleanup();
+        // Create a folder for the session files.
+        await vscode.workspace.fs.createDirectory(this.sessionsFolder);
 
-        this.migrateWhitespaceAroundPipeSetting();
+        // Migrate things.
+        await this.migrateWhitespaceAroundPipeSetting();
 
-        try {
-            let powerShellExeDetails;
-            if (this.sessionSettings.powerShellDefaultVersion) {
-                for (const details of this.powershellExeFinder.enumeratePowerShellInstallations()) {
-                    // Need to compare names case-insensitively, from https://stackoverflow.com/a/2140723
-                    const wantedName = this.sessionSettings.powerShellDefaultVersion;
-                    if (wantedName.localeCompare(details.displayName, undefined, { sensitivity: "accent" }) === 0) {
-                        powerShellExeDetails = details;
-                        break;
-                    }
-                }
-            }
+        // Update non-PowerShell settings.
+        this.shellIntegrationEnabled =
+            vscode.workspace
+                .getConfiguration("terminal.integrated.shellIntegration")
+                .get<boolean>("enabled") ?? false;
 
-            this.PowerShellExeDetails = powerShellExeDetails ||
-                this.powershellExeFinder.getFirstAvailablePowerShellInstallation();
+        // Find the PowerShell executable to use for the server.
+        this.PowerShellExeDetails = await this.findPowerShell();
 
-        } catch (e) {
-            this.log.writeError(`Error occurred while searching for a PowerShell executable:\n${e}`);
+        if (this.PowerShellExeDetails === undefined) {
+            const message =
+                "Unable to find PowerShell!" +
+                " Do you have it installed?" +
+                " You can also configure custom installations" +
+                " with the 'powershell.powerShellAdditionalExePaths' setting.";
+            void this.setSessionFailedGetPowerShell(message);
+            return;
         }
 
-        this.suppressRestartPrompt = false;
-
-        if (!this.PowerShellExeDetails) {
-            const message = "Unable to find PowerShell."
-                + " Do you have PowerShell installed?"
-                + " You can also configure custom PowerShell installations"
-                + " with the 'powershell.powerShellAdditionalExePaths' setting.";
-
-            this.log.writeAndShowErrorWithActions(message, [
-                {
-                    prompt: "Get PowerShell",
-                    action: async () => {
-                        const getPSUri = vscode.Uri.parse("https://aka.ms/get-powershell-vscode");
-                        vscode.env.openExternal(getPSUri);
-                    },
-                },
-            ]);
+        // Refresh the status with the found executable details.
+        this.refreshSessionStatus();
+        this.logger.write(
+            `Starting '${this.PowerShellExeDetails.displayName}' at: ${this.PowerShellExeDetails.exePath}`,
+        );
+
+        // Start the server.
+        this.languageServerProcess = await this.startLanguageServerProcess(
+            this.PowerShellExeDetails,
+            cancellationToken,
+        );
+
+        // Check that we got session details and that they had a "started" status.
+        if (
+            this.sessionDetails === undefined ||
+            !this.sessionStarted(this.sessionDetails)
+        ) {
+            if (!cancellationToken.isCancellationRequested) {
+                // If it failed but we didn't cancel it, handle the common reasons.
+                await this.handleFailedProcess(this.languageServerProcess);
+            }
+            this.languageServerProcess.dispose();
+            this.languageServerProcess = undefined;
             return;
         }
 
-        this.bundledModulesPath = path.resolve(__dirname, this.sessionSettings.bundledModulesPath);
-
-        if (this.InDevelopmentMode) {
-            const devBundledModulesPath =
-                path.resolve(
-                    __dirname,
-                    this.sessionSettings.developer.bundledModulesPath);
-
-            // Make sure the module's bin path exists
-            if (fs.existsSync(path.join(devBundledModulesPath, "PowerShellEditorServices/bin"))) {
-                this.bundledModulesPath = devBundledModulesPath;
-            } else {
-                this.log.write(
-                    "\nWARNING: In development mode but PowerShellEditorServices dev module path cannot be " +
-                    `found (or has not been built yet): ${devBundledModulesPath}\n`);
+        // If we got good session details from the server, try to connect to it.
+        this.languageClient = await this.startLanguageClient(
+            this.sessionDetails,
+        );
+
+        if (this.languageClient.isRunning()) {
+            this.versionDetails = await this.getVersionDetails();
+            if (this.versionDetails === undefined) {
+                void this.setSessionFailedOpenBug(
+                    "Unable to get version details!",
+                );
+                return;
             }
-        }
 
-        this.editorServicesArgs =
-            `-HostName 'Visual Studio Code Host' ` +
-            `-HostProfileId 'Microsoft.VSCode' ` +
-            `-HostVersion '${this.HostVersion}' ` +
-            `-AdditionalModules @('PowerShellEditorServices.VSCode') ` +
-            `-BundledModulesPath '${PowerShellProcess.escapeSingleQuotes(this.bundledModulesPath)}' ` +
-            `-EnableConsoleRepl `;
+            this.logger.write(
+                `Started PowerShell v${this.versionDetails.version}.`,
+            );
+            this.setSessionRunningStatus(); // Yay, we made it!
 
-        if (this.sessionSettings.integratedConsole.suppressStartupBanner) {
-            this.editorServicesArgs += "-StartupBanner '' ";
+            await this.writePidIfInDevMode(this.languageServerProcess);
+
+            // Fire and forget the updater.
+            const updater = new UpdatePowerShell(
+                this.sessionSettings,
+                this.logger,
+                this.versionDetails,
+            );
+            void updater.checkForUpdate();
         } else {
-            const startupBanner = `=====> ${this.HostName} Integrated Console v${this.HostVersion} <=====
-`;
-            this.editorServicesArgs += `-StartupBanner '${startupBanner}' `;
+            void this.setSessionFailedOpenBug("Never finished startup!");
         }
+    }
 
-        if (this.sessionSettings.developer.editorServicesWaitForDebugger) {
-            this.editorServicesArgs += "-WaitForDebugger ";
-        }
-        if (this.sessionSettings.developer.editorServicesLogLevel) {
-            this.editorServicesArgs += `-LogLevel '${this.sessionSettings.developer.editorServicesLogLevel}' `;
+    private async stop(): Promise<void> {
+        this.setSessionStatus("Stopping...", SessionStatus.Stopping);
+        // Cancel start-up if we're still waiting.
+        this.startCancellationTokenSource?.cancel();
+
+        // Stop and dispose the language client.
+        try {
+            // If the stop fails, so will the dispose, I think this is a bug in
+            // the client library.
+            await this.languageClient?.stop(2000);
+            await this.languageClient?.dispose();
+        } catch (err) {
+            this.logger.writeError(
+                `Error occurred while stopping language client:\n${err}`,
+            );
         }
 
-        this.startPowerShell();
+        this.languageClient = undefined;
+
+        // Stop and dispose the PowerShell process(es).
+        this.debugSessionProcess?.dispose();
+        this.debugSessionProcess = undefined;
+        this.debugEventHandler?.dispose();
+        this.debugEventHandler = undefined;
+
+        this.languageServerProcess?.dispose();
+        this.languageServerProcess = undefined;
+
+        // Clean up state to start again.
+        this.startCancellationTokenSource?.dispose();
+        this.startCancellationTokenSource = undefined;
+        this.sessionDetails = undefined;
+        this.traceLogLevelHandler?.dispose();
+        this.traceLogLevelHandler = undefined;
+
+        this.setSessionStatus("Not Started", SessionStatus.NotStarted);
     }
 
-    public stop() {
+    private async restartSession(exeNameOverride?: string): Promise<void> {
+        this.logger.write("Restarting session...");
+        await this.stop();
 
-        // Shut down existing session if there is one
-        this.log.write("Shutting down language client...");
+        // Re-load the settings.
+        this.sessionSettings = getSettings();
 
-        if (this.sessionStatus === SessionStatus.Failed) {
-            // Before moving further, clear out the client and process if
-            // the process is already dead (i.e. it crashed)
-            this.languageServerClient = undefined;
-            this.languageServerProcess = undefined;
+        if (exeNameOverride) {
+            // Reset the version and PowerShell details since we're launching a
+            // new executable.
+            this.logger.writeDebug(
+                `Starting with executable overriden to: ${exeNameOverride}`,
+            );
+            this.sessionSettings.powerShellDefaultVersion = exeNameOverride;
+            this.versionDetails = undefined;
+            this.PowerShellExeDetails = undefined;
         }
 
-        this.sessionStatus = SessionStatus.Stopping;
+        await this.start();
+    }
 
-        // Close the language server client
-        if (this.languageServerClient !== undefined) {
-            this.languageServerClient.stop();
-            this.languageServerClient = undefined;
+    /** In Development mode, write the PID to a file where the parent session can find it, to attach the dotnet debugger. */
+    private async writePidIfInDevMode(
+        pwshProcess: PowerShellProcess,
+    ): Promise<void> {
+        if (
+            this.extensionContext.extensionMode !==
+            vscode.ExtensionMode.Development
+        ) {
+            return;
         }
+        const parentSessionId = process.env.VSCODE_PARENT_SESSION_ID;
+        const pidFilePath = vscode.Uri.joinPath(
+            this.sessionsFolder,
+            `PSES-${parentSessionId}.pid`,
+        );
 
-        // Kill the PowerShell proceses we spawned
-        if (this.debugSessionProcess) {
-            this.debugSessionProcess.dispose();
-        }
-        if (this.languageServerProcess) {
-            this.languageServerProcess.dispose();
+        if (parentSessionId === undefined) {
+            return;
         }
 
-        this.sessionStatus = SessionStatus.NotStarted;
-    }
-
-    public restartSession(exeNameOverride?: string) {
-        this.stop();
-        this.start(exeNameOverride);
+        const fs = vscode.workspace.fs;
+        const pid = (await pwshProcess.getPid())!.toString();
+        await fs.writeFile(pidFilePath, Buffer.from(pid));
+        const deletePidOnExit = pwshProcess.onExited(() => {
+            deletePidOnExit.dispose();
+            fs.delete(pidFilePath, { useTrash: false });
+            console.log(`Deleted PID file: ${pidFilePath}`);
+        });
+        this.registeredCommands.push(deletePidOnExit);
+        this.extensionContext.subscriptions.push(deletePidOnExit);
     }
 
-    public getSessionDetails(): utils.IEditorServicesSessionDetails {
+    public getSessionDetails(): IEditorServicesSessionDetails | undefined {
+        // This is used by the debugger which should have already called `start`.
+        if (this.sessionDetails === undefined) {
+            void this.logger.writeAndShowError(
+                "PowerShell session unavailable for debugging!",
+            );
+        }
         return this.sessionDetails;
     }
 
-    public getSessionStatus(): SessionStatus {
-        return this.sessionStatus;
+    public async getLanguageServerPid(): Promise<number | undefined> {
+        if (this.languageServerProcess === undefined) {
+            void this.logger.writeAndShowError(
+                "PowerShell Extension Terminal unavailable!",
+            );
+        }
+        return this.languageServerProcess?.getPid();
     }
 
-    public getPowerShellVersionDetails(): IPowerShellVersionDetails {
+    public getPowerShellVersionDetails():
+        | IPowerShellVersionDetails
+        | undefined {
         return this.versionDetails;
     }
 
-    public createDebugSessionProcess(
-        sessionPath: string,
-        sessionSettings: Settings.ISettings): PowerShellProcess {
+    private getNewSessionFilePath(): vscode.Uri {
+        const uniqueId: number = Math.floor(100000 + Math.random() * 900000);
+        return vscode.Uri.joinPath(
+            this.sessionsFolder,
+            `PSES-VSCode-${process.env.VSCODE_PID}-${uniqueId}.json`,
+        );
+    }
 
-        this.debugSessionProcess =
-            new PowerShellProcess(
-                this.PowerShellExeDetails.exePath,
-                this.bundledModulesPath,
-                "[TEMP] PowerShell Integrated Console",
-                this.log,
-                this.editorServicesArgs + "-DebugServiceOnly ",
-                sessionPath,
-                sessionSettings);
+    public setLanguageClientConsumers(
+        languageClientConsumers: LanguageClientConsumer[],
+    ): void {
+        this.languageClientConsumers = languageClientConsumers;
+    }
+
+    public async createDebugSessionProcess(
+        settings: Settings,
+        powershellExeName?: string,
+    ): Promise<PowerShellProcess> {
+        // NOTE: We only support one temporary Extension Terminal at a time. To
+        // support more, we need to track each separately, and tie the session
+        // for the event handler to the right process (and dispose of the event
+        // handler when the process is disposed).
+        this.debugSessionProcess?.dispose();
+        this.debugEventHandler?.dispose();
+        if (this.PowerShellExeDetails === undefined) {
+            return Promise.reject(
+                new Error("Required PowerShellExeDetails undefined!"),
+            );
+        }
+
+        const debugPowerShellExeDetails =
+            powershellExeName === undefined
+                ? this.PowerShellExeDetails
+                : ((await this.findPowerShell(powershellExeName)) ??
+                  this.PowerShellExeDetails);
+
+        // TODO: It might not be totally necessary to update the session
+        // settings here, but I don't want to accidentally change this behavior
+        // just yet. Working on getting things to be more idempotent!
+        this.sessionSettings = settings;
+
+        const bundledModulesPath = await this.getBundledModulesPath();
+        this.debugSessionProcess = new PowerShellProcess(
+            debugPowerShellExeDetails.exePath,
+            bundledModulesPath,
+            true,
+            false,
+            this.logger,
+            this.extensionContext.logUri,
+            this.getEditorServicesArgs(
+                bundledModulesPath,
+                this.PowerShellExeDetails,
+            ) + "-DebugServiceOnly ",
+            this.getNewSessionFilePath(),
+            this.sessionSettings,
+        );
+
+        // Similar to the regular Extension Terminal, we need to send a key
+        // press to the process spawned for temporary Extension Terminals when
+        // the server requests a cancellation os Console.ReadKey.
+        this.debugEventHandler =
+            vscode.debug.onDidReceiveDebugSessionCustomEvent((e) => {
+                if (e.event === "powerShell/sendKeyPress") {
+                    this.debugSessionProcess?.sendKeyPress();
+                }
+            });
 
         return this.debugSessionProcess;
     }
 
     public async waitUntilStarted(): Promise<void> {
-        while(!this.started) {
-            await utils.sleep(300);
+        while (this.sessionStatus !== SessionStatus.Running) {
+            await utils.sleep(200);
         }
     }
 
-    // ----- LanguageClient middleware methods -----
-
+    // TODO: Is this used by the magic of "Middleware" in the client library?
     public resolveCodeLens(
         codeLens: vscode.CodeLens,
         token: vscode.CancellationToken,
-        next: ResolveCodeLensSignature): vscode.ProviderResult<vscode.CodeLens> {
-            const resolvedCodeLens = next(codeLens, token);
-            const resolveFunc =
-                (codeLensToFix: vscode.CodeLens): vscode.CodeLens => {
-                    if (codeLensToFix.command?.command === "editor.action.showReferences") {
-                        const oldArgs = codeLensToFix.command.arguments;
-
-                        // Our JSON objects don't get handled correctly by
-                        // VS Code's built in editor.action.showReferences
-                        // command so we need to convert them into the
-                        // appropriate types to send them as command
-                        // arguments.
-
-                        codeLensToFix.command.arguments = [
-                            vscode.Uri.parse(oldArgs[0]),
-                            new vscode.Position(oldArgs[1].line, oldArgs[1].character),
-                            oldArgs[2].map((position) => {
-                                return new vscode.Location(
-                                    vscode.Uri.parse(position.uri),
-                                    new vscode.Range(
-                                        position.range.start.line,
-                                        position.range.start.character,
-                                        position.range.end.line,
-                                        position.range.end.character));
-                            }),
-                        ];
-                    }
-
+        next: ResolveCodeLensSignature,
+    ): vscode.ProviderResult<vscode.CodeLens> {
+        const resolvedCodeLens = next(codeLens, token);
+        const resolveFunc = (
+            codeLensToFix: vscode.CodeLens,
+        ): vscode.CodeLens => {
+            if (
+                codeLensToFix.command?.command ===
+                "editor.action.showReferences"
+            ) {
+                const oldArgs = codeLensToFix.command.arguments;
+                if (oldArgs === undefined || oldArgs.length < 3) {
+                    this.logger.writeError(
+                        "Code Lens arguments were malformed!",
+                    );
                     return codeLensToFix;
-                };
+                }
 
-            if ((resolvedCodeLens as Thenable<vscode.CodeLens>).then) {
-                return (resolvedCodeLens as Thenable<vscode.CodeLens>).then(resolveFunc);
-            } else if (resolvedCodeLens as vscode.CodeLens) {
-                return resolveFunc(resolvedCodeLens as vscode.CodeLens);
+                // Our JSON objects don't get handled correctly by
+                // VS Code's built in editor.action.showReferences
+                // command so we need to convert them into the
+                // appropriate types to send them as command
+                // arguments.
+
+                codeLensToFix.command.arguments = [
+                    vscode.Uri.parse(oldArgs[0]),
+                    new vscode.Position(oldArgs[1].line, oldArgs[1].character),
+                    oldArgs[2].map(
+                        (position: {
+                            uri: string;
+                            range: {
+                                start: { line: number; character: number };
+                                end: { line: number; character: number };
+                            };
+                        }) => {
+                            return new vscode.Location(
+                                vscode.Uri.parse(position.uri),
+                                new vscode.Range(
+                                    position.range.start.line,
+                                    position.range.start.character,
+                                    position.range.end.line,
+                                    position.range.end.character,
+                                ),
+                            );
+                        },
+                    ),
+                ];
             }
 
-            return resolvedCodeLens;
+            return codeLensToFix;
+        };
+
+        // TODO: This makes zero sense, but appears to be "working" and copied by others per https://github.com/microsoft/vscode-languageserver-node/issues/495. Thing is, ESLint says these conditionals are always truthy.
+        // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+        if ((resolvedCodeLens as Thenable<vscode.CodeLens>).then) {
+            return (resolvedCodeLens as Thenable<vscode.CodeLens>).then(
+                resolveFunc,
+            );
+            // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+        } else if (resolvedCodeLens as vscode.CodeLens) {
+            return resolveFunc(resolvedCodeLens as vscode.CodeLens);
+        }
+
+        return resolvedCodeLens;
     }
 
-    // Move old setting codeFormatting.whitespaceAroundPipe to new setting codeFormatting.addWhitespaceAroundPipe
-    private async migrateWhitespaceAroundPipeSetting() {
-        const configuration = vscode.workspace.getConfiguration(utils.PowerShellLanguageId);
-        const deprecatedSetting = 'codeFormatting.whitespaceAroundPipe'
-        const newSetting = 'codeFormatting.addWhitespaceAroundPipe'
-        const configurationTargetOfNewSetting = await Settings.getEffectiveConfigurationTarget(newSetting);
-        const configurationTargetOfOldSetting = await Settings.getEffectiveConfigurationTarget(deprecatedSetting);
-        if (configurationTargetOfOldSetting !== null && configurationTargetOfNewSetting === null) {
-            const value = configuration.get(deprecatedSetting, configurationTargetOfOldSetting)
-            await Settings.change(newSetting, value, configurationTargetOfOldSetting);
-            await Settings.change(deprecatedSetting, undefined, configurationTargetOfOldSetting);
+    // TODO: Remove this migration code. Move old setting
+    // codeFormatting.whitespaceAroundPipe to new setting
+    // codeFormatting.addWhitespaceAroundPipe.
+    private async migrateWhitespaceAroundPipeSetting(): Promise<void> {
+        const configuration = vscode.workspace.getConfiguration(
+            utils.PowerShellLanguageId,
+        );
+        const deprecatedSetting = "codeFormatting.whitespaceAroundPipe";
+        const newSetting = "codeFormatting.addWhitespaceAroundPipe";
+        const configurationTargetOfNewSetting =
+            getEffectiveConfigurationTarget(newSetting);
+        const configurationTargetOfOldSetting =
+            getEffectiveConfigurationTarget(deprecatedSetting);
+        if (
+            configurationTargetOfOldSetting !== undefined &&
+            configurationTargetOfNewSetting === undefined
+        ) {
+            this.logger.writeWarning(
+                "Deprecated setting: whitespaceAroundPipe",
+            );
+            const value = configuration.get(
+                deprecatedSetting,
+                configurationTargetOfOldSetting,
+            );
+            await changeSetting(
+                newSetting,
+                value,
+                configurationTargetOfOldSetting,
+                this.logger,
+            );
+            await changeSetting(
+                deprecatedSetting,
+                undefined,
+                configurationTargetOfOldSetting,
+                this.logger,
+            );
         }
     }
 
-    private async promptPowerShellExeSettingsCleanup() {
-        if (this.sessionSettings.powerShellExePath) {
-            let warningMessage = "The 'powerShell.powerShellExePath' setting is no longer used. ";
-            warningMessage += this.sessionSettings.powerShellDefaultVersion
-                ? "We can automatically remove it for you."
-                : "We can remove it from your settings and prompt you for which PowerShell you want to use.";
-
-            const choice = await vscode.window.showWarningMessage(warningMessage, "Let's do it!");
+    /** There are some changes we cannot "hot" set, so these require a restart of the session */
+    private async restartOnCriticalConfigChange(
+        changeEvent: vscode.ConfigurationChangeEvent,
+    ): Promise<void> {
+        if (this.suppressRestartPrompt) {
+            return;
+        }
+        if (this.sessionStatus !== SessionStatus.Running) {
+            return;
+        }
 
-            if (choice === undefined) {
-                // They hit the 'x' to close the dialog.
-                return;
+        // Restart not needed if shell integration is enabled but the shell is backgrounded.
+        const settings = getSettings();
+        if (
+            changeEvent.affectsConfiguration(
+                "terminal.integrated.shellIntegration.enabled",
+            )
+        ) {
+            const shellIntegrationEnabled =
+                vscode.workspace
+                    .getConfiguration("terminal.integrated.shellIntegration")
+                    .get<boolean>("enabled") ?? false;
+            if (
+                shellIntegrationEnabled &&
+                !settings.integratedConsole.startInBackground
+            ) {
+                return this.restartWithPrompt();
             }
+        }
 
-            this.suppressRestartPrompt = true;
-            try {
-                await Settings.change("powerShellExePath", undefined, true);
-            } finally {
-                this.suppressRestartPrompt = false;
-            }
+        // Early return if the change doesn't affect the PowerShell extension settings from this point forward
+        if (!changeEvent.affectsConfiguration("powershell")) {
+            return;
+        }
 
-            // Show the session menu at the end if they don't have a PowerShellDefaultVersion.
-            if (!this.sessionSettings.powerShellDefaultVersion) {
-                await vscode.commands.executeCommand(this.ShowSessionMenuCommandName);
+        // Detect any setting changes that would affect the session.
+        const coldRestartSettingNames = [
+            "developer.traceLsp",
+            "developer.traceDap",
+            "developer.editorServicesLogLevel",
+        ];
+        for (const settingName of coldRestartSettingNames) {
+            if (
+                changeEvent.affectsConfiguration(
+                    "powershell" + "." + settingName,
+                )
+            ) {
+                return this.restartWithPrompt();
             }
         }
-    }
-
-    private onConfigurationUpdated() {
-        const settings = Settings.load();
-
-        this.focusConsoleOnExecute = settings.integratedConsole.focusConsoleOnExecute;
 
-        // Detect any setting changes that would affect the session
-        if (!this.suppressRestartPrompt &&
-            (settings.useX86Host !==
-                this.sessionSettings.useX86Host ||
-             settings.powerShellDefaultVersion.toLowerCase() !==
-                this.sessionSettings.powerShellDefaultVersion.toLowerCase() ||
-             settings.developer.editorServicesLogLevel.toLowerCase() !==
-                this.sessionSettings.developer.editorServicesLogLevel.toLowerCase() ||
-             settings.developer.bundledModulesPath.toLowerCase() !==
-                this.sessionSettings.developer.bundledModulesPath.toLowerCase() ||
+        // TODO: Migrate these to affectsConfiguration style above
+        if (
+            settings.cwd !== this.sessionSettings.cwd ||
+            settings.powerShellDefaultVersion !==
+                this.sessionSettings.powerShellDefaultVersion ||
+            settings.developer.bundledModulesPath !==
+                this.sessionSettings.developer.bundledModulesPath ||
+            settings.developer.editorServicesWaitForDebugger !==
+                this.sessionSettings.developer.editorServicesWaitForDebugger ||
+            settings.developer.setExecutionPolicy !==
+                this.sessionSettings.developer.setExecutionPolicy ||
             settings.integratedConsole.useLegacyReadLine !==
-                this.sessionSettings.integratedConsole.useLegacyReadLine)) {
-
-            vscode.window.showInformationMessage(
-                "The PowerShell runtime configuration has changed, would you like to start a new session?",
-                "Yes", "No")
-                .then((response) => {
-                    if (response === "Yes") {
-                        this.restartSession();
-                    }
-                });
+                this.sessionSettings.integratedConsole.useLegacyReadLine ||
+            settings.integratedConsole.startInBackground !==
+                this.sessionSettings.integratedConsole.startInBackground ||
+            settings.integratedConsole.startLocation !==
+                this.sessionSettings.integratedConsole.startLocation
+        ) {
+            return this.restartWithPrompt();
         }
     }
 
-    private setStatusBarVersionString(runspaceDetails: IRunspaceDetails) {
-
-        const psVersion = runspaceDetails.powerShellVersion;
+    private async restartWithPrompt(): Promise<void> {
+        this.logger.writeDebug("Settings changed, prompting to restart...");
+        const response = await vscode.window.showInformationMessage(
+            "The PowerShell runtime configuration has changed, would you like to start a new session?",
+            "Yes",
+            "No",
+        );
 
-        let versionString =
-            this.versionDetails.architecture === "x86"
-                ? `${psVersion.displayVersion} (${psVersion.architecture})`
-                : psVersion.displayVersion;
-
-        if (runspaceDetails.runspaceType !== RunspaceType.Local) {
-            versionString += ` [${runspaceDetails.connectionString}]`;
+        if (response === "Yes") {
+            await this.restartSession();
         }
-
-        this.setSessionStatus(
-            versionString,
-            SessionStatus.Running);
     }
 
     private registerCommands(): void {
         this.registeredCommands = [
-            vscode.commands.registerCommand("PowerShell.RestartSession", () => { this.restartSession(); }),
-            vscode.commands.registerCommand(this.ShowSessionMenuCommandName, () => { this.showSessionMenu(); }),
-            vscode.workspace.onDidChangeConfiguration(() => this.onConfigurationUpdated()),
             vscode.commands.registerCommand(
-                "PowerShell.ShowSessionConsole", (isExecute?: boolean) => { this.showSessionConsole(isExecute); }),
+                "PowerShell.RestartSession",
+                async () => {
+                    await this.restartSession();
+                },
+            ),
+            vscode.commands.registerCommand(
+                this.ShowSessionMenuCommandName,
+                async () => {
+                    await this.showSessionMenu();
+                },
+            ),
+            vscode.workspace.onDidChangeConfiguration((e) =>
+                this.restartOnCriticalConfigChange(e),
+            ),
+            vscode.commands.registerCommand(
+                "PowerShell.ShowSessionConsole",
+                (isExecute?: boolean) => {
+                    this.showSessionTerminal(isExecute);
+                },
+            ),
         ];
     }
 
-    private startPowerShell() {
+    private async findPowerShell(
+        wantedName?: string,
+    ): Promise<IPowerShellExeDetails | undefined> {
+        this.logger.writeDebug("Finding PowerShell...");
+        const powershellExeFinder = new PowerShellExeFinder(
+            this.platformDetails,
+            this.sessionSettings.powerShellAdditionalExePaths,
+            this.logger,
+        );
 
-        this.setSessionStatus(
-            "Starting PowerShell...",
-            SessionStatus.Initializing);
+        let foundPowerShell: IPowerShellExeDetails | undefined;
+        try {
+            let defaultPowerShell: IPowerShellExeDetails | undefined;
+            wantedName ??= this.sessionSettings.powerShellDefaultVersion;
+            if (wantedName !== "") {
+                for await (const details of powershellExeFinder.enumeratePowerShellInstallations()) {
+                    // Need to compare names case-insensitively, from https://stackoverflow.com/a/2140723
+                    if (
+                        wantedName.localeCompare(
+                            details.displayName,
+                            undefined,
+                            { sensitivity: "accent" },
+                        ) === 0
+                    ) {
+                        defaultPowerShell = details;
+                        break;
+                    }
+                }
+            }
+            foundPowerShell =
+                defaultPowerShell ??
+                (await powershellExeFinder.getFirstAvailablePowerShellInstallation());
+            if (
+                wantedName !== "" &&
+                defaultPowerShell === undefined &&
+                foundPowerShell !== undefined
+            ) {
+                void this.logger.writeAndShowWarning(
+                    `The 'powerShellDefaultVersion' setting was '${wantedName}' but this was not found!` +
+                        ` Instead using first available installation '${foundPowerShell.displayName}' at '${foundPowerShell.exePath}'!`,
+                );
+            }
+        } catch (err) {
+            this.logger.writeError(
+                `Error occurred while searching for a PowerShell executable:\n${err}`,
+            );
+        }
 
-        const sessionFilePath =
-            utils.getSessionFilePath(
-                Math.floor(100000 + Math.random() * 900000));
+        return foundPowerShell;
+    }
 
-        this.languageServerProcess =
-            new PowerShellProcess(
-                this.PowerShellExeDetails.exePath,
-                this.bundledModulesPath,
-                "PowerShell Integrated Console",
-                this.log,
-                this.editorServicesArgs,
-                sessionFilePath,
-                this.sessionSettings);
+    private async startLanguageServerProcess(
+        powerShellExeDetails: IPowerShellExeDetails,
+        cancellationToken: vscode.CancellationToken,
+    ): Promise<PowerShellProcess> {
+        const bundledModulesPath = await this.getBundledModulesPath();
+
+        // Dispose any stale terminals from previous killed sessions.
+        PowerShellProcess.cleanUpTerminals();
+        const languageServerProcess = new PowerShellProcess(
+            powerShellExeDetails.exePath,
+            bundledModulesPath,
+            false,
+            this.shellIntegrationEnabled,
+            this.logger,
+            this.extensionContext.logUri,
+            this.getEditorServicesArgs(
+                bundledModulesPath,
+                powerShellExeDetails,
+            ),
+            this.getNewSessionFilePath(),
+            this.sessionSettings,
+            this.extensionContext.extensionMode ==
+                vscode.ExtensionMode.Development,
+        );
+
+        languageServerProcess.onExited(() => {
+            LanguageClientConsumer.onLanguageClientExited();
+
+            if (
+                this.sessionStatus === SessionStatus.Running ||
+                this.sessionStatus === SessionStatus.Busy
+            ) {
+                this.setSessionStatus("Session Exited!", SessionStatus.Failed);
+                void this.promptForRestart();
+            }
+        });
 
-        this.languageServerProcess.onExited(
-            () => {
-                if (this.sessionStatus === SessionStatus.Running) {
-                    this.setSessionStatus("Session exited", SessionStatus.Failed);
-                    this.promptForRestart();
-                }
+        this.sessionDetails =
+            await languageServerProcess.start(cancellationToken);
+
+        return languageServerProcess;
+    }
+
+    // The process failed to start, so check for common user errors (generally
+    // out-of-support versions of PowerShell).
+    private async handleFailedProcess(
+        powerShellProcess: PowerShellProcess,
+    ): Promise<void> {
+        const version = await powerShellProcess.getVersionCli();
+        let shouldUpdate = true;
+
+        if (satisfies(version, "<5.1.0")) {
+            void this.setSessionFailedGetPowerShell(
+                `PowerShell v${version} is not supported, please update!`,
+            );
+        } else if (satisfies(version, ">=5.1.0 <6.0.0")) {
+            void this.setSessionFailedGetPowerShell(
+                "It looks like you're trying to use Windows PowerShell, which is supported on a best-effort basis. Can you try PowerShell 7?",
+            );
+        } else if (satisfies(version, ">=6.0.0 <7.4.0")) {
+            void this.setSessionFailedGetPowerShell(
+                `PowerShell v${version} has reached end-of-support, please update!`,
+            );
+        } else {
+            shouldUpdate = false;
+            void this.setSessionFailedOpenBug(
+                "PowerShell Language Server process didn't start!",
+            );
+        }
+
+        if (shouldUpdate) {
+            // Run the update notifier since it won't run later as we failed
+            // to start, but we have enough details to do so now.
+            const versionDetails: IPowerShellVersionDetails = {
+                version: version,
+                edition: "", // Unused by UpdatePowerShell
+                commit: version, // Actually used by UpdatePowerShell
+                architecture: process.arch, // Best guess based off Code's architecture
+            };
+            const updater = new UpdatePowerShell(
+                this.sessionSettings,
+                this.logger,
+                versionDetails,
+            );
+            void updater.checkForUpdate();
+        }
+    }
+
+    private sessionStarted(
+        sessionDetails: IEditorServicesSessionDetails,
+    ): boolean {
+        this.logger.writeDebug(
+            `Session details: ${JSON.stringify(sessionDetails, undefined, 2)}`,
+        );
+        if (sessionDetails.status === "started") {
+            // Successful server start with a session file
+            return true;
+        }
+        if (sessionDetails.status === "failed") {
+            // Server started but indicated it failed
+            if (sessionDetails.reason === "powerShellVersion") {
+                void this.setSessionFailedGetPowerShell(
+                    `PowerShell ${sessionDetails.powerShellVersion} is not supported, please update!`,
+                );
+            } else if (sessionDetails.reason === "dotNetVersion") {
+                // Only applies to PowerShell 5.1
+                void this.setSessionFailedGetDotNet(
+                    ".NET Framework is out-of-date, please install at least 4.8!",
+                );
+            } else {
+                void this.setSessionFailedOpenBug(
+                    `PowerShell could not be started for an unknown reason: ${sessionDetails.reason}`,
+                );
+            }
+        } else {
+            void this.setSessionFailedOpenBug(
+                `PowerShell could not be started with an unknown status: ${sessionDetails.status}, and reason: ${sessionDetails.reason}`,
+            );
+        }
+        return false;
+    }
+
+    private async startLanguageClient(
+        sessionDetails: IEditorServicesSessionDetails,
+    ): Promise<LanguageClient> {
+        this.logger.writeDebug("Connecting to language service...");
+        const connectFunc = (): Promise<StreamInfo> => {
+            return new Promise<StreamInfo>((resolve, _reject) => {
+                const socket = net.connect(
+                    sessionDetails.languageServicePipeName,
+                );
+                socket.on("connect", () => {
+                    this.logger.writeDebug("Language service connected.");
+                    resolve({ writer: socket, reader: socket });
+                });
             });
+        };
+
+        const clientOptions: LanguageClientOptions = {
+            documentSelector: this.documentSelector,
+            synchronize: {
+                // TODO: This is deprecated and they should be pulled by the server.
+                // backend uses "files" and "search" to ignore references.
+                configurationSection: [
+                    utils.PowerShellLanguageId,
+                    "files",
+                    "search",
+                ],
+                // TODO: fileEvents: vscode.workspace.createFileSystemWatcher('**/.eslintrc')
+            },
+            // NOTE: Some settings are only applicable on startup, so we send them during initialization.
+            // When Terminal Shell Integration is enabled, we pass the path to the script that the server should execute.
+            // Passing an empty string implies integration is disabled.
+            initializationOptions: {
+                enableProfileLoading: this.sessionSettings.enableProfileLoading,
+                initialWorkingDirectory: await validateCwdSetting(this.logger),
+                shellIntegrationScript: this.shellIntegrationEnabled
+                    ? utils.ShellIntegrationScript
+                    : "",
+            },
+            errorHandler: {
+                // Override the default error handler to prevent it from
+                // closing the LanguageClient incorrectly when the socket
+                // hangs up (ECONNRESET errors).
+                error: (
+                    _error: Error,
+                    _message: Message,
+                    _count: number,
+                ): ErrorHandlerResult => {
+                    // TODO: Is there any error worth terminating on?
+                    this.logger.writeError(
+                        `${_error.name}: ${_error.message} ${_error.cause}`,
+                    );
+                    return { action: ErrorAction.Continue };
+                },
+                closed: (): CloseHandlerResult => {
+                    this.logger.write("Language service connection closed.");
+                    // We have our own restart experience
+                    return {
+                        action: CloseAction.DoNotRestart,
+                        message:
+                            "Connection to PowerShell Editor Services (the Extension Terminal) was closed. See below prompt to restart!",
+                    };
+                },
+            },
+            middleware: this,
+            traceOutputChannel: new LanguageClientOutputChannelAdapter(
+                "PowerShell: Trace LSP",
+                LspTraceParser,
+            ),
+            // This is named the same as the Client log to merge the logs, but will be handled and disposed separately.
+            outputChannel: new LanguageClientOutputChannelAdapter(
+                "PowerShell",
+                PsesParser,
+            ),
+            revealOutputChannelOn: RevealOutputChannelOn.Never,
+        };
+
+        const languageClient = new LanguageClient(
+            "powershell",
+            "PowerShell Editor Services Client",
+            connectFunc,
+            clientOptions,
+        );
+
+        // This enables handling Semantic Highlighting messages in PowerShell Editor Services
+        // TODO: We should only turn this on in preview.
+        languageClient.registerProposedFeatures();
+
+        // NOTE: We don't currently send any events from PSES, but may again in
+        // the future so we're leaving this side wired up.
+        languageClient.onTelemetry((event) => {
+            const eventName: string = event.eventName ?? "PSESEvent";
+            // eslint-disable-next-line @typescript-eslint/no-explicit-any
+            const data: any = event.data ?? event;
+            this.sendTelemetryEvent(eventName, data);
+        });
 
-        this.languageServerProcess
-            .start("EditorServices")
-            .then(
-                (sessionDetails) => {
-                    this.sessionDetails = sessionDetails;
-
-                    if (sessionDetails.status === "started") {
-                        this.log.write("Language server started.");
-
-                        // Start the language service client
-                        this.startLanguageClient(sessionDetails);
-                    } else if (sessionDetails.status === "failed") {
-                        if (sessionDetails.reason === "unsupported") {
-                            this.setSessionFailure(
-                                "PowerShell language features are only supported on PowerShell version 5.1 and 6.1" +
-                                ` and above. The current version is ${sessionDetails.powerShellVersion}.`);
-                        } else if (sessionDetails.reason === "languageMode") {
-                            this.setSessionFailure(
-                                "PowerShell language features are disabled due to an unsupported LanguageMode: " +
-                                `${sessionDetails.detail}`);
-                        } else {
-                            this.setSessionFailure(
-                                `PowerShell could not be started for an unknown reason '${sessionDetails.reason}'`);
-                        }
+        // Send the new LanguageClient to extension features
+        // so that they can register their message handlers
+        // before the connection is established.
+        for (const consumer of this.languageClientConsumers) {
+            consumer.onLanguageClientSet(languageClient);
+        }
+
+        this.registeredHandlers = [
+            // NOTE: This fixes a quirk where PSES has a thread stuck on
+            // Console.ReadKey, since it's not cancellable. On
+            // "cancellation" the server asks us to send pretend to
+            // press a key, thus mitigating all the quirk.
+            languageClient.onNotification(SendKeyPressNotificationType, () => {
+                this.languageServerProcess?.sendKeyPress();
+            }),
+
+            languageClient.onNotification(
+                ExecutionBusyStatusNotificationType,
+                (isBusy: boolean) => {
+                    if (isBusy) {
+                        this.setSessionBusyStatus();
                     } else {
-                        // TODO: Handle other response cases
+                        this.setSessionRunningStatus();
                     }
                 },
-                (error) => {
-                    this.log.write("Language server startup failed.");
-                    this.setSessionFailure("The language service could not be started: ", error);
-                },
-            )
-            .catch((error) => {
-                this.log.write("Language server startup failed.");
-                this.setSessionFailure("The language server could not be started: ", error);
-            });
+            ),
+        ];
+
+        try {
+            await languageClient.start();
+            LanguageClientConsumer.onLanguageClientStarted(languageClient);
+        } catch (err) {
+            void this.setSessionFailedOpenBug(
+                "Language client failed to start: " +
+                    (err instanceof Error ? err.message : "unknown"),
+            );
+        }
+
+        return languageClient;
     }
 
-    private promptForRestart() {
-        vscode.window.showErrorMessage(
-            "The PowerShell session has terminated due to an error, would you like to restart it?",
-            "Yes", "No")
-            .then((answer) => { if (answer === "Yes") { this.restartSession(); }});
+    private async getBundledModulesPath(): Promise<string> {
+        // Because the extension is always at `<root>/out/main.js`
+        let bundledModulesPath = path.resolve(__dirname, "../modules");
+
+        if (
+            this.extensionContext.extensionMode ===
+            vscode.ExtensionMode.Development
+        ) {
+            const devBundledModulesPath = path.resolve(
+                __dirname,
+                this.sessionSettings.developer.bundledModulesPath,
+            );
+
+            // Make sure the module's bin path exists
+            if (await utils.checkIfDirectoryExists(devBundledModulesPath)) {
+                bundledModulesPath = devBundledModulesPath;
+            } else {
+                void this.logger.writeAndShowWarning(
+                    "In development mode but PowerShellEditorServices dev module path cannot be " +
+                        `found (or has not been built yet): ${devBundledModulesPath}\n`,
+                );
+            }
+        }
+
+        return bundledModulesPath;
     }
 
-    private startLanguageClient(sessionDetails: utils.IEditorServicesSessionDetails) {
-        // Log the session details object
-        this.log.write(JSON.stringify(sessionDetails));
+    private getEditorServicesArgs(
+        bundledModulesPath: string,
+        powerShellExeDetails: IPowerShellExeDetails,
+    ): string {
+        let editorServicesArgs =
+            "-HostName 'Visual Studio Code Host' " +
+            "-HostProfileId 'Microsoft.VSCode' " +
+            `-HostVersion '${this.HostVersion}' ` +
+            `-BundledModulesPath '${utils.escapeSingleQuotes(bundledModulesPath)}' ` +
+            "-EnableConsoleRepl ";
 
-        try {
-            this.log.write(`Connecting to language service on pipe ${sessionDetails.languageServicePipeName}...`);
-
-            const connectFunc = () => {
-                return new Promise<StreamInfo>(
-                    (resolve, reject) => {
-                        const socket = net.connect(sessionDetails.languageServicePipeName);
-                        socket.on(
-                            "connect",
-                            () => {
-                                this.log.write("Language service connected.");
-                                resolve({writer: socket, reader: socket});
-                            });
-                    });
-            };
+        if (this.sessionSettings.integratedConsole.suppressStartupBanner) {
+            editorServicesArgs += "-StartupBanner '' ";
+        } else if (
+            utils.isWindows &&
+            !powerShellExeDetails.supportsProperArguments
+        ) {
+            // NOTE: On Windows we don't Base64 encode the startup command
+            // because it annoys some poorly implemented anti-virus scanners.
+            // Unfortunately this means that for some installs of PowerShell
+            // (such as through the `dotnet` package manager), we can't include
+            // a multi-line startup banner as the quotes break the command.
+            editorServicesArgs += `-StartupBanner '${this.DisplayName} Extension v${this.HostVersion}' `;
+        } else {
+            const startupBanner = `${this.DisplayName} Extension v${this.HostVersion}
+Copyright (c) Microsoft Corporation.
 
-            const clientOptions: LanguageClientOptions = {
-                documentSelector: this.documentSelector,
-                synchronize: {
-                    // backend uses "files" and "search" to ignore references.
-                    configurationSection: [ utils.PowerShellLanguageId, "files", "search" ],
-                    // fileEvents: vscode.workspace.createFileSystemWatcher('**/.eslintrc')
-                },
-                errorHandler: {
-                    // Override the default error handler to prevent it from
-                    // closing the LanguageClient incorrectly when the socket
-                    // hangs up (ECONNRESET errors).
-                    error: (error: any, message: Message, count: number): ErrorAction => {
-                        // TODO: Is there any error worth terminating on?
-                        return ErrorAction.Continue;
-                    },
-                    closed: () => {
-                        // We have our own restart experience
-                        return CloseAction.DoNotRestart;
-                    },
-                },
-                revealOutputChannelOn: RevealOutputChannelOn.Never,
-                middleware: this,
-            };
+https://aka.ms/vscode-powershell
+Type 'help' to get help.
+`;
+            editorServicesArgs += `-StartupBanner "${startupBanner}" `;
+        }
 
-            this.languageServerClient =
-                new LanguageClient(
-                    "PowerShell Editor Services",
-                    connectFunc,
-                    clientOptions);
+        // We guard this here too out of an abundance of precaution.
+        if (
+            this.sessionSettings.developer.editorServicesWaitForDebugger &&
+            this.extensionContext.extensionMode ===
+                vscode.ExtensionMode.Development
+        ) {
+            editorServicesArgs += "-WaitForDebugger ";
+        }
+        const logLevel = vscode.workspace
+            .getConfiguration("powershell.developer")
+            .get<string>("editorServicesLogLevel");
+        editorServicesArgs += `-LogLevel '${logLevel}' `;
 
-            // This enables handling Semantic Highlighting messages in PowerShell Editor Services
-            this.languageServerClient.registerProposedFeatures();
+        return editorServicesArgs;
+    }
 
-            if (!this.InDevelopmentMode) {
-                this.languageServerClient.onTelemetry((event) => {
-                    const eventName: string = event.eventName ? event.eventName : "PSESEvent";
-                    const data: any = event.data ? event.data : event
-                    this.telemetryReporter.sendTelemetryEvent(eventName, data);
-                });
-            }
+    private async getVersionDetails(): Promise<
+        IPowerShellVersionDetails | undefined
+    > {
+        // Take one minute to get version details, otherwise cancel and fail.
+        const timeout = new vscode.CancellationTokenSource();
+        setTimeout(() => {
+            timeout.cancel();
+        }, 60 * 1000);
+
+        const versionDetails = await this.languageClient?.sendRequest(
+            PowerShellVersionRequestType,
+            timeout.token,
+        );
+
+        // This is pretty much the only telemetry event we care about.
+        // TODO: We actually could send this earlier from PSES itself.
+        this.sendTelemetryEvent("powershellVersionCheck", {
+            powershellVersion: versionDetails?.version ?? "unknown",
+        });
 
-            this.languageServerClient.onReady().then(
-                () => {
-                    this.languageServerClient
-                        .sendRequest(PowerShellVersionRequestType)
-                        .then(
-                            async (versionDetails) => {
-                                this.versionDetails = versionDetails;
-                                this.started = true;
-
-                                if (!this.InDevelopmentMode) {
-                                    this.telemetryReporter.sendTelemetryEvent("powershellVersionCheck",
-                                        { powershellVersion: versionDetails.version });
-                                }
-
-                                this.setSessionStatus(
-                                    this.versionDetails.architecture === "x86"
-                                        ? `${this.versionDetails.displayVersion} (${this.versionDetails.architecture})`
-                                        : this.versionDetails.displayVersion,
-                                    SessionStatus.Running);
-
-                                // If the user opted to not check for updates, then don't.
-                                if (!this.sessionSettings.promptToUpdatePowerShell) { return; }
-
-                                try {
-                                    const localVersion = semver.parse(this.versionDetails.version);
-                                    if (semver.lt(localVersion, "6.0.0")) {
-                                        // Skip prompting when using Windows PowerShell for now.
-                                        return;
-                                    }
-
-                                    // Fetch the latest PowerShell releases from GitHub.
-                                    const isPreRelease = !!semver.prerelease(localVersion);
-                                    const release: GitHubReleaseInformation =
-                                        await GitHubReleaseInformation.FetchLatestRelease(isPreRelease);
-
-                                    await InvokePowerShellUpdateCheck(
-                                        this,
-                                        this.languageServerClient,
-                                        localVersion,
-                                        this.versionDetails.architecture,
-                                        release);
-                                } catch (e) {
-                                    // best effort. This probably failed to fetch the data from GitHub.
-                                    this.log.writeWarning(e.message);
-                                }
-                            });
-
-                    // Send the new LanguageClient to extension features
-                    // so that they can register their message handlers
-                    // before the connection is established.
-                    this.updateLanguageClientConsumers(this.languageServerClient);
-                    this.languageServerClient.onNotification(
-                        RunspaceChangedEventType,
-                        (runspaceDetails) => { this.setStatusBarVersionString(runspaceDetails); });
+        return versionDetails;
+    }
+
+    private async promptForRestart(): Promise<void> {
+        await this.logger.writeAndShowErrorWithActions(
+            "The PowerShell Extension Terminal has stopped, would you like to restart it? IntelliSense and other features will not work without it!",
+            [
+                {
+                    prompt: "Yes",
+                    action: async (): Promise<void> => {
+                        await this.restartSession();
+                    },
                 },
-                (reason) => {
-                    this.setSessionFailure("Could not start language service: ", reason);
-                });
+                {
+                    prompt: "No",
+                    action: undefined,
+                },
+            ],
+        );
+    }
 
-            this.languageServerClient.start();
-        } catch (e) {
-            this.setSessionFailure("The language service could not be started: ", e);
+    private sendTelemetryEvent(
+        eventName: string,
+        properties?: TelemetryEventProperties,
+        measures?: TelemetryEventMeasurements,
+    ): void {
+        if (
+            this.extensionContext.extensionMode ===
+            vscode.ExtensionMode.Production
+        ) {
+            this.telemetryReporter.sendTelemetryEvent(
+                eventName,
+                properties,
+                measures,
+            );
         }
     }
 
-    private updateLanguageClientConsumers(languageClient: LanguageClient) {
-        this.languageClientConsumers.forEach((feature) => {
-            feature.setLanguageClient(languageClient);
-        });
+    private createStatusBarItem(): vscode.LanguageStatusItem {
+        const statusTitle = "Show PowerShell Session Menu";
+        const languageStatusItem = vscode.languages.createLanguageStatusItem(
+            "powershell",
+            this.documentSelector,
+        );
+        languageStatusItem.command = {
+            title: statusTitle,
+            command: this.ShowSessionMenuCommandName,
+        };
+        languageStatusItem.text = "$(terminal-powershell)";
+        languageStatusItem.detail = "PowerShell";
+        return languageStatusItem;
     }
 
-    private createStatusBarItem() {
-        if (this.statusBarItem === undefined) {
-            // Create the status bar item and place it right next
-            // to the language indicator
-            this.statusBarItem =
-                vscode.window.createStatusBarItem(
-                    vscode.StatusBarAlignment.Right,
-                    1);
-
-            this.statusBarItem.command = this.ShowSessionMenuCommandName;
-            this.statusBarItem.tooltip = "Show PowerShell Session Menu";
-            this.statusBarItem.show();
-            vscode.window.onDidChangeActiveTextEditor((textEditor) => {
-                if (textEditor === undefined
-                    || textEditor.document.languageId !== "powershell") {
-                    this.statusBarItem.hide();
-                } else {
-                    this.statusBarItem.show();
-                }
-            });
+    private async waitWhileStarting(): Promise<void> {
+        while (this.sessionStatus === SessionStatus.Starting) {
+            if (
+                this.startCancellationTokenSource?.token.isCancellationRequested
+            ) {
+                return;
+            }
+            await utils.sleep(200);
         }
     }
 
-    private setSessionStatus(statusText: string, status: SessionStatus): void {
+    private async waitWhileStopping(): Promise<void> {
+        while (this.sessionStatus === SessionStatus.Stopping) {
+            await utils.sleep(200);
+        }
+    }
+
+    private setSessionStatus(detail: string, status: SessionStatus): void {
+        this.logger.writeDebug(
+            `Session status changing from '${this.sessionStatus}' to '${status}'.`,
+        );
         this.sessionStatus = status;
+        this.languageStatusItem.text = "$(terminal-powershell)";
+        this.languageStatusItem.detail = "PowerShell";
+
+        if (this.versionDetails !== undefined) {
+            const semver = new SemVer(this.versionDetails.version);
+            this.languageStatusItem.text += ` ${semver.major}.${semver.minor}`;
+            this.languageStatusItem.detail += ` ${this.versionDetails.commit} (${this.versionDetails.architecture.toLowerCase()})`;
+        } else if (this.PowerShellExeDetails?.displayName) {
+            // When it hasn't started yet.
+            this.languageStatusItem.text += ` ${this.PowerShellExeDetails.displayName}`;
+            this.languageStatusItem.detail += ` at '${this.PowerShellExeDetails.exePath}'`;
+        } else if (this.sessionSettings.powerShellDefaultVersion) {
+            // When it hasn't been found yet.
+            this.languageStatusItem.text += ` ${this.sessionSettings.powerShellDefaultVersion}`;
+            this.languageStatusItem.detail = `Looking for '${this.sessionSettings.powerShellDefaultVersion}'...`;
+        }
+
+        if (detail) {
+            this.languageStatusItem.detail += ": " + detail;
+        }
+
         switch (status) {
             case SessionStatus.Running:
-            case SessionStatus.NeverStarted:
             case SessionStatus.NotStarted:
-                // This icon is available since 1.56, now our current engine version.
-                this.statusBarItem.text = "$(terminal-powershell)";
-                // These have to be reset because this function mutates state.
-                this.statusBarItem.color = undefined;
-                this.statusBarItem.backgroundColor = undefined;
+                this.languageStatusItem.busy = false;
+                this.languageStatusItem.severity =
+                    vscode.LanguageStatusSeverity.Information;
                 break;
-            case SessionStatus.Initializing:
+            case SessionStatus.Busy:
+                this.languageStatusItem.busy = true;
+                this.languageStatusItem.severity =
+                    vscode.LanguageStatusSeverity.Information;
+                break;
+            case SessionStatus.Starting:
             case SessionStatus.Stopping:
-                this.statusBarItem.text = "$(sync)";
-                // The warning colors were added later than our current engine version.
-                // https://code.visualstudio.com/api/references/theme-color#status-bar-colors
-                this.statusBarItem.color = (semver.gte(vscode.version, "1.59.0"))
-                    ? new vscode.ThemeColor("statusBarItem.warningForeground")
-                    : new vscode.ThemeColor("statusBarItem.errorForeground");
-                this.statusBarItem.backgroundColor = (semver.gte(vscode.version, "1.59.0"))
-                    ? new vscode.ThemeColor("statusBarItem.warningBackground")
-                    : new vscode.ThemeColor("statusBarItem.errorBackground");
+                this.languageStatusItem.busy = true;
+                this.languageStatusItem.severity =
+                    vscode.LanguageStatusSeverity.Warning;
                 break;
             case SessionStatus.Failed:
-                this.statusBarItem.text = "$(alert)";
-                // The error colors have been available since 1.53.
-                this.statusBarItem.color = new vscode.ThemeColor("statusBarItem.errorForeground");
-                this.statusBarItem.backgroundColor = new vscode.ThemeColor("statusBarItem.errorBackground");
+                this.languageStatusItem.busy = false;
+                this.languageStatusItem.severity =
+                    vscode.LanguageStatusSeverity.Error;
                 break;
         }
-        this.statusBarItem.text += " " + statusText;
     }
 
-    private setSessionFailure(message: string, ...additionalMessages: string[]) {
-        this.log.writeAndShowError(message, ...additionalMessages);
+    // Refreshes the Language Status Item details with ehe same status.
+    private refreshSessionStatus(): void {
+        this.setSessionStatus("", this.sessionStatus);
+    }
 
-        this.setSessionStatus(
-            "Initialization Error",
-            SessionStatus.Failed);
+    private setSessionRunningStatus(): void {
+        this.setSessionStatus("", SessionStatus.Running);
     }
 
-    private async changePowerShellDefaultVersion(exePath: IPowerShellExeDetails) {
+    private setSessionBusyStatus(): void {
+        this.setSessionStatus("Executing...", SessionStatus.Busy);
+    }
+
+    private async setSessionFailedOpenBug(message: string): Promise<void> {
+        this.setSessionStatus("Startup Error!", SessionStatus.Failed);
+        await this.logger.writeAndShowErrorWithActions(message, [
+            {
+                prompt: "Open an Issue",
+                action: async (): Promise<void> => {
+                    await vscode.commands.executeCommand(
+                        "PowerShell.GenerateBugReport",
+                    );
+                },
+            },
+        ]);
+    }
+
+    private async setSessionFailedGetPowerShell(
+        message: string,
+    ): Promise<void> {
+        this.setSessionStatus("Startup Error!", SessionStatus.Failed);
+        await this.logger.writeAndShowErrorWithActions(message, [
+            {
+                prompt: "Open PowerShell Install Documentation",
+                action: async (): Promise<void> => {
+                    await vscode.env.openExternal(
+                        vscode.Uri.parse(
+                            "https://aka.ms/get-powershell-vscode",
+                        ),
+                    );
+                },
+            },
+        ]);
+    }
+
+    private async setSessionFailedGetDotNet(message: string): Promise<void> {
+        this.setSessionStatus("Startup Error!", SessionStatus.Failed);
+        await this.logger.writeAndShowErrorWithActions(message, [
+            {
+                prompt: "Open .NET Framework Documentation",
+                action: async (): Promise<void> => {
+                    await vscode.env.openExternal(
+                        vscode.Uri.parse(
+                            "https://dotnet.microsoft.com/en-us/download/dotnet-framework",
+                        ),
+                    );
+                },
+            },
+        ]);
+    }
+
+    private async changePowerShellDefaultVersion(
+        exePath: IPowerShellExeDetails,
+    ): Promise<void> {
         this.suppressRestartPrompt = true;
-        await Settings.change("powerShellDefaultVersion", exePath.displayName, true);
+        try {
+            await changeSetting(
+                "powerShellDefaultVersion",
+                exePath.displayName,
+                true,
+                this.logger,
+            );
+        } finally {
+            this.suppressRestartPrompt = false;
+        }
 
         // We pass in the display name so that we force the extension to use that version
         // rather than pull from the settings. The issue we prevent here is when a
         // workspace setting is defined which gets priority over user settings which
         // is what the change above sets.
-        this.restartSession(exePath.displayName);
+        await this.restartSession(exePath.displayName);
     }
 
-    private showSessionConsole(isExecute?: boolean) {
-        if (this.languageServerProcess) {
-            this.languageServerProcess.showConsole(isExecute && !this.focusConsoleOnExecute);
+    // Shows the temp debug terminal if it exists, otherwise the session terminal.
+    public showDebugTerminal(isExecute?: boolean): void {
+        if (this.debugSessionProcess) {
+            this.debugSessionProcess.showTerminal(
+                isExecute &&
+                    !this.sessionSettings.integratedConsole
+                        .focusConsoleOnExecute,
+            );
+        } else {
+            this.languageServerProcess?.showTerminal(
+                isExecute &&
+                    !this.sessionSettings.integratedConsole
+                        .focusConsoleOnExecute,
+            );
         }
     }
 
-    private showSessionMenu() {
-        const availablePowerShellExes = this.powershellExeFinder.getAllAvailablePowerShellInstallations();
-
-        let sessionText: string;
-
-        switch (this.sessionStatus) {
-            case SessionStatus.Running:
-            case SessionStatus.Initializing:
-            case SessionStatus.NotStarted:
-            case SessionStatus.NeverStarted:
-            case SessionStatus.Stopping:
-                const currentPowerShellExe =
-                availablePowerShellExes
-                    .find((item) => item.displayName.toLowerCase() === this.PowerShellExeDetails.displayName.toLowerCase());
-
-                const powerShellSessionName =
-                    currentPowerShellExe ?
-                        currentPowerShellExe.displayName :
-                        `PowerShell ${this.versionDetails.displayVersion} ` +
-                        `(${this.versionDetails.architecture}) ${this.versionDetails.edition} Edition ` +
-                        `[${this.versionDetails.version}]`;
-
-                sessionText = `Current session: ${powerShellSessionName}`;
-                break;
-
-            case SessionStatus.Failed:
-                sessionText = "Session initialization failed, click here to show PowerShell extension logs";
-                break;
-
-            default:
-                throw new TypeError("Not a valid value for the enum 'SessionStatus'");
-        }
+    // Always shows the session terminal.
+    private showSessionTerminal(isExecute?: boolean): void {
+        this.languageServerProcess?.showTerminal(
+            isExecute &&
+                !this.sessionSettings.integratedConsole.focusConsoleOnExecute,
+        );
+    }
 
-        const powerShellItems =
-            availablePowerShellExes
-                .filter((item) => item.displayName !== this.PowerShellExeDetails.displayName)
-                .map((item) => {
-                    return new SessionMenuItem(
-                        `Switch to: ${item.displayName}`,
-                        () => { this.changePowerShellDefaultVersion(item); });
-                });
+    private async showSessionMenu(): Promise<void> {
+        const powershellExeFinder = new PowerShellExeFinder(
+            this.platformDetails,
+            // We don't pull from session settings because we want them fresh!
+            getSettings().powerShellAdditionalExePaths,
+            this.logger,
+        );
+        const availablePowerShellExes =
+            await powershellExeFinder.getAllAvailablePowerShellInstallations();
+
+        const powerShellItems = availablePowerShellExes
+            .filter(
+                (item) =>
+                    item.displayName !== this.PowerShellExeDetails?.displayName,
+            )
+            .map((item) => {
+                return new SessionMenuItem(
+                    `Switch to: ${item.displayName}`,
+                    async () => {
+                        await this.changePowerShellDefaultVersion(item);
+                    },
+                );
+            });
 
         const menuItems: SessionMenuItem[] = [
             new SessionMenuItem(
-                sessionText,
-                () => { vscode.commands.executeCommand("PowerShell.ShowLogs"); }),
+                `Current session: ${this.PowerShellExeDetails?.displayName ?? "Unknown"} (click to show logs)`,
+                async () => {
+                    await vscode.commands.executeCommand("PowerShell.ShowLogs");
+                },
+            ),
 
             // Add all of the different PowerShell options
             ...powerShellItems,
 
-            new SessionMenuItem(
-                "Restart Current Session",
-                () => {
-                    // We pass in the display name so we guarentee that the session
-                    // will be the same PowerShell.
-                    this.restartSession(this.PowerShellExeDetails.displayName);
-                }),
+            new SessionMenuItem("Restart current session", async () => {
+                // We pass in the display name so we guarantee that the session
+                // will be the same PowerShell.
+                if (this.PowerShellExeDetails) {
+                    await this.restartSession(
+                        this.PowerShellExeDetails.displayName,
+                    );
+                } else {
+                    await this.restartSession();
+                }
+            }),
 
-            new SessionMenuItem(
-                "Open Session Logs Folder",
-                () => { vscode.commands.executeCommand("PowerShell.OpenLogFolder"); }),
+            new SessionMenuItem("Open session logs folder", async () => {
+                await vscode.commands.executeCommand(
+                    "PowerShell.OpenLogFolder",
+                );
+            }),
 
             new SessionMenuItem(
-                "Modify 'powerShell.powerShellAdditionalExePaths' in Settings",
-                () => { vscode.commands.executeCommand("workbench.action.openSettingsJson"); }),
+                "Modify list of additional PowerShell locations",
+                async () => {
+                    await vscode.commands.executeCommand(
+                        "workbench.action.openSettings",
+                        "powerShellAdditionalExePaths",
+                    );
+                },
+            ),
         ];
 
-        vscode
-            .window
-            .showQuickPick<SessionMenuItem>(menuItems)
-            .then((selectedItem) => { selectedItem.callback(); });
+        const selectedItem =
+            await vscode.window.showQuickPick<SessionMenuItem>(menuItems);
+        await selectedItem?.callback();
     }
 }
 
 class SessionMenuItem implements vscode.QuickPickItem {
-    public description: string;
+    public description: string | undefined;
 
     constructor(
         public readonly label: string,
-        // tslint:disable-next-line:no-empty
-        public readonly callback: () => void = () => {}) {
-    }
-}
-
-export const PowerShellVersionRequestType =
-    new RequestType0<IPowerShellVersionDetails, void>(
-        "powerShell/getVersion");
-
-export const RunspaceChangedEventType =
-    new NotificationType<IRunspaceDetails>(
-        "powerShell/runspaceChanged");
-
-export enum RunspaceType {
-    Local,
-    Process,
-    Remote,
-}
-
-export interface IPowerShellVersionDetails {
-    version: string;
-    displayVersion: string;
-    edition: string;
-    architecture: string;
-}
 
-export interface IRunspaceDetails {
-    powerShellVersion: IPowerShellVersionDetails;
-    runspaceType: RunspaceType;
-    connectionString: string;
+        // eslint-disable-next-line @typescript-eslint/no-empty-function
+        public readonly callback = async (): Promise<void> => {},
+    ) {}
 }
diff --git a/src/settings.ts b/src/settings.ts
index 32f5aa0d6e..9664c10cf1 100644
--- a/src/settings.ts
+++ b/src/settings.ts
@@ -1,23 +1,59 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-"use strict";
-
 import vscode = require("vscode");
 import utils = require("./utils");
+import os = require("os");
+import untildify from "untildify";
+import type { ILogger } from "./logging";
+import path = require("path");
+
+// TODO: Quite a few of these settings are unused in the client and instead
+// exist just for the server. Those settings do not need to be represented in
+// this class, as the LSP layers take care of communicating them. Frankly, this
+// class is over-engineered and seems to have originally been created to avoid
+// using vscode.workspace.getConfiguration() directly. It wasn't a bad idea to
+// keep things organized so consistent...but it ended up failing in execution.
+// Perhaps we just get rid of this entirely?
+
+// eslint-disable-next-line @typescript-eslint/no-extraneous-class
+class PartialSettings {}
+
+export class Settings extends PartialSettings {
+    powerShellAdditionalExePaths: PowerShellAdditionalExePathSettings = {};
+    powerShellDefaultVersion = "";
+    promptToUpdatePowerShell = true;
+    suppressAdditionalExeNotFoundWarning = false;
+    startAsLoginShell = new StartAsLoginShellSettings();
+    startAutomatically = true;
+    enableProfileLoading = true;
+    helpCompletion = CommentType.BlockComment;
+    scriptAnalysis = new ScriptAnalysisSettings();
+    debugging = new DebuggingSettings();
+    developer = new DeveloperSettings();
+    codeFormatting = new CodeFormattingSettings();
+    integratedConsole = new IntegratedConsoleSettings();
+    sideBar = new SideBarSettings();
+    pester = new PesterSettings();
+    buttons = new ButtonSettings();
+    cwd = ""; // NOTE: use validateCwdSetting() instead of this directly!
+    enableReferencesCodeLens = true;
+    analyzeOpenDocumentsOnly = false;
+    // TODO: Add (deprecated) useX86Host (for testing)
+}
 
-enum CodeFormattingPreset {
-    Custom,
-    Allman,
-    OTBS,
-    Stroustrup,
+export enum CodeFormattingPreset {
+    Custom = "Custom",
+    Allman = "Allman",
+    OTBS = "OTBS",
+    Stroustrup = "Stroustrup",
 }
 
-enum PipelineIndentationStyle {
-    IncreaseIndentationForFirstPipeline,
-    IncreaseIndentationAfterEveryPipeline,
-    NoIndentation,
-    None,
+export enum PipelineIndentationStyle {
+    IncreaseIndentationForFirstPipeline = "IncreaseIndentationForFirstPipeline",
+    IncreaseIndentationAfterEveryPipeline = "IncreaseIndentationAfterEveryPipeline",
+    NoIndentation = "NoIndentation",
+    None = "None",
 }
 
 export enum CommentType {
@@ -26,296 +62,359 @@ export enum CommentType {
     LineComment = "LineComment",
 }
 
-export interface IPowerShellAdditionalExePathSettings {
-    versionName: string;
-    exePath: string;
+export enum StartLocation {
+    Editor = "Editor",
+    Panel = "Panel",
 }
 
-export interface IBugReportingSettings {
-    project: string;
+export enum ExecuteMode {
+    Call = "Call",
+    DotSource = "DotSource",
 }
 
-export interface ICodeFoldingSettings {
-    enable?: boolean;
-    showLastLine?: boolean;
+export type PowerShellAdditionalExePathSettings = Record<string, string>;
+
+class CodeFormattingSettings extends PartialSettings {
+    autoCorrectAliases = false;
+    avoidSemicolonsAsLineTerminators = false;
+    preset = CodeFormattingPreset.Custom;
+    openBraceOnSameLine = true;
+    newLineAfterOpenBrace = true;
+    newLineAfterCloseBrace = true;
+    pipelineIndentationStyle = PipelineIndentationStyle.NoIndentation;
+    whitespaceBeforeOpenBrace = true;
+    whitespaceBeforeOpenParen = true;
+    whitespaceAroundOperator = true;
+    whitespaceAfterSeparator = true;
+    whitespaceBetweenParameters = false;
+    whitespaceInsideBrace = true;
+    addWhitespaceAroundPipe = true;
+    trimWhitespaceAroundPipe = false;
+    ignoreOneLineBlock = true;
+    alignPropertyValuePairs = true;
+    useConstantStrings = false;
+    useCorrectCasing = false;
 }
 
-export interface ICodeFormattingSettings {
-    autoCorrectAliases: boolean;
-    preset: CodeFormattingPreset;
-    openBraceOnSameLine: boolean;
-    newLineAfterOpenBrace: boolean;
-    newLineAfterCloseBrace: boolean;
-    pipelineIndentationStyle: PipelineIndentationStyle;
-    whitespaceBeforeOpenBrace: boolean;
-    whitespaceBeforeOpenParen: boolean;
-    whitespaceAroundOperator: boolean;
-    whitespaceAfterSeparator: boolean;
-    whitespaceBetweenParameters: boolean;
-    whitespaceInsideBrace: boolean;
-    addWhitespaceAroundPipe: boolean;
-    trimWhitespaceAroundPipe: boolean;
-    ignoreOneLineBlock: boolean;
-    alignPropertyValuePairs: boolean;
-    useConstantStrings: boolean;
-    useCorrectCasing: boolean;
+class ScriptAnalysisSettings extends PartialSettings {
+    enable = true;
+    settingsPath = "PSScriptAnalyzerSettings.psd1";
 }
 
-export interface IScriptAnalysisSettings {
-    enable?: boolean;
-    settingsPath: string;
+class DebuggingSettings extends PartialSettings {
+    createTemporaryIntegratedConsole = false;
+    executeMode = ExecuteMode.DotSource;
 }
 
-export interface IDebuggingSettings {
-    createTemporaryIntegratedConsole?: boolean;
+class DeveloperSettings extends PartialSettings {
+    featureFlags: string[] = [];
+    // From `<root>/out/main.js` we go to the directory before <root> and
+    // then into the other repo.
+    bundledModulesPath = "../../PowerShellEditorServices/module";
+    editorServicesWaitForDebugger = false;
+    setExecutionPolicy = true;
+    waitForSessionFileTimeoutSeconds = 240;
 }
 
-export interface IDeveloperSettings {
-    featureFlags?: string[];
-    bundledModulesPath?: string;
-    editorServicesLogLevel?: string;
-    editorServicesWaitForDebugger?: boolean;
-    waitForSessionFileTimeoutSeconds?: number;
+// We follow the same convention as VS Code - https://github.com/microsoft/vscode/blob/ff00badd955d6cfcb8eab5f25f3edc86b762f49f/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts#L105-L107
+//   "Unlike on Linux, ~/.profile is not sourced when logging into a macOS session. This
+//   is the reason terminals on macOS typically run login shells by default which set up
+//   the environment. See http://unix.stackexchange.com/a/119675/115410"
+class StartAsLoginShellSettings extends PartialSettings {
+    osx = true;
+    linux = false;
 }
 
-export interface ISettings {
-    powerShellAdditionalExePaths?: IPowerShellAdditionalExePathSettings[];
-    powerShellDefaultVersion?: string;
-    // This setting is no longer used but is here to assist in cleaning up the users settings.
-    powerShellExePath?: string;
-    promptToUpdatePowerShell?: boolean;
-    promptToUpdatePackageManagement?: boolean;
-    bundledModulesPath?: string;
-    startAsLoginShell?: IStartAsLoginShellSettings;
-    startAutomatically?: boolean;
-    useX86Host?: boolean;
-    enableProfileLoading?: boolean;
-    helpCompletion: string;
-    scriptAnalysis?: IScriptAnalysisSettings;
-    debugging?: IDebuggingSettings;
-    developer?: IDeveloperSettings;
-    codeFolding?: ICodeFoldingSettings;
-    codeFormatting?: ICodeFormattingSettings;
-    integratedConsole?: IIntegratedConsoleSettings;
-    bugReporting?: IBugReportingSettings;
-    sideBar?: ISideBarSettings;
-    pester?: IPesterSettings;
-    buttons?: IButtonSettings;
-    cwd?: string;
-    notebooks?: INotebooksSettings;
+class IntegratedConsoleSettings extends PartialSettings {
+    showOnStartup = true;
+    startInBackground = false;
+    focusConsoleOnExecute = true;
+    useLegacyReadLine = false;
+    forceClearScrollbackBuffer = false;
+    suppressStartupBanner = false;
+    startLocation = StartLocation.Panel;
 }
 
-export interface IStartAsLoginShellSettings {
-    osx?: boolean;
-    linux?: boolean;
+class SideBarSettings extends PartialSettings {
+    CommandExplorerVisibility = false;
+    CommandExplorerExcludeFilter: string[] = [];
 }
 
-export interface IIntegratedConsoleSettings {
-    showOnStartup?: boolean;
-    focusConsoleOnExecute?: boolean;
-    useLegacyReadLine?: boolean;
-    forceClearScrollbackBuffer?: boolean;
-    suppressStartupBanner?: boolean;
+class PesterSettings extends PartialSettings {
+    useLegacyCodeLens = true;
+    outputVerbosity = "FromPreference";
+    debugOutputVerbosity = "Diagnostic";
 }
 
-export interface ISideBarSettings {
-    CommandExplorerVisibility?: boolean;
+class ButtonSettings extends PartialSettings {
+    showRunButtons = true;
+    showPanelMovementButtons = false;
 }
 
-export interface IPesterSettings {
-    useLegacyCodeLens?: boolean;
-    outputVerbosity?: string;
-    debugOutputVerbosity?: string;
-}
+// This is a recursive function which unpacks a WorkspaceConfiguration into our settings.
+function getSetting<TSetting>(
+    key: string | undefined,
+    value: TSetting,
+    configuration: vscode.WorkspaceConfiguration,
+): TSetting {
+    // Base case where we're looking at a primitive type (or our special record).
+    if (key !== undefined && !(value instanceof PartialSettings)) {
+        return configuration.get<TSetting>(key, value);
+    }
 
-export interface IButtonSettings {
-    showRunButtons?: boolean;
-    showPanelMovementButtons?: boolean;
-}
+    // Otherwise we're looking at one of our interfaces and need to extract.
+    for (const property in value) {
+        const subKey = key !== undefined ? `${key}.${property}` : property;
+        value[property] = getSetting(subKey, value[property], configuration);
+    }
 
-export interface INotebooksSettings {
-    saveMarkdownCellsAs?: CommentType;
+    return value;
 }
 
-export function load(): ISettings {
+export function getSettings(): Settings {
     const configuration: vscode.WorkspaceConfiguration =
-        vscode.workspace.getConfiguration(
-            utils.PowerShellLanguageId);
-
-    const defaultBugReportingSettings: IBugReportingSettings = {
-        project: "https://github.com/PowerShell/vscode-powershell",
-    };
-
-    const defaultScriptAnalysisSettings: IScriptAnalysisSettings = {
-        enable: true,
-        settingsPath: "PSScriptAnalyzerSettings.psd1",
-    };
-
-    const defaultDebuggingSettings: IDebuggingSettings = {
-        createTemporaryIntegratedConsole: false,
-    };
-
-    const defaultDeveloperSettings: IDeveloperSettings = {
-        featureFlags: [],
-        // From `<root>/out/main.js` we go to the directory before <root> and
-        // then into the other repo.
-        bundledModulesPath: "../../PowerShellEditorServices/module",
-        editorServicesLogLevel: "Normal",
-        editorServicesWaitForDebugger: false,
-        waitForSessionFileTimeoutSeconds: 240,
-    };
-
-    const defaultCodeFoldingSettings: ICodeFoldingSettings = {
-        enable: true,
-        showLastLine: false,
-    };
-
-    const defaultCodeFormattingSettings: ICodeFormattingSettings = {
-        autoCorrectAliases: false,
-        preset: CodeFormattingPreset.Custom,
-        openBraceOnSameLine: true,
-        newLineAfterOpenBrace: true,
-        newLineAfterCloseBrace: true,
-        pipelineIndentationStyle: PipelineIndentationStyle.NoIndentation,
-        whitespaceBeforeOpenBrace: true,
-        whitespaceBeforeOpenParen: true,
-        whitespaceAroundOperator: true,
-        whitespaceAfterSeparator: true,
-        whitespaceBetweenParameters: false,
-        whitespaceInsideBrace: true,
-        addWhitespaceAroundPipe: true,
-        trimWhitespaceAroundPipe: false,
-        ignoreOneLineBlock: true,
-        alignPropertyValuePairs: true,
-        useConstantStrings: false,
-        useCorrectCasing: false,
-    };
-
-    const defaultStartAsLoginShellSettings: IStartAsLoginShellSettings = {
-        osx: true,
-        linux: false,
-    };
-
-    const defaultIntegratedConsoleSettings: IIntegratedConsoleSettings = {
-        showOnStartup: true,
-        focusConsoleOnExecute: true,
-        useLegacyReadLine: false,
-        forceClearScrollbackBuffer: false,
-    };
-
-    const defaultSideBarSettings: ISideBarSettings = {
-        CommandExplorerVisibility: true,
-    };
-
-    const defaultButtonSettings: IButtonSettings = {
-        showRunButtons: true,
-        showPanelMovementButtons: false
-    };
-
-    const defaultPesterSettings: IPesterSettings = {
-        useLegacyCodeLens: true,
-        outputVerbosity: "FromPreference",
-        debugOutputVerbosity: "Diagnostic",
-    };
-
-    const defaultNotebooksSettings: INotebooksSettings = {
-        saveMarkdownCellsAs: CommentType.BlockComment,
-    };
-
-    return {
-        startAutomatically:
-            configuration.get<boolean>("startAutomatically", true),
-        powerShellAdditionalExePaths:
-            configuration.get<IPowerShellAdditionalExePathSettings[]>("powerShellAdditionalExePaths", undefined),
-        powerShellDefaultVersion:
-            configuration.get<string>("powerShellDefaultVersion", undefined),
-        powerShellExePath:
-            configuration.get<string>("powerShellExePath", undefined),
-        promptToUpdatePowerShell:
-            configuration.get<boolean>("promptToUpdatePowerShell", true),
-        promptToUpdatePackageManagement:
-            configuration.get<boolean>("promptToUpdatePackageManagement", true),
-        bundledModulesPath:
-            "../modules", // Because the extension is always at `<root>/out/main.js`
-        useX86Host:
-            configuration.get<boolean>("useX86Host", false),
-        enableProfileLoading:
-            configuration.get<boolean>("enableProfileLoading", false),
-        helpCompletion:
-            configuration.get<string>("helpCompletion", CommentType.BlockComment),
-        scriptAnalysis:
-            configuration.get<IScriptAnalysisSettings>("scriptAnalysis", defaultScriptAnalysisSettings),
-        debugging:
-            configuration.get<IDebuggingSettings>("debugging", defaultDebuggingSettings),
-        developer:
-            getWorkspaceSettingsWithDefaults<IDeveloperSettings>(configuration, "developer", defaultDeveloperSettings),
-        codeFolding:
-            configuration.get<ICodeFoldingSettings>("codeFolding", defaultCodeFoldingSettings),
-        codeFormatting:
-            configuration.get<ICodeFormattingSettings>("codeFormatting", defaultCodeFormattingSettings),
-        integratedConsole:
-            configuration.get<IIntegratedConsoleSettings>("integratedConsole", defaultIntegratedConsoleSettings),
-        bugReporting:
-            configuration.get<IBugReportingSettings>("bugReporting", defaultBugReportingSettings),
-        sideBar:
-            configuration.get<ISideBarSettings>("sideBar", defaultSideBarSettings),
-        pester:
-            configuration.get<IPesterSettings>("pester", defaultPesterSettings),
-        buttons:
-            configuration.get<IButtonSettings>("buttons", defaultButtonSettings),
-        notebooks:
-            configuration.get<INotebooksSettings>("notebooks", defaultNotebooksSettings),
-        startAsLoginShell:
-            // tslint:disable-next-line
-            // We follow the same convention as VS Code - https://github.com/microsoft/vscode/blob/ff00badd955d6cfcb8eab5f25f3edc86b762f49f/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts#L105-L107
-            //   "Unlike on Linux, ~/.profile is not sourced when logging into a macOS session. This
-            //   is the reason terminals on macOS typically run login shells by default which set up
-            //   the environment. See http://unix.stackexchange.com/a/119675/115410"
-            configuration.get<IStartAsLoginShellSettings>("startAsLoginShell", defaultStartAsLoginShellSettings),
-        cwd:
-            configuration.get<string>("cwd", null),
-    };
+        vscode.workspace.getConfiguration(utils.PowerShellLanguageId);
+
+    return getSetting(undefined, new Settings(), configuration);
 }
 
 // Get the ConfigurationTarget (read: scope) of where the *effective* setting value comes from
-export async function getEffectiveConfigurationTarget(settingName: string): Promise<vscode.ConfigurationTarget> {
-    const configuration = vscode.workspace.getConfiguration(utils.PowerShellLanguageId);
-
+export function getEffectiveConfigurationTarget(
+    settingName: string,
+): vscode.ConfigurationTarget | undefined {
+    const configuration = vscode.workspace.getConfiguration(
+        utils.PowerShellLanguageId,
+    );
     const detail = configuration.inspect(settingName);
-    let configurationTarget = null;
-    if (typeof detail.workspaceFolderValue !== "undefined") {
-        configurationTarget = vscode.ConfigurationTarget.WorkspaceFolder;
-    }
-    else if (typeof detail.workspaceValue !== "undefined") {
-        configurationTarget = vscode.ConfigurationTarget.Workspace;
+    if (detail === undefined) {
+        return undefined;
+    } else if (typeof detail.workspaceFolderValue !== "undefined") {
+        return vscode.ConfigurationTarget.WorkspaceFolder;
+    } else if (typeof detail.workspaceValue !== "undefined") {
+        return vscode.ConfigurationTarget.Workspace;
+    } else if (typeof detail.globalValue !== "undefined") {
+        return vscode.ConfigurationTarget.Global;
     }
-    else if (typeof detail.globalValue !== "undefined") {
-        configurationTarget = vscode.ConfigurationTarget.Global;
-    }
-    return configurationTarget;
+    return undefined;
 }
 
-export async function change(
+export async function changeSetting(
     settingName: string,
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     newValue: any,
-    configurationTarget?: vscode.ConfigurationTarget | boolean): Promise<void> {
+    configurationTarget: vscode.ConfigurationTarget | boolean | undefined,
+    logger: ILogger | undefined,
+): Promise<void> {
+    logger?.writeDebug(
+        `Changing '${settingName}' at scope '${configurationTarget}' to '${newValue}'.`,
+    );
+
+    try {
+        const configuration = vscode.workspace.getConfiguration(
+            utils.PowerShellLanguageId,
+        );
+        await configuration.update(settingName, newValue, configurationTarget);
+    } catch (err) {
+        logger?.writeError(`Failed to change setting: ${err}`);
+    }
+}
 
-    const configuration = vscode.workspace.getConfiguration(utils.PowerShellLanguageId);
+// We don't want to query the user more than once, so this is idempotent.
+let hasChosen = false;
+let chosenWorkspace: vscode.WorkspaceFolder | undefined = undefined;
+export async function getChosenWorkspace(
+    logger: ILogger | undefined,
+): Promise<vscode.WorkspaceFolder | undefined> {
+    if (hasChosen) {
+        return chosenWorkspace;
+    }
 
-    await configuration.update(settingName, newValue, configurationTarget);
+    // If there is no workspace, or there is but it has no folders, fallback.
+    if (
+        vscode.workspace.workspaceFolders === undefined ||
+        vscode.workspace.workspaceFolders.length === 0
+    ) {
+        chosenWorkspace = undefined;
+        // If there is exactly one workspace folder, use that.
+    } else if (vscode.workspace.workspaceFolders.length === 1) {
+        chosenWorkspace = vscode.workspace.workspaceFolders[0];
+        // If there is more than one workspace folder, prompt the user once.
+    } else if (vscode.workspace.workspaceFolders.length > 1) {
+        const options: vscode.WorkspaceFolderPickOptions = {
+            placeHolder:
+                "Select a workspace folder to use for the PowerShell Extension.",
+        };
+
+        chosenWorkspace = await vscode.window.showWorkspaceFolderPick(options);
+
+        logger?.writeDebug(
+            `User selected workspace: '${chosenWorkspace?.name}'`,
+        );
+        if (chosenWorkspace === undefined) {
+            chosenWorkspace = vscode.workspace.workspaceFolders[0];
+        } else {
+            const response = await vscode.window.showInformationMessage(
+                `Would you like to save this choice by setting this workspace's 'powershell.cwd' value to '${chosenWorkspace.name}'?`,
+                "Yes",
+                "No",
+            );
+
+            if (response === "Yes") {
+                await changeSetting(
+                    "cwd",
+                    chosenWorkspace.name,
+                    vscode.ConfigurationTarget.Workspace,
+                    logger,
+                );
+            }
+        }
+    }
+
+    // NOTE: We don't rely on checking if `chosenWorkspace` is undefined because
+    // that may be the case if the user dismissed the prompt, and we don't want
+    // to show it again this session.
+    hasChosen = true;
+    return chosenWorkspace;
 }
 
-function getWorkspaceSettingsWithDefaults<TSettings>(
-    workspaceConfiguration: vscode.WorkspaceConfiguration,
-    settingName: string,
-    defaultSettings: TSettings): TSettings {
+export async function validateCwdSetting(
+    logger: ILogger | undefined,
+): Promise<string> {
+    let cwd =
+        utils.stripQuotePair(
+            vscode.workspace
+                .getConfiguration(utils.PowerShellLanguageId)
+                .get<string>("cwd"),
+        ) ?? "";
+
+    // Replace ~ with home directory.
+    cwd = untildify(cwd);
+
+    // Use the cwd setting if it's absolute and exists. We don't use or resolve
+    // relative paths here because it'll be relative to the Code process's cwd,
+    // which is not what the user is expecting.
+    if (path.isAbsolute(cwd) && (await utils.checkIfDirectoryExists(cwd))) {
+        return cwd;
+    }
 
-    const importedSettings: TSettings = workspaceConfiguration.get<TSettings>(settingName, defaultSettings);
+    // If the cwd matches the name of a workspace folder, use it. Essentially
+    // "choose" a workspace folder based off the cwd path, and so set the state
+    // appropriately for `getChosenWorkspace`.
+    if (vscode.workspace.workspaceFolders) {
+        for (const workspaceFolder of vscode.workspace.workspaceFolders) {
+            // TODO: With some more work, we could support paths relative to a
+            // workspace folder name too.
+            if (cwd === workspaceFolder.name) {
+                hasChosen = true;
+                chosenWorkspace = workspaceFolder;
+                cwd = "";
+            }
+        }
+    }
+
+    // Otherwise get a cwd from the workspace, if possible.
+    const workspace = await getChosenWorkspace(logger);
+    if (workspace === undefined) {
+        logger?.writeDebug("Workspace was undefined, using homedir!");
+        return os.homedir();
+    }
+
+    const workspacePath = workspace.uri.fsPath;
 
-    for (const setting in importedSettings) {
-        if (importedSettings[setting]) {
-            defaultSettings[setting] = importedSettings[setting];
+    // Use the chosen workspace's root to resolve the cwd.
+    const relativePath = path.join(workspacePath, cwd);
+    if (await utils.checkIfDirectoryExists(relativePath)) {
+        return relativePath;
+    }
+
+    // Just use the workspace path.
+    if (await utils.checkIfDirectoryExists(workspacePath)) {
+        return workspacePath;
+    }
+
+    // If all else fails, use the home directory.
+    return os.homedir();
+}
+
+/**
+ * Options for the `onSettingChange` function.
+ * @param scope the scope in which the vscode setting should be evaluated.
+ * @param run Indicates whether the function should be run now in addition to when settings change, or if it should be run only once and stop listening after a single change. If this is undefined, the function will be run only when the setting changes.
+ */
+interface onSettingChangeOptions {
+    scope?: vscode.ConfigurationScope;
+    run?: "now" | "once";
+}
+
+/**
+ * Invokes the specified action when a setting changes
+ * @param section the section of the vscode settings to evaluate. Defaults to `powershell`
+ * @param setting a string representation of the setting you wish to evaluate, e.g. `trace.server`
+ * @param action the action to take when the setting changes
+ * @param scope the scope in which the vscode setting should be evaluated.
+ * @returns a Disposable object that can be used to stop listening for changes with dispose()
+ * @example
+ * onSettingChange("powershell", "settingName", (newValue) => console.log(newValue));
+ */
+
+// Because we actually do use the constraint in the callback
+// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
+export function onSettingChange<T>(
+    section: string,
+    setting: string,
+    action: (newValue: T | undefined) => void,
+    options?: onSettingChangeOptions,
+): vscode.Disposable {
+    const settingPath = `${section}.${setting}`;
+    const disposable = vscode.workspace.onDidChangeConfiguration((e) => {
+        if (!e.affectsConfiguration(settingPath, options?.scope)) {
+            return;
+        }
+
+        doOnSettingsChange(section, setting, action, options?.scope);
+        if (options?.run === "once") {
+            disposable.dispose(); // Javascript black magic, referring to an outer reference before it exists
         }
+    });
+    if (options?.run === "now") {
+        doOnSettingsChange(section, setting, action, options.scope);
     }
-    return defaultSettings;
+    return disposable;
+}
+
+/** Implementation is separate to avoid duplicate code for run now */
+
+// Because we actually do use the constraint in the callback
+// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
+function doOnSettingsChange<T>(
+    section: string,
+    setting: string,
+    action: (newValue: T | undefined) => void,
+    scope?: vscode.ConfigurationScope,
+): void {
+    const value = vscode.workspace
+        .getConfiguration(section, scope)
+        .get<T>(setting);
+    action(value);
+}
+
+/**
+ * Invokes the specified action when a PowerShell setting changes. Convenience function for `onSettingChange`
+ * @param setting a string representation of the setting you wish to evaluate, e.g. `trace.server`
+ * @param action the action to take when the setting changes
+ * @param scope the scope in which the vscode setting should be evaluated.n
+ * @returns a Disposable object that can be used to stop listening for changes
+ * @example
+ * onPowerShellSettingChange("settingName", (newValue) => console.log(newValue));
+ */
+
+// Because we actually do use the constraint in the callback
+// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
+export function onPowerShellSettingChange<T>(
+    setting: string,
+    action: (newValue: T | undefined) => void,
+    options?: onSettingChangeOptions,
+): vscode.Disposable {
+    const section = "powershell";
+    return onSettingChange(section, setting, action, options);
 }
diff --git a/src/utils.ts b/src/utils.ts
index e4c89b2bbe..a3236ebceb 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,46 +1,47 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-"use strict";
-
-import fs = require("fs");
 import os = require("os");
 import path = require("path");
 import vscode = require("vscode");
 
 export const PowerShellLanguageId = "powershell";
 
-export function ensurePathExists(targetPath: string): void {
-    // Ensure that the path exists
-    try {
-        // TODO: Use vscode.workspace.fs
-        fs.mkdirSync(targetPath);
-    } catch (e) {
-        // If the exception isn't to indicate that the folder exists already, rethrow it.
-        if (e.code !== "EEXIST") {
-            throw e;
-        }
-    }
+// Path to the shell integration script in the VS Code installation.
+// See commit 21114288b if it moves again.
+export const ShellIntegrationScript = path.join(
+    vscode.env.appRoot,
+    "out",
+    "vs",
+    "workbench",
+    "contrib",
+    "terminal",
+    "common",
+    "scripts",
+    "shellIntegration.ps1",
+);
+
+export function escapeSingleQuotes(p: string): string {
+    return p.replace(new RegExp("'", "g"), "''");
 }
 
-// Check that the file exists in an asynchronous manner that relies solely on the VS Code API, not Node's fs library.
-export async function fileExists(targetPath: string | vscode.Uri): Promise<boolean> {
-    try {
-            await vscode.workspace.fs.stat(
-                targetPath instanceof vscode.Uri
-                    ? targetPath
-                    : vscode.Uri.file(targetPath));
-        return true;
-    } catch (e) {
-        if (e instanceof vscode.FileSystemError.FileNotFound) {
-            return false;
-        }
-        throw e;
+export function stripQuotePair(p: string | undefined): string | undefined {
+    if (p === undefined) {
+        return p;
     }
 
+    // Remove matching surrounding quotes from p (without regex)
+    if (
+        (p.startsWith("'") && p.endsWith("'")) ||
+        (p.startsWith('"') && p.endsWith('"'))
+    ) {
+        return p.slice(1, -1);
+    }
+
+    return p;
 }
 
-export function getPipePath(pipeName: string) {
+export function getPipePath(pipeName: string): string {
     if (os.platform() === "win32") {
         return "\\\\.\\pipe\\" + pipeName;
     } else {
@@ -50,72 +51,60 @@ export function getPipePath(pipeName: string) {
     }
 }
 
-export interface IEditorServicesSessionDetails {
-    status: string;
-    reason: string;
-    detail: string;
-    powerShellVersion: string;
-    channel: string;
-    languageServicePort: number;
-    debugServicePort: number;
-    languageServicePipeName: string;
-    debugServicePipeName: string;
-}
-
-export type IReadSessionFileCallback = (details: IEditorServicesSessionDetails) => void;
-
-const sessionsFolder = path.resolve(__dirname, "../sessions");
-const sessionFilePathPrefix = path.resolve(sessionsFolder, "PSES-VSCode-" + process.env.VSCODE_PID);
-
-// Create the sessions path if it doesn't exist already
-ensurePathExists(sessionsFolder);
-
-export function getSessionFilePath(uniqueId: number) {
-    return `${sessionFilePathPrefix}-${uniqueId}`;
-}
-
-export function getDebugSessionFilePath() {
-    return `${sessionFilePathPrefix}-Debug`;
-}
-
-export function writeSessionFile(sessionFilePath: string, sessionDetails: IEditorServicesSessionDetails) {
-    ensurePathExists(sessionsFolder);
-
-    const writeStream = fs.createWriteStream(sessionFilePath);
-    writeStream.write(JSON.stringify(sessionDetails));
-    writeStream.close();
+// Check that the file or directory exists in an asynchronous manner that relies
+// solely on the VS Code API, not Node's fs library, ignoring symlinks.
+async function checkIfFileOrDirectoryExists(
+    targetPath: string | vscode.Uri,
+    type: vscode.FileType,
+): Promise<boolean> {
+    if (targetPath === "") {
+        return false;
+    }
+    try {
+        const stat: vscode.FileStat = await vscode.workspace.fs.stat(
+            targetPath instanceof vscode.Uri
+                ? targetPath
+                : vscode.Uri.file(targetPath),
+        );
+        return (stat.type & type) !== 0;
+    } catch {
+        return false;
+    }
 }
 
-
-export function readSessionFile(sessionFilePath: string): IEditorServicesSessionDetails {
-    const fileContents = fs.readFileSync(sessionFilePath, "utf-8");
-    return JSON.parse(fileContents);
+export async function checkIfFileExists(
+    filePath: string | vscode.Uri,
+): Promise<boolean> {
+    return await checkIfFileOrDirectoryExists(filePath, vscode.FileType.File);
 }
 
-export function deleteSessionFile(sessionFilePath: string) {
-    try {
-        fs.unlinkSync(sessionFilePath);
-    } catch (e) {
-        // TODO: Be more specific about what we're catching
-    }
+export async function checkIfDirectoryExists(
+    directoryPath: string | vscode.Uri,
+): Promise<boolean> {
+    return await checkIfFileOrDirectoryExists(
+        directoryPath,
+        vscode.FileType.Directory,
+    );
 }
 
-export function checkIfFileExists(filePath: string): boolean {
-    try {
-        fs.accessSync(filePath, fs.constants.R_OK);
-        return true;
-    } catch (e) {
-        return false;
-    }
+export async function readDirectory(
+    directoryPath: string | vscode.Uri,
+): Promise<string[]> {
+    const items = await vscode.workspace.fs.readDirectory(
+        directoryPath instanceof vscode.Uri
+            ? directoryPath
+            : vscode.Uri.file(directoryPath),
+    );
+    return items.map(([name, _type]) => name);
 }
 
-export function getTimestampString() {
+export function getTimestampString(): string {
     const time = new Date();
     return `[${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}]`;
 }
 
 export function sleep(ms: number): Promise<void> {
-    return new Promise(resolve => setTimeout(resolve, ms));
+    return new Promise((resolve) => setTimeout(resolve, ms));
 }
 
 export const isMacOS: boolean = process.platform === "darwin";
diff --git a/test/OneBranch.code-workspace b/test/OneBranch.code-workspace
new file mode 100644
index 0000000000..d17440aded
--- /dev/null
+++ b/test/OneBranch.code-workspace
@@ -0,0 +1,18 @@
+{
+  // A simple test environment that suppresses some first start warnings we don't care about.
+  "folders": [
+    {
+      "path": "mocks",
+    },
+  ],
+  "settings": {
+    "git.openRepositoryInParentFolders": "never",
+    "csharp.suppressDotnetRestoreNotification": true,
+    "extensions.ignoreRecommendations": true,
+    // The settings tests account for this fix
+    "powershell.powerShellAdditionalExePaths": {
+      "OneBranch": "C:\\powershell-7\\pwsh.exe",
+    },
+    "powershell.powerShellDefaultVersion": "OneBranch",
+  },
+}
diff --git a/test/TestEnvironment.code-workspace b/test/TestEnvironment.code-workspace
new file mode 100644
index 0000000000..4915d16693
--- /dev/null
+++ b/test/TestEnvironment.code-workspace
@@ -0,0 +1,13 @@
+{
+  // A simple test environment that suppresses some first start warnings we don't care about.
+  "folders": [
+    {
+      "path": "mocks",
+    },
+  ],
+  "settings": {
+    "git.openRepositoryInParentFolders": "never",
+    "csharp.suppressDotnetRestoreNotification": true,
+    "extensions.ignoreRecommendations": true,
+  },
+}
diff --git a/test/core/paths.test.ts b/test/core/paths.test.ts
index e0f27c7515..e68fc1a88b 100644
--- a/test/core/paths.test.ts
+++ b/test/core/paths.test.ts
@@ -1,27 +1,40 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import * as assert from "assert";
-import * as fs from "fs";
-import * as path from "path";
+import assert from "assert";
 import * as vscode from "vscode";
+import type { IPowerShellExtensionClient } from "../../src/features/ExternalApi";
+import {
+    checkIfDirectoryExists,
+    checkIfFileExists,
+    ShellIntegrationScript,
+} from "../../src/utils";
 import utils = require("../utils");
 
 describe("Path assumptions", function () {
-    before(utils.ensureEditorServicesIsConnected);
+    let globalStorageUri: vscode.Uri;
+    let logUri: vscode.Uri;
+    before(async () => {
+        const extension: IPowerShellExtensionClient =
+            await utils.ensureEditorServicesIsConnected();
+        globalStorageUri = extension.getStorageUri();
+        logUri = extension.getLogUri();
+    });
 
-    // TODO: This is skipped because it intereferes with other tests. Either
-    // need to find a way to close the opened folder via a Code API, or find
-    // another way to test this.
-    it.skip("Opens the examples folder at the expected path", async function () {
-        assert(await vscode.commands.executeCommand("PowerShell.OpenExamplesFolder"));
+    it("Creates the session folder at the correct path", async function () {
+        assert(
+            await checkIfDirectoryExists(
+                vscode.Uri.joinPath(globalStorageUri, "sessions"),
+            ),
+        );
     });
 
-    it("Creates the session folder at the correct path", function () {
-        assert(fs.existsSync(path.resolve(utils.rootPath, "sessions")));
+    it("Creates the log folder at the correct path", async function () {
+        assert(await checkIfDirectoryExists(logUri));
     });
 
-    it("Creates the log folder at the correct path", function () {
-        assert(fs.existsSync(path.resolve(utils.rootPath, "logs")));
+    it("Finds the Terminal Shell Integration Script", async function () {
+        // If VS Code changes the location of the script, we need to know ASAP (as it's not a public API).
+        assert(await checkIfFileExists(ShellIntegrationScript));
     });
 });
diff --git a/test/core/platform.test.ts b/test/core/platform.test.ts
index b813f60dd8..e6de6a5f3a 100644
--- a/test/core/platform.test.ts
+++ b/test/core/platform.test.ts
@@ -2,11 +2,12 @@
 // Licensed under the MIT License.
 
 import * as assert from "assert";
-import mockFS = require("mock-fs");
-import FileSystem = require("mock-fs/lib/filesystem");
+import * as os from "os";
 import * as path from "path";
 import * as sinon from "sinon";
 import * as platform from "../../src/platform";
+import mockFS = require("mock-fs");
+import FileSystem = require("mock-fs/lib/filesystem");
 
 /**
  * Describes a platform on which the PowerShell extension should work,
@@ -16,7 +17,7 @@ interface ITestPlatform {
     name: string;
     platformDetails: platform.IPlatformDetails;
     filesystem: FileSystem.DirectoryItems;
-    environmentVars?: Record<string, string>;
+    environmentVars: Record<string, string>;
 }
 
 /**
@@ -31,13 +32,26 @@ interface ITestPlatformSuccessCase extends ITestPlatform {
 // Platform configurations where we expect to find a set of PowerShells
 let successTestCases: ITestPlatformSuccessCase[];
 
-let msixAppDir = null;
-let pwshMsixPath = null;
-let pwshPreviewMsixPath = null;
+// Platform configurations for testing the powerShellAdditionalExePaths setting
+let additionalPowerShellExes: Record<string, string>;
+let successAdditionalTestCases: ITestPlatformSuccessCase[];
+
 if (process.platform === "win32") {
-    msixAppDir = path.join(process.env.LOCALAPPDATA, "Microsoft", "WindowsApps");
-    pwshMsixPath = path.join(msixAppDir, "Microsoft.PowerShell_8wekyb3d8bbwe", "pwsh.exe");
-    pwshPreviewMsixPath = path.join(msixAppDir, "Microsoft.PowerShellPreview_8wekyb3d8bbwe", "pwsh.exe");
+    const msixAppDir = path.join(
+        process.env.LOCALAPPDATA!,
+        "Microsoft",
+        "WindowsApps",
+    );
+    const pwshMsixPath = path.join(
+        msixAppDir,
+        "Microsoft.PowerShell_8wekyb3d8bbwe",
+        "pwsh.exe",
+    );
+    const pwshPreviewMsixPath = path.join(
+        msixAppDir,
+        "Microsoft.PowerShellPreview_8wekyb3d8bbwe",
+        "pwsh.exe",
+    );
 
     successTestCases = [
         {
@@ -48,42 +62,54 @@ if (process.platform === "win32") {
                 isProcess64Bit: true,
             },
             environmentVars: {
-                "ProgramFiles": "C:\\Program Files",
+                ProgramFiles: "C:\\Program Files",
                 "ProgramFiles(x86)": "C:\\Program Files (x86)",
-                "windir": "C:\\WINDOWS",
+                windir: "C:\\WINDOWS",
             },
             expectedPowerShellSequence: [
                 {
                     exePath: "C:\\Program Files\\PowerShell\\6\\pwsh.exe",
                     displayName: "PowerShell (x64)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: "C:\\Program Files (x86)\\PowerShell\\6\\pwsh.exe",
                     displayName: "PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: pwshMsixPath,
                     displayName: "PowerShell (Store)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
+                    exePath:
+                        "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
                     displayName: "PowerShell Preview (x64)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: pwshPreviewMsixPath,
                     displayName: "PowerShell Preview (Store)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe",
+                    exePath:
+                        "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe",
                     displayName: "PowerShell Preview (x86)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x64)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
             ],
             filesystem: {
@@ -127,18 +153,22 @@ if (process.platform === "win32") {
                 isProcess64Bit: true,
             },
             environmentVars: {
-                "ProgramFiles": "C:\\Program Files",
+                ProgramFiles: "C:\\Program Files",
                 "ProgramFiles(x86)": "C:\\Program Files (x86)",
-                "windir": "C:\\WINDOWS",
+                windir: "C:\\WINDOWS",
             },
             expectedPowerShellSequence: [
                 {
-                    exePath: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x64)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
             ],
             filesystem: {
@@ -158,42 +188,54 @@ if (process.platform === "win32") {
                 isProcess64Bit: false,
             },
             environmentVars: {
-                "ProgramFiles": "C:\\Program Files (x86)",
+                ProgramFiles: "C:\\Program Files (x86)",
                 "ProgramFiles(x86)": "C:\\Program Files (x86)",
-                "windir": "C:\\WINDOWS",
+                windir: "C:\\WINDOWS",
             },
             expectedPowerShellSequence: [
                 {
                     exePath: "C:\\Program Files (x86)\\PowerShell\\6\\pwsh.exe",
                     displayName: "PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: "C:\\Program Files\\PowerShell\\6\\pwsh.exe",
                     displayName: "PowerShell (x64)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: pwshMsixPath,
                     displayName: "PowerShell (Store)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe",
+                    exePath:
+                        "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe",
                     displayName: "PowerShell Preview (x86)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: pwshPreviewMsixPath,
                     displayName: "PowerShell Preview (Store)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
+                    exePath:
+                        "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
                     displayName: "PowerShell Preview (x64)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x64)",
+                    supportsProperArguments: true,
                 },
             ],
             filesystem: {
@@ -237,18 +279,22 @@ if (process.platform === "win32") {
                 isProcess64Bit: false,
             },
             environmentVars: {
-                "ProgramFiles": "C:\\Program Files (x86)",
+                ProgramFiles: "C:\\Program Files (x86)",
                 "ProgramFiles(x86)": "C:\\Program Files (x86)",
-                "windir": "C:\\WINDOWS",
+                windir: "C:\\WINDOWS",
             },
             expectedPowerShellSequence: [
                 {
-                    exePath: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\Sysnative\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x64)",
+                    supportsProperArguments: true,
                 },
             ],
             filesystem: {
@@ -268,30 +314,37 @@ if (process.platform === "win32") {
                 isProcess64Bit: false,
             },
             environmentVars: {
-                "ProgramFiles": "C:\\Program Files (x86)",
+                ProgramFiles: "C:\\Program Files (x86)",
                 "ProgramFiles(x86)": "C:\\Program Files (x86)",
-                "windir": "C:\\WINDOWS",
+                windir: "C:\\WINDOWS",
             },
             expectedPowerShellSequence: [
                 {
                     exePath: "C:\\Program Files (x86)\\PowerShell\\6\\pwsh.exe",
                     displayName: "PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: pwshMsixPath,
                     displayName: "PowerShell (Store)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe",
+                    exePath:
+                        "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe",
                     displayName: "PowerShell Preview (x86)",
+                    supportsProperArguments: true,
                 },
                 {
                     exePath: pwshPreviewMsixPath,
                     displayName: "PowerShell Preview (Store)",
+                    supportsProperArguments: true,
                 },
                 {
-                    exePath: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
             ],
             filesystem: {
@@ -324,14 +377,16 @@ if (process.platform === "win32") {
                 isProcess64Bit: false,
             },
             environmentVars: {
-                "ProgramFiles": "C:\\Program Files (x86)",
+                ProgramFiles: "C:\\Program Files (x86)",
                 "ProgramFiles(x86)": "C:\\Program Files (x86)",
-                "windir": "C:\\WINDOWS",
+                windir: "C:\\WINDOWS",
             },
             expectedPowerShellSequence: [
                 {
-                    exePath: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
                     displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
                 },
             ],
             filesystem: {
@@ -340,6 +395,115 @@ if (process.platform === "win32") {
                 },
             },
         },
+        {
+            name: "Windows (dotnet)",
+            platformDetails: {
+                operatingSystem: platform.OperatingSystem.Windows,
+                isOS64Bit: true,
+                isProcess64Bit: true,
+            },
+            environmentVars: {
+                USERNAME: "test",
+                USERPROFILE: "C:\\Users\\test",
+                ProgramFiles: "C:\\Program Files",
+                "ProgramFiles(x86)": "C:\\Program Files (x86)",
+                windir: "C:\\WINDOWS",
+            },
+            expectedPowerShellSequence: [
+                {
+                    exePath: "C:\\Users\\test\\.dotnet\\tools\\pwsh.exe",
+                    displayName: ".NET Core PowerShell Global Tool",
+                    supportsProperArguments: false,
+                },
+                {
+                    exePath:
+                        "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    displayName: "Windows PowerShell (x64)",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath:
+                        "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe",
+                    displayName: "Windows PowerShell (x86)",
+                    supportsProperArguments: true,
+                },
+            ],
+            filesystem: {
+                "C:\\Users\\test\\.dotnet\\tools": {
+                    "pwsh.exe": "",
+                },
+            },
+        },
+    ];
+
+    additionalPowerShellExes = {
+        pwsh: "C:\\Users\\test\\pwsh\\pwsh.exe",
+        "pwsh-tilde": "~\\pwsh\\pwsh.exe",
+        "pwsh-no-exe": "C:\\Users\\test\\pwsh\\pwsh",
+        "pwsh-folder": "C:\\Users\\test\\pwsh\\",
+        "pwsh-folder-no-slash": "C:\\Users\\test\\pwsh",
+        "pwsh-single-quotes": "'C:\\Users\\test\\pwsh\\pwsh.exe'",
+        "pwsh-double-quotes": '"C:\\Users\\test\\pwsh\\pwsh.exe"',
+    };
+
+    successAdditionalTestCases = [
+        {
+            name: "Windows (Additional PowerShell Executables)",
+            platformDetails: {
+                operatingSystem: platform.OperatingSystem.Windows,
+                isOS64Bit: true,
+                isProcess64Bit: true,
+            },
+            environmentVars: {
+                USERNAME: "test",
+                USERPROFILE: "C:\\Users\\test",
+            },
+            expectedPowerShellSequence: [
+                {
+                    exePath: "C:\\Users\\test\\pwsh\\pwsh.exe",
+                    displayName: "pwsh",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: path.join(os.homedir(), "pwsh", "pwsh.exe"),
+                    displayName: "pwsh-tilde",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "C:\\Users\\test\\pwsh\\pwsh.exe",
+                    displayName: "pwsh-no-exe",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "C:\\Users\\test\\pwsh\\pwsh.exe",
+                    displayName: "pwsh-folder",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "C:\\Users\\test\\pwsh\\pwsh.exe",
+                    displayName: "pwsh-folder-no-slash",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "C:\\Users\\test\\pwsh\\pwsh.exe",
+                    displayName: "pwsh-single-quotes",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "C:\\Users\\test\\pwsh\\pwsh.exe",
+                    displayName: "pwsh-double-quotes",
+                    supportsProperArguments: true,
+                },
+            ],
+            filesystem: {
+                "C:\\Users\\test\\pwsh": {
+                    "pwsh.exe": "",
+                },
+                [path.join(os.homedir(), "pwsh")]: {
+                    "pwsh.exe": "",
+                },
+            },
+        },
     ];
 } else {
     successTestCases = [
@@ -350,19 +514,36 @@ if (process.platform === "win32") {
                 isOS64Bit: true,
                 isProcess64Bit: true,
             },
+            environmentVars: {},
             expectedPowerShellSequence: [
-                { exePath: "/usr/bin/pwsh", displayName: "PowerShell" },
-                { exePath: "/snap/bin/pwsh", displayName: "PowerShell Snap" },
-                { exePath: "/usr/bin/pwsh-preview", displayName: "PowerShell Preview" },
-                { exePath: "/snap/bin/pwsh-preview", displayName: "PowerShell Preview Snap" },
+                {
+                    exePath: "/usr/bin/pwsh",
+                    displayName: "PowerShell",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/snap/bin/pwsh",
+                    displayName: "PowerShell Snap",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/usr/bin/pwsh-preview",
+                    displayName: "PowerShell Preview",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/snap/bin/pwsh-preview",
+                    displayName: "PowerShell Preview Snap",
+                    supportsProperArguments: true,
+                },
             ],
             filesystem: {
                 "/usr/bin": {
-                    "pwsh": "",
+                    pwsh: "",
                     "pwsh-preview": "",
                 },
                 "/snap/bin": {
-                    "pwsh": "",
+                    pwsh: "",
                     "pwsh-preview": "",
                 },
             },
@@ -374,13 +555,42 @@ if (process.platform === "win32") {
                 isOS64Bit: true,
                 isProcess64Bit: true,
             },
+            environmentVars: {},
             expectedPowerShellSequence: [
-                { exePath: "/usr/local/bin/pwsh", displayName: "PowerShell" },
-                { exePath: "/usr/local/bin/pwsh-preview", displayName: "PowerShell Preview" },
+                {
+                    exePath: "/usr/local/bin/pwsh",
+                    displayName: "PowerShell",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/opt/homebrew/bin/pwsh",
+                    displayName: "PowerShell (Homebrew)",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/opt/homebrew/bin/pwsh-lts",
+                    displayName: "PowerShell LTS (Homebrew)",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/usr/local/bin/pwsh-preview",
+                    displayName: "PowerShell Preview",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/opt/homebrew/bin/pwsh-preview",
+                    displayName: "PowerShell Preview (Homebrew)",
+                    supportsProperArguments: true,
+                },
             ],
             filesystem: {
                 "/usr/local/bin": {
-                    "pwsh": "",
+                    pwsh: "",
+                    "pwsh-preview": "",
+                },
+                "/opt/homebrew/bin/": {
+                    pwsh: "",
+                    "pwsh-lts": "",
                     "pwsh-preview": "",
                 },
             },
@@ -392,8 +602,13 @@ if (process.platform === "win32") {
                 isOS64Bit: true,
                 isProcess64Bit: true,
             },
+            environmentVars: {},
             expectedPowerShellSequence: [
-                { exePath: "/usr/bin/pwsh", displayName: "PowerShell" },
+                {
+                    exePath: "/usr/bin/pwsh",
+                    displayName: "PowerShell",
+                    supportsProperArguments: true,
+                },
             ],
             filesystem: {
                 "/usr/bin": {
@@ -408,8 +623,13 @@ if (process.platform === "win32") {
                 isOS64Bit: true,
                 isProcess64Bit: true,
             },
+            environmentVars: {},
             expectedPowerShellSequence: [
-                { exePath: "/snap/bin/pwsh", displayName: "PowerShell Snap" },
+                {
+                    exePath: "/snap/bin/pwsh",
+                    displayName: "PowerShell Snap",
+                    supportsProperArguments: true,
+                },
             ],
             filesystem: {
                 "/snap/bin": {
@@ -424,8 +644,13 @@ if (process.platform === "win32") {
                 isOS64Bit: true,
                 isProcess64Bit: true,
             },
+            environmentVars: {},
             expectedPowerShellSequence: [
-                { exePath: "/usr/local/bin/pwsh", displayName: "PowerShell" },
+                {
+                    exePath: "/usr/local/bin/pwsh",
+                    displayName: "PowerShell",
+                    supportsProperArguments: true,
+                },
             ],
             filesystem: {
                 "/usr/local/bin": {
@@ -433,6 +658,119 @@ if (process.platform === "win32") {
                 },
             },
         },
+        {
+            name: "MacOS (dotnet)",
+            platformDetails: {
+                operatingSystem: platform.OperatingSystem.MacOS,
+                isOS64Bit: true,
+                isProcess64Bit: true,
+            },
+            environmentVars: {
+                USER: "test",
+                HOME: "/Users/test",
+            },
+            expectedPowerShellSequence: [
+                {
+                    exePath: "/Users/test/.dotnet/tools/pwsh",
+                    displayName: ".NET Core PowerShell Global Tool",
+                    supportsProperArguments: false,
+                },
+            ],
+            filesystem: {
+                "/Users/test/.dotnet/tools": {
+                    pwsh: "",
+                },
+            },
+        },
+        {
+            name: "Linux (dotnet)",
+            platformDetails: {
+                operatingSystem: platform.OperatingSystem.Linux,
+                isOS64Bit: true,
+                isProcess64Bit: true,
+            },
+            environmentVars: {
+                USER: "test",
+                HOME: "/home/test",
+            },
+            expectedPowerShellSequence: [
+                {
+                    exePath: "/home/test/.dotnet/tools/pwsh",
+                    displayName: ".NET Core PowerShell Global Tool",
+                    supportsProperArguments: false,
+                },
+            ],
+            filesystem: {
+                "/home/test/.dotnet/tools": {
+                    pwsh: "",
+                },
+            },
+        },
+    ];
+
+    additionalPowerShellExes = {
+        pwsh: "/home/test/bin/pwsh",
+        "pwsh-tilde": "~/bin/pwsh",
+        "pwsh-folder": "/home/test/bin/",
+        "pwsh-folder-no-slash": "/home/test/bin",
+        "pwsh-single-quotes": "'/home/test/bin/pwsh'",
+        "pwsh-double-quotes": '"/home/test/bin/pwsh"',
+    };
+
+    successAdditionalTestCases = [
+        {
+            name: "Linux/macOS (Additional PowerShell Executables)",
+            platformDetails: {
+                operatingSystem: platform.OperatingSystem.Linux,
+                isOS64Bit: true,
+                isProcess64Bit: true,
+            },
+            environmentVars: {
+                USER: "test",
+                HOME: "/home/test",
+            },
+            expectedPowerShellSequence: [
+                {
+                    exePath: "/home/test/bin/pwsh",
+                    displayName: "pwsh",
+                    supportsProperArguments: true,
+                },
+                {
+                    // untildify ignores the HOME mock so this is platform-dependent
+                    exePath: path.join(os.homedir(), "bin", "pwsh"),
+                    displayName: "pwsh-tilde",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/home/test/bin/pwsh",
+                    displayName: "pwsh-folder",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/home/test/bin/pwsh",
+                    displayName: "pwsh-folder-no-slash",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/home/test/bin/pwsh",
+                    displayName: "pwsh-single-quotes",
+                    supportsProperArguments: true,
+                },
+                {
+                    exePath: "/home/test/bin/pwsh",
+                    displayName: "pwsh-double-quotes",
+                    supportsProperArguments: true,
+                },
+            ],
+            filesystem: {
+                "/home/test/bin": {
+                    pwsh: "",
+                },
+                [path.join(os.homedir(), "bin")]: {
+                    pwsh: "",
+                },
+            },
+        },
     ];
 }
 
@@ -444,6 +782,7 @@ const errorTestCases: ITestPlatform[] = [
             isOS64Bit: true,
             isProcess64Bit: true,
         },
+        environmentVars: {},
         filesystem: {},
     },
     {
@@ -453,67 +792,85 @@ const errorTestCases: ITestPlatform[] = [
             isOS64Bit: true,
             isProcess64Bit: true,
         },
+        environmentVars: {},
         filesystem: {},
     },
 ];
 
-function setupTestEnvironment(testPlatform: ITestPlatform) {
+function setupTestEnvironment(testPlatform: ITestPlatform): void {
     mockFS(testPlatform.filesystem);
 
-    if (testPlatform.environmentVars) {
-        for (const envVar of Object.keys(testPlatform.environmentVars)) {
-            sinon.stub(process.env, envVar).value(testPlatform.environmentVars[envVar]);
-        }
+    for (const envVar of Object.keys(testPlatform.environmentVars)) {
+        sinon
+            .stub(process.env, envVar)
+            .value(testPlatform.environmentVars[envVar]);
     }
 }
 
 describe("Platform module", function () {
+    afterEach(function () {
+        mockFS.restore();
+    });
+
     it("Gets the correct platform details", function () {
-        const platformDetails: platform.IPlatformDetails = platform.getPlatformDetails();
+        const platformDetails: platform.IPlatformDetails =
+            platform.getPlatformDetails();
         switch (process.platform) {
             case "darwin":
                 assert.strictEqual(
                     platformDetails.operatingSystem,
                     platform.OperatingSystem.MacOS,
-                    "Platform details operating system should be MacOS");
+                    "Platform details operating system should be MacOS",
+                );
                 assert.strictEqual(
                     platformDetails.isProcess64Bit,
                     true,
-                    "VSCode on darwin should be 64-bit");
+                    "VSCode on darwin should be 64-bit",
+                );
                 assert.strictEqual(
                     platformDetails.isOS64Bit,
                     true,
-                    "Darwin is 64-bit only");
+                    "Darwin is 64-bit only",
+                );
                 break;
 
             case "linux":
                 assert.strictEqual(
                     platformDetails.operatingSystem,
                     platform.OperatingSystem.Linux,
-                    "Platform details operating system should be Linux");
+                    "Platform details operating system should be Linux",
+                );
                 assert.strictEqual(
                     platformDetails.isProcess64Bit,
                     true,
-                    "Only 64-bit VSCode supported on Linux");
+                    "Only 64-bit VSCode supported on Linux",
+                );
                 assert.strictEqual(
                     platformDetails.isOS64Bit,
                     true,
-                    "Only 64-bit Linux supported by PowerShell");
+                    "Only 64-bit Linux supported by PowerShell",
+                );
                 return;
 
             case "win32":
                 assert.strictEqual(
                     platformDetails.operatingSystem,
                     platform.OperatingSystem.Windows,
-                    "Platform details operating system should be Windows");
+                    "Platform details operating system should be Windows",
+                );
                 assert.strictEqual(
                     platformDetails.isProcess64Bit,
-                    process.arch === "x64",
-                    "Windows process bitness should match process arch");
+                    process.arch === "x64" || process.arch === "arm64",
+                    "Windows process bitness should match process arch",
+                );
                 assert.strictEqual(
                     platformDetails.isOS64Bit,
-                    !!(platformDetails.isProcess64Bit || process.env.ProgramW6432),
-                    "Windows OS arch should match process bitness unless 64-bit env var set");
+                    !!(
+                        platformDetails.isProcess64Bit ||
+                        process.env.ProgramW6432
+                    ),
+                    "Windows OS arch should match process bitness unless 64-bit env var set",
+                );
                 return;
 
             default:
@@ -522,97 +879,128 @@ describe("Platform module", function () {
     });
 
     describe("Default PowerShell installation", function () {
-        afterEach(function () {
-            sinon.restore();
-            mockFS.restore();
-        });
-
         for (const testPlatform of successTestCases) {
-            it(`Finds it on ${testPlatform.name}`, function () {
+            it(`Finds it on ${testPlatform.name}`, async function () {
                 setupTestEnvironment(testPlatform);
 
-                const powerShellExeFinder = new platform.PowerShellExeFinder(testPlatform.platformDetails);
+                const powerShellExeFinder = new platform.PowerShellExeFinder(
+                    testPlatform.platformDetails,
+                    {},
+                );
 
-                const defaultPowerShell = powerShellExeFinder.getFirstAvailablePowerShellInstallation();
-                const expectedPowerShell = testPlatform.expectedPowerShellSequence[0];
+                const defaultPowerShell =
+                    await powerShellExeFinder.getFirstAvailablePowerShellInstallation();
+                const expectedPowerShell =
+                    testPlatform.expectedPowerShellSequence[0];
 
-                assert.strictEqual(defaultPowerShell.exePath, expectedPowerShell.exePath);
-                assert.strictEqual(defaultPowerShell.displayName, expectedPowerShell.displayName);
+                assert.strictEqual(
+                    defaultPowerShell!.exePath,
+                    expectedPowerShell.exePath,
+                );
+                assert.strictEqual(
+                    defaultPowerShell!.displayName,
+                    expectedPowerShell.displayName,
+                );
+                assert.strictEqual(
+                    defaultPowerShell!.supportsProperArguments,
+                    expectedPowerShell.supportsProperArguments,
+                );
             });
         }
 
         for (const testPlatform of errorTestCases) {
-            it(`Fails gracefully on ${testPlatform.name}`, function () {
+            it(`Fails gracefully on ${testPlatform.name}`, async function () {
                 setupTestEnvironment(testPlatform);
 
-                const powerShellExeFinder = new platform.PowerShellExeFinder(testPlatform.platformDetails);
+                const powerShellExeFinder = new platform.PowerShellExeFinder(
+                    testPlatform.platformDetails,
+                    {},
+                );
 
-                const defaultPowerShell = powerShellExeFinder.getFirstAvailablePowerShellInstallation();
+                const defaultPowerShell =
+                    await powerShellExeFinder.getFirstAvailablePowerShellInstallation();
                 assert.strictEqual(defaultPowerShell, undefined);
             });
         }
     });
 
     describe("Expected PowerShell installation list", function () {
-        afterEach(function () {
-            sinon.restore();
-            mockFS.restore();
-        });
-
         for (const testPlatform of successTestCases) {
-            it(`Finds them on ${testPlatform.name}`, function () {
+            it(`Finds them on ${testPlatform.name}`, async function () {
                 setupTestEnvironment(testPlatform);
 
-                const powerShellExeFinder = new platform.PowerShellExeFinder(testPlatform.platformDetails);
+                const powerShellExeFinder = new platform.PowerShellExeFinder(
+                    testPlatform.platformDetails,
+                    {},
+                );
 
-                const foundPowerShells = powerShellExeFinder.getAllAvailablePowerShellInstallations();
+                const foundPowerShells =
+                    await powerShellExeFinder.getAllAvailablePowerShellInstallations();
 
-                for (let i = 0; i < testPlatform.expectedPowerShellSequence.length; i++) {
+                for (
+                    let i = 0;
+                    i < testPlatform.expectedPowerShellSequence.length;
+                    i++
+                ) {
                     const foundPowerShell = foundPowerShells[i];
-                    const expectedPowerShell = testPlatform.expectedPowerShellSequence[i];
+                    const expectedPowerShell =
+                        testPlatform.expectedPowerShellSequence[i];
 
-                    assert.strictEqual(foundPowerShell && foundPowerShell.exePath, expectedPowerShell.exePath);
-                    assert.strictEqual(foundPowerShell && foundPowerShell.displayName, expectedPowerShell.displayName);
+                    assert.strictEqual(
+                        foundPowerShell.exePath,
+                        expectedPowerShell.exePath,
+                    );
+                    assert.strictEqual(
+                        foundPowerShell.displayName,
+                        expectedPowerShell.displayName,
+                    );
+                    assert.strictEqual(
+                        foundPowerShell.supportsProperArguments,
+                        expectedPowerShell.supportsProperArguments,
+                    );
                 }
 
                 assert.strictEqual(
                     foundPowerShells.length,
                     testPlatform.expectedPowerShellSequence.length,
-                    "Number of expected PowerShells found does not match");
+                    "Number of expected PowerShells found does not match",
+                );
             });
         }
 
         for (const testPlatform of errorTestCases) {
-            it(`Fails gracefully on ${testPlatform.name}`, function () {
+            it(`Fails gracefully on ${testPlatform.name}`, async function () {
                 setupTestEnvironment(testPlatform);
 
-                const powerShellExeFinder = new platform.PowerShellExeFinder(testPlatform.platformDetails);
+                const powerShellExeFinder = new platform.PowerShellExeFinder(
+                    testPlatform.platformDetails,
+                    {},
+                );
 
-                const foundPowerShells = powerShellExeFinder.getAllAvailablePowerShellInstallations();
+                const foundPowerShells =
+                    await powerShellExeFinder.getAllAvailablePowerShellInstallations();
                 assert.strictEqual(foundPowerShells.length, 0);
             });
         }
     });
 
     describe("Windows PowerShell path fix", function () {
-        afterEach(function () {
-            sinon.restore();
-            mockFS.restore();
-        });
-
-        for (const testPlatform of successTestCases
-            .filter((tp) => tp.platformDetails.operatingSystem === platform.OperatingSystem.Windows)) {
-
+        for (const testPlatform of successTestCases.filter(
+            (tp) =>
+                tp.platformDetails.operatingSystem ===
+                platform.OperatingSystem.Windows,
+        )) {
             it(`Corrects the Windows PowerShell path on ${testPlatform.name}`, function () {
                 setupTestEnvironment(testPlatform);
 
-                function getWinPSPath(systemDir: string) {
+                function getWinPSPath(systemDir: string): string {
                     return path.join(
                         testPlatform.environmentVars.windir,
                         systemDir,
                         "WindowsPowerShell",
                         "v1.0",
-                        "powershell.exe");
+                        "powershell.exe",
+                    );
                 }
 
                 const winPSPath = getWinPSPath("System32");
@@ -626,12 +1014,52 @@ describe("Platform module", function () {
                     altWinPSPath = null;
                 }
 
-                const powerShellExeFinder = new platform.PowerShellExeFinder(testPlatform.platformDetails);
+                const powerShellExeFinder = new platform.PowerShellExeFinder(
+                    testPlatform.platformDetails,
+                    {},
+                );
 
-                assert.strictEqual(powerShellExeFinder.fixWindowsPowerShellPath(winPSPath), winPSPath);
+                assert.strictEqual(
+                    powerShellExeFinder.fixWindowsPowerShellPath(winPSPath),
+                    winPSPath,
+                );
 
                 if (altWinPSPath) {
-                    assert.strictEqual(powerShellExeFinder.fixWindowsPowerShellPath(altWinPSPath), winPSPath);
+                    assert.strictEqual(
+                        powerShellExeFinder.fixWindowsPowerShellPath(
+                            altWinPSPath,
+                        ),
+                        winPSPath,
+                    );
+                }
+            });
+        }
+    });
+
+    describe("PowerShell executables from 'powerShellAdditionalExePaths' are found", function () {
+        for (const testPlatform of successAdditionalTestCases) {
+            it(`Guesses for ${testPlatform.name}`, async function () {
+                setupTestEnvironment(testPlatform);
+
+                const powerShellExeFinder = new platform.PowerShellExeFinder(
+                    testPlatform.platformDetails,
+                    additionalPowerShellExes,
+                );
+
+                let i = 0;
+                for await (const additionalPwsh of powerShellExeFinder.enumerateAdditionalPowerShellInstallations()) {
+                    const expectedPowerShell =
+                        testPlatform.expectedPowerShellSequence[i];
+                    i++;
+
+                    assert.strictEqual(
+                        additionalPwsh.exePath,
+                        expectedPowerShell.exePath,
+                    );
+                    assert.strictEqual(
+                        additionalPwsh.displayName,
+                        expectedPowerShell.displayName,
+                    );
                 }
             });
         }
diff --git a/test/core/settings.test.ts b/test/core/settings.test.ts
index b938aadf0e..117035a390 100644
--- a/test/core/settings.test.ts
+++ b/test/core/settings.test.ts
@@ -2,47 +2,137 @@
 // Licensed under the MIT License.
 
 import * as assert from "assert";
+import { existsSync } from "fs";
+import * as os from "os";
+import path from "path";
 import * as vscode from "vscode";
-import Settings = require("../../src/settings");
+import {
+    changeSetting,
+    CommentType,
+    getEffectiveConfigurationTarget,
+    getSettings,
+    Settings,
+    validateCwdSetting,
+} from "../../src/settings";
+import { ensureEditorServicesIsConnected } from "../utils";
 
-describe("Settings module", function () {
-    it("Loads without error", function () {
-        assert.doesNotThrow(Settings.load);
+describe("Settings E2E", function () {
+    async function changeCwdSetting(cwd: string | undefined): Promise<void> {
+        await changeSetting(
+            "cwd",
+            cwd,
+            vscode.ConfigurationTarget.Workspace,
+            undefined,
+        );
+    }
+
+    async function resetCwdSetting(): Promise<void> {
+        await changeCwdSetting(undefined);
+    }
+
+    describe("The 'getSettings' method loads the 'Settings' class", function () {
+        before(resetCwdSetting);
+
+        it("Loads without error", function () {
+            assert.doesNotThrow(getSettings);
+        });
+
+        it("Loads the correct defaults", function () {
+            const testSettings = new Settings();
+            if (existsSync("C:\\powershell-7\\pwsh.exe")) {
+                testSettings.powerShellAdditionalExePaths = {
+                    OneBranch: "C:\\powershell-7\\pwsh.exe",
+                };
+                testSettings.powerShellDefaultVersion = "OneBranch";
+            }
+            const actualSettings = getSettings();
+            assert.deepStrictEqual(actualSettings, testSettings);
+        });
     });
 
-    it("Updates correctly with 'then' syntax", async function () {
-        Settings.change("helpCompletion", "BlockComment", false).then(() =>
-            assert.strictEqual(Settings.load().helpCompletion, "BlockComment"));
+    describe("The 'changeSetting' method", function () {
+        it("Updates correctly", async function () {
+            await changeSetting(
+                "helpCompletion",
+                CommentType.LineComment,
+                vscode.ConfigurationTarget.Workspace,
+                undefined,
+            );
+            assert.strictEqual(
+                getSettings().helpCompletion,
+                CommentType.LineComment,
+            );
+        });
     });
 
-    it("Updates correctly with 'async/await' syntax", async function () {
-        await Settings.change("helpCompletion", "LineComment", false);
-        assert.strictEqual(Settings.load().helpCompletion, "LineComment");
+    describe("The 'getEffectiveConfigurationTarget' method'", function () {
+        it("Works for 'Workspace' target", async function () {
+            await changeSetting(
+                "helpCompletion",
+                CommentType.LineComment,
+                vscode.ConfigurationTarget.Workspace,
+                undefined,
+            );
+            const target = getEffectiveConfigurationTarget("helpCompletion");
+            assert.strictEqual(target, vscode.ConfigurationTarget.Workspace);
+        });
+
+        it("Works for 'undefined' target", async function () {
+            await changeSetting(
+                "helpCompletion",
+                undefined,
+                vscode.ConfigurationTarget.Workspace,
+                undefined,
+            );
+            const target = getEffectiveConfigurationTarget("helpCompletion");
+            assert.strictEqual(target, undefined);
+        });
     });
 
-    describe("User-only settings", async function () {
-        const psExeDetails = [{
-            versionName: "My PowerShell",
-            exePath: "dummyPath",
-        }];
+    describe("The CWD setting", function () {
+        // We're relying on this to be sure that the workspace is loaded.
+        before(ensureEditorServicesIsConnected);
+        before(resetCwdSetting);
+        afterEach(resetCwdSetting);
+
+        const workspace = vscode.workspace.workspaceFolders![0].uri.fsPath;
 
-        it("Throws when updating at workspace-level", async function () {
-            assert.rejects(async () => await Settings.change("powerShellAdditionalExePaths", psExeDetails, false /* workspace-level */));
+        it("Defaults to the 'mocks' workspace folder", async function () {
+            assert.strictEqual(await validateCwdSetting(undefined), workspace);
         });
 
-        it("Doesn't throw when updating at user-level", async function () {
-            await Settings.change("powerShellAdditionalExePaths", psExeDetails, true /* user-level */);
-            assert.strictEqual(Settings.load().powerShellAdditionalExePaths[0].versionName, psExeDetails[0].versionName);
+        it("Uses the default when given a non-existent folder", async function () {
+            await changeCwdSetting("/a/totally/fake/folder");
+            assert.strictEqual(await validateCwdSetting(undefined), workspace);
         });
-    });
 
-    it("Gets the effective configuration target", async function () {
-        await Settings.change("helpCompletion", "LineComment", false);
-        let target = await Settings.getEffectiveConfigurationTarget("helpCompletion");
-        assert.strictEqual(target, vscode.ConfigurationTarget.Workspace);
+        it("Uses the given folder when it exists", async function () {
+            // A different than default folder that definitely exists
+            const cwd = path.resolve(path.join(process.cwd(), ".."));
+            await changeCwdSetting(cwd);
+            assert.strictEqual(await validateCwdSetting(undefined), cwd);
+        });
 
-        await Settings.change("helpCompletion", undefined, false);
-        target = await Settings.getEffectiveConfigurationTarget("helpCompletion");
-        assert.strictEqual(target, null);
+        it("Uses the home folder for ~ (tilde)", async function () {
+            await changeCwdSetting("~");
+            assert.strictEqual(
+                await validateCwdSetting(undefined),
+                os.homedir(),
+            );
+        });
+
+        it("Accepts relative paths", async function () {
+            // A different than default folder that definitely exists and is relative
+            const cwd = path.join("~", "somewhere", "..");
+            const expected = path.join(os.homedir(), "somewhere", "..");
+            await changeCwdSetting(cwd);
+            assert.strictEqual(await validateCwdSetting(undefined), expected);
+        });
+
+        it("Handles relative paths", async function () {
+            await changeCwdSetting("./BinaryModule");
+            const expected = path.join(workspace, "./BinaryModule");
+            assert.strictEqual(await validateCwdSetting(undefined), expected);
+        });
     });
 });
diff --git a/test/features/CustomViews.test.ts b/test/features/CustomViews.test.ts
deleted file mode 100644
index 33286747c8..0000000000
--- a/test/features/CustomViews.test.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import * as assert from "assert";
-import fs = require("fs");
-import path = require("path");
-import rewire = require("rewire");
-import vscode = require("vscode");
-
-// Setup types that are not exported.
-const customViews = rewire("../../src/features/CustomViews");
-const htmlContentViewClass = customViews.__get__("HtmlContentView");
-const HtmlContentView: typeof htmlContentViewClass = htmlContentViewClass;
-
-// interfaces for tests
-interface ITestFile {
-    fileName: string;
-    content: string;
-}
-
-interface IHtmlContentViewTestCase {
-    name: string;
-    htmlContent: string;
-    javaScriptFiles: ITestFile[];
-    cssFiles: ITestFile[];
-    expectedHtmlString: string;
-}
-
-function convertToVSCodeResourceScheme(filePath: string): string {
-    return vscode.Uri.file(filePath).toString().replace("file://", "vscode-resource://");
-}
-
-describe("CustomViews feature", function () {
-    const testCases: IHtmlContentViewTestCase[] = [
-        {
-            name: "with no JavaScript or CSS",
-            htmlContent: "hello",
-            javaScriptFiles: [],
-            cssFiles: [],
-            expectedHtmlString: `<html><head></head><body>
-hello
-</body></html>`,
-        },
-
-        // A test that adds a js file.
-        {
-            name: "with a JavaScript file but no CSS",
-            htmlContent: "hello",
-            javaScriptFiles: [
-                {
-                    fileName: "testCustomViews.js",
-                    content: "console.log('asdf');",
-                },
-            ],
-            cssFiles: [],
-            expectedHtmlString: `<html><head></head><body>
-hello
-<script src="${convertToVSCodeResourceScheme(path.join(__dirname, "testCustomViews.js"))}"></script>
-</body></html>`,
-        },
-
-        // A test that adds a js file in the current directory, and the parent directory.
-        {
-            name: "with two JavaScript files in different locations, but no CSS",
-            htmlContent: "hello",
-            javaScriptFiles: [
-                {
-                    fileName: "testCustomViews.js",
-                    content: "console.log('asdf');",
-                },
-                {
-                    fileName: "../testCustomViews.js",
-                    content: "console.log('asdf');",
-                },
-            ],
-            cssFiles: [],
-            expectedHtmlString: `<html><head></head><body>
-hello
-<script src="${convertToVSCodeResourceScheme(path.join(__dirname, "testCustomViews.js"))}"></script>
-<script src="${convertToVSCodeResourceScheme(path.join(__dirname, "../testCustomViews.js"))}"></script>
-</body></html>`,
-        },
-
-        // A test that adds a js file and a css file.
-        {
-            name: "with a JavaScript and a CSS file",
-            htmlContent: "hello",
-            javaScriptFiles: [
-                {
-                    fileName: "testCustomViews.js",
-                    content: "console.log('asdf');",
-                },
-            ],
-            cssFiles: [
-                {
-                    fileName: "testCustomViews.css",
-                    content: "body: { background-color: green; }",
-                },
-            ],
-            expectedHtmlString: `<html><head><link rel="stylesheet" href="${convertToVSCodeResourceScheme(path.join(__dirname, "testCustomViews.css"))}">
-</head><body>
-hello
-<script src="${convertToVSCodeResourceScheme(path.join(__dirname, "testCustomViews.js"))}"></script>
-</body></html>`,
-        },
-    ];
-
-    for (const testCase of testCases) {
-        it(`Correctly creates an HtmlContentView ${testCase.name}`, function () {
-            const htmlContentView = new HtmlContentView();
-
-            const jsPaths = testCase.javaScriptFiles.map((jsFile) => {
-                const jsPath: string = path.join(__dirname, jsFile.fileName);
-                fs.writeFileSync(jsPath, jsFile.content);
-                return vscode.Uri.file(jsPath).toString();
-            });
-
-            const cssPaths = testCase.cssFiles.map((cssFile) => {
-                const cssPath: string = path.join(__dirname, cssFile.fileName);
-                fs.writeFileSync(cssPath, cssFile.content);
-                return vscode.Uri.file(cssPath).toString();
-            });
-
-            htmlContentView.htmlContent = {
-                bodyContent: testCase.htmlContent,
-                javaScriptPaths: jsPaths,
-                styleSheetPaths: cssPaths,
-            };
-            try {
-                assert.strictEqual(htmlContentView.getContent(), testCase.expectedHtmlString);
-            } finally {
-                jsPaths.forEach((jsPath) => fs.unlinkSync(vscode.Uri.parse(jsPath).fsPath));
-                cssPaths.forEach((cssPath) => fs.unlinkSync(vscode.Uri.parse(cssPath).fsPath));
-            }
-        });
-    }
-});
diff --git a/test/features/DebugSession.test.ts b/test/features/DebugSession.test.ts
new file mode 100644
index 0000000000..986fbd45f7
--- /dev/null
+++ b/test/features/DebugSession.test.ts
@@ -0,0 +1,817 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import structuredClone from "@ungap/structured-clone"; //Polyfill for structuredClone which will be present in Node 17.
+import * as assert from "assert";
+import Sinon from "sinon";
+import {
+    DebugAdapterNamedPipeServer,
+    type DebugConfiguration,
+    type DebugSession,
+    type Extension,
+    type ExtensionContext,
+    Range,
+    SourceBreakpoint,
+    type TextDocument,
+    type TextEditor,
+    Uri,
+    commands,
+    debug,
+    extensions,
+    window,
+    workspace,
+} from "vscode";
+import { Disposable } from "vscode-languageserver-protocol";
+import {
+    DebugConfig,
+    DebugConfigurations,
+    DebugSessionFeature,
+} from "../../src/features/DebugSession";
+import type { IPowerShellExtensionClient } from "../../src/features/ExternalApi";
+import type { IPlatformDetails } from "../../src/platform";
+import * as platform from "../../src/platform";
+import {
+    type IEditorServicesSessionDetails,
+    type IPowerShellVersionDetails,
+    SessionManager,
+} from "../../src/session";
+import * as utils from "../../src/utils";
+import {
+    BuildBinaryModuleMock,
+    WaitEvent,
+    ensureEditorServicesIsConnected,
+    stubInterface,
+    testLogger,
+} from "../utils";
+
+const TEST_NUMBER = 7357; // 7357 = TEST. Get it? :)
+
+let defaultDebugConfig: DebugConfiguration;
+beforeEach(() => {
+    // This prevents state from creeping into the template between test runs
+    defaultDebugConfig = structuredClone(
+        DebugConfigurations[DebugConfig.LaunchCurrentFile],
+    );
+});
+
+describe("DebugSessionFeature", () => {
+    // These constructor stubs are required for all tests so we don't interfere with the E2E vscode instance
+    let registerProviderStub: Sinon.SinonStub;
+    let registerFactoryStub: Sinon.SinonStub;
+
+    /**
+     * Convenience function for creating a DebugSessionFeature with stubbed dependencies. We want the actual methods and Sinon.stubInstance is awkward because it stubs all methods and the constructor, and we just want to stub the constructor basically.
+     */
+    function createDebugSessionFeatureStub({
+        context = stubInterface<ExtensionContext>({
+            subscriptions: Array<Disposable>(), //Needed for constructor
+        }),
+        sessionManager = Sinon.createStubInstance(SessionManager),
+        logger = testLogger,
+    }): DebugSessionFeature {
+        return new DebugSessionFeature(context, sessionManager, logger);
+    }
+
+    /** Representation of an untitled powershell document window in the Editor */
+    const untitledEditor = stubInterface<TextEditor>({
+        document: stubInterface<TextDocument>({
+            uri: Uri.parse("file:///fakeUntitled.ps1"),
+            languageId: "powershell",
+            isUntitled: true,
+        }),
+    });
+
+    beforeEach(() => {
+        // Because we recreate DebugSessionFeature constantly, we need to avoid registering the same commands over and over.
+        Sinon.stub(commands, "registerCommand").returns(
+            Disposable.create(() => {
+                "Stubbed";
+            }),
+        );
+        registerProviderStub = Sinon.stub(
+            debug,
+            "registerDebugConfigurationProvider",
+        ).returns(
+            Disposable.create(() => {
+                "Stubbed";
+            }),
+        );
+        registerFactoryStub = Sinon.stub(
+            debug,
+            "registerDebugAdapterDescriptorFactory",
+        ).returns(
+            Disposable.create(() => {
+                "Stubbed";
+            }),
+        );
+    });
+
+    afterEach(() => {
+        Sinon.restore();
+    });
+
+    describe("Constructor", () => {
+        it("Registers debug configuration provider and factory", () => {
+            const context = stubInterface<ExtensionContext>({
+                subscriptions: Array<Disposable>(),
+            });
+
+            createDebugSessionFeatureStub({ context: context });
+            assert.ok(
+                registerFactoryStub.calledOnce,
+                "Debug adapter factory method called",
+            );
+            assert.ok(
+                registerProviderStub.calledTwice,
+                "Debug config provider registered for both Initial and Dynamic",
+            );
+            assert.equal(
+                context.subscriptions.length,
+                4,
+                "DebugSessionFeature disposables populated",
+            );
+            // TODO: Validate the registration content, such as the language name
+        });
+    });
+
+    describe("resolveDebugConfiguration", () => {
+        it("Defaults to LaunchCurrentFile if no request type was specified", async () => {
+            const noRequestConfig: DebugConfiguration = defaultDebugConfig;
+            noRequestConfig.request = "";
+            // Need to have an editor window "open" for this not to error out
+            Sinon.stub(window, "activeTextEditor").value(untitledEditor);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfiguration(undefined, noRequestConfig);
+
+            assert.equal(actual!.current_document, true);
+            assert.equal(
+                actual!.request,
+                DebugConfigurations[DebugConfig.LaunchCurrentFile].request,
+            );
+        });
+
+        it("Errors if current file config was specified but no file is open in the editor", async () => {
+            Sinon.stub(window, "activeTextEditor").value(undefined);
+            const logger = Sinon.stub(testLogger);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfiguration(undefined, defaultDebugConfig);
+
+            assert.equal(actual!, undefined);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /you must first open a PowerShell script file/,
+            );
+        });
+
+        it("Detects an untitled document", async () => {
+            Sinon.stub(window, "activeTextEditor").value(untitledEditor);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfiguration(undefined, defaultDebugConfig);
+
+            assert.equal(actual!.untitled_document, true);
+            assert.equal(actual!.script, "file:///fakeUntitled.ps1");
+        });
+    });
+
+    describe("resolveDebugConfigurationWithSubstitutedVariables", () => {
+        it("Sets internalConsoleOptions to neverOpen", async () => {
+            Sinon.stub(window, "activeTextEditor").value(untitledEditor);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                defaultDebugConfig,
+            );
+
+            assert.equal(actual!.internalConsoleOptions, "neverOpen");
+        });
+        it("Rejects invalid request type", async () => {
+            const invalidRequestConfig: DebugConfiguration = defaultDebugConfig;
+            invalidRequestConfig.request = "notAttachOrLaunch";
+            const logger = Sinon.stub(testLogger);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                invalidRequestConfig,
+            );
+
+            assert.equal(actual, null);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /request type was invalid/,
+            );
+        });
+
+        it("Uses createTemporaryIntegratedConsole config setting if not explicitly specified", async () => {
+            Sinon.stub(window, "activeTextEditor").value(untitledEditor);
+            assert.equal(
+                defaultDebugConfig.createTemporaryIntegratedConsole,
+                undefined,
+                "Default config should have no temp integrated console setting",
+            );
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                defaultDebugConfig,
+            );
+
+            assert.notEqual(
+                actual!.createTemporaryIntegratedConsole,
+                undefined,
+                "createTemporaryIntegratedConsole should have received a value from the settings and no longer be undefined",
+            );
+        });
+
+        it("LaunchCurrentFile: Rejects non-Powershell language active editor", async () => {
+            const nonPSEditor = stubInterface<TextEditor>({
+                document: stubInterface<TextDocument>({
+                    uri: Uri.parse("file:///fakeUntitled.ps1"),
+                    languageId: "NotPowerShell",
+                    isUntitled: true,
+                }),
+            });
+            const currentDocConfig: DebugConfiguration = defaultDebugConfig;
+            currentDocConfig.current_document = true;
+            Sinon.stub(window, "activeTextEditor").value(nonPSEditor);
+            const logger = Sinon.stub(testLogger);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                currentDocConfig,
+            );
+
+            assert.equal(actual, undefined, "Debug session should end");
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /debugging this language mode/,
+            );
+        });
+
+        // Skipped until we can fix the stub
+        it.skip("LaunchScript: Rejects scripts without a powershell script extension", async () => {
+            const currentDocConfig: DebugConfiguration = defaultDebugConfig;
+            currentDocConfig.current_document = true;
+            currentDocConfig.script = "file:///notPowerShell.txt";
+            // This check is currently dependent on the languageID check which is why this is needed still
+            Sinon.stub(window, "activeTextEditor").value(untitledEditor);
+            Sinon.stub(utils, "checkIfFileExists").resolves(true);
+            const logger = Sinon.stub(testLogger);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                currentDocConfig,
+            );
+
+            assert.equal(actual, undefined);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /debugging this file type/,
+            );
+            Sinon.restore();
+        });
+
+        it("Prevents debugging untitled files in a temp console", async () => {
+            const currentDocConfig: DebugConfiguration = defaultDebugConfig;
+            currentDocConfig.untitled_document = true;
+            currentDocConfig.createTemporaryIntegratedConsole = true;
+            Sinon.stub(window, "activeTextEditor").value(untitledEditor);
+            const logger = Sinon.stub(testLogger);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                currentDocConfig,
+            );
+
+            assert.equal(actual, undefined);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /debugging untitled/,
+            );
+        });
+
+        it("Attach: Exits if session version details cannot be retrieved", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.request = "attach";
+            const logger = Sinon.stub(testLogger);
+            const sessionManager = Sinon.createStubInstance(SessionManager, {});
+            sessionManager.getPowerShellVersionDetails.returns(undefined);
+
+            const actual = await createDebugSessionFeatureStub({
+                sessionManager: sessionManager,
+            }).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                attachConfig,
+            );
+
+            assert.equal(actual, undefined);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /session version details were not found/,
+            );
+            assert.ok(sessionManager.getPowerShellVersionDetails.calledOnce);
+        });
+
+        // Skipped until we can fix the stub
+        it.skip("Attach: Prevents attach on non-windows if not PS7.0 or higher", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.request = "attach";
+            const logger = Sinon.stub(testLogger);
+            const sessionManager = Sinon.createStubInstance(SessionManager, {});
+            Sinon.stub(platform, "getPlatformDetails").returns(
+                stubInterface<IPlatformDetails>({
+                    operatingSystem: platform.OperatingSystem.MacOS,
+                }),
+            );
+            sessionManager.getPowerShellVersionDetails.returns(
+                stubInterface<IPowerShellVersionDetails>({
+                    version: "6.2.3",
+                }),
+            );
+
+            const actual = await createDebugSessionFeatureStub({
+                sessionManager: sessionManager,
+            }).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                attachConfig,
+            );
+
+            assert.equal(actual, undefined);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /requires PowerShell 7/,
+            );
+            assert.ok(sessionManager.getPowerShellVersionDetails.calledOnce);
+        });
+
+        it("Attach: Prompts for PS Process if not specified", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.request = "attach";
+            // This effectively skips this check
+            attachConfig.runspaceId = TEST_NUMBER;
+            attachConfig.runspaceName = "TEST";
+            const sessionManager = Sinon.createStubInstance(SessionManager, {});
+            sessionManager.getPowerShellVersionDetails.returns(
+                stubInterface<IPowerShellVersionDetails>({
+                    version: "7.2.3",
+                }),
+            );
+            const debugSessionFeatureStub = createDebugSessionFeatureStub({
+                sessionManager: sessionManager,
+            });
+
+            const pickPSHostProcessStub = Sinon.stub(
+                debugSessionFeatureStub,
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                "pickPSHostProcess" as any,
+            ).resolves(7357);
+
+            const actual =
+                await debugSessionFeatureStub.resolveDebugConfigurationWithSubstitutedVariables(
+                    undefined,
+                    attachConfig,
+                );
+
+            assert.equal(actual!.processId, TEST_NUMBER);
+            assert.ok(pickPSHostProcessStub.calledOnce);
+        });
+
+        it("Attach: Exits if process was not selected from the picker", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.request = "attach";
+            // This effectively skips this check
+            attachConfig.runspaceId = TEST_NUMBER;
+            attachConfig.runspaceName = "TEST";
+            const sessionManager = Sinon.createStubInstance(SessionManager, {});
+            sessionManager.getPowerShellVersionDetails.returns(
+                stubInterface<IPowerShellVersionDetails>({
+                    version: "7.2.3",
+                }),
+            );
+            const debugSessionFeatureStub = createDebugSessionFeatureStub({
+                sessionManager: sessionManager,
+            });
+
+            const pickPSHostProcessStub = Sinon.stub(
+                debugSessionFeatureStub,
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                "pickPSHostProcess" as any,
+            ).resolves(undefined);
+
+            const actual =
+                await debugSessionFeatureStub.resolveDebugConfigurationWithSubstitutedVariables(
+                    undefined,
+                    attachConfig,
+                );
+
+            assert.equal(actual, undefined);
+            assert.ok(pickPSHostProcessStub.calledOnce);
+        });
+
+        it("Attach: Prompts for Runspace if not specified", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.request = "attach";
+            // This effectively skips this check
+            attachConfig.processId = TEST_NUMBER;
+            const sessionManager = Sinon.createStubInstance(SessionManager, {});
+            sessionManager.getPowerShellVersionDetails.returns(
+                stubInterface<IPowerShellVersionDetails>({
+                    version: "7.2.3",
+                }),
+            );
+            const debugSessionFeatureStub = createDebugSessionFeatureStub({
+                sessionManager: sessionManager,
+            });
+
+            const pickRunspaceStub = Sinon.stub(
+                debugSessionFeatureStub,
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                "pickRunspace" as any,
+            ).resolves(TEST_NUMBER);
+
+            const actual =
+                await debugSessionFeatureStub.resolveDebugConfigurationWithSubstitutedVariables(
+                    undefined,
+                    attachConfig,
+                );
+
+            assert.equal(actual!.runspaceId, TEST_NUMBER);
+            assert.ok(pickRunspaceStub.calledOnceWith(TEST_NUMBER));
+        });
+
+        it("Attach: Exits if runspace was not selected from the picker", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.request = "attach";
+            // This effectively skips this check
+            attachConfig.processId = TEST_NUMBER;
+            const sessionManager = Sinon.createStubInstance(SessionManager, {});
+            sessionManager.getPowerShellVersionDetails.returns(
+                stubInterface<IPowerShellVersionDetails>({
+                    version: "7.2.3",
+                }),
+            );
+            const debugSessionFeatureStub = createDebugSessionFeatureStub({
+                sessionManager: sessionManager,
+            });
+
+            const pickRunspaceStub = Sinon.stub(
+                debugSessionFeatureStub,
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                "pickRunspace" as any,
+            ).resolves(undefined);
+
+            const actual =
+                await debugSessionFeatureStub.resolveDebugConfigurationWithSubstitutedVariables(
+                    undefined,
+                    attachConfig,
+                );
+            assert.equal(actual, undefined);
+            assert.ok(pickRunspaceStub.calledOnceWith(TEST_NUMBER));
+        });
+
+        it("Starts dotnet attach debug session with default config", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.script = "test.ps1"; // This bypasses the ${file} logic
+            attachConfig.createTemporaryIntegratedConsole = true;
+            attachConfig.attachDotnetDebugger = true;
+            Sinon.stub(extensions, "getExtension").returns(
+                stubInterface<Extension<IPowerShellExtensionClient>>(),
+            );
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                attachConfig,
+            );
+
+            const dotnetAttachConfig = actual!.dotnetAttachConfig;
+            assert.equal(
+                dotnetAttachConfig.name,
+                "Dotnet Debugger: Temporary Extension Terminal",
+            );
+            assert.equal(dotnetAttachConfig.request, "attach");
+            assert.equal(dotnetAttachConfig.type, "coreclr");
+            assert.equal(dotnetAttachConfig.processId, undefined);
+            assert.equal(dotnetAttachConfig.logging.moduleLoad, false);
+        });
+
+        it("Prevents dotnet attach session if terminal is not temporary", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.script = "test.ps1"; // This bypasses the ${file} logic
+            attachConfig.attachDotnetDebugger = true;
+            const logger = Sinon.stub(testLogger);
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                attachConfig,
+            );
+
+            assert.equal(actual!, null);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /dotnet debugging without using a temporary console/,
+            );
+        });
+
+        it("Errors if dotnetDebuggerConfigName was provided but the config was not found", async () => {
+            const attachConfig: DebugConfiguration = defaultDebugConfig;
+            attachConfig.script = "test.ps1"; // This bypasses the ${file} logic
+            attachConfig.createTemporaryIntegratedConsole = true;
+            attachConfig.attachDotnetDebugger = true;
+            attachConfig.dotnetDebuggerConfigName = "not a real config";
+            const logger = Sinon.stub(testLogger);
+            Sinon.stub(extensions, "getExtension").returns(
+                stubInterface<Extension<IPowerShellExtensionClient>>(),
+            );
+
+            const actual = await createDebugSessionFeatureStub(
+                {},
+            ).resolveDebugConfigurationWithSubstitutedVariables(
+                undefined,
+                attachConfig,
+            );
+
+            assert.equal(actual!, null);
+            assert.match(
+                logger.writeAndShowError.firstCall.args[0],
+                /matching launch config was not found/,
+            );
+        });
+
+        it("Finds the correct dotnetDebuggerConfigName", async () => {
+            const foundDotnetConfig: DebugConfiguration = {
+                name: "TestDotnetAttachConfig",
+                request: "attach",
+                type: "coreclr",
+            };
+            const candidateDotnetConfigs: DebugConfiguration[] = [
+                {
+                    name: "BadCandidate1",
+                    type: "powershell",
+                    request: "attach",
+                },
+                {
+                    name: "BadCandidate2",
+                    type: "coreclr",
+                    request: "attach",
+                },
+                {
+                    // This one has launch instead of attach and even tho it has same name, should not be matched
+                    name: foundDotnetConfig.name,
+                    type: "coreclr",
+                    request: "launch",
+                },
+                foundDotnetConfig, //This is the one we want to match
+                {
+                    name: foundDotnetConfig.name,
+                    type: "notcoreclrExactly",
+                    request: "attach",
+                },
+                {
+                    name: `${foundDotnetConfig.name}notexactlythisname`,
+                    type: "coreclr",
+                    request: "attach",
+                },
+            ];
+            const attachConfig = defaultDebugConfig;
+            attachConfig.script = "test.ps1"; // This bypasses the ${file} logic
+            attachConfig.createTemporaryIntegratedConsole = true;
+            attachConfig.attachDotnetDebugger = true;
+            attachConfig.dotnetDebuggerConfigName = foundDotnetConfig.name;
+            const debugSessionFeature = createDebugSessionFeatureStub({});
+
+            Sinon.stub(
+                debugSessionFeature,
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                "getLaunchConfigurations" as any,
+            ).returns(candidateDotnetConfigs);
+
+            const config =
+                await debugSessionFeature.resolveDebugConfigurationWithSubstitutedVariables(
+                    undefined,
+                    attachConfig,
+                );
+
+            // This config will only be present if the C# extension is installed.
+            if (extensions.getExtension("ms-dotnettools.csharp")) {
+                assert.ok(config);
+                assert.deepStrictEqual(
+                    config.dotnetAttachConfig,
+                    foundDotnetConfig,
+                );
+            } else {
+                assert.ok(!config);
+            }
+        });
+    });
+
+    describe("createDebugAdapterDescriptor", () => {
+        it("Creates a named pipe server for the debug adapter", async () => {
+            const debugSessionFeature = createDebugSessionFeatureStub({
+                sessionManager: Sinon.createStubInstance(SessionManager, {
+                    getSessionDetails:
+                        stubInterface<IEditorServicesSessionDetails>({
+                            debugServicePipeName: "testPipeName",
+                        }),
+                }),
+            });
+            const debugSession = stubInterface<DebugSession>({
+                configuration: stubInterface<DebugConfiguration>({
+                    createTemporaryIntegratedConsole: false,
+                }),
+            });
+
+            const debugAdapterDescriptor =
+                await debugSessionFeature.createDebugAdapterDescriptor(
+                    debugSession,
+                    undefined,
+                );
+
+            // Confirm debugAdapterDescriptor is of type debugadapternamedpipeserver
+            assert.ok(
+                debugAdapterDescriptor instanceof DebugAdapterNamedPipeServer,
+            );
+            assert.equal(debugAdapterDescriptor.path, "testPipeName");
+        });
+    });
+});
+
+describe("DebugSessionFeature E2E", function () {
+    before(async () => {
+        // Registers and warms up the debug adapter and the PowerShell Extension Terminal
+        await ensureEditorServicesIsConnected();
+    });
+
+    it("Starts and stops a debugging session", async () => {
+        // Inspect the debug session via the started events to ensure it is correct
+        const startDebugSession = new Promise<DebugSession>((resolve) => {
+            const event = debug.onDidStartDebugSession((session) => {
+                resolve(session);
+                event.dispose();
+            });
+        });
+        const stopDebugSession = new Promise<DebugSession>((resolve) => {
+            const event = debug.onDidTerminateDebugSession((session) => {
+                resolve(session);
+                event.dispose();
+            });
+        });
+
+        const config = DebugConfigurations[DebugConfig.InteractiveSession];
+        assert.ok(
+            await debug.startDebugging(undefined, config),
+            "Debug session should start",
+        );
+        assert.equal(
+            (await startDebugSession).name,
+            config.name,
+            "Debug session name should match when started",
+        );
+
+        await debug.stopDebugging(await startDebugSession);
+        assert.ok(await stopDebugSession, "Debug session should stop");
+        assert.equal(
+            (await stopDebugSession).name,
+            config.name,
+            "Debug session name should match when stopped",
+        );
+        assert.equal(
+            (await stopDebugSession).configuration.internalConsoleOptions,
+            "neverOpen",
+            "Debug session should always have neverOpen internalConsoleOptions",
+        );
+    });
+
+    describe("Binary Modules", () => {
+        let binaryModulePath: Uri;
+
+        before(async function binarySetup() {
+            if (!extensions.getExtension("ms-dotnettools.csharp")) {
+                // These tests require that extension to be installed in the test environment.
+                this.skip();
+            }
+            binaryModulePath = Uri.joinPath(
+                workspace.workspaceFolders![0].uri,
+                "BinaryModule",
+            );
+            BuildBinaryModuleMock();
+            await ensureEditorServicesIsConnected();
+        });
+
+        afterEach(async () => {
+            // Cleanup E2E testing state
+            await debug.stopDebugging(undefined);
+            // Close all editors
+            await commands.executeCommand("workbench.action.closeAllEditors");
+        });
+
+        it("Debugs a binary module script", async () => {
+            const launchScriptConfig = structuredClone(
+                DebugConfigurations[DebugConfig.LaunchScript],
+            );
+            launchScriptConfig.script = Uri.joinPath(
+                binaryModulePath,
+                "BinaryModuleTest.ps1",
+            ).fsPath;
+            launchScriptConfig.attachDotnetDebugger = true;
+            launchScriptConfig.createTemporaryIntegratedConsole = true;
+            const startDebugging = Sinon.spy(debug, "startDebugging");
+
+            const debugStarted = await debug.startDebugging(
+                undefined,
+                launchScriptConfig,
+            );
+            assert.ok(debugStarted);
+
+            await debug.stopDebugging(undefined);
+
+            assert.ok(startDebugging.calledTwice);
+            assert.ok(startDebugging.calledWith(undefined, launchScriptConfig));
+            // The C# child process
+            assert.ok(
+                startDebugging.calledWithMatch(
+                    undefined,
+                    Sinon.match.has("type", "coreclr"), // The new child debugger
+                    Sinon.match.has("type", "PowerShell"), // The parent session
+                ),
+                "The C# debugger child process is created with the PowerShell debugger as the parent",
+            );
+        });
+
+        it("Stops at a binary module breakpoint", async () => {
+            const launchScriptConfig = structuredClone(
+                DebugConfigurations[DebugConfig.LaunchCurrentFile],
+            );
+            launchScriptConfig.attachDotnetDebugger = true;
+            launchScriptConfig.createTemporaryIntegratedConsole = true;
+            const testScriptPath = Uri.joinPath(
+                binaryModulePath,
+                "BinaryModuleTest.ps1",
+            );
+            const cmdletSourcePath = Uri.joinPath(
+                binaryModulePath,
+                "TestSampleCmdletCommand.cs",
+            );
+            const testScriptDocument =
+                await workspace.openTextDocument(testScriptPath);
+            await window.showTextDocument(testScriptDocument);
+
+            // We cant see when a breakpoint is hit because the code we would spy on is in the C# extension or is vscode private, but we can see if the debug session changes which should only happen when the debug session context switches to C#, so that's good enough.
+
+            //We wire this up before starting the debug session so the event is registered
+            const dotnetDebugSessionActive = WaitEvent(
+                debug.onDidChangeActiveDebugSession,
+                (session) => {
+                    return !!session?.name.match(/Dotnet Debugger/);
+                },
+            );
+
+            // Break at beginProcessing of the cmdlet
+            debug.addBreakpoints([
+                new SourceBreakpoint(
+                    {
+                        uri: cmdletSourcePath,
+                        range: new Range(26, 0, 26, 0), //BeginProcessing
+                    },
+                    true,
+                    undefined,
+                    undefined,
+                    "TEST-BinaryModuleBreakpoint",
+                ),
+            ]);
+
+            const debugStarted = await debug.startDebugging(
+                undefined,
+                launchScriptConfig,
+            );
+            console.log(debug.breakpoints);
+            const dotnetDebugSession = await dotnetDebugSessionActive;
+            console.log(debug.activeDebugSession);
+            console.log(debug.breakpoints);
+
+            await debug.stopDebugging(undefined);
+
+            assert.ok(debugStarted);
+            assert.ok(dotnetDebugSession);
+        });
+    });
+});
diff --git a/test/features/ExternalApi.test.ts b/test/features/ExternalApi.test.ts
index 0bc44c2811..d0b3e56641 100644
--- a/test/features/ExternalApi.test.ts
+++ b/test/features/ExternalApi.test.ts
@@ -2,76 +2,94 @@
 // Licensed under the MIT License.
 
 import * as assert from "assert";
+import type {
+    IExternalPowerShellDetails,
+    IPowerShellExtensionClient,
+} from "../../src/features/ExternalApi";
 import utils = require("../utils");
-import { IExternalPowerShellDetails, IPowerShellExtensionClient } from "../../src/features/ExternalApi";
 
 describe("ExternalApi feature", function () {
     describe("External extension registration", function () {
-        let powerShellExtensionClient: IPowerShellExtensionClient;
+        let extension: IPowerShellExtensionClient;
         before(async function () {
-            const powershellExtension = await utils.ensureExtensionIsActivated();
-            powerShellExtensionClient = powershellExtension!.exports as IPowerShellExtensionClient;
+            extension = await utils.ensureExtensionIsActivated();
         });
 
         it("Registers and unregisters an extension", function () {
-            const sessionId: string = powerShellExtensionClient.registerExternalExtension(utils.extensionId);
+            const sessionId: string = extension.registerExternalExtension(
+                utils.extensionId,
+            );
             assert.notStrictEqual(sessionId, "");
             assert.notStrictEqual(sessionId, null);
             assert.strictEqual(
-                powerShellExtensionClient.unregisterExternalExtension(sessionId),
-                true);
+                extension.unregisterExternalExtension(sessionId),
+                true,
+            );
         });
 
         it("Registers and unregisters an extension with a version", function () {
-            const sessionId: string = powerShellExtensionClient.registerExternalExtension(utils.extensionId, "v2");
+            const sessionId: string = extension.registerExternalExtension(
+                utils.extensionId,
+                "v2",
+            );
             assert.notStrictEqual(sessionId, "");
             assert.notStrictEqual(sessionId, null);
             assert.strictEqual(
-                powerShellExtensionClient.unregisterExternalExtension(sessionId),
-                true);
+                extension.unregisterExternalExtension(sessionId),
+                true,
+            );
         });
 
         it("Rejects if not registered", async function () {
-            assert.rejects(
-                async () => await powerShellExtensionClient.getPowerShellVersionDetails(""))
+            await assert.rejects(
+                async () => await extension.getPowerShellVersionDetails(""),
+            );
         });
 
-        it("Throws if attempting to register an extension more than once", async function () {
-            const sessionId: string = powerShellExtensionClient.registerExternalExtension(utils.extensionId);
+        it("Throws if attempting to register an extension more than once", function () {
+            const sessionId: string = extension.registerExternalExtension(
+                utils.extensionId,
+            );
             try {
                 assert.throws(
-                    () => powerShellExtensionClient.registerExternalExtension(utils.extensionId),
+                    () =>
+                        extension.registerExternalExtension(utils.extensionId),
                     {
-                        message: `The extension '${utils.extensionId}' is already registered.`
-                    });
+                        message: `The extension '${utils.extensionId}' is already registered.`,
+                    },
+                );
             } finally {
-                powerShellExtensionClient.unregisterExternalExtension(sessionId);
+                extension.unregisterExternalExtension(sessionId);
             }
         });
 
-        it("Throws when unregistering an extension that isn't registered", async function () {
+        it("Throws when unregistering an extension that isn't registered", function () {
             assert.throws(
-                () => powerShellExtensionClient.unregisterExternalExtension("not-real"),
+                () => extension.unregisterExternalExtension("not-real"),
                 {
-                    message: `No extension registered with session UUID: not-real`
-                });
+                    message:
+                        "No extension registered with session UUID: not-real",
+                },
+            );
         });
     });
 
     describe("PowerShell version details", () => {
         let sessionId: string;
-        let powerShellExtensionClient: IPowerShellExtensionClient;
+        let extension: IPowerShellExtensionClient;
 
         before(async function () {
-            const powershellExtension = await utils.ensureExtensionIsActivated();
-            powerShellExtensionClient = powershellExtension!.exports as IPowerShellExtensionClient;
-            sessionId = powerShellExtensionClient.registerExternalExtension(utils.extensionId);
+            extension = await utils.ensureExtensionIsActivated();
+            sessionId = extension.registerExternalExtension(utils.extensionId);
         });
 
-        after(function () { powerShellExtensionClient.unregisterExternalExtension(sessionId); });
+        after(function () {
+            extension.unregisterExternalExtension(sessionId);
+        });
 
         it("Gets non-empty version details from the PowerShell Editor Services", async function () {
-            const versionDetails: IExternalPowerShellDetails = await powerShellExtensionClient.getPowerShellVersionDetails(sessionId);
+            const versionDetails: IExternalPowerShellDetails =
+                await extension.getPowerShellVersionDetails(sessionId);
 
             assert.notStrictEqual(versionDetails.architecture, "");
             assert.notStrictEqual(versionDetails.architecture, null);
diff --git a/test/features/ISECompatibility.test.ts b/test/features/ISECompatibility.test.ts
index d93adca2e0..19a768c56a 100644
--- a/test/features/ISECompatibility.test.ts
+++ b/test/features/ISECompatibility.test.ts
@@ -7,71 +7,144 @@ import { ISECompatibilityFeature } from "../../src/features/ISECompatibility";
 import utils = require("../utils");
 
 describe("ISE compatibility feature", function () {
-    let currentTheme: string;
+    let currentTheme: string | undefined;
 
-    async function enableISEMode() { await vscode.commands.executeCommand("PowerShell.EnableISEMode"); }
-    async function disableISEMode() { await vscode.commands.executeCommand("PowerShell.DisableISEMode"); }
+    async function enableISEMode(): Promise<void> {
+        await vscode.commands.executeCommand("PowerShell.EnableISEMode");
+    }
+    async function disableISEMode(): Promise<void> {
+        await vscode.commands.executeCommand("PowerShell.DisableISEMode");
+    }
+    async function toggleISEMode(): Promise<void> {
+        await vscode.commands.executeCommand("PowerShell.ToggleISEMode");
+    }
 
     before(async function () {
         // Save user's current theme.
-        currentTheme = await vscode.workspace.getConfiguration("workbench").get("colorTheme");
+        currentTheme = await vscode.workspace
+            .getConfiguration("workbench")
+            .get("colorTheme");
         await utils.ensureEditorServicesIsConnected();
     });
 
     after(async function () {
         // Reset user's current theme.
-        await vscode.workspace.getConfiguration("workbench").update("colorTheme", currentTheme, true);
-        assert.strictEqual(vscode.workspace.getConfiguration("workbench").get("colorTheme"), currentTheme);
+        await vscode.workspace
+            .getConfiguration("workbench")
+            .update("colorTheme", currentTheme, true);
+        assert.strictEqual(
+            vscode.workspace.getConfiguration("workbench").get("colorTheme"),
+            currentTheme,
+        );
     });
 
-    describe("EnableISEMode command", async function () {
+    describe("Enable ISE Mode updates expected settings", function () {
         before(enableISEMode);
         after(disableISEMode);
         for (const iseSetting of ISECompatibilityFeature.settings) {
             it(`Sets ${iseSetting.name} correctly`, function () {
-                const currently = vscode.workspace.getConfiguration(iseSetting.path).get(iseSetting.name);
+                const currently = vscode.workspace
+                    .getConfiguration(iseSetting.path)
+                    .get(iseSetting.name);
                 assert.strictEqual(currently, iseSetting.value);
             });
         }
     });
 
-    describe("DisableISEMode command", async function () {
+    describe("Disable ISE Mode reverts expected settings", function () {
         before(enableISEMode);
         before(disableISEMode);
+        after(disableISEMode);
+        for (const iseSetting of ISECompatibilityFeature.settings) {
+            it(`Reverts ${iseSetting.name} correctly`, function () {
+                const currently = vscode.workspace
+                    .getConfiguration(iseSetting.path)
+                    .get(iseSetting.name);
+                assert.notStrictEqual(currently, iseSetting.value);
+            });
+        }
+    });
+
+    describe("Toggle switches from enabled to disabled", function () {
+        before(enableISEMode);
+        before(toggleISEMode);
+        after(disableISEMode);
         for (const iseSetting of ISECompatibilityFeature.settings) {
-            it(`Unsets ${iseSetting.name} correctly`, function () {
-                const currently = vscode.workspace.getConfiguration(iseSetting.path).get(iseSetting.name);
+            it(`Reverts ${iseSetting.name} correctly`, function () {
+                const currently = vscode.workspace
+                    .getConfiguration(iseSetting.path)
+                    .get(iseSetting.name);
                 assert.notStrictEqual(currently, iseSetting.value);
             });
         }
     });
 
-    describe("Color theme interactions", async function () {
+    describe("Toggle switches from disabled to enabled", function () {
+        before(disableISEMode);
+        before(toggleISEMode);
+        after(disableISEMode);
+        for (const iseSetting of ISECompatibilityFeature.settings) {
+            it(`Sets ${iseSetting.name} correctly`, function () {
+                const currently = vscode.workspace
+                    .getConfiguration(iseSetting.path)
+                    .get(iseSetting.name);
+                assert.strictEqual(currently, iseSetting.value);
+            });
+        }
+    });
+
+    describe("Color theme interactions", function () {
         beforeEach(enableISEMode);
 
-        function assertISESettings() {
+        function assertISESettings(): void {
             for (const iseSetting of ISECompatibilityFeature.settings) {
-                const currently = vscode.workspace.getConfiguration(iseSetting.path).get(iseSetting.name);
+                const currently = vscode.workspace
+                    .getConfiguration(iseSetting.path)
+                    .get(iseSetting.name);
                 assert.notStrictEqual(currently, iseSetting.value);
             }
         }
 
         it("Changes the theme back from PowerShell ISE", async function () {
             // Change state to something that DisableISEMode will change
-            await vscode.workspace.getConfiguration("workbench").update("colorTheme", "PowerShell ISE", true);
-            assert.strictEqual(vscode.workspace.getConfiguration("workbench").get("colorTheme"), "PowerShell ISE");
+            await vscode.workspace
+                .getConfiguration("workbench")
+                .update("colorTheme", "PowerShell ISE", true);
+            assert.strictEqual(
+                vscode.workspace
+                    .getConfiguration("workbench")
+                    .get("colorTheme"),
+                "PowerShell ISE",
+            );
             await disableISEMode();
             assertISESettings();
         });
 
         it("Doesn't change theme if it was manually changed", async function () {
-            assert.strictEqual(vscode.workspace.getConfiguration("workbench").get("colorTheme"), "PowerShell ISE");
+            assert.strictEqual(
+                vscode.workspace
+                    .getConfiguration("workbench")
+                    .get("colorTheme"),
+                "PowerShell ISE",
+            );
             // "Manually" change theme after enabling ISE mode. Use a built-in theme but not the default.
-            await vscode.workspace.getConfiguration("workbench").update("colorTheme", "Monokai", true);
-            assert.strictEqual(vscode.workspace.getConfiguration("workbench").get("colorTheme"), "Monokai");
+            await vscode.workspace
+                .getConfiguration("workbench")
+                .update("colorTheme", "Monokai", true);
+            assert.strictEqual(
+                vscode.workspace
+                    .getConfiguration("workbench")
+                    .get("colorTheme"),
+                "Monokai",
+            );
             await disableISEMode();
             assertISESettings();
-            assert.strictEqual(vscode.workspace.getConfiguration("workbench").get("colorTheme"), "Monokai");
+            assert.strictEqual(
+                vscode.workspace
+                    .getConfiguration("workbench")
+                    .get("colorTheme"),
+                "Monokai",
+            );
         });
     });
 });
diff --git a/test/features/RunCode.test.ts b/test/features/RunCode.test.ts
deleted file mode 100644
index d016436fe0..0000000000
--- a/test/features/RunCode.test.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-import * as assert from "assert";
-import * as fs from "fs";
-import * as path from "path";
-import rewire = require("rewire");
-import vscode = require("vscode");
-import utils = require("../utils");
-import { sleep } from "../../src/utils";
-
-// Setup function that is not exported.
-const customViews = rewire("../../src/features/RunCode");
-const createLaunchConfig = customViews.__get__("createLaunchConfig");
-
-enum LaunchType {
-    Debug,
-    Run,
-}
-
-describe("RunCode feature", function () {
-    before(utils.ensureEditorServicesIsConnected);
-
-    it("Creates the launch config", function () {
-        const commandToRun: string = "Invoke-Build";
-        const args: string[] = ["Clean"];
-
-        const expected: object = {
-            request: "launch",
-            type: "PowerShell",
-            name: "PowerShell Run Code",
-            script: commandToRun,
-            args,
-            internalConsoleOptions: "neverOpen",
-            noDebug: false,
-            createTemporaryIntegratedConsole: false,
-            cwd: vscode.workspace.rootPath,
-        };
-
-        const actual: object = createLaunchConfig(LaunchType.Debug, commandToRun, args);
-
-        assert.deepStrictEqual(actual, expected);
-    });
-
-    it("Runs Pester tests from a file", async function () {
-        const pesterTests = path.resolve(__dirname, "../../../examples/Tests/SampleModule.Tests.ps1");
-        assert(fs.existsSync(pesterTests));
-
-        // Open the PowerShell file with Pester tests and then wait a while for
-        // the extension to finish connecting to the server.
-        await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(pesterTests));
-
-        // Now run the Pester tests, check the debugger started, wait a bit for
-        // it to run, and then kill it for safety's sake.
-        assert(await vscode.commands.executeCommand("PowerShell.RunPesterTestsFromFile"));
-        assert(vscode.debug.activeDebugSession !== undefined);
-        await vscode.debug.stopDebugging();
-    });
-});
diff --git a/test/features/UpdatePowerShell.test.ts b/test/features/UpdatePowerShell.test.ts
index 3dacaf1793..ef5049b43e 100644
--- a/test/features/UpdatePowerShell.test.ts
+++ b/test/features/UpdatePowerShell.test.ts
@@ -1,27 +1,136 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-import * as assert from "assert";
-import { GitHubReleaseInformation } from "../../src/features/UpdatePowerShell";
+import assert from "assert";
+import { UpdatePowerShell } from "../../src/features/UpdatePowerShell";
+import type { IPowerShellVersionDetails } from "../../src/session";
+import { Settings } from "../../src/settings";
+import { testLogger } from "../utils";
 
 describe("UpdatePowerShell feature", function () {
+    let currentUpdateSetting: string | undefined;
+    const settings = new Settings();
+
     before(function () {
-        // NOTE: GitHub API is rate limited in CI
-        if (process.env.TF_BUILD) { this.skip(); }
+        currentUpdateSetting = process.env.POWERSHELL_UPDATECHECK;
+    });
+
+    beforeEach(function () {
+        settings.promptToUpdatePowerShell = true;
+        process.env.POWERSHELL_UPDATECHECK = "Default";
     });
 
-    it("Gets the latest version", async function () {
-        const release: GitHubReleaseInformation = await GitHubReleaseInformation.FetchLatestRelease(false);
-        assert.strictEqual(release.isPreview, false, "expected to not be preview.");
-        assert.strictEqual(
-            release.version.prerelease.length === 0, true, "expected to not have preview in version.");
-        assert.strictEqual(release.assets.length > 0, true, "expected to have assets.");
+    after(function () {
+        process.env.POWERSHELL_UPDATECHECK = currentUpdateSetting;
     });
 
-    it("Gets the latest preview version", async function () {
-        const release: GitHubReleaseInformation = await GitHubReleaseInformation.FetchLatestRelease(true);
-        assert.strictEqual(release.isPreview, true, "expected to be preview.");
-        assert.strictEqual(release.version.prerelease.length > 0, true, "expected to have preview in version.");
-        assert.strictEqual(release.assets.length > 0, true, "expected to have assets.");
+    describe("When it should check for an update", function () {
+        it("Won't check if 'promptToUpdatePowerShell' is false", function () {
+            settings.promptToUpdatePowerShell = false;
+            const version: IPowerShellVersionDetails = {
+                version: "7.3.0",
+                edition: "Core",
+                commit: "7.3.0",
+                architecture: "X64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            assert(!updater.shouldCheckForUpdate());
+        });
+
+        it("Won't check for Windows PowerShell", function () {
+            const version: IPowerShellVersionDetails = {
+                version: "5.1.22621",
+                edition: "Desktop",
+                commit: "5.1.22621",
+                architecture: "X64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            assert(!updater.shouldCheckForUpdate());
+        });
+
+        it("Won't check for a development build of PowerShell", function () {
+            const version: IPowerShellVersionDetails = {
+                version: "7.3.0-preview.3",
+                edition: "Core",
+                commit: "7.3.0-preview.3-508-g07175ae0ff8eb7306fe0b0fc7d19bdef4fbf2d67",
+                architecture: "Arm64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            assert(!updater.shouldCheckForUpdate());
+        });
+
+        it("Won't check for a daily build of PowerShell", function () {
+            const version: IPowerShellVersionDetails = {
+                version: "7.3.0-daily20221206.1",
+                edition: "Core",
+                commit: "7.3.0-daily20221206.1",
+                architecture: "Arm64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            assert(!updater.shouldCheckForUpdate());
+        });
+
+        it("Won't check if POWERSHELL_UPDATECHECK is 'Off'", function () {
+            process.env.POWERSHELL_UPDATECHECK = "Off";
+            const version: IPowerShellVersionDetails = {
+                version: "7.3.0",
+                edition: "Core",
+                commit: "7.3.0",
+                architecture: "X64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            assert(!updater.shouldCheckForUpdate());
+        });
+
+        it("Should otherwise check to update PowerShell", function () {
+            const version: IPowerShellVersionDetails = {
+                version: "7.3.0",
+                edition: "Core",
+                commit: "7.3.0",
+                architecture: "X64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            assert(updater.shouldCheckForUpdate());
+        });
+    });
+
+    describe("Which version it gets", function () {
+        it("Would update to LTS", async function () {
+            process.env.POWERSHELL_UPDATECHECK = "LTS";
+            const version: IPowerShellVersionDetails = {
+                version: "7.2.0",
+                edition: "Core",
+                commit: "7.2.0",
+                architecture: "X64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            const tag: string = (await updater.maybeGetNewRelease()) ?? "";
+            // NOTE: This will need to be updated each time an LTS is released.
+            // Also sometimes the prior LTS is more recently updated than the latest LTS.
+            assert(tag.startsWith("v7.4"));
+        });
+
+        it("Would update to stable", async function () {
+            const version: IPowerShellVersionDetails = {
+                version: "7.3.0",
+                edition: "Core",
+                commit: "7.3.0",
+                architecture: "X64",
+            };
+            const updater = new UpdatePowerShell(settings, testLogger, version);
+            // @ts-expect-error method is private.
+            const tag: string | undefined = await updater.maybeGetNewRelease();
+            // NOTE: This will need to be updated each new major stable.
+            // TODO: Upstream bug causes LTS releases to update the stable info.
+            // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+            assert(tag?.startsWith("v7.5") || tag?.startsWith("v7.4"));
+        });
     });
 });
diff --git a/test/index.ts b/test/index.ts
deleted file mode 100644
index dd3954019c..0000000000
--- a/test/index.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-// NOTE: This code is borrowed under permission from:
-// https://github.com/microsoft/vscode-extension-samples/tree/main/helloworld-test-sample/src/test
-
-import * as path from "path";
-import * as Mocha from "mocha";
-import * as glob from "glob";
-
-export function run(): Promise<void> {
-    // Create the mocha test
-    const mocha = new Mocha({
-        color: !process.env.TF_BUILD, // colored output from test results
-        reporter: "mocha-multi-reporters",
-        timeout: 30000, // 30s because PowerShell startup is slow!
-        reporterOptions: {
-            // NOTE: The XML output by Mocha's xUnit reporter is actually in the
-            // JUnit style. I'm unsure how no one else has noticed this.
-            reporterEnabled: "spec, xunit",
-            xunitReporterOptions: {
-                output: path.join(__dirname, "..", "..", "test-results.xml"),
-            }
-        },
-    });
-
-    return new Promise((c, e) => {
-        glob("**/**.test.js", { cwd: __dirname }, (err, files) => {
-            if (err) {
-                return e(err);
-            }
-
-            // Add files to the test suite
-            files.forEach(f => mocha.addFile(path.resolve(__dirname, f)));
-
-            try {
-                // Run the mocha test
-                mocha.run(failures => {
-                    if (failures > 0) {
-                        e(new Error(`${failures} tests failed.`));
-                    } else {
-                        c();
-                    }
-                });
-            } catch (err) {
-                // tslint:disable-next-line:no-console
-                console.error(err);
-                e(err);
-            }
-        });
-    });
-}
diff --git a/test/mocks/BinaryModule/BinaryModule.csproj b/test/mocks/BinaryModule/BinaryModule.csproj
new file mode 100644
index 0000000000..5f9e3d340d
--- /dev/null
+++ b/test/mocks/BinaryModule/BinaryModule.csproj
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+        <TargetFramework>netstandard2.0</TargetFramework>
+        <AssemblyName>BinaryModule</AssemblyName>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="PowerShellStandard.Library">
+        <PrivateAssets>All</PrivateAssets>
+        </PackageReference>
+    </ItemGroup>
+</Project>
diff --git a/test/mocks/BinaryModule/BinaryModuleTest.ps1 b/test/mocks/BinaryModule/BinaryModuleTest.ps1
new file mode 100644
index 0000000000..8954566517
--- /dev/null
+++ b/test/mocks/BinaryModule/BinaryModuleTest.ps1
@@ -0,0 +1,2 @@
+Import-Module $PSScriptRoot\bin\Debug\netstandard2.0\BinaryModule.dll
+Test-SampleCmdlet
diff --git a/test/mocks/BinaryModule/TestSampleCmdletCommand.cs b/test/mocks/BinaryModule/TestSampleCmdletCommand.cs
new file mode 100644
index 0000000000..039f6c1e6c
--- /dev/null
+++ b/test/mocks/BinaryModule/TestSampleCmdletCommand.cs
@@ -0,0 +1,49 @@
+﻿using System.Management.Automation;
+
+namespace BinaryModule
+{
+    [Cmdlet(VerbsDiagnostic.Test, "SampleCmdlet")]
+    [OutputType(typeof(FavoriteStuff))]
+    public class TestSampleCmdletCommand : PSCmdlet
+    {
+        [Parameter(
+            Position = 0,
+            ValueFromPipeline = true,
+            ValueFromPipelineByPropertyName = true)]
+        public int FavoriteNumber { get; set; } = 42;
+
+        [Parameter(
+            Position = 1,
+            ValueFromPipelineByPropertyName = true)]
+        [ValidateSet("Cat", "Dog", "Horse")]
+        public string FavoritePet { get; set; } = "Dog";
+
+        // This method gets called once for each cmdlet in the pipeline when the pipeline starts executing
+        protected override void BeginProcessing()
+        {
+            WriteVerbose("Begin!");
+        }
+
+        // This method will be called for each input received from the pipeline to this cmdlet; if no input is received, this method is not called
+        protected override void ProcessRecord()
+        {
+            WriteObject(new FavoriteStuff
+            {
+                FavoriteNumber = FavoriteNumber,
+                FavoritePet = FavoritePet
+            });
+        }
+
+        // This method will be called once at the end of pipeline execution; if no input is received, this method is not called
+        protected override void EndProcessing()
+        {
+            WriteVerbose("End!");
+        }
+    }
+
+    public class FavoriteStuff
+    {
+        public int FavoriteNumber { get; set; }
+        public string FavoritePet { get; set; }
+    }
+}
diff --git a/test/mocks/BinaryModule/nuget.config b/test/mocks/BinaryModule/nuget.config
new file mode 100644
index 0000000000..f003b0fbd5
--- /dev/null
+++ b/test/mocks/BinaryModule/nuget.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <packageSources>
+    <clear />
+    <add key="PowerShellCore_PublicPackages" value="https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/powershell/nuget/v3/index.json" />
+  </packageSources>
+</configuration>
diff --git a/test/runTests.ts b/test/runTests.ts
deleted file mode 100644
index b449ae7cc4..0000000000
--- a/test/runTests.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-// NOTE: This code is borrowed under permission from:
-// https://github.com/microsoft/vscode-extension-samples/tree/main/helloworld-test-sample/src/test
-
-import * as path from "path";
-
-import { runTests } from "@vscode/test-electron";
-
-async function main() {
-    try {
-        // The folder containing the Extension Manifest package.json
-        // Passed to `--extensionDevelopmentPath`
-        const extensionDevelopmentPath = path.resolve(__dirname, "../../");
-
-        // The path to the extension test script
-        // Passed to --extensionTestsPath
-        const extensionTestsPath = path.resolve(__dirname, "./index");
-
-        // Download VS Code, unzip it and run the integration test
-        await runTests({
-            extensionDevelopmentPath,
-            extensionTestsPath,
-            launchArgs: ["--disable-extensions", "./test"],
-            // This is necessary because the tests fail if more than once
-            // instance of Code is running.
-            version: "insiders"
-        });
-    } catch (err) {
-        // tslint:disable-next-line:no-console
-        console.error(`Failed to run tests: ${err}`);
-        process.exit(1);
-    }
-}
-
-main();
diff --git a/test/utils.ts b/test/utils.ts
index c9710b5b71..aef25f0e64 100644
--- a/test/utils.ts
+++ b/test/utils.ts
@@ -1,29 +1,131 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-"use strict";
-
+import { execSync } from "child_process";
 import * as path from "path";
 import * as vscode from "vscode";
-import { IPowerShellExtensionClient } from "../src/features/ExternalApi";
+import type { IPowerShellExtensionClient } from "../src/features/ExternalApi";
+import type { ILogger } from "../src/logging";
+import { sleep } from "../src/utils";
 
 // This lets us test the rest of our path assumptions against the baseline of
-// this test file existing at `<root>/out/test/utils.js`.
-export const rootPath = path.resolve(__dirname, "../../")
-// tslint:disable-next-line: no-var-requires
-const packageJSON: any = require(path.resolve(rootPath, "package.json"));
-export const extensionId = `${packageJSON.publisher}.${packageJSON.name}`;
-
-export async function ensureExtensionIsActivated(): Promise<vscode.Extension<any>> {
-    const extension = vscode.extensions.getExtension(extensionId);
-    if (!extension.isActive) { await extension.activate(); }
+// this test file existing at `<root>/test/utils.js`.
+import { name, publisher } from "../package.json";
+export const extensionId = `${publisher}.${name}`;
+
+export class TestLogger implements ILogger {
+    logDirectoryPath: vscode.Uri = vscode.Uri.file("");
+    updateLogLevel(_logLevelName: string): void {
+        return;
+    }
+    write(_message: string, ..._additionalMessages: string[]): void {
+        return;
+    }
+    writeAndShowInformation(
+        _message: string,
+        ..._additionalMessages: string[]
+    ): Promise<void> {
+        return Promise.resolve();
+    }
+    writeTrace(_message: string, ..._additionalMessages: string[]): void {
+        return;
+    }
+    writeDebug(_message: string, ..._additionalMessages: string[]): void {
+        return;
+    }
+    writeWarning(_message: string, ..._additionalMessages: string[]): void {
+        return;
+    }
+    writeAndShowWarning(
+        _message: string,
+        ..._additionalMessages: string[]
+    ): Promise<void> {
+        return Promise.resolve();
+    }
+    writeError(_message: string, ..._additionalMessages: string[]): void {
+        return;
+    }
+    writeAndShowError(
+        _message: string,
+        ..._additionalMessages: string[]
+    ): Promise<void> {
+        return Promise.resolve();
+    }
+    writeAndShowErrorWithActions(
+        _message: string,
+        _actions: {
+            prompt: string;
+            action: (() => Promise<void>) | undefined;
+        }[],
+    ): Promise<void> {
+        return Promise.resolve();
+    }
+}
+
+export const testLogger = new TestLogger();
+
+export async function ensureExtensionIsActivated(): Promise<IPowerShellExtensionClient> {
+    let extension = vscode.extensions.getExtension(extensionId);
+    while (!extension) {
+        // Wait for VS Code to be ready
+        testLogger.writeDebug(`Extension ${extensionId} not yet found...`);
+        await sleep(200);
+        extension = vscode.extensions.getExtension(extensionId);
+        // Wait for VS Code to be ready
+        await sleep(200);
+    }
+    if (!extension.isActive) {
+        await extension.activate();
+    }
+    return extension.exports as IPowerShellExtensionClient;
+}
+
+export async function ensureEditorServicesIsConnected(): Promise<IPowerShellExtensionClient> {
+    const extension = await ensureExtensionIsActivated();
+    const sessionId = extension.registerExternalExtension(extensionId);
+    await extension.waitUntilStarted(sessionId);
+    extension.unregisterExternalExtension(sessionId);
     return extension;
 }
 
-export async function ensureEditorServicesIsConnected(): Promise<void> {
-    const powershellExtension = await ensureExtensionIsActivated();
-    const client = powershellExtension!.exports as IPowerShellExtensionClient;
-    const sessionId = client.registerExternalExtension(extensionId);
-    await client.waitUntilStarted(sessionId);
-    client.unregisterExternalExtension(sessionId);
+/**
+ * This is a workaround for sinon not being able to stub interfaces. Interfaces are a TypeScript-only concept so this effectively allows us to stub interfaces by not providing the entire implementation but only what matters for the test. "What matters" is not type checked so you must be careful to stub everything you need, otherwise you should provide a default implementation instead if you do not know.
+ */
+export function stubInterface<T>(object?: Partial<T>): T {
+    return object ? (object as T) : ({} as T);
+}
+
+/** Builds the sample binary module code. We need to do this because the source maps have absolute paths so they are not portable between machines, and while we could do deterministic with source maps, that's way more complicated and everywhere we build has dotnet already anyways */
+export function BuildBinaryModuleMock(): void {
+    const projectPath = path.resolve(
+        `${__dirname}/../test/mocks/BinaryModule/BinaryModule.csproj`,
+    );
+    try {
+        execSync(`dotnet publish ${projectPath}`, {
+            encoding: "utf8",
+        });
+    } catch (err) {
+        throw new Error(
+            `Failed to build the binary module mock. Please ensure that you have the .NET Core SDK installed: ${err}`,
+        );
+    }
+}
+
+/** Waits until the registered vscode event is fired and returns the trigger result of the event.
+ * @param event The event to wait for
+ * @param filter An optional filter to apply to the event TResult. The filter will continue to monitor the event firings until the filter returns true.
+ * @returns A promise that resolves when the specified event is fired with the TResult subject of the event. If a filter is specified, the promise will not resolve until the filter returns true.
+ */
+export function WaitEvent<TResult>(
+    event: vscode.Event<TResult>,
+    filter?: (event: TResult) => boolean | undefined,
+): Promise<TResult> {
+    return new Promise<TResult>((resolve) => {
+        const listener = event((result: TResult) => {
+            if (!filter || filter(result)) {
+                listener.dispose();
+                resolve(result);
+            }
+        });
+    });
 }
diff --git a/themes/theme-psise/theme.json b/themes/theme-psise/theme.json
index 44474a7289..fcf52d0067 100644
--- a/themes/theme-psise/theme.json
+++ b/themes/theme-psise/theme.json
@@ -1,211 +1,189 @@
 {
-    "name": "PowerShell ISE",
-    "semanticHighlighting": true,
-    "tokenColors": [{
-            "settings": {
-                "background": "#FFFFFF",
-                "foreground": "#000000"
-            }
-        },
-        {
-            "name": "Comments",
-            "scope": [
-                "comment",
-                "punctuation.definition.comment"
-            ],
-            "settings": {
-                "fontStyle": "italic",
-                "foreground": "#006400"
-            }
-        },
-        {
-            "name": "Comments: Preprocessor",
-            "scope": "comment.block.preprocessor",
-            "settings": {
-                "fontStyle": "",
-                "foreground": "#006400"
-            }
-        },
-        {
-            "name": "Comments: Documentation",
-            "scope": [
-                "comment.documentation",
-                "comment.block.documentation"
-            ],
-            "settings": {
-                "foreground": "#006400"
-            }
-        },
-        {
-            "name": "Invalid - Deprecated",
-            "scope": "invalid.deprecated",
-            "settings": {
-                "background": "#96000014"
-            }
-        },
-        {
-            "name": "Invalid - Illegal",
-            "scope": "invalid.illegal",
-            "settings": {
-                "background": "#96000014",
-                "foreground": "#660000"
-            }
-        },
-        {
-            "name": "Operators",
-            "scope": "keyword.operator",
-            "settings": {
-                "foreground": "#A9A9A9"
-            }
-        },
-        {
-            "name": "Keywords",
-            "scope": [
-                "keyword",
-                "storage"
-            ],
-            "settings": {
-                "foreground": "#00008B"
-            }
-        },
-        {
-            "name": "Types",
-            "scope": [
-                "storage.type",
-                "support.type"
-            ],
-            "settings": {
-                "foreground": "#00008B"
-            }
-        },
-        {
-            "name": "Language Constants",
-            "scope": [
-                "constant.language",
-                "support.constant",
-                "variable.language"
-            ],
-            "settings": {
-                "foreground": "#008080"
-            }
-        },
-        {
-            "name": "Keys and Properties",
-            "scope": [
-                "property",
-                "variable.other.property",
-                "variable.other.property.powershell"
-            ],
-            "settings": {
-                "foreground": "#2d2e45"
-            }
-        },
-        {
-            "name": "Variables",
-            "scope": [
-                "variable",
-                "support.variable",
-                "punctuation.definition.variable.powershell",
-                "variable.other.readwrite.powershell"
-            ],
-            "settings": {
-                "foreground": "#FF4500"
-            }
-        },
-        {
-            "name": "Functions",
-            "scope": [
-                "entity.name.function",
-                "support.function"
-            ],
-            "settings": {
-                "foreground": "#0000FF"
-            }
-        },
-        {
-            "name": "Classes",
-            "scope": [
-                "entity.name.type",
-                "entity.other.inherited-class",
-                "support.class"
-            ],
-            "settings": {
-                "foreground": "#7A3E9D"
-            }
-        },
-        {
-            "name": "Exceptions",
-            "scope": "entity.name.exception",
-            "settings": {
-                "foreground": "#660000"
-            }
-        },
-        {
-            "name": "Sections",
-            "scope": "entity.name.section",
-            "settings": {}
-        },
-        {
-            "name": "Numbers, Characters",
-            "scope": [
-                "constant.numeric",
-                "constant.character",
-                "constant"
-            ],
-            "settings": {
-                "foreground": "#800080"
-            }
-        },
-        {
-            "name": "Strings",
-            "scope": "string",
-            "settings": {
-                "foreground": "#8B0000"
-            }
-        },
-        {
-            "name": "Strings: Escape Sequences",
-            "scope": "constant.character.escape",
-            "settings": {
-                "foreground": "#8B0000"
-            }
-        },
-        {
-            "name": "Strings: Regular Expressions",
-            "scope": "string.regexp",
-            "settings": {
-                "foreground": "#8B0000"
-            }
-        },
-        {
-            "name": "Strings: Symbols",
-            "scope": "constant.other.symbol",
-            "settings": {
-                "foreground": "#8B0000"
-            }
-        },
-        {
-            "name": "Punctuation",
-            "scope": "punctuation",
-            "settings": {
-                "foreground": "#000000"
-            }
-        }
-    ],
-    "colors": {
-        "activityBar.background": "#E1ECF9",
-        "activityBar.foreground": "#A9A9A9",
-        "activityBarBadge.background": "#A9A9A9",
-        "editor.lineHighlightBackground": "#add8e6",
-        "editor.selectionBackground": "#94c6f7",
-        "settings.checkboxBorder": "#A9A9A9",
-        "settings.dropdownBorder": "#A9A9A9",
-        "settings.numberInputBorder": "#A9A9A9",
-        "settings.textInputBorder": "#A9A9A9",
-        "statusBar.background": "#999999",
-        "statusBar.debuggingBackground": "#FF4500",
-        "statusBar.noFolderBackground": "#999999",
-        "terminal.background": "#012456",
-        "terminal.foreground": "#F5F5F5"
+  "name": "PowerShell ISE",
+  "semanticHighlighting": true,
+  "tokenColors": [
+    {
+      "settings": {
+        "background": "#FFFFFF",
+        "foreground": "#000000"
+      }
+    },
+    {
+      "name": "Comments",
+      "scope": ["comment", "punctuation.definition.comment"],
+      "settings": {
+        "fontStyle": "italic",
+        "foreground": "#006400"
+      }
+    },
+    {
+      "name": "Comments: Preprocessor",
+      "scope": "comment.block.preprocessor",
+      "settings": {
+        "fontStyle": "",
+        "foreground": "#006400"
+      }
+    },
+    {
+      "name": "Comments: Documentation",
+      "scope": ["comment.documentation", "comment.block.documentation"],
+      "settings": {
+        "foreground": "#006400"
+      }
+    },
+    {
+      "name": "Invalid - Deprecated",
+      "scope": "invalid.deprecated",
+      "settings": {
+        "background": "#96000014"
+      }
+    },
+    {
+      "name": "Invalid - Illegal",
+      "scope": "invalid.illegal",
+      "settings": {
+        "background": "#96000014",
+        "foreground": "#660000"
+      }
+    },
+    {
+      "name": "Operators",
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#A9A9A9"
+      }
+    },
+    {
+      "name": "Keywords",
+      "scope": ["keyword", "storage"],
+      "settings": {
+        "foreground": "#00008B"
+      }
+    },
+    {
+      "name": "Types",
+      "scope": ["storage.type", "support.type"],
+      "settings": {
+        "foreground": "#00008B"
+      }
+    },
+    {
+      "name": "Language Constants",
+      "scope": ["constant.language", "support.constant", "variable.language"],
+      "settings": {
+        "foreground": "#008080"
+      }
+    },
+    {
+      "name": "Keys and Properties",
+      "scope": [
+        "property",
+        "variable.other.property",
+        "variable.other.property.powershell"
+      ],
+      "settings": {
+        "foreground": "#2d2e45"
+      }
+    },
+    {
+      "name": "Variables",
+      "scope": [
+        "variable",
+        "support.variable",
+        "punctuation.definition.variable.powershell",
+        "variable.other.readwrite.powershell"
+      ],
+      "settings": {
+        "foreground": "#FF4500"
+      }
+    },
+    {
+      "name": "Functions",
+      "scope": ["entity.name.function", "support.function"],
+      "settings": {
+        "foreground": "#0000FF"
+      }
+    },
+    {
+      "name": "Classes",
+      "scope": [
+        "entity.name.type",
+        "entity.other.inherited-class",
+        "support.class"
+      ],
+      "settings": {
+        "foreground": "#7A3E9D"
+      }
+    },
+    {
+      "name": "Exceptions",
+      "scope": "entity.name.exception",
+      "settings": {
+        "foreground": "#660000"
+      }
+    },
+    {
+      "name": "Sections",
+      "scope": "entity.name.section",
+      "settings": {}
+    },
+    {
+      "name": "Numbers, Characters",
+      "scope": ["constant.numeric", "constant.character", "constant"],
+      "settings": {
+        "foreground": "#800080"
+      }
+    },
+    {
+      "name": "Strings",
+      "scope": "string",
+      "settings": {
+        "foreground": "#8B0000"
+      }
+    },
+    {
+      "name": "Strings: Escape Sequences",
+      "scope": "constant.character.escape",
+      "settings": {
+        "foreground": "#8B0000"
+      }
+    },
+    {
+      "name": "Strings: Regular Expressions",
+      "scope": "string.regexp",
+      "settings": {
+        "foreground": "#8B0000"
+      }
+    },
+    {
+      "name": "Strings: Symbols",
+      "scope": "constant.other.symbol",
+      "settings": {
+        "foreground": "#8B0000"
+      }
+    },
+    {
+      "name": "Punctuation",
+      "scope": "punctuation",
+      "settings": {
+        "foreground": "#000000"
+      }
     }
-}
\ No newline at end of file
+  ],
+  "colors": {
+    "activityBar.background": "#E1ECF9",
+    "activityBar.foreground": "#A9A9A9",
+    "activityBarBadge.background": "#A9A9A9",
+    "editor.lineHighlightBackground": "#add8e6",
+    "editor.selectionBackground": "#94c6f7",
+    "settings.checkboxBorder": "#A9A9A9",
+    "settings.dropdownBorder": "#A9A9A9",
+    "settings.numberInputBorder": "#A9A9A9",
+    "settings.textInputBorder": "#A9A9A9",
+    "statusBar.background": "#999999",
+    "statusBar.debuggingBackground": "#FF4500",
+    "statusBar.noFolderBackground": "#999999",
+    "terminal.background": "#012456",
+    "terminal.foreground": "#F5F5F5"
+  }
+}
diff --git a/tools/ReleaseTools.psm1 b/tools/ReleaseTools.psm1
deleted file mode 100644
index 85ea6ca4a4..0000000000
--- a/tools/ReleaseTools.psm1
+++ /dev/null
@@ -1,497 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-
-#requires -Version 7.0
-
-using module PowerShellForGitHub
-using namespace System.Management.Automation
-
-class RepoNames: IValidateSetValuesGenerator {
-    # NOTE: This is super over-engineered, but it was fun.
-    static [string[]] $Values = "vscode-powershell", "PowerShellEditorServices"
-    [String[]] GetValidValues() { return [RepoNames]::Values }
-}
-
-$ChangelogFile = "CHANGELOG.md"
-
-<#
-.SYNOPSIS
-  Given the repository name, execute the script in its directory.
-#>
-function Use-Repository {
-    [CmdletBinding()]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName,
-
-        [Parameter(Mandatory)]
-        [scriptblock]$Script
-    )
-    try {
-        switch ($RepositoryName) {
-            "vscode-powershell" {
-                Push-Location -Path "$PSScriptRoot/../"
-            }
-            "PowerShellEditorServices" {
-                Push-Location -Path "$PSScriptRoot/../../PowerShellEditorServices"
-            }
-        }
-        & $Script
-    } finally {
-        Pop-Location
-    }
-}
-
-<#
-.SYNOPSIS
-  Given a collection of PRs, generates a bulleted list.
-#>
-function Get-Bullets {
-    [CmdletBinding()]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName,
-
-        [Parameter(Mandatory, ValueFromPipeline)]
-        [PSCustomObject[]]$PullRequests
-    )
-    begin {
-        $SkipThanks = @(
-            'andschwa'
-            'daxian-dbw'
-            'PaulHigin'
-            'rjmholt'
-            'SteveL-MSFT'
-            'TylerLeonhardt'
-        )
-
-        $IssueEmojis = @{
-            'Issue-Enhancement'         = '✨'
-            'Issue-Bug'                 = '🐛'
-            'Issue-Performance'         = '⚡️'
-        }
-
-        $AreaEmojis = @{
-            'Area-Build & Release'      = '👷'
-            'Area-Code Formatting'      = '💎'
-            'Area-Configuration'        = '🔧'
-            'Area-Debugging'            = '🔍'
-            'Area-Documentation'        = '📖'
-            'Area-Engine'               = '🚂'
-            'Area-Folding'              = '📚'
-            'Area-Integrated Console'   = '📟'
-            'Area-IntelliSense'         = '🧠'
-            'Area-Logging'              = '💭'
-            'Area-Pester'               = '🐢'
-            'Area-Script Analysis'      = '‍🕵️'
-            'Area-Snippets'             = '✂️'
-            'Area-Startup'              = '🛫'
-            'Area-Symbols & References' = '🔗'
-            'Area-Tasks'                = '✅'
-            'Area-Test'                 = '🚨'
-            'Area-Threading'            = '⏱️'
-            'Area-UI'                   = '📺'
-            'Area-Workspaces'           = '📁'
-        }
-
-        $CloseKeywords = @(
-            'close'
-            'closes'
-            'closed'
-            'fix'
-            'fixes'
-            'fixed'
-            'resolve'
-            'resolves'
-            'resolved'
-        )
-
-        # NOTE: The URL matcher must be explicit because the body of a PR may
-        # contain other URLs with digits (like an image asset).
-        $IssueRegex = '(' + ($CloseKeywords -join '|') + ')\s+((https://github.com/PowerShell/(?<repo>(' + ([RepoNames]::Values -join '|') + '))/issues/)|#)(?<number>\d+)'
-    }
-
-    process {
-        $PullRequests | ForEach-Object {
-            # Map all the labels to emoji (or use a default).
-            $labels = if ($_.labels) { $_.labels.LabelName } else { "" }
-            $issueEmoji = $IssueEmojis[$labels] + "#️⃣" | Select-Object -First 1
-            $areaEmoji = $AreaEmojis[$labels] + "🙏" | Select-Object -First 1
-
-            # Get a linked issue number if it exists (or use the PR).
-            $link = if ($_.body -match $IssueRegex) {
-                $number = $Matches.number
-                $repo = $Matches.repo
-                # Handle links to issues in both repos, in both shortcode and URLs.
-                $name = [RepoNames]::Values | Where-Object { $repo -match $_ } | Select-Object -First 1
-                "$($name ?? $RepositoryName) #$number"
-            } else {
-                "$RepositoryName #$($_.number)"
-            }
-
-            # Thank the contributor if they are not one of us.
-            $thanks = if ($_.user.UserName -notin $SkipThanks) {
-                "(Thanks @$($_.user.UserName)!)"
-            }
-
-            # Put the bullet point together.
-            ("-", $issueEmoji, $areaEmoji, "[$link]($($_.html_url))", "-", "$($_.title).", $thanks -join " ").Trim()
-        }
-    }
-}
-
-<#
-.SYNOPSIS
-  Gets the unpublished content from the changelog.
-.DESCRIPTION
-  This is used so that we can manually touch-up the automatically updated
-  changelog, and then bring its contents into the extension's changelog or
-  the GitHub release. It just gets the first header's contents.
-#>
-function Get-FirstChangelog {
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName
-    )
-    $Changelog = Use-Repository -RepositoryName $RepositoryName -Script {
-        Get-Content -Path $ChangelogFile
-    }
-    # NOTE: The space after the header marker is important! Otherwise ### matches.
-    $Header = $Changelog.Where({$_.StartsWith("## ")}, "First")
-    $Changelog.Where(
-        { $_ -eq $Header }, "SkipUntil"
-    ).Where(
-        { $_.StartsWith("## ") -and $_ -ne $Header }, "Until"
-    )
-}
-
-<#
-.SYNOPSIS
-  Creates and checks out `release` if not already on it.
-#>
-function Update-Branch {
-    [CmdletBinding(SupportsShouldProcess)]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName
-    )
-    Use-Repository -RepositoryName $RepositoryName -Script {
-        $Branch = git branch --show-current
-        if ($Branch -ne "release") {
-            if ($PSCmdlet.ShouldProcess("release", "git checkout -B")) {
-                git checkout -B "release"
-            }
-        }
-    }
-}
-
-<#
-.SYNOPSIS
-  Gets current version from changelog as `[semver]`.
-#>
-function Get-Version {
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName
-    )
-    # NOTE: The first line should always be the header.
-    $Changelog = (Get-FirstChangelog -RepositoryName $RepositoryName)[0]
-    if ($Changelog -match '## v(?<version>\d+\.\d+\.\d+(-preview\.?\d*)?)') {
-        return [semver]$Matches.version
-    } else {
-        Write-Error "Couldn't find version from changelog!"
-    }
-}
-
-<#
-.SYNOPSIS
-  Updates the CHANGELOG file with PRs merged since the last release.
-.DESCRIPTION
-  Uses the local Git repositories but does not pull, so ensure HEAD is where you
-  want it. Creates the branch `release` if not already checked out. Handles any
-  merge option for PRs, but is a little slow as it queries all PRs.
-#>
-function Update-Changelog {
-    [CmdletBinding(SupportsShouldProcess)]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName,
-
-        # TODO: Validate version style for each repo.
-        [Parameter(Mandatory)]
-        [ValidateScript({ $_.StartsWith("v") })]
-        [string]$Version
-    )
-
-    # Get the repo object, latest release, and commits since its tag.
-    $Repo = Get-GitHubRepository -OwnerName PowerShell -RepositoryName $RepositoryName
-    $Commits = Use-Repository -RepositoryName $RepositoryName -Script {
-        git rev-list "v$(Get-Version -RepositoryName $RepositoryName)..."
-    }
-
-    # NOTE: This is a slow API as it gets all PRs, and then filters.
-    $Bullets = $Repo | Get-GitHubPullRequest -State All |
-        Where-Object { $_.merge_commit_sha -in $Commits } |
-        Where-Object { -not $_.user.UserName.EndsWith("[bot]") } |
-        Where-Object { "Ignore" -notin $_.labels.LabelName } |
-        Where-Object { -not $_.title.StartsWith("[Ignore]") } |
-        Where-Object { -not $_.title.StartsWith("Release ``v") } |
-        Get-Bullets -RepositoryName $RepositoryName
-
-    $NewSection = switch ($RepositoryName) {
-        "vscode-powershell" {
-            @(
-                "#### [vscode-powershell](https://github.com/PowerShell/vscode-powershell)"
-                ""
-                $Bullets
-                ""
-                "#### [PowerShellEditorServices](https://github.com/PowerShell/PowerShellEditorServices)"
-                ""
-                (Get-FirstChangelog -RepositoryName "PowerShellEditorServices").Where({ $_.StartsWith("- ") }, "SkipUntil")
-            )
-        }
-        "PowerShellEditorServices" {
-            @($Bullets, "")
-        }
-    }
-
-    Update-Branch -RepositoryName $RepositoryName
-
-    Use-Repository -RepositoryName $RepositoryName -Script {
-        $CurrentChangelog = Get-Content -Path $ChangelogFile
-        @(
-            $CurrentChangelog[0..1]
-            "## $Version"
-            "### $([datetime]::Now.ToString('dddd, MMMM dd, yyyy'))"
-            ""
-            $NewSection
-            $CurrentChangelog[2..$CurrentChangelog.Length]
-        ) | Set-Content -Encoding utf8NoBOM -Path $ChangelogFile
-
-        if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git commit")) {
-            git add $ChangelogFile
-            git commit -m "Update CHANGELOG for ``$Version``"
-        }
-    }
-}
-
-<#
-.SYNOPSIS
-  Updates version in repository.
-.DESCRIPTION
-  Note that our Git tags and changelog prefix all versions with `v`.
-
-  PowerShellEditorServices: version is `X.Y.Z-preview`
-
-  - PowerShellEditorServices.psd1:
-    - `ModuleVersion` variable with `'X.Y.Z'` string, no pre-release info
-  - PowerShellEditorServices.Common.props:
-    - `VersionPrefix` field with `X.Y.Z`
-    - `VersionSuffix` field with pre-release portion excluding hyphen
-
-  vscode-powershell: version is `YYYY.M.X-preview`
-
-  - package.json:
-    - `version` field with `"X.Y.Z"` and no prefix or suffix
-    - `preview` field set to `true` or `false` if version is a preview
-    - `name` field has `-preview` appended similarly
-    - `displayName` field has ` Preview` appended similarly
-    - `description` field has `(Preview) ` prepended similarly
-    - `icon` field has `_Preview ` inserted similarly
-#>
-function Update-Version {
-    [CmdletBinding(SupportsShouldProcess)]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName
-    )
-    $Version = Get-Version -RepositoryName $RepositoryName
-    $v = "$($Version.Major).$($Version.Minor).$($Version.Patch)"
-
-    Update-Branch -RepositoryName $RepositoryName
-
-    # TODO: Maybe cleanup the replacement logic.
-    Use-Repository -RepositoryName $RepositoryName -Script {
-        switch ($RepositoryName) {
-            "vscode-powershell" {
-                $d = "Develop PowerShell modules, commands and scripts in Visual Studio Code!"
-                if ($Version.PreReleaseLabel) {
-                    $name = "powershell-preview"
-                    $displayName = "PowerShell Preview"
-                    $preview = "true"
-                    $description = "(Preview) $d"
-                    $icon = "media/PowerShell_Preview_Icon.png"
-                } else {
-                    $name = "powershell"
-                    $displayName = "PowerShell"
-                    $preview = "false"
-                    $description = $d
-                    $icon = "media/PowerShell_Icon.png"
-                }
-
-                $path = "package.json"
-                $f = Get-Content -Path $path
-                # NOTE: The prefix regex match two spaces exactly to avoid matching
-                # nested objects in the file.
-                $f = $f -replace '^(?<prefix>  "name":\s+")(.+)(?<suffix>",)$', "`${prefix}${name}`${suffix}"
-                $f = $f -replace '^(?<prefix>  "displayName":\s+")(.+)(?<suffix>",)$', "`${prefix}${displayName}`${suffix}"
-                $f = $f -replace '^(?<prefix>  "version":\s+")(.+)(?<suffix>",)$', "`${prefix}${v}`${suffix}"
-                $f = $f -replace '^(?<prefix>  "preview":\s+)(.+)(?<suffix>,)$', "`${prefix}${preview}`${suffix}"
-                $f = $f -replace '^(?<prefix>  "description":\s+")(.+)(?<suffix>",)$', "`${prefix}${description}`${suffix}"
-                $f = $f -replace '^(?<prefix>  "icon":\s+")(.+)(?<suffix>",)$', "`${prefix}${icon}`${suffix}"
-                $f | Set-Content -Path $path
-                git add $path
-            }
-            "PowerShellEditorServices" {
-                $path = "PowerShellEditorServices.Common.props"
-                $f = Get-Content -Path $path
-                $f = $f -replace '^(?<prefix>\s+<VersionPrefix>)(.+)(?<suffix></VersionPrefix>)$', "`${prefix}${v}`${suffix}"
-                $f = $f -replace '^(?<prefix>\s+<VersionSuffix>)(.*)(?<suffix></VersionSuffix>)$', "`${prefix}$($Version.PreReleaseLabel)`${suffix}"
-                $f | Set-Content -Path $path
-                git add $path
-
-                $path = "module/PowerShellEditorServices/PowerShellEditorServices.psd1"
-                $f = Get-Content -Path $path
-                $f = $f -replace "^(?<prefix>ModuleVersion = ')(.+)(?<suffix>')`$", "`${prefix}${v}`${suffix}"
-                $f | Set-Content -Path $path
-                git add $path
-            }
-        }
-
-        if ($PSCmdlet.ShouldProcess("$RepositoryName/v$Version", "git commit")) {
-            git commit -m "Bump version to ``v$Version``"
-        } # TODO: Git reset to unstage
-    }
-}
-
-<#
-.SYNOPSIS
-  Creates a new draft GitHub PR from the release branch.
-.DESCRIPTION
-  Pushes the release branch to `origin` and then opens a draft PR.
-#>
-function New-ReleasePR {
-    [CmdletBinding(SupportsShouldProcess)]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName
-    )
-    $Version = Get-Version -RepositoryName $RepositoryName
-
-    Update-Branch -RepositoryName $RepositoryName
-    Use-Repository -RepositoryName $RepositoryName -Script {
-        if ($PSCmdlet.ShouldProcess("$RepositoryName/release", "git push")) {
-            Write-Host "Pushing release branch..."
-            git push --set-upstream --force-with-lease origin release
-        }
-    }
-
-    $Repo = Get-GitHubRepository -OwnerName PowerShell -RepositoryName $RepositoryName
-
-    $Params = @{
-        Head  = "release"
-        Base  = "master"
-        Draft = $true
-        Title = "Release ``v$Version``"
-        Body  = "Automated PR for new release!"
-        # TODO: Fix passing Confirm/WhatIf (again)
-    }
-
-    $PR = $Repo | New-GitHubPullRequest @Params
-    Write-Host "Draft PR URL: $($PR.html_url)"
-
-    # NOTE: The API is weird. According to GitHub, all PRs are Issues, so this
-    # works, but the module doesn't support it as easily as it could.
-    $Repo | Add-GitHubIssueLabel -Issue $PR.PullRequestNumber -LabelName "Ignore"
-}
-
-<#
-.SYNOPSIS
-  Kicks off the whole release process.
-.DESCRIPTION
-  This first updates the changelog (which creates and checks out the `release`
-  branch), commits the changes, updates the version (and commits), pushes the
-  branch, and then creates a GitHub PR for the release for both repositories.
-
-  This is the function meant to be called by a maintainer as the first manual
-  step to creating a release: it calls the correct functions in order to prepare
-  the release. Each repository's release branch then needs to be pushed to the
-  internal Azure DevOps mirror, at which point the automatic release pipeline
-  will build and sign the assets, and queue up draft GitHub releases (using
-  `New-DraftRelease` below). Those releases need to be manually validated and
-  approved, and finally the last step is to approve the pipeline to publish the
-  assets to the marketplace and gallery.
-#>
-function New-Release {
-    [CmdletBinding(SupportsShouldProcess)]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateScript({ $_.StartsWith("v") })]
-        [string]$PsesVersion,
-
-        [Parameter(Mandatory)]
-        [ValidateScript({ $_.StartsWith("v") })]
-        [string]$VsceVersion
-    )
-    "PowerShellEditorServices", "vscode-powershell" | ForEach-Object {
-        $Version = switch ($_) {
-            "PowerShellEditorServices" { $PsesVersion }
-            "vscode-powershell" { $VsceVersion }
-        }
-        Update-Changelog -RepositoryName $_ -Version $Version
-        Update-Version -RepositoryName $_
-        New-ReleasePR -RepositoryName $_
-    }
-}
-
-<#
-.SYNOPSIS
-  Creates a new draft GitHub release and Git tag from the updated changelog.
-.DESCRIPTION
-  Requires that the changelog has been updated first as it pulls the release
-  content and new version number from it. Note that our tags and version name
-  are prefixed with a `v`. Creates a Git tag if it does not already exist.
-#>
-function New-DraftRelease {
-    [CmdletBinding(SupportsShouldProcess)]
-    param(
-        [Parameter(Mandatory)]
-        [ValidateSet([RepoNames])]
-        [string]$RepositoryName,
-
-        [Parameter()]
-        [string[]]$Assets
-    )
-    $Version = Get-Version -RepositoryName $RepositoryName
-    $Changelog = (Get-FirstChangelog -RepositoryName $RepositoryName) -join "`n"
-    $ReleaseParams = @{
-        # NOTE: We rely on GitHub to create the tag at that branch.
-        Tag            = "v$Version"
-        Committish     = "release"
-        Name           = "v$Version"
-        Body           = $ChangeLog
-        Draft          = $true
-        PreRelease     = [bool]$Version.PreReleaseLabel
-        OwnerName      = "PowerShell"
-        RepositoryName = $RepositoryName
-        # TODO: Fix passing Confirm/WhatIf (again)
-    }
-
-    $Release = New-GitHubRelease @ReleaseParams
-    if ($Release) {
-        Write-Host "Draft release URL: $($Release.html_url)"
-        # NOTE: We must loop around `New-GitHubReleaseAsset` so we can pipe
-        # `$Release` or it can fail to find the newly created release by its ID
-        # (probably a race condition).
-        Write-Host "Uploading assets..."
-        $Assets | ForEach-Object { $Release | New-GitHubReleaseAsset -Path $_ }
-    }
-}
diff --git a/tools/credScan/suppress.json b/tools/credScan/suppress.json
deleted file mode 100644
index f4f3ff9157..0000000000
--- a/tools/credScan/suppress.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "tool": "Credential Scanner",
-  "suppressions": [
-    {
-      "folder": "node_modules",
-      "_justification": "Third-party code must not be scanned"
-    },
-    {
-      "folder": "PSScriptAnalyzer",
-      "_justification": "Bundled upstream project with false-positives"
-    }
-  ]
-}
diff --git a/tools/installPSResources.ps1 b/tools/installPSResources.ps1
new file mode 100644
index 0000000000..3bb642aced
--- /dev/null
+++ b/tools/installPSResources.ps1
@@ -0,0 +1,24 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+param(
+    [ValidateSet("PSGallery", "CFS")]
+    [string]$PSRepository = "PSGallery"
+)
+
+if ($PSRepository -eq "CFS" -and -not (Get-PSResourceRepository -Name CFS -ErrorAction SilentlyContinue)) {
+    Register-PSResourceRepository -Name CFS -Uri "https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/PowerShellGalleryMirror/nuget/v3/index.json"
+}
+
+# NOTE: Due to a bug in Install-PSResource with upstream feeds, we have to
+# request an exact version. Otherwise, if a newer version is available in the
+# upstream feed, it will fail to install any version at all.
+Install-PSResource -Verbose -TrustRepository -RequiredResource  @{
+    InvokeBuild = @{
+        version = "5.12.1"
+        repository = $PSRepository
+      }
+    platyPS = @{
+        version = "0.14.2"
+        repository = $PSRepository
+    }
+}
diff --git a/tools/setupReleaseTools.ps1 b/tools/setupReleaseTools.ps1
deleted file mode 100644
index 6a57a9fc6c..0000000000
--- a/tools/setupReleaseTools.ps1
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-
-param(
-    [Parameter(Mandatory)]
-    [string]$Token
-)
-
-Write-Host "Install and import PowerShell modules"
-Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | Out-Null
-Install-Module -Name PowerShellForGitHub -Scope CurrentUser -Force
-Import-Module $PSScriptRoot/ReleaseTools.psm1
-
-Write-Host "Setup authentication"
-Set-GitHubConfiguration -SuppressTelemetryReminder
-$password = ConvertTo-SecureString -String $Token -AsPlainText -Force
-Set-GitHubAuthentication -Credential (New-Object System.Management.Automation.PSCredential ("token", $password))
diff --git a/tools/terms/FileTypeSet.xml b/tools/terms/FileTypeSet.xml
deleted file mode 100644
index 82f9f4d09e..0000000000
--- a/tools/terms/FileTypeSet.xml
+++ /dev/null
@@ -1,379 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xmldata>
-    <PckFileTypes TotalTypes="35" TotalExts="198" UnsupportedFilesOnly="False">
-        <Type ID="0" Check="1">
-            <Name>Pure Text Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.txt</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.des</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pwd</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.asm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cmd</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ini</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.poc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pwt</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hpj</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sql</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.inf</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.log</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.def</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.url</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.bat</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.aspx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.idl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sys</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.resources</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.strings</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.md</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.yml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.yaml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.spelling</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.gitignore</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.gitattributes</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.gitmodules</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.csv</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.tsv</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="1" Check="1">
-            <Name>CodeFiles</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.frm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.inc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cpp</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cls</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.c</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hpp</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vbs</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.java</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cs</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cxx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.h</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.jav</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.bas</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.js</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.rc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.json</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.resjson</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fs</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fsi</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fsx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.m</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.psm1</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.config</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ps1</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.psd1</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cmake</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sh</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cshtml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.plist</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mof</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mc</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="2" Check="1">
-            <Name>XML Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxa</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxk</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xsl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxt</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.resx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxe</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxf</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxv</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.acctb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accfl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xaml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ttml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ddue</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.sln</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.props</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ps1xml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.csproj</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xsd</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.svg</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.clixml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.nuspec</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cdxml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.manifest</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="3" Check="1">
-            <Name>Microsoft Word Documents</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.doc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dot</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.wiz</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="4" Check="1">
-            <Name>Microsoft Access Database Compatible</Name>
-            <Extensions>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.mdb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mda</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mde</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mpd</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mdt</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="5" Check="1">
-            <Name>Microsoft PowerPoint Presentation</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppt</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pot</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pps</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="6" Check="1">
-            <Name>Microsoft Publisher Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pub</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="7" Check="1">
-            <Name>Microsoft Excel Workbooks</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xls</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlt</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="8" Check="1">
-            <Name>Pure Binary Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.com</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.bin</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.tlb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.drv</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.fon</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.blg</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.gif</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.png</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.icns</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.ico</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.bmp</Ext>
-                <Ext Check="0" UseCustomParser="0" DllPath="" ClassName="">.pfx</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="9" Check="1">
-            <Name>Localization resource databases</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.edb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.lcl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlf</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xliff</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="10" Check="1">
-            <Name>Microsoft Project Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mpp</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mpt</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="11" Check="1">
-            <Name>Microsoft Visio Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vsd</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vdx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vss</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vst</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="12" Check="1">
-            <Name>Windows Installer databases</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.msi</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.msm</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="13" Check="1">
-            <Name>Zip Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.zip</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accdt</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.axtr</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="14" Check="1">
-            <Name>Cabinet / MS Compression Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cab</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="15" Check="1">
-            <Name>Table driven IME lexicons</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mb</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="16" Check="1">
-            <Name>IME ( IMD ) Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.imd</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="17" Check="1">
-            <Name>TrueType Font Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ttf</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="18" Check="1">
-            <Name>Microsoft Outlook Mail Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.msg</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.oft</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="19" Check="1">
-            <Name>HTML Help 2.0 Files / InfoTech5.x Storage System Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.its</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxh</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxr</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxw</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxi</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxs</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hxq</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="20" Check="1">
-            <Name>Adobe Acrobat PDF Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pdf</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="21" Check="1">
-            <Name>HTML Files / Web Page</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dtd</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hhk</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htw</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.asp</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.htx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.html</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.hhc</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.css</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.stm</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="22" Check="1">
-            <Name>Rich Text Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.rtf</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="23" Check="1">
-            <Name>Windows 3.x Write Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.wri</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="24" Check="1">
-            <Name>MHTML Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.eml</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.nws</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mht</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="25" Check="1">
-            <Name>Word 2007 Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.docx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.docm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dotx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dotm</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="26" Check="1">
-            <Name>Excel 2007 Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlsx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlsm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xltx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xltm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlsb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.xlam</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="27" Check="1">
-            <Name>Power Point 2007 Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pptx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.pptm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.potx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.potm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppsx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppsm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ppam</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="28" Check="1">
-            <Name>Access 2007 Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accdb</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accde</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.accdr</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="29" Check="1">
-            <Name>Win32/64-based executable (image) Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.exe</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.dll</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ocx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.scr</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.acm</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.rll</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.cpl</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.mui</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ax</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.ime</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="30" Check="1">
-            <Name>HTML Help 1.0 Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.chm</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="31" Check="1">
-            <Name>LocStudio lsg</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.lsg</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="32" Check="1">
-            <Name>Microsoft Office OneNote Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.one</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.onepkg</Ext>
-            </Extensions>
-        </Type>
-        <Type ID="33" Check="1">
-            <Name>Custom Parsers</Name>
-            <Extensions>
-            </Extensions>
-        </Type>
-        <Type ID="34" Check="1">
-            <Name>Visio 2011 Files</Name>
-            <Extensions>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vstx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vsdx</Ext>
-                <Ext Check="1" UseCustomParser="0" DllPath="" ClassName="">.vssx</Ext>
-            </Extensions>
-        </Type>
-
-    </PckFileTypes>
-</xmldata>
diff --git a/tools/terms/UserExclusions.xml b/tools/terms/UserExclusions.xml
deleted file mode 100644
index e0e9d1be89..0000000000
--- a/tools/terms/UserExclusions.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<PoliCheckExclusions>
-  <!-- All strings must be UPPER CASE -->
-  <!--Each of these exclusions is a folder name -if \[name]\exists in the file path, it will be skipped -->
-  <!--<Exclusion Type="FolderPathFull">ABC|XYZ</Exclusion>-->
-  <Exclusion Type="FolderPathFull">.GIT|NODE_MODULES</Exclusion>
-  <!--Each of these exclusions is a folder name -if any folder or file starts with "\[name]", it will be skipped -->
-  <!--<Exclusion Type="FolderPathStart">ABC|XYZ</Exclusion>-->
-  <!--Each of these file types will be completely skipped for the entire scan -->
-  <!--<Exclusion Type="FileType">.ABC|.XYZ</Exclusion>-->
-  <!--The specified file names will be skipped during the scan regardless which folder they are in -->
-  <!--<Exclusion Type="FileName">ABC.TXT|XYZ.CS</Exclusion>-->
-</PoliCheckExclusions>
diff --git a/tools/updateVersion.ps1 b/tools/updateVersion.ps1
new file mode 100644
index 0000000000..dd007486df
--- /dev/null
+++ b/tools/updateVersion.ps1
@@ -0,0 +1,73 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+param(
+    [Parameter(Mandatory)]
+    [semver]$Version,
+
+    [Parameter(Mandatory)]
+    [string]$Changes
+)
+
+git diff --staged --quiet --exit-code
+if ($LASTEXITCODE -ne 0) {
+    throw "There are staged changes in the repository. Please commit or reset them before running this script."
+}
+
+if ($Version.Major -ne $(Get-Date).Year) {
+    throw "Major version should be the current year!"
+}
+
+if ($Version.PreReleaseLabel) {
+    if ($Version.Minor % 2 -eq 0) {
+        throw "Minor version must be odd for pre-release!"
+    }
+} else {
+    if ($Version.Minor % 2 -ne 0) {
+        throw "Minor version must be even for pre-release!"
+    }
+}
+
+$v = "$($Version.Major).$($Version.Minor).$($Version.Patch)"
+
+$Path = "package.json"
+$f = Get-Content -Path $Path
+# NOTE: The prefix regex match two spaces exactly to avoid matching
+# nested objects in the file.
+$f = $f -replace '^(?<prefix>  "version":\s+")(.+)(?<suffix>",)$', "`${prefix}${v}`${suffix}"
+
+# TODO: Bring this back when the marketplace supports it.
+# if ($Version.PreReleaseLabel) {
+#     $icon = "media/PowerShell_Preview_Icon.png"
+# } else {
+#     $icon = "media/PowerShell_Icon.png"
+# }
+# $f = $f -replace '^(?<prefix>  "icon":\s+")(.+)(?<suffix>",)$', "`${prefix}${icon}`${suffix}"
+
+# NOTE: This is not a "preview" extension even when the version is a pre-release.
+$f | Set-Content -Path $Path
+git add $Path
+
+[xml]$PsesProps = Get-Content ../PowerShellEditorServices/PowerShellEditorServices.Common.props
+$PsesVersion = $PsesProps.Project.PropertyGroup.VersionPrefix
+$PsesSuffix = $PsesProps.Project.PropertyGroup.VersionSuffix
+if ($PsesSuffix) { $PsesVersion += "-$PsesSuffix" }
+
+$Path = "CHANGELOG.md"
+$Changelog = Get-Content -Path $Path
+@(
+    $Changelog[0..1]
+    "## v$Version"
+    "### $([datetime]::Now.ToString('dddd, MMMM dd, yyyy'))"
+    ""
+    "With PowerShell Editor Services [v$PsesVersion](https://github.com/PowerShell/PowerShellEditorServices/releases/tag/v$PsesVersion)!"
+    ""
+    $Changes
+    ""
+    "See more details at the GitHub Release for [v$Version](https://github.com/PowerShell/vscode-powershell/releases/tag/v$Version)."
+    ""
+    $Changelog[2..$Changelog.Length]
+) | Set-Content -Encoding utf8NoBOM -Path $Path
+git add $Path
+
+git commit --edit --message "v$($Version): $Changes"
diff --git a/tsconfig.json b/tsconfig.json
index 1bfaad4864..33ba7e18aa 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,18 +1,17 @@
 {
   "compilerOptions": {
-    // NOTE: The TypeScript compiler is only used for building the tests (and
-    // the sources which the tests need). The extension is built with `esbuild`.
-    "module": "commonjs",
-    "outDir": "out",
-    "target": "ES6",
-    "lib": [ "ES6", "DOM" ],
-    "sourceMap": true,
-    "rootDir": ".",
-    // TODO: We need to enable stricter checking...
-    // "strict": true,
-    // "noImplicitReturns": true,
-    // "noFallthroughCasesInSwitch": true,
-    // "noUnusedParameters": true
+    "target": "ESNext",
+    "esModuleInterop": true,
+    "skipLibCheck": true,
+    "allowJs": true,
+    "checkJs": true,
+    "resolveJsonModule": true,
+    "moduleDetection": "force",
+    "verbatimModuleSyntax": true,
+    "strict": true,
+    "noEmit": true,
+    "module": "Preserve"
   },
-  "include": [ "src", "test" ],
+  "include": ["**/*.ts", "eslint.config.mjs", ".vscode-test.mjs"],
+  "exclude": ["node_modules"]
 }
diff --git a/tslint.json b/tslint.json
deleted file mode 100644
index b1a5fad007..0000000000
--- a/tslint.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    "defaultSeverity": "error",
-    "extends": [
-        "tslint:recommended"
-    ],
-    "jsRules": {},
-    "rules": {
-        "indent": [true, "spaces", 4],
-        "max-classes-per-file": false,
-        "object-literal-sort-keys": false,
-        "only-arrow-functions": false,
-        "file-header": [
-          true,
-          {
-            "allow-single-line-comments": true,
-            "match": "Copyright \\(c\\) Microsoft Corporation."
-          }
-        ]
-    },
-    "rulesDirectory": []
-}
diff --git a/vscode-powershell.build.ps1 b/vscode-powershell.build.ps1
index c8e0ffae45..4bcc737e33 100644
--- a/vscode-powershell.build.ps1
+++ b/vscode-powershell.build.ps1
@@ -7,12 +7,7 @@ param(
     [string]$EditorServicesRepoPath = $null
 )
 
-#Requires -Modules @{ModuleName="InvokeBuild";ModuleVersion="3.0.0"}
-
-# Grab package.json data which is used throughout the build.
-$script:PackageJson = Get-Content -Raw $PSScriptRoot/package.json | ConvertFrom-Json
-$script:IsPreviewExtension = $script:PackageJson.name -like "*preview*" -or $script:PackageJson.displayName -like "*preview*"
-Write-Host "`n### Extension: $($script:PackageJson.name)-$($script:PackageJson.version)`n" -ForegroundColor Green
+#Requires -Modules @{ ModuleName = "InvokeBuild"; ModuleVersion = "5.0.0" }
 
 function Get-EditorServicesPath {
     $psesRepoPath = if ($EditorServicesRepoPath) {
@@ -22,20 +17,19 @@ function Get-EditorServicesPath {
     }
     # NOTE: The ErrorActionPreference for both Invoke-Build and Azure DevOps
     # scripts is Stop, but we want to continue and return false here.
-    return Resolve-Path "$psesRepoPath/PowerShellEditorServices.build.ps1" -ErrorAction Continue
+    return Resolve-Path "$psesRepoPath/PowerShellEditorServices.build.ps1" -ErrorAction SilentlyContinue
 }
 
 #region Setup tasks
 
-task RestoreNodeModules -If { !(Test-Path ./node_modules) } {
-    Write-Host "`n### Restoring vscode-powershell dependencies`n" -ForegroundColor Green
-    # When in a CI build use the --loglevel=error parameter so that
-    # package install warnings don't cause PowerShell to throw up
-    if ($env:TF_BUILD) {
-        exec { & npm ci --loglevel=error }
-    } else {
-        exec { & npm install }
-    }
+task RestoreNode -If { !(Test-Path ./node_modules/esbuild) } {
+    Write-Build DarkGreen "Restoring build dependencies"
+    Invoke-BuildExec { & npm ci --omit=optional }
+}
+
+task RestoreNodeOptional -If { !(Test-Path ./node_modules/eslint) } {
+    Write-Build DarkMagenta "Restoring build, test, and lint dependencies"
+    Invoke-BuildExec { & npm ci --include=optional }
 }
 
 task RestoreEditorServices -If (Get-EditorServicesPath) {
@@ -44,61 +38,61 @@ task RestoreEditorServices -If (Get-EditorServicesPath) {
             # When debugging, we always rebuild PSES and ensure its symlinked so
             # that developers always have the latest local bits.
             if ((Get-Item ./modules -ErrorAction SilentlyContinue).LinkType -ne "SymbolicLink") {
-                Write-Host "`n### Creating symbolic link to PSES" -ForegroundColor Green
-                remove ./modules
+                Write-Build DarkMagenta "Creating symbolic link to PSES"
+                Remove-BuildItem ./modules
                 New-Item -ItemType SymbolicLink -Path ./modules -Target "$(Split-Path (Get-EditorServicesPath))/module"
             }
 
-            Write-Host "`n### Building PSES`n" -ForegroundColor Green
-            Invoke-Build Build (Get-EditorServicesPath)
+            Write-Build DarkGreen "Building PSES"
+            Invoke-Build Build (Get-EditorServicesPath) -Configuration $Configuration
         }
         "Release" {
             # When releasing, we ensure the bits are not symlinked but copied,
             # and only if they don't already exist.
             if ((Get-Item ./modules -ErrorAction SilentlyContinue).LinkType -eq "SymbolicLink") {
-                Write-Host "`n### Deleting PSES symbolic link" -ForegroundColor Green
-                remove ./modules
+                Write-Build DarkRed "Deleting PSES symbolic link"
+                Remove-BuildItem ./modules
             }
 
             if (!(Test-Path ./modules)) {
                 # We only build if it hasn't been built at all.
                 if (!(Test-Path "$(Split-Path (Get-EditorServicesPath))/module/PowerShellEditorServices/bin")) {
-                    Write-Host "`n### Building PSES`n" -ForegroundColor Green
-                    Invoke-Build Build (Get-EditorServicesPath)
+                    Write-Build DarkGreen "Building PSES"
+                    Invoke-Build Build (Get-EditorServicesPath) -Configuration $Configuration
                 }
 
-                Write-Host "`n### Copying PSES`n" -ForegroundColor Green
+                Write-Build DarkGreen "Copying PSES"
                 Copy-Item -Recurse -Force "$(Split-Path (Get-EditorServicesPath))/module" ./modules
             }
         }
     }
 }
 
-task Restore RestoreEditorServices, RestoreNodeModules
-
 #endregion
 #region Clean tasks
 
 task Clean {
-    Write-Host "`n### Cleaning vscode-powershell`n" -ForegroundColor Green
-    remove ./modules, ./out, ./node_modules, *.vsix
+    Write-Build DarkMagenta "Cleaning vscode-powershell"
+    Remove-BuildItem *.js, *.js.map, ./dist, ./modules, ./node_modules, ./out
 }
 
 task CleanEditorServices -If (Get-EditorServicesPath) {
-    Write-Host "`n### Cleaning PowerShellEditorServices`n" -ForegroundColor Green
+    Write-Build DarkMagenta "Cleaning PSES"
     Invoke-Build Clean (Get-EditorServicesPath)
 }
 
 #endregion
 #region Build tasks
+task Lint RestoreNodeOptional, {
+    Write-Build DarkMagenta "Linting TypeScript"
+    Invoke-BuildExec { & npm run lint }
+    Write-Build DarkMagenta "Checking formatting of TypeScript, JSON, etc."
+    Invoke-BuildExec { & npm run format }
+}
 
-task Build Restore, {
-    Write-Host "`n### Building vscode-powershell`n" -ForegroundColor Green
-    assert (Test-Path ./modules/PowerShellEditorServices/bin) "Extension requires PSES"
-
-    # TODO: TSLint is deprecated and we need to switch to ESLint.
-    # https://github.com/PowerShell/vscode-powershell/pull/3331
-    exec { & npm run lint }
+task Build RestoreEditorServices, RestoreNode, {
+    Write-Build DarkGreen "Building vscode-powershell"
+    Assert-Build (Test-Path ./modules/PowerShellEditorServices/bin) "Extension requires PSES"
 
     # TODO: When supported we should use `esbuild` for the tests too. Although
     # we now use `esbuild` to transpile, bundle, and minify the extension, we
@@ -107,49 +101,54 @@ task Build Restore, {
     # Unfortunately `esbuild` doesn't support emitting 1:1 files (yet).
     # https://github.com/evanw/esbuild/issues/944
     switch ($Configuration) {
-        "Debug" { exec { & npm run build -- --sourcemap } }
-        "Release" { exec { & npm run build -- --minify } }
+        "Debug" { Invoke-BuildExec { & npm run compile } }
+        "Release" { Invoke-BuildExec { & npm run compile -- --minify } }
     }
 }
 
 #endregion
 #region Test tasks
 
-task Test -If (!($env:TF_BUILD -and $global:IsLinux)) Build, {
-    Write-Host "`n### Running extension tests" -ForegroundColor Green
-    exec { & npm run test }
+task Test Lint, Build, {
+    Write-Build DarkMagenta "Running extension tests"
+    Invoke-BuildExec { & npm run test }
+    # Reset the state of files modified by tests
+    Invoke-BuildExec { git checkout test/TestEnvironment.code-workspace }
 }
 
 task TestEditorServices -If (Get-EditorServicesPath) {
-    Write-Host "`n### Testing PowerShellEditorServices`n" -ForegroundColor Green
+    Write-Build DarkMagenta "Testing PSES"
     Invoke-Build Test (Get-EditorServicesPath)
 }
 
 #endregion
 #region Package tasks
 
-task UpdateReadme -If { $script:IsPreviewExtension } {
-    # Add the preview text
-    $newReadmeTop = '# PowerShell Language Support for Visual Studio Code
-
-> ## ATTENTION: This is the PREVIEW version of the PowerShell extension for VSCode which contains features that are being evaluated for stable. It works with PowerShell 5.1 and up.
-> ### If you are looking for the stable version, please [go here](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell) or install the extension called "PowerShell" (not "PowerShell Preview")
-> ## NOTE: If you have both stable (aka "PowerShell") and preview (aka "PowerShell Preview") installed, you MUST [DISABLE](https://code.visualstudio.com/docs/editor/extension-gallery#_disable-an-extension) one of them for the best performance. Docs on how to disable an extension can be found [here](https://code.visualstudio.com/docs/editor/extension-gallery#_disable-an-extension)'
-    $readmePath = (Join-Path $PSScriptRoot README.md)
-
-    $readmeContent = Get-Content -Path $readmePath
-    if (!($readmeContent -match "This is the PREVIEW version of the PowerShell extension")) {
-        $readmeContent[0] = $newReadmeTop
-        $readmeContent | Set-Content $readmePath -Encoding utf8
+task Package {
+    [semver]$version = $((Get-Content -Raw -Path package.json | ConvertFrom-Json).version)
+    Write-Build DarkGreen "Packaging powershell-$version.vsix"
+    Remove-BuildItem ./out
+    New-Item -ItemType Directory -Force out | Out-Null
+
+    Assert-Build (Test-Path ./dist/extension.js) "Extension must be built!"
+
+    # Packaging requires a copy of the modules folder, not a symbolic link. But
+    # we might have built in Debug configuration, not Release, and still want to
+    # package it. So delete the symlink and copy what we just built.
+    if ((Get-Item ./modules -ErrorAction SilentlyContinue).LinkType -eq "SymbolicLink") {
+        Write-Build DarkRed "PSES is a symbolic link, replacing with copy!"
+        Remove-BuildItem ./modules
+        Copy-Item -Recurse -Force "$(Split-Path (Get-EditorServicesPath))/module" ./modules
     }
-}
 
-task Package UpdateReadme, Build, {
-    Write-Host "`n### Packaging $($script:PackageJson.name)-$($script:PackageJson.version).vsix`n" -ForegroundColor Green
-    assert ((Get-Item ./modules).LinkType -ne "SymbolicLink") "Packaging requires a copy of PSES, not a symlink!"
-    exec { & npm run package }
+    if ($version.Minor % 2 -ne 0) {
+        Write-Build DarkRed "This is a pre-release!"
+        Invoke-BuildExec { & npm run package -- --pre-release }
+    } else {
+        Invoke-BuildExec { & npm run package }
+    }
 }
 
 #endregion
 
-task . Build, Test, Package
+task . Test, Package
