Skip to content

Release v1.0.3 — web build, eight-locale localization, CI - #26

Merged
ElecTreeFrying merged 17 commits into
mainfrom
release/v1.0.3
Aug 8, 2026
Merged

ElecTreeFrying merged 17 commits into
mainfrom
release/v1.0.3

Conversation

@ElecTreeFrying

Copy link
Copy Markdown
Owner

Release branch for v1.0.3. Merges into main, after which R3 cuts the version commit, tag, and the three publish targets.

User-facing

  • Web build. A browser bundle now ships beside the desktop one, so the extension loads on vscode.dev and github.dev — dragging a file in, or the paste-as-import commands, produce the same relative-path import there. package.json gains browser: ./dist/web/extension.js.
  • Eight-locale manifest localization — every command title, displayName, description, configuration.title, and each setting's title / description / enumDescriptions become %key% placeholders resolved from package.nls.json plus zh-cn, es, fr, pt-br, ru, de, ja, tr. The Auto Import brand prefix stays verbatim in every language, and the legacy extension.* ids resolve through the same keys as their auto-import.* twins.
  • Deliberately not localized — configuration enum values and defaults are runtime-matched and stay English (the three-site config sync depends on those literals); runtime toasts, pickers, and button labels likewise, since the two-site button-label byte-sync depends on them.
  • README — Open VSX badge and listing link, verified-publisher note, a Web: line in Compatibility, WinterNova5 in prose, GitHub Sponsors.

How the web build works

esbuild.js grows a second target at platform: 'browser', which makes esbuild reject any Node built-in at build time — that rejection is the web-cleanliness gate. path is the only built-in the runtime code imports, so it is the only thing aliased: in the browser target the bare path specifier resolves to src/path/_browser.ts, a POSIX-only stand-in covered by src/test/path/browser-shim.test.ts. The node target gets no alias, so the desktop bundle keeps Node's own path, Windows behaviour included, completely untouched.

Maintainer-facing

  • CI — npm ci, npm run compile, then npm run package, which is exactly what vscode:prepublish runs.
  • Dependabot — weekly.
  • Community health — code of conduct, contributing guide, security policy, funding config.

The POSIX stand-in the web bundle uses in place of Node's `path` returned "."
for a basename of "..", where Node returns "". Its `index <= 0` guard covers a
lone "." but not "..", whose last dot sits at index 1 and got sliced out as a
bare extension. `parse()` inherited the same result through its `ext`/`name`
fields.

Found by differentially fuzzing the shim against `path.posix`: 340,850 checks
across generated absolute paths. `relative()` — the function every generated
import actually goes through — matched Node on all 240,560 of its cases both
before and after, so no import path was ever affected.

Node contradicts itself on the single input "/..", where `parse().ext` reports
"." while `extname()` reports "" for the same string. The shim keeps "" in both,
matching `extname` and its own nested-path behaviour; the module note records
why that deviation is deliberate rather than an oversight.

Web bundle only — the desktop bundle keeps Node's own `path` and its sha256 is
unchanged by this commit.
CI proved `npm run compile` passed, which is not what a release depends on. Two
gaps closed:

`.github/scripts/check-nls.js` — a dependency-free gate over the package.nls
bundles. VS Code substitutes a manifest string only when the whole value matches
%key%, so an unresolved key renders literally in the UI and a placeholder
embedded in a longer string never substitutes at all. Neither is visible to tsc,
eslint, or vsce. It also rejects keys localized in runtime-matched positions
(enum values, defaults, command ids), keys missing from any locale, duplicates
that JSON.parse would silently collapse, and a .vscodeignore glob that would
stop the bundles shipping. Verified to fire on each of those cases, not just to
pass on a clean tree.

A `package` job that builds the actual VSIX and inspects the archive: all nine
nls bundles present, and no maintainer-only tree (src/, .github/, CLAUDE.md,
SPEC.md, and each repo's own) leaked in. This is the gate the publish wave
depends on and the one CI never ran.

Also: job timeouts, and a node 20/22 build matrix so a toolchain break on a
newer runtime surfaces here rather than on a dev machine.
The template's checklist covers what CI cannot: that a manifest string change
reached all eight locale files, that no enum value or default was localized,
that README and CHANGELOG links are absolute (both ship inside the VSIX, where
relative paths do not resolve), and that the version was not hand-bumped.

CODEOWNERS makes every pull request, including Dependabot's, request a review
rather than sit unnoticed. It uses the ElecTreeFrying account handle, which is
unchanged — only the publisher's display name is WinterNova5.
The release localizes every command title and setting into eight display
languages, and the SPEC documents it — but the README, which IS the Marketplace
and Open VSX listing, said nothing. Anyone browsing the listing had no way to
know the extension speaks their language.

Added as a Compatibility bullet, directly below the web-build line added earlier
in this release and worded to match. It records that the brand prefix stays
verbatim in every language, so a single palette search still surfaces the whole
command set.

The changelog entry's Compatibility sentence now mentions it too.
`vsce` and `@vscode/vsce` are two different npm packages. The unscoped one is
deprecated and frozen at 2.15.0, and that version rejects any manifest with
`main` but no `activationEvents` — which VS Code has auto-generated from
`contributes.commands` since 1.74. Nothing declared @vscode/vsce, so `npx vsce`
resolved to the 2023 binary from an npx cache and failed with an error that
reads like a manifest bug rather than a stale tool.

Declaring it makes the correct version the only reachable one. It was already
present in this repo's lockfile as an undeclared transitive dev dependency,
which meant any unrelated upgrade could have removed it silently.

CI's packaging step now invokes ./node_modules/.bin/vsce by explicit path
rather than `npx vsce` or `npm exec -- vsce`. Both of those fall back to the
registry when the binary is absent, which is exactly how the deprecated package
gets pulled in; the explicit path can only resolve to the locked version, so CI
and a local publish run are guaranteed to use the same tool.

Dev-only. Verified across all four repos: zero production dependencies changed,
esbuild and typescript unmoved, and every shipped bundle byte-identical before
and after — auto-import 23ac46b3…, drag-import eabd651b…, insert-random-text
bfa4e191…. The large lockfile diffs are npm restructuring the dev tree.
@ElecTreeFrying
ElecTreeFrying merged commit e5e75c7 into main Aug 8, 2026
5 checks 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.

1 participant