take the release version from the tag - #11
Merged
Conversation
The version lived in five files, kept in step by a script on npm's `version` lifecycle hook. Every release therefore began with a commit whose only content was that number written down five times, and the tag had to be created from that commit or the publish guard rejected it. package.json now carries 0.0.0-dev in git and the release workflow stamps the tag into it immediately before publishing, without committing. Verified end to end: tag v0.2.2 produces keenetic-mcp-0.2.2.tgz whose handshake reports 0.2.2. The plugin manifests lose the field entirely. They are read straight from the repository by Claude Code and Codex, never built and never published, so there is no point in the pipeline where a version could be stamped into them. The field is optional and the official Anthropic plugins omit it too. .mcp.json keeps a pin, narrowed to keenetic-mcp@^0. It is the one version-shaped string left, and the exception is deliberate: it stops a major upgrade arriving unannounced on people who installed the plugin, while tracking only the major means it changes once, at 1.0. A checkout reports 0.0.0-dev. KEENETIC_MCP_VERSION overrides that, and a .env next to package.json is read if it exists - the package root rather than the working directory, so an installed copy never reads one and an agent cannot steer it by choosing where to launch the server. Node gives a variable already in the environment precedence over that file, so the same .env can hold router credentials without shadowing real ones. scripts/sync-versions.ts is gone, along with its CI step. The invariant it enforced is now a test, which also covers the Codex catalogue the script never looked at, and which the release job already runs before it stamps anything.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The version lived in five files kept in step by a script on npm's
versionhook, so every release started with a commit whose only content was that number written down five times.Now
package.jsoncarries0.0.0-devin git and the release workflow stamps the tag into it just before publishing, without committing. A release isgit push origin v0.2.2and nothing else.The plugin manifests lose the field entirely: Claude Code and Codex read them straight from the repository, so there is no point in the pipeline where a version could be stamped in. It is optional, and the official Anthropic plugins omit it too.
.mcp.jsonkeeps a pin, narrowed tokeenetic-mcp@^0so it tracks the major only and is edited once, at 1.0.A checkout reports
0.0.0-dev.KEENETIC_MCP_VERSIONoverrides it, and a.envbesidepackage.jsonis read if present - the package root rather than the working directory, so an installed copy never reads one. A real environment variable still wins over that file, which means the same.envcan hold router credentials without shadowing real ones.scripts/sync-versions.tsand its CI step are gone. The invariant is a test now, which also covers the Codex catalogue the script never looked at, and which the release job runs before it stamps anything.Verified
Simulated the whole release path rather than reasoning about it:
npm version 0.2.2 --no-git-tag-versionon the tagged tree,npm pack, install the tarball, speak MCP to it.Precedence checked in all three directions:
.envalone gives7.7.7-from-dotenv, an environment variable over it gives8.8.8-from-shell, neither gives0.0.0-dev. The tag pattern acceptsv1.0.0-rc.1and rejectsv0.2andvfoo.217 tests, typecheck and build clean.