Skip to content

Release v0.3.0 - #5

Merged
JesseHerrick merged 5 commits into
mainfrom
release-v0.3.0
Sep 11, 2026
Merged

JesseHerrick merged 5 commits into
mainfrom
release-v0.3.0

Conversation

@remotecom

Copy link
Copy Markdown
Contributor

Prepares the v0.3.0 release, with fixes found while reviewing the changes since v0.2.1.

Review of the changes since v0.2.1

The auto-install work is correct. I checked it against the live upstream repo rather than by reading alone:

  • The asset names in platformRelease() match the real v0.7.1 release, and checksums.txt uses the <hash> <filename> format that verifyChecksum() parses.
  • The archive layout is dexter_Darwin_arm64/dexter, matching the tar path the installer extracts.
  • dexter version prints 0.7.1 with no v prefix, so the update comparison works.
  • Upstream publishes no Intel macOS and no Windows build, so the platform map is complete and the "best effort Windows" wording is accurate.
  • The checksum is verified before extraction, redirects are capped, and no token is forwarded.

Bugs fixed

  • dexter.restart was never contributed. It was registered in code but missing from contributes.commands, so it did not appear in the Command Palette — which the auto-update notification depends on.
  • The restart command did not apply settings. Settings were read once during activation and baked into both serverOptions and clientOptions, so a restart re-sent the old values and a changed dexter.binary was ignored until a window reload. Startup now lives in startClient, which re-reads settings and re-resolves the binary on every call. Changing any dexter.* setting offers a restart.
  • The command was registered after client.start(), so it did not exist when startup failed, and the restart did not await start(), losing errors.
  • dexter.binary was passed straight to spawn. A missing or non-executable path failed with a raw spawn error. It is now validated, ~ is expanded, a relative path resolves against the workspace folder, and a bare command name is looked up on PATH.
  • Dev files were shipped inside the extension. Makefile, .tool-versions, and the old .gitlab-ci.yml were all in the .vsix.
  • maxTransientDocuments was not exposed despite being a documented upstream LSP option.
  • The changelog had no v0.2.1 section, so that version shipped undocumented. Backfilled.

Release pipeline

.gitlab-ci.yml could not run on GitHub, and it never published to a marketplace anyway — it only uploaded a .vsix to the GitLab package registry. So the previous README claim that "CI will pick up the tag and publish the extension automatically" was wrong twice over, and every release so far was manual.

Two workflows replace it:

  • ci.yml compiles, runs the tests, and packages the extension on every pull request, so a malformed package.json fails before a tag rather than after.
  • release.yml runs on a v*.*.* tag. It verifies the tag matches package.json, builds a package for each marketplace, and creates the GitHub release using that version's CHANGELOG.md section as the notes.

Marketplace publishing stays manual via make publish.

Publisher namespaces

The two marketplaces use different publisher namespaces, and a .vsix embeds its publisher, so one file cannot serve both:

Editor Marketplace Extension ID
VS Code Visual Studio Marketplace remoteoss.dexter-lsp
Cursor Open VSX remote-com-oss.dexter-lsp

make package-openvsx swaps the publisher, builds, and restores package.json via a shell trap, so it restores even on failure.

Tests

The binary resolution, checksum verification, and asset mapping all run on a user's machine and were untested. There is now a suite covering them. It stubs the vscode module through a loader hook, so it runs under plain Node with the built-in test runner — no editor, no new dependencies.

The mapping tests assert that darwin-x64 and win32 stay unmapped, so adding a target upstream does not publish would fail the suite rather than 404 at install time.

Verified against mutations — dropping ~ expansion, adding a darwin-x64 target, making the checksum compare case-sensitive, and treating the default "dexter" value as a configured path are each caught.

Docs

  • Documented editor.defaultFormatter for both editors. This release stopped forcing format on save off for Elixir, so users with another Elixir extension may now need to set it, and the ID differs per editor.
  • Added a Commands section and documented the dexter.binary path forms.

