diff --git a/.github/scripts/label-release-pr.sh b/.github/scripts/label-release-pr.sh new file mode 100755 index 0000000..b11e7f2 --- /dev/null +++ b/.github/scripts/label-release-pr.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Marks the open release-please PR with the channel it will publish to. +# +# Every cycle ships twice - an odd-minor pre-release first, then the even-minor +# release (see VERSIONING.md). Which one a Release PR is, is decided by the +# version it carries, so this says it on the PR instead of making the reviewer +# work out the minor's parity. +# +# Labels rather than renames on purpose: release-please parses the Release PR +# *title* to recover the version when the PR merges ("must be able to parse out +# the component and version from the pull request"), so editing the title risks +# breaking the release. Labels and comments are not parsed. +# +# Requires GH_TOKEN and REPO in the environment. Safe to run repeatedly. +set -euo pipefail + +pr=$(gh pr list --repo "$REPO" --state open --limit 50 \ + --json number,headRefName,title \ + --jq '[.[] | select(.headRefName | startswith("release-please"))][0] // empty') + +if [ -z "$pr" ]; then + echo "No open Release PR; nothing to label." + exit 0 +fi + +number=$(echo "$pr" | jq -r .number) +version=$(echo "$pr" | jq -r .title | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1) + +if [ -z "$version" ]; then + echo "::warning::Could not read a version out of Release PR #$number; skipping the channel label." + exit 0 +fi + +minor=$(echo "$version" | cut -d. -f2) +if [ $((minor % 2)) -eq 1 ]; then + keep="pre-release" + drop="release" + colour="fbca04" + note="🚧 **Pre-release \`$version\`** (odd minor). Merging this publishes to both registries with \`--pre-release\`, so only users who opted into pre-releases get it. The matching **release** PR is opened automatically once this one has shipped." +else + keep="release" + drop="pre-release" + colour="0e8a16" + note="πŸš€ **Release \`$version\`** (even minor). Merging this publishes the stable version to both registries." +fi + +echo "Release PR #$number carries $version -> $keep" + +# --force makes label creation idempotent across runs. +gh label create "$keep" --repo "$REPO" --color "$colour" \ + --description "Release channel, see VERSIONING.md" --force + +gh pr edit "$number" --repo "$REPO" --add-label "$keep" +# The PR can carry the other label from an earlier version proposal; removing a +# label that isn't there is an error, so this is allowed to fail. +gh pr edit "$number" --repo "$REPO" --remove-label "$drop" 2>/dev/null || true + +# Only say it once - release-please amends this PR on every push to main. +if gh pr view "$number" --repo "$REPO" --json comments --jq '.comments[].body' \ + | grep -qF "\`$version\`"; then + echo "Channel comment for $version already present." +else + gh pr comment "$number" --repo "$REPO" --body "$note" +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c909f9..41bfe37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,25 @@ name: CI +# Least privilege for the GITHUB_TOKEN: this workflow only reads the repo. +# Without it the token inherits the repository default (read-write) and +# actions/checkout leaves it in .git/config for every later step to use. +permissions: + contents: read + on: push: branches: - main - develop pull_request: + # Fallback for release-please.yml. The Release PR does fire `pull_request`, + # but GitHub can park that run at `action_required` when the repository + # requires approval for workflows from outside/first-time contributors - the + # PR's author is github-actions[bot], which trips that policy. release-please.yml + # approves the parked run (the normal path, and it puts the check on the PR + # where it belongs); if that approval is refused it dispatches this workflow + # instead, since workflow_dispatch is never gated. + workflow_dispatch: jobs: test: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..433790c --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,150 @@ +# Builds the .vsix once and publishes that exact artifact to both registries: +# the Visual Studio Marketplace (vsce) and the Open VSX Registry (ovsx). Open +# VSX is what Cursor, VSCodium, Windsurf, Gitpod and Theia install from - see +# issue #18. +name: publish + +on: + # Called by release-please.yml right after it creates a release. This is the + # normal path: a release created with GITHUB_TOKEN does NOT emit a usable + # `release` event ("Events triggered by the GITHUB_TOKEN will not create a + # new workflow run"), so the release workflow has to invoke this one itself. + workflow_call: + inputs: + tag: + description: Tag to publish. + required: true + type: string + publish: + description: Publish to the registries, or only build the package. + required: false + type: boolean + default: true + # Still useful for releases published by a human in the GitHub UI, which do + # emit the event. + release: + types: [published] + workflow_dispatch: + inputs: + tag: + description: Tag or ref to (re)publish (e.g. v1.3.0, or main). Must exist on the remote. + required: true + type: string + publish: + description: Actually publish to the registries (vs build-only smoke test)? + type: boolean + default: true + +permissions: + contents: write + +concurrency: + group: extension-publish + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-latest + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + # A `release` event carries no inputs and always means "publish". + SHOULD_PUBLISH: ${{ github.event_name == 'release' || inputs.publish }} + steps: + - uses: actions/checkout@v4 + with: + # `inputs` covers both workflow_call and workflow_dispatch; on a + # `release` event it is empty and github.ref is the release tag. + ref: ${{ inputs.tag || github.ref }} + + - uses: actions/setup-node@v4 + with: + # Kept explicit rather than read from a file, because this workflow + # also checks out old tags to re-publish them. Keep in step with ci.yml. + node-version: 24 + cache: npm + + - name: Install dependencies + run: npm ci + + # The version decides the channel - there is no input to get wrong. + # VERSIONING.md: odd minor (1.3.x) = pre-release, even minor (1.4.x) = + # release. Every cycle ships both, so this runs twice per feature: once + # for the odd pre-release, once for the even release. + - name: Determine release channel + id: channel + run: | + version=$(node -p "require('./package.json').version") + minor=$(echo "$version" | cut -d. -f2) + if [ $((minor % 2)) -eq 1 ]; then + prerelease=true + channel=pre-release + else + prerelease=false + channel=release + fi + echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT" + echo "channel=$channel" >> "$GITHUB_OUTPUT" + echo "Version $version (minor $minor) -> $channel" + + # vsce runs `vscode:prepublish` itself, which produces the minified + # dist/extension.js bundle that `main` points at. (.npmrc sets + # ignore-scripts=true, which disables npm pre/post hooks but not + # explicitly invoked `npm run` scripts.) + - name: Package extension + id: package + run: | + if [ "$PRERELEASE" = "true" ]; then + npm run package:preRelease + else + npm run package + fi + vsix=$(ls -1 ./*.vsix | head -n 1) + echo "vsix=$vsix" >> "$GITHUB_OUTPUT" + echo "Packaged $vsix" + env: + PRERELEASE: ${{ steps.channel.outputs.prerelease }} + + - name: Publish to Visual Studio Marketplace + if: env.SHOULD_PUBLISH == 'true' + run: | + npx vsce publish --packagePath "$VSIX" ${{ steps.channel.outputs.prerelease == 'true' && '--pre-release' || '' }} + env: + VSIX: ${{ steps.package.outputs.vsix }} + + # Skipped with a warning rather than failing while the Open VSX account + # setup is still pending (Eclipse publisher agreement + `Soulcode` + # namespace, see RELEASE.md). Once OVSX_PAT is set, this step starts + # publishing on the very next release with no further changes. + - name: Publish to Open VSX + if: env.SHOULD_PUBLISH == 'true' + run: | + if [ -z "$OVSX_PAT" ]; then + echo "::warning::OVSX_PAT is not set - skipping the Open VSX publish. Cursor/VSCodium users will not get this version. See RELEASE.md -> One-time setup." + exit 0 + fi + npx ovsx publish "$VSIX" ${{ steps.channel.outputs.prerelease == 'true' && '--pre-release' || '' }} + env: + VSIX: ${{ steps.package.outputs.vsix }} + + - name: Attach .vsix to the GitHub Release + # Runs for a release event, for the release-please chain (workflow_call + # inherits the caller's `push` event name), and for a manual re-publish. + # Skipped outright on a build-only smoke test (`publish: false`). + if: github.event_name == 'release' || github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish) + # A dispatch may name a ref that has no GitHub Release (e.g. `main`, or + # a tag whose release was never created), so check first and skip + # cleanly instead of failing the run. The automatic paths keep failing + # loudly: there the release is guaranteed to exist, and a missing one is + # a bug. + run: | + if [ "$EVENT_NAME" = "workflow_dispatch" ] && ! gh release view "$TAG" >/dev/null 2>&1; then + echo "No GitHub Release for '$TAG'; nothing to attach." + exit 0 + fi + gh release upload "$TAG" "$VSIX" --clobber + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EVENT_NAME: ${{ github.event_name }} + TAG: ${{ github.event.release.tag_name || inputs.tag }} + VSIX: ${{ steps.package.outputs.vsix }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..ce3bab5 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,188 @@ +# Release automation, mirroring the setup used in SoulcodeAgency/bexio-chrome-extension. +# +# Flow: merge `develop` into `main` as usual -> release-please reads the +# conventional-commit messages since the last tag and opens (or amends) a +# Release PR titled `chore(main): release ` carrying the version bump, +# the package-lock sync and the CHANGELOG entry. Merging that PR creates the +# tag + GitHub Release and triggers the publish workflow. Nothing is published +# until a human merges the Release PR. +name: release-please + +on: + push: + branches: [main] + +permissions: + contents: write + pull-requests: write + # Needed to approve / dispatch the Release PR's parked CI run, see below. + actions: write + # Labels live on the issues API, and the Release PR gets a channel label. + issues: write + +jobs: + release-please: + runs-on: ubuntu-latest + outputs: + release_created: ${{ steps.release.outputs.release_created }} + tag_name: ${{ steps.release.outputs.tag_name }} + steps: + # release-please itself works over the API and needs no checkout; this is + # here for the channel-labelling script below. + - uses: actions/checkout@v4 + + - uses: googleapis/release-please-action@v5 + id: release + with: + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + token: ${{ secrets.GITHUB_TOKEN }} + + # Says on the Release PR which of the cycle's two shipments it is - the + # odd-minor pre-release or the even-minor release. See the script header + # for why this labels instead of renaming the PR. + - name: Label the Release PR with its channel + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: .github/scripts/label-release-pr.sh + + # Make sure the Release PR actually carries a build check. + # + # GitHub does start a `pull_request` run for the Release PR, but can park + # it at `action_required` when the repository requires approval for + # workflow runs from first-time/outside contributors: the PR's author is + # github-actions[bot], which trips that policy. A parked run means the PR + # shows no build check and stays that way forever, because nobody is + # watching for a run that needs clicking. So approve it here. + # + # If approval is refused - GitHub may well decide a token should not + # approve its own run - fall back to dispatching CI directly. That + # produces a green check on the same commit, though it does not appear in + # the PR's own check list, since the rollup only shows runs the PR itself + # triggered. + # + # Deliberately not gated on the `prs_created` output: that output is + # documented as "created or updated" but is only true on creation, so a + # commit that merely amends an existing Release PR would skip this step. + # It is a cheap no-op when there is nothing to do, so it just runs. + - name: Make sure the Release PR gets a build check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: | + # Find the open Release PR by its branch rather than trusting the + # action's outputs - it exists whether this run created it or an + # earlier one did. + branch=$(gh pr list --repo "$REPO" --state open --limit 50 \ + --json headRefName \ + --jq '[.[] | select(.headRefName | startswith("release-please"))][0].headRefName // empty') + if [ -z "$branch" ]; then + echo "No open Release PR; nothing to do." + exit 0 + fi + + # The pull_request run is created a moment after the PR itself, so + # give it a little time to show up before concluding there is none. + run_id="" + for _ in $(seq 1 10); do + # `action_required` shows up as the *conclusion* of a completed run, + # not as its status - a parked run reads `completed/action_required`. + # Match both, since an in-flight one can carry it as the status. + run_id=$(gh run list --repo "$REPO" --workflow=ci.yml \ + --branch "$branch" --limit 20 \ + --json databaseId,status,conclusion,event \ + --jq '[.[] | select(.event == "pull_request" and (.status == "action_required" or .conclusion == "action_required"))][0].databaseId // empty') + [ -n "$run_id" ] && break + sleep 6 + done + + if [ -z "$run_id" ]; then + echo "No run awaiting approval for '$branch' - either it started on its own or none exists yet." + exit 0 + fi + + echo "Run $run_id on '$branch' is waiting for approval; approving." + if gh api -X POST "repos/$REPO/actions/runs/$run_id/approve" >/dev/null 2>&1; then + echo "Approved." + else + echo "::warning::Could not approve run $run_id (GITHUB_TOKEN may not approve runs). Dispatching CI against '$branch' instead; the check lands on the commit but not in the PR's check list." + gh workflow run ci.yml --repo "$REPO" --ref "$branch" + fi + + # release-please creates the GitHub Release with GITHUB_TOKEN, and GitHub + # suppresses workflow runs for events raised by that token ("Events triggered + # by the GITHUB_TOKEN will not create a new workflow run"). The `release` + # trigger in publish.yml therefore never fires for it, so the publish is + # invoked here instead. + publish: + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + uses: ./.github/workflows/publish.yml + with: + tag: ${{ needs.release-please.outputs.tag_name }} + publish: true + secrets: inherit + + # The second half of the cycle. A pre-release that has shipped is followed by + # the identical code going out as a real release, so once the odd-minor + # version is published this opens the even-minor Release PR for it without + # anyone having to remember the Release-As footer. Merge it when the + # pre-release has soaked long enough; until then it just sits there. + # + # Nothing to do after an even-minor release: that closes the cycle, and the + # next one starts from real work (see RELEASE.md). + promote: + needs: [release-please, publish] + if: needs.release-please.outputs.release_created == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + + - name: Queue the release that follows this pre-release + id: promote + env: + TAG: ${{ needs.release-please.outputs.tag_name }} + run: | + version="${TAG#v}" + major=$(echo "$version" | cut -d. -f1) + minor=$(echo "$version" | cut -d. -f2) + + if [ $((minor % 2)) -eq 0 ]; then + echo "$version is an even-minor release - the cycle is complete, nothing to queue." + exit 0 + fi + + next="$major.$((minor + 1)).0" + echo "Pre-release $version shipped; queueing release $next." + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + # Empty commit: the code is already on main, this only carries the + # Release-As footer that tells release-please which version to propose. + # `chore:` keeps it out of the changelog. + git commit --allow-empty \ + -m "chore: promote $version to release $next" \ + -m "Release-As: $next" + git push origin main + echo "promoted=true" >> "$GITHUB_OUTPUT" + + # A push made with GITHUB_TOKEN does not start a new workflow run, so the + # release-please job would never see the commit above. Run it right here + # instead - the action reads repository state, it does not need the event. + - uses: googleapis/release-please-action@v5 + if: steps.promote.outputs.promoted == 'true' + with: + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Label the queued Release PR + if: steps.promote.outputs.promoted == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: .github/scripts/label-release-pr.sh diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..8d35a90 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "1.2.4" +} diff --git a/.vscodeignore b/.vscodeignore index 2f5e056..c03d22b 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -18,7 +18,12 @@ webpack.config.js exampleProject img *.md +.github +release-please-config.json +.release-please-manifest.json # DO NOT IGNORE THESE FILES !README.md +# Both registries render this as the extension's "Changelog" tab +!CHANGELOG.md !dist/extension.js \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 33b7b88..a4c724d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -61,10 +61,16 @@ Small codebase, one activation flow. Core rule: **all decision logic lives in `s ## Versioning & release -VS Code Marketplace does not support semver prerelease tags. This repo uses: **odd minor = pre-release** (1.1.x, 1.3.x), **even minor = release** (1.2.x, 1.4.x). See VERSIONING.md and RELEASE.md. Per release: update CHANGELOG.md and add an entry to `src/config/releaseMessages.conf.ts` (keyed by exact version). Release via `npm run release` / `npm run pre-release`. +VS Code Marketplace does not support semver prerelease tags. This repo uses: **odd minor = pre-release** (1.1.x, 1.3.x), **even minor = release** (1.2.x, 1.4.x). See VERSIONING.md and RELEASE.md. + +Releases are automated with `release-please` (`.github/workflows/release-please.yml`): a push to `main` opens a Release PR, merging it tags + creates the GitHub Release and triggers `.github/workflows/publish.yml`, which builds one `.vsix` and publishes it to **both** the Visual Studio Marketplace (`vsce`, secret `VSCE_PAT`) and the **Open VSX Registry** (`ovsx`, secret `OVSX_PAT` β€” the registry Cursor/VSCodium install from, see issue #18). `npm run release` / `npm run pre-release` remain as the local fallback and cover both registries too. + +**Every cycle ships twice β€” two Release PRs:** the odd-minor pre-release (`1.3.0`, labelled `pre-release`) and then the even-minor release (`1.4.0`, labelled `release`). The channel is never an input anywhere: `publish.yml` derives `--pre-release` from the parity of the minor in `package.json`, so the number and the channel cannot disagree. `release-please-config.json` uses `always-bump-patch` so nothing crosses a minor boundary by itself; you open a cycle with `Release-As: 1.3.0` in a commit body, and the `promote` job pushes the `Release-As: 1.4.0` commit for the second PR by itself. The Release PR is labelled rather than renamed because release-please parses its own PR title to recover the version on merge (`.github/scripts/label-release-pr.sh`). + +Two things release-please cannot do for you: the entry in `src/config/releaseMessages.conf.ts` (keyed by exact version, drives the in-editor update popup) has to be committed onto the Release PR branch before merging it, and `main` has to be back-merged into `develop` afterwards. ## Conventions - `.npmrc` enforces `save-exact` and `ignore-scripts` β€” dependency versions are exact, no `^`/`~`. -- Commit messages follow `type(Scope) Message`, e.g. `fix(Maintenance) Fixed types`. +- Commit messages follow **conventional commits**: `type(scope): Message`, e.g. `fix(maintenance): Fixed types`. The colon is load-bearing β€” `release-please` ignores anything it cannot parse, so a malformed message silently never ships. `feat:`/`fix:` produce a release, `chore:`/`docs:`/`test:`/`refactor:`/`ci:` do not. (Commits before v1.2.4 use the older `type(Scope) Message` style without the colon.) - Branches: `develop` is the working branch, `main` holds releases (merged from develop). diff --git a/README.md b/README.md index 379e887..6480a62 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,13 @@ Because of VSCode limitations, it's not possible to do it automatically, but we More details can be read in this [πŸ‘€ blog post](https://www.garaio.com/blog/vscode-extensions-unwanted-recommendations). +## πŸ“₯ Installation + +* **VS Code** β€” [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Soulcode.vscode-unwanted-extensions), or run `ext install Soulcode.vscode-unwanted-extensions`. +* **Cursor, VSCodium, Windsurf, Gitpod, Theia** β€” [Open VSX Registry](https://open-vsx.org/extension/Soulcode/vscode-unwanted-extensions). These editors cannot use the Visual Studio Marketplace, so they install from Open VSX instead. Search for *Unwanted Extensions* in the built-in extension view. + +Both registries receive the same `.vsix` build from the same release. + ## ↗️Successor [Unwanted extensions](https://marketplace.visualstudio.com/items?itemName=Soulcode.vscode-unwanted-extensions) is the continuation of the previous extension ~~[Unwanted Recommendations](https://marketplace.visualstudio.com/items?itemName=GARAIOAG.garaio-vscode-unwanted-recommendations)~~ which is not maintained anymore. It's just a new publisher, still the same maintainer. diff --git a/RELEASE.md b/RELEASE.md index 074ae61..659f2a7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,41 +1,109 @@ # Release -To create a new Visual Studio Code extension release, you typically need to follow these steps: +**Two ways to release.** The automatic CI path is the default; the manual local path is preserved as a fallback. Pick one per release β€” don't interleave. -* Compile the TypeScript code. -* Package the extension. -* Publish the extension. +Every release goes to **two registries**: -## Checklist +* [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Soulcode.vscode-unwanted-extensions) β€” VS Code (`vsce`) +* [Open VSX Registry](https://open-vsx.org/extension/Soulcode/vscode-unwanted-extensions) β€” Cursor, VSCodium, Windsurf, Gitpod, Theia (`ovsx`) -* Verify first if pre-release or release version! -* Update [README](README.md), [CHANGELOG](CHANGELOG.md) -* Check package & package.lock for having correct version number -* Update message for release in [releaseMessages](src/config/releaseMessages.conf.ts) -* Execute building steps according to your release +Both get the identical `.vsix` file, built once per release. + +## Automatic β€” via `release-please` (preferred) + +**Every cycle ships twice: a pre-release first, then the release.** Following +[VERSIONING.md](VERSIONING.md), the pre-release takes the odd minor (`1.3.0`) +and the release that follows it takes the even one (`1.4.0`). So each cycle +produces **two Release PRs**, and each is labelled with the channel it will +publish to: + +| Release PR | Version | Label | What merging it does | +| --- | --- | --- | --- | +| 1st | odd minor, `1.3.0` | `pre-release` | publishes with `--pre-release` to both registries β€” only users who opted into pre-releases get it | +| 2nd | even minor, `1.4.0` | `release` | publishes the stable version to both registries | + +Nothing anywhere asks you which channel a release is: the **version decides**. +`publish.yml` reads the minor's parity out of `package.json` and adds +`--pre-release` on odd. A mismatch between the number and the channel is +therefore not possible. + +### The cycle + +1. Merge your work into `develop` with conventional-commit messages (`feat: …` / `fix: …` trigger a release; `chore:` / `docs:` / `test:` / `refactor:` don't). +2. Merge `develop` into `main` when you want to ship. **Put `Release-As: 1.3.0` in a commit body** (next odd minor) β€” that opens the cycle. Without it the automation proposes a patch of the current even minor, which would be a release without a pre-release in front of it. +3. `release-please` opens the **pre-release PR**, `chore(main): release 1.3.0`, labelled `pre-release`, containing the version bump (`package.json` + `package-lock.json`) and the `CHANGELOG.md` entry. +4. **Before merging it**, push one commit onto the Release PR branch adding the matching entry to [`src/config/releaseMessages.conf.ts`](src/config/releaseMessages.conf.ts), keyed by the exact version in the PR title. This is the in-editor "what's new" popup β€” release-please cannot write it, and without it users see no update notice. +5. Merge it. That tags, creates the GitHub Release, and publishes the pre-release to both registries. +6. The **release PR** (`chore(main): release 1.4.0`, labelled `release`) is then opened **automatically** β€” the workflow pushes an empty commit carrying `Release-As: 1.4.0`, so you don't have to remember it. It sits there until you merge it. +7. Soak the pre-release for as long as you want. When you're happy, repeat step 4 for `1.4.0` and merge the release PR. Same code, now published as the stable version. +8. Back-merge `main` into `develop` so the version bumps and changelog travel back to the working branch. + +**Fixing something during the soak.** A `fix:` commit landing on `main` while +the release PR is open is folded into that pending `1.4.0` β€” it does *not* +automatically get its own pre-release. If you want to test the fix as a +pre-release first, put `Release-As: 1.3.1` in its commit body; the later +`Release-As` wins and the PR goes back to being a pre-release. + +If the publish workflow fails after a Release PR merge, re-run it from the Actions tab β€” `publish` β†’ "Run workflow" β†’ enter the tag, leaving `publish: true`. The re-run rebuilds, re-publishes and re-attaches the `.vsix` to the existing GitHub Release. Publishing a version a registry already has will fail; that is expected, and means the publish had in fact succeeded. + +**Branch protection.** Step 6 pushes that empty commit to `main` as +`github-actions[bot]`. If `main` is protected, allow the Actions bot to push or +the promotion step fails β€” the pre-release is out by then, and the release PR +just has to be opened by hand with a `Release-As: 1.4.0` commit. + +### One-time setup + +Two repository secrets under *Settings β†’ Secrets and variables β†’ Actions*: -## Execute +| Secret | Where it comes from | +| --- | --- | +| `VSCE_PAT` | Azure DevOps personal access token for the `Soulcode` publisher, scope *Marketplace β†’ Manage*. | +| `OVSX_PAT` | Access token from the [open-vsx.org](https://open-vsx.org) user settings. | + +Getting an Open VSX token requires, once: + +1. Log in to [open-vsx.org](https://open-vsx.org) with GitHub. +2. Create an Eclipse Foundation account and sign the **Eclipse Publisher Agreement** from the Open VSX profile page. +3. Claim the publisher namespace: `npx ovsx create-namespace Soulcode -p `. +4. Optional but recommended: request namespace ownership via an issue on [`EclipseFdn/open-vsx.org`](https://github.com/EclipseFdn/open-vsx.org/issues) so the extension shows as *verified* instead of carrying an "unverified publisher" note. + +Until `OVSX_PAT` exists the publish workflow **skips** the Open VSX step with a warning instead of failing β€” the Marketplace release still goes out. Once the secret is added, the next release publishes to both with no further changes. + +## Manual β€” local fallback + +Use this when you need to bypass the automated flow: emergency releases, debugging the workflow, or a pre-release. + +### Checklist + +* Verify first if pre-release or release version β€” see [VERSIONING.md](VERSIONING.md)! +* Update [README](README.md), [CHANGELOG](CHANGELOG.md) +* Check `package.json` & `package-lock.json` for having the correct version number +* Update the message for the release in [releaseMessages](src/config/releaseMessages.conf.ts) +* Export `VSCE_PAT` and `OVSX_PAT` in your shell β€” both CLIs read them from the environment +* Execute the building steps according to your release ### Release version -Run `npm run release` or manually: +Run `npm run release`, or manually: Compile the TypeScript code: `npm run compile` Package the extension: `npm run package` -Publish the extension: `npm run publish` +Publish to the Marketplace: `npm run publish` -### Pre-release +Publish to Open VSX: `npm run publish:openvsx` -If you are creating a pre-release version, you can use the following commands instead: +### Pre-release -Run `npm run pre-release` or manually: +Run `npm run pre-release`, or manually: Compile the TypeScript code: `npm run compile` Package the extension as a pre-release: `npm run package:preRelease` -Publish the extension as a pre-release: `npm run publish:preRelease` +Publish to the Marketplace as a pre-release: `npm run publish:preRelease` + +Publish to Open VSX as a pre-release: `npm run publish:openvsx:preRelease` -These commands will compile your code, package it into a .vsix file, and then publish it to the Visual Studio Code Marketplace. +A pre-release can also be shipped through CI: Actions β†’ `publish` β†’ "Run workflow" and enter the tag. There is no pre-release checkbox β€” the workflow reads the parity of the minor in the tagged `package.json`, so an odd-minor tag publishes as a pre-release on its own. diff --git a/VERSIONING.md b/VERSIONING.md index 4f557a0..276da63 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -17,3 +17,32 @@ Make sure to use the right command for **pre releases**! Real releases should stick to **1.2** / **1.4** etc. > `major.EVEN_NUMBER.patch` + +## How this interacts with `release-please` + +Every cycle ships **both** numbers, in this order: + +```text +1.3.0 pre-release (odd minor) -> published with --pre-release +1.4.0 release (even minor) -> published as the stable version +``` + +So the automated flow ([RELEASE.md](RELEASE.md)) produces **two Release PRs per +cycle**, each labelled `pre-release` or `release`. The version is the single +source of truth for the channel: `publish.yml` derives `--pre-release` from the +minor's parity, so the number and the channel cannot disagree. + +`release-please-config.json` sets `"versioning": "always-bump-patch"` so nothing +crosses a minor boundary by itself β€” an automatic `feat:` bump would walk +`1.2.4 β†’ 1.3.0` and silently turn a release into a pre-release. Crossing is +always deliberate, via a commit body footer: + +```text +Release-As: 1.3.0 +``` + +You write that once, to open a cycle. The promotion to `1.4.0` afterwards is +pushed by the release workflow itself. + +Patch bumps stay inside their channel, which is what you want: `1.3.0 β†’ 1.3.1` +is another pre-release, `1.4.0 β†’ 1.4.1` another release. diff --git a/package-lock.json b/package-lock.json index 96dafba..20c39eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "glob": "13.0.6", "jiti": "2.7.0", "mocha": "11.8.0", + "ovsx": "1.1.0", "typescript": "6.0.3", "typescript-eslint": "8.66.0" }, @@ -241,6 +242,40 @@ "node": ">=6.9.0" } }, + "node_modules/@emnapi/core": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz", + "integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", + "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", @@ -861,85 +896,1036 @@ "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core/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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/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, + "license": "MIT" + }, + "node_modules/@inquirer/core/node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@inquirer/core/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, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "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": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": 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" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": 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" + } + }, + "node_modules/@napi-rs/keyring": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring/-/keyring-1.3.0.tgz", + "integrity": "sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/keyring-darwin-arm64": "1.3.0", + "@napi-rs/keyring-darwin-x64": "1.3.0", + "@napi-rs/keyring-freebsd-x64": "1.3.0", + "@napi-rs/keyring-linux-arm-gnueabihf": "1.3.0", + "@napi-rs/keyring-linux-arm64-gnu": "1.3.0", + "@napi-rs/keyring-linux-arm64-musl": "1.3.0", + "@napi-rs/keyring-linux-riscv64-gnu": "1.3.0", + "@napi-rs/keyring-linux-x64-gnu": "1.3.0", + "@napi-rs/keyring-linux-x64-musl": "1.3.0", + "@napi-rs/keyring-win32-arm64-msvc": "1.3.0", + "@napi-rs/keyring-win32-ia32-msvc": "1.3.0", + "@napi-rs/keyring-win32-x64-msvc": "1.3.0" + } + }, + "node_modules/@napi-rs/keyring-darwin-arm64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-arm64/-/keyring-darwin-arm64-1.3.0.tgz", + "integrity": "sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-darwin-x64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-x64/-/keyring-darwin-x64-1.3.0.tgz", + "integrity": "sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-freebsd-x64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-freebsd-x64/-/keyring-freebsd-x64-1.3.0.tgz", + "integrity": "sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-arm-gnueabihf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm-gnueabihf/-/keyring-linux-arm-gnueabihf-1.3.0.tgz", + "integrity": "sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-arm64-gnu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-gnu/-/keyring-linux-arm64-gnu-1.3.0.tgz", + "integrity": "sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-arm64-musl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-musl/-/keyring-linux-arm64-musl-1.3.0.tgz", + "integrity": "sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-riscv64-gnu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-riscv64-gnu/-/keyring-linux-riscv64-gnu-1.3.0.tgz", + "integrity": "sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-x64-gnu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-gnu/-/keyring-linux-x64-gnu-1.3.0.tgz", + "integrity": "sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-linux-x64-musl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-musl/-/keyring-linux-x64-musl-1.3.0.tgz", + "integrity": "sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-win32-arm64-msvc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-arm64-msvc/-/keyring-win32-arm64-msvc-1.3.0.tgz", + "integrity": "sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-win32-ia32-msvc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-ia32-msvc/-/keyring-win32-ia32-msvc-1.3.0.tgz", + "integrity": "sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/keyring-win32-x64-msvc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-x64-msvc/-/keyring-win32-x64-msvc-1.3.0.tgz", + "integrity": "sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@node-rs/crc32": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32/-/crc32-1.10.6.tgz", + "integrity": "sha512-+llXfqt+UzgoDzT9of5vPQPGqTAVCohU74I9zIBkNo5TH6s2P31DFJOGsJQKN207f0GHnYv5pV3wh3BCY/un/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/crc32-android-arm-eabi": "1.10.6", + "@node-rs/crc32-android-arm64": "1.10.6", + "@node-rs/crc32-darwin-arm64": "1.10.6", + "@node-rs/crc32-darwin-x64": "1.10.6", + "@node-rs/crc32-freebsd-x64": "1.10.6", + "@node-rs/crc32-linux-arm-gnueabihf": "1.10.6", + "@node-rs/crc32-linux-arm64-gnu": "1.10.6", + "@node-rs/crc32-linux-arm64-musl": "1.10.6", + "@node-rs/crc32-linux-x64-gnu": "1.10.6", + "@node-rs/crc32-linux-x64-musl": "1.10.6", + "@node-rs/crc32-wasm32-wasi": "1.10.6", + "@node-rs/crc32-win32-arm64-msvc": "1.10.6", + "@node-rs/crc32-win32-ia32-msvc": "1.10.6", + "@node-rs/crc32-win32-x64-msvc": "1.10.6" + } + }, + "node_modules/@node-rs/crc32-android-arm-eabi": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm-eabi/-/crc32-android-arm-eabi-1.10.6.tgz", + "integrity": "sha512-vZAMuJXm3TpWPOkkhxdrofWDv+Q+I2oO7ucLRbXyAPmXFNDhHtBxbO1rk9Qzz+M3eep8ieS4/+jCL1Q0zacNMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-android-arm64": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-android-arm64/-/crc32-android-arm64-1.10.6.tgz", + "integrity": "sha512-Vl/JbjCinCw/H9gEpZveWCMjxjcEChDcDBM8S4hKay5yyoRCUHJPuKr4sjVDBeOm+1nwU3oOm6Ca8dyblwp4/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-darwin-arm64": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-arm64/-/crc32-darwin-arm64-1.10.6.tgz", + "integrity": "sha512-kARYANp5GnmsQiViA5Qu74weYQ3phOHSYQf0G+U5wB3NB5JmBHnZcOc46Ig21tTypWtdv7u63TaltJQE41noyg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-darwin-x64": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-x64/-/crc32-darwin-x64-1.10.6.tgz", + "integrity": "sha512-Q99bevJVMfLTISpkpKBlXgtPUItrvTWKFyiqoKH5IvscZmLV++NH4V13Pa17GTBmv9n18OwzgQY4/SRq6PQNVA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-freebsd-x64": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-freebsd-x64/-/crc32-freebsd-x64-1.10.6.tgz", + "integrity": "sha512-66hpawbNjrgnS9EDMErta/lpaqOMrL6a6ee+nlI2viduVOmRZWm9Rg9XdGTK/+c4bQLdtC6jOd+Kp4EyGRYkAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-linux-arm-gnueabihf": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm-gnueabihf/-/crc32-linux-arm-gnueabihf-1.10.6.tgz", + "integrity": "sha512-E8Z0WChH7X6ankbVm8J/Yym19Cq3otx6l4NFPS6JW/cWdjv7iw+Sps2huSug+TBprjbcEA+s4TvEwfDI1KScjg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-linux-arm64-gnu": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-gnu/-/crc32-linux-arm64-gnu-1.10.6.tgz", + "integrity": "sha512-LmWcfDbqAvypX0bQjQVPmQGazh4dLiVklkgHxpV4P0TcQ1DT86H/SWpMBMs/ncF8DGuCQ05cNyMv1iddUDugoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-linux-arm64-musl": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-arm64-musl/-/crc32-linux-arm64-musl-1.10.6.tgz", + "integrity": "sha512-k8ra/bmg0hwRrIEE8JL1p32WfaN9gDlUUpQRWsbxd1WhjqvXea7kKO6K4DwVxyxlPhBS9Gkb5Urq7Y4mXANzaw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-linux-x64-gnu": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-gnu/-/crc32-linux-x64-gnu-1.10.6.tgz", + "integrity": "sha512-IfjtqcuFK7JrSZ9mlAFhb83xgium30PguvRjIMI45C3FJwu18bnLk1oR619IYb/zetQT82MObgmqfKOtgemEKw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/crc32-linux-x64-musl": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-linux-x64-musl/-/crc32-linux-x64-musl-1.10.6.tgz", + "integrity": "sha512-LbFYsA5M9pNunOweSt6uhxenYQF94v3bHDAQRPTQ3rnjn+mK6IC7YTAYoBjvoJP8lVzcvk9hRj8wp4Jyh6Y80g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/@node-rs/crc32-wasm32-wasi": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-wasm32-wasi/-/crc32-wasm32-wasi-1.10.6.tgz", + "integrity": "sha512-KaejdLgHMPsRaxnM+OG9L9XdWL2TabNx80HLdsCOoX9BVhEkfh39OeahBo8lBmidylKbLGMQoGfIKDjq0YMStw==", + "cpu": [ + "wasm32" + ], "dev": true, - "license": "ISC", + "license": "MIT", + "optional": true, "dependencies": { - "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" + "@napi-rs/wasm-runtime": "^0.2.5" }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/@node-rs/crc32-win32-arm64-msvc": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-arm64-msvc/-/crc32-win32-arm64-msvc-1.10.6.tgz", + "integrity": "sha512-x50AXiSxn5Ccn+dCjLf1T7ZpdBiV1Sp5aC+H2ijhJO4alwznvXgWbopPRVhbp2nj0i+Gb6kkDUEyU+508KAdGQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 10" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/@node-rs/crc32-win32-ia32-msvc": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-ia32-msvc/-/crc32-win32-ia32-msvc-1.10.6.tgz", + "integrity": "sha512-DpDxQLaErJF9l36aghe1Mx+cOnYLKYo6qVPqPL9ukJ5rAGLtCdU0C+Zoi3gs9ySm8zmbFgazq/LvmsZYU42aBw==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "node_modules/@node-rs/crc32-win32-x64-msvc": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-x64-msvc/-/crc32-win32-x64-msvc-1.10.6.tgz", + "integrity": "sha512-5B1vXosIIBw1m2Rcnw62IIfH7W9s9f7H7Ma0rRuhT8HR4Xh8QCgw6NJSI2S2MCngsGktYnAhyUvs81b7efTyQw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">= 10" } }, "node_modules/@nodelib/fs.scandir": { @@ -1286,6 +2272,17 @@ "@textlint/ast-node-types": "15.8.0" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -2258,6 +3255,13 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", + "dev": true, + "license": "MIT" + }, "node_modules/cheerio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", @@ -2326,6 +3330,13 @@ "license": "ISC", "optional": true }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true, + "license": "MIT" + }, "node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -2355,6 +3366,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -2472,6 +3493,26 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cross-keychain": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cross-keychain/-/cross-keychain-1.1.0.tgz", + "integrity": "sha512-244DWNdGepLKD5vEn3reZqwzZFiE/LD4U+XV9IaXQbtIXKvQkf0VkRaOj/9vPYauPdR12PSGB3U0cE7jJi3WTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/prompts": "^7.8.6", + "meow": "^14.0.0" + }, + "bin": { + "cross-keychain": "dist/cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@napi-rs/keyring": "^1.2.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2612,6 +3653,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", @@ -2625,6 +3684,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3350,6 +4427,27 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -3557,6 +4655,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", @@ -3607,6 +4722,19 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -3826,6 +4954,19 @@ "license": "ISC", "optional": true }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", @@ -3905,6 +5046,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-it-type": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/is-it-type/-/is-it-type-5.1.3.tgz", + "integrity": "sha512-AX2uU0HW+TxagTgQXOJY7+2fbFHemC7YFBwN1XqD8qQMKdtfbOC8OC3fUb4s5NU59a3662Dzwto8tWDdZYRXxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globalthis": "^1.0.2" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4388,6 +5542,19 @@ "dev": true, "license": "MIT" }, + "node_modules/meow": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz", + "integrity": "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4742,6 +5909,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4886,6 +6063,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ovsx": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-1.1.0.tgz", + "integrity": "sha512-portv4pwDJTlZrvgDMpLTgA+Ctu60kRQfD/cBu4JBhakXabeHVoBAzOba8jMt7RAq+4C0PMHvANalu/S3+s6+w==", + "dev": true, + "license": "EPL-2.0", + "dependencies": { + "@inquirer/prompts": "^7.10.1", + "@vscode/vsce": "^3.7.1", + "commander": "^6.2.1", + "cross-keychain": "^1.1.0", + "follow-redirects": "^1.16.0", + "is-ci": "^2.0.0", + "leven": "^3.1.0", + "semver": "^7.6.0", + "tmp": "^0.2.3", + "yauzl-promise": "^4.0.0" + }, + "bin": { + "ovsx": "bin/ovsx" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/ovsx/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5676,6 +6888,16 @@ "simple-concat": "^1.0.0" } }, + "node_modules/simple-invariant": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/simple-invariant/-/simple-invariant-2.0.1.tgz", + "integrity": "sha512-1sbhsxqI+I2tqlmjbz99GXNmZtr6tKIyEgGGnJw/MKGblalqk/XoOYYFJlBzTKZCxx8kLaD3FD5s9BEEjx5Pyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -6712,6 +7934,21 @@ "node": ">=12" } }, + "node_modules/yauzl-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yauzl-promise/-/yauzl-promise-4.0.0.tgz", + "integrity": "sha512-/HCXpyHXJQQHvFq9noqrjfa/WpQC2XYs3vI7tBiAi4QiIU1knvYhZGaO1QPjwIVMdqflxbmwgMXtYeaRiAE0CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@node-rs/crc32": "^1.7.0", + "is-it-type": "^5.1.2", + "simple-invariant": "^2.0.1" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/yazl": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", @@ -6733,6 +7970,19 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 260e51f..529e8b3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "description": "Warn developers about unwanted extensions", "icon": "icon.png", "version": "1.2.4", + "license": "MIT", "repository": { + "type": "git", "url": "https://github.com/SoulcodeAgency/vscode-unwanted-extensions" }, "publisher": "Soulcode", @@ -59,13 +61,15 @@ "package:preRelease": "vsce package --pre-release", "publish": "vsce publish", "publish:preRelease": "vsce publish --pre-release", + "publish:openvsx": "ovsx publish", + "publish:openvsx:preRelease": "ovsx publish --pre-release", "vscode:prepublish": "npm run esbuild-base -- --minify", "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=dist/extension.js --external:vscode --format=cjs --platform=node", "esbuild": "npm run esbuild-base -- --sourcemap", "esbuild-watch": "npm run esbuild-base -- --sourcemap --watch", "test-compile": "tsc -p ./", - "release": "npm run compile && npm run package && npm run publish", - "pre-release": "npm run compile && npm run package:preRelease && npm run publish:preRelease" + "release": "npm run compile && npm run package && npm run publish && npm run publish:openvsx", + "pre-release": "npm run compile && npm run package:preRelease && npm run publish:preRelease && npm run publish:openvsx:preRelease" }, "devDependencies": { "@types/hjson": "2.4.6", @@ -80,6 +84,7 @@ "glob": "13.0.6", "jiti": "2.7.0", "mocha": "11.8.0", + "ovsx": "1.1.0", "typescript": "6.0.3", "typescript-eslint": "8.66.0" }, diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..338b460 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "node", + "include-component-in-tag": false, + "include-v-in-tag": true, + "versioning": "always-bump-patch", + "changelog-sections": [ + { "type": "feat", "section": "Features" }, + { "type": "fix", "section": "Bug Fixes" }, + { "type": "perf", "section": "Performance Improvements" }, + { "type": "revert", "section": "Reverts" }, + { "type": "refactor", "section": "Code Refactoring" }, + { "type": "build", "section": "Build System" }, + { "type": "chore", "section": "Miscellaneous Chores" }, + { "type": "ci", "section": "Continuous Integration", "hidden": true }, + { "type": "docs", "section": "Documentation", "hidden": true }, + { "type": "style", "section": "Styles", "hidden": true }, + { "type": "test", "section": "Tests", "hidden": true } + ], + "packages": { + ".": { + "package-name": "vscode-unwanted-extensions" + } + } +}