Not done

  • Update notifications are still dismissible without recourse. If dismissed, the current session keeps the old server until the window reloads. This self-resolves on the next editor start, and re-prompting would be a nag.
  • workspaceContains:mix.exs activation would start the ~11s first index at project open, but would also trigger a binary download for anyone who merely has a mix.exs in a polyglot repo. The current onLanguage trigger is the more conservative choice.
  • The update check saves its timestamp before it succeeds, so a failed network call still suppresses the next check for 24 hours. Possibly deliberate rate limiting.

Test plan

  • npm test — 25 tests pass
  • make package and make package-openvsx both build, with the correct embedded publisher, and package.json is left at remoteoss
  • Both workflows parse, and the changelog extraction was checked against the newest entry, a mid-file entry, and an absent version
  • Neither workflow has run before this PR, so ci.yml going green here is the first real execution

🤖 Generated with Claude Code

JesseHerrick and others added 5 commits September 10, 2026 01:32
Bump the version, add the v0.3.0 changelog entry, and backfill the missing
v0.2.1 entry.

Fixes found while reviewing the changes since v0.2.1:

- Contribute `dexter.restart` in package.json. The command was registered in
  code but never declared, so it did not appear in the Command Palette. The
  auto-update notification tells users to restart, so they need it.
- Register the restart command before `client.start()`, so it still exists when
  startup fails, and await the restart so errors are reported.
- Expose the `dexter.maxTransientDocuments` LSP option that upstream documents.

Release process:

- Document that releases are published by hand. The `.gitlab-ci.yml` file does
  not run on GitHub, and it never published to a marketplace anyway.
- Add `package-openvsx` and the publish targets. The two marketplaces use
  different publisher namespaces (`remoteoss` on the VS Code Marketplace,
  `remote-com-oss` on Open VSX) and a .vsix embeds its publisher, so each one
  needs its own package.
- Make `make release` check that the tag matches package.json.

Docs:

- Document `editor.defaultFormatter` for both editors. This release stopped
  forcing format on save off for Elixir, so users may need to set it.
- Add a Commands section.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `.gitlab-ci.yml` file could not run on GitHub, and it never published to a
marketplace — it only uploaded a .vsix to the GitLab package registry.

Two workflows replace it:

- `ci.yml` compiles on pull requests and pushes to main, then packages the
  extension so a malformed package.json fails before a tag, not after.
- `release.yml` runs on a `v*.*.*` tag. It checks the tag against
  package.json, builds a package for each marketplace publisher, and creates
  the GitHub release with that version's CHANGELOG.md section as the notes.

Marketplace publishing stays manual via `make publish`.

Also stop shipping dev files inside the extension. `Makefile`,
`.tool-versions`, and the old `.gitlab-ci.yml` were all bundled into the
.vsix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Settings were read once during activation and baked into both serverOptions
and clientOptions, so the restart command re-sent the old values and a changed
`dexter.binary` was ignored until the window reloaded.

Move the start into `startClient`, which reads settings and re-resolves the
binary on every call. The restart command now disposes the client and builds a
new one, so a restart really does apply the current settings. Changing any
`dexter.*` setting offers a restart.

Also validate `dexter.binary` instead of passing it straight to spawn. A path
that does not exist, or one that is not executable, now reports which value is
wrong and how to correct it. A `~` path is expanded, a relative path resolves
against the workspace folder, and a bare command name is looked up on PATH.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`make package` ran `npm install` unconditionally, so the release workflow did
it again right after `npm ci`. That wasted time and let `npm install` rewrite
the lockfile in CI.

Make `node_modules` a real target that depends on `package-lock.json`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The binary resolution, checksum verification, and release asset mapping added
in this release all run on a user's machine and were untested. Add a suite that
covers them.

The tests stub the `vscode` module through a loader hook, so they run under
plain Node with the built-in test runner and need no editor and no new
dependencies. CI runs them on every pull request.

The asset mapping tests assert that darwin-x64 and win32 stay unmapped, so
adding a target upstream does not publish would fail rather than 404 at install
time. Checked against mutations: dropping `~` expansion, adding a darwin-x64
target, making the checksum compare case-sensitive, and treating the default
"dexter" value as a configured path are all caught.

Metadata: add the Formatters category now that the extension formats, add
phoenix/heex/livebook/formatter keywords, and add homepage and bugs fields.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@JesseHerrick
JesseHerrick merged commit 8c288a6 into main Sep 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants