Repository navigation
feat(agents): track agent versions live from npm - #576
YauheniHHH wants to merge 57 commits into
Conversation
4876e08 to
f5f2aa5
Compare
The earlier change quoted exec()'s command whenever shell mode was on, which turned caller-assembled command lines (native installers' `curl | bash` / `irm | iex`, user-configured hooks) into one quoted, nonexistent program name. Quote the command only in the structured exec(bin, args) form, where an env-overridden binary name still needs it; zero-arg command lines reach the shell unchanged. Adds unmocked exec() tests for the raw pipe line, arg quoting, and an injection attempt through the command name. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
When the npm lookup failed, getCachedLatestVersion returned the old cached entry however old it was, which callers then presented as the current version. It now returns null unless the entry is still inside its 24h TTL, logs every failure via logger.warn (log file only), keeps a successfully fetched value even if persisting it fails, and treats a future fetchedAt as stale. Cache writes are now atomic via a shared writeFileAtomically helper in src/utils (the VS Code connector's writeAtomically delegates to it). Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
With version checks off or the npm lookup failing, the resolver used to return the hardcoded fallback constant, which every consumer then presented as the current version (e.g. "tracking Kimi v0.42.0" while Kimi is 2.x) — against ticket criteria codemie-ai#4 and codemie-ai#5. - resolveSupportedVersionDetailed() returns {version, isLive}; checkVersionCompatibility() exposes it as versionKnown. When unknown, the launch notice, doctor, setup and update stay silent. The minimumSupportedVersion gate is computed separately and still blocks. - install --supported resolves to the live version or the `latest` channel, never the stale constant; with the version unknown it now installs instead of silently returning "already installed". - The versionChecks toggle is resolved env var > project > global, so a global false holds in projects with their own workspace block and the env var works without an active profile. - run() resolves compatibility once for both checks, so an offline launch pays one lookup instead of two. - kimi-acp is live-tracked like kimi (same package and binary). - Codex/Gemini self-update suppression only applies while checks are on, and Codex only writes into the CodeMie-owned CODEX_HOME. - update/install print a dim note instead of misleading output when checks are off; the below-minimum message no longer prints "vlatest". Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Adds an "Agent Version Checks" section to CONFIGURATION.md (env var, config example, precedence, behavior when off). Revises the EPMCDME-14767 spec so it describes the implemented behavior: an unknown tracked version is reported as unknown instead of falling back to the hardcoded constant, per ticket criteria codemie-ai#4 and codemie-ai#5. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ache `doctor --refresh-versions` deleted the whole version cache, so run offline it threw away entries that were still valid. It now re-checks each live-tracked package in place, bypassing only the 24h TTL, keeps the existing entry when a lookup fails, and reports how many packages were checked. clearVersionCache() had no other callers and is removed. The cache also treats npm output that isn't a version string as a failed lookup (never cached), and ignores malformed cache files or entries so the next successful write repairs them. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
The "already set" check pattern-matched the text before the first line starting with `[`, so a quoted key, or a key after a multi-line array, was missed and a duplicate top-level key made config.toml invalid. It now parses the file with @iarna/toml, checks only the top level, and leaves a file that doesn't parse untouched. Adds tests for those TOML cases, the Windows `shell` option in Codex and Gemini getVersion, and Gemini's auto-update default (checks on, checks off, existing user value kept). Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Asserts that a live-tracked agent whose lookup fails is never offered its hardcoded fallback as an update, that --force-refresh re-checks npm despite a fresh cache entry, and that it is a no-op with a note when version checks are disabled. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Documents that the Codex/Gemini self-update settings CodeMie adds stay after version checks are turned off, and how to restore the agents' own auto-update. Updates spec section 5 and its criterion to the "tracking" wording used throughout, plus the per-package doctor refresh and cache validation behavior. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…mport Adds JSDoc to isLiveTrackedAgent, resolveSupportedVersionDetailed and getCachedLatestVersion, and replaces the wildcard fs import in version-cache.ts with a named readFile import. Refs PR codemie-ai#576 review Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Existing mocks returned the pinned fallback as the "live" value, so a
bug that compared against or installed the fallback would pass. The
notice, Codex compatibility and Codex/Claude installVersion('supported')
tests now use a live version that differs from the fallback, and cover
the not-live case. Adds the first Claude installVersion tests.
Refs PR codemie-ai#576 review
Generated with AI
Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Spawning `npm view` took 2.5-3.8s per package on Windows (about 4s each in parallel), so the 3s lookup limit was routinely hit and live version tracking silently did nothing. The version cache now makes one HTTP GET to <registry>/<name>/latest (about 0.25s), honoring npm's registry and @scope:registry settings and HTTPS_PROXY/HTTP_PROXY/NO_PROXY. Also, per PR review, removes changes this ticket doesn't need: the forced-refresh path, the shared atomic-write helper (a torn cache file already reads as empty), and the exec() command quoting, which moves to its own PR. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Copilot CLI is not one of the ticket's four agents, so it leaves the live-tracked list. Agents outside that list keep their maintainer-pinned version as current, as on main, instead of losing their version notice. The version-checks toggle now applies to every agent. The resolver's flag is renamed isLive -> isCurrent to match that meaning. Also drops the forceRefresh input, points the Codex update-check write back at the existing writeAtomically helper, and shortens its comment. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…nstall Removes `doctor --refresh-versions` and `update --force-refresh`, which the ticket doesn't ask for (doctor is out of its scope). `install --supported` with an unknown tracked version now asks before reinstalling an already-installed agent with the latest release, instead of reinstalling silently. Setup and install copy no longer say "supported version", and a stale setup.ts comment and the unused CODEMIE_VERSION_CHECKS_ENABLED mapping in ConfigLoader are removed. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Updates CONFIGURATION.md and the spec for the direct registry lookup, the four tracked agents, and the removed refresh flags. Removes the planning run logs and review artifacts from the task folder, keeping spec.md and plan.md. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
df40b74 to
2976808
Compare
The earlier change quoted exec()'s command whenever shell mode was on, which turned caller-assembled command lines (native installers' `curl | bash` / `irm | iex`, user-configured hooks) into one quoted, nonexistent program name. Quote the command only in the structured exec(bin, args) form, where an env-overridden binary name still needs it; zero-arg command lines reach the shell unchanged. Adds unmocked exec() tests for the raw pipe line, arg quoting, and an injection attempt through the command name. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
When the npm lookup failed, getCachedLatestVersion returned the old cached entry however old it was, which callers then presented as the current version. It now returns null unless the entry is still inside its 24h TTL, logs every failure via logger.warn (log file only), keeps a successfully fetched value even if persisting it fails, and treats a future fetchedAt as stale. Cache writes are now atomic via a shared writeFileAtomically helper in src/utils (the VS Code connector's writeAtomically delegates to it). Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
With version checks off or the npm lookup failing, the resolver used to return the hardcoded fallback constant, which every consumer then presented as the current version (e.g. "tracking Kimi v0.42.0" while Kimi is 2.x) — against ticket criteria codemie-ai#4 and codemie-ai#5. - resolveSupportedVersionDetailed() returns {version, isLive}; checkVersionCompatibility() exposes it as versionKnown. When unknown, the launch notice, doctor, setup and update stay silent. The minimumSupportedVersion gate is computed separately and still blocks. - install --supported resolves to the live version or the `latest` channel, never the stale constant; with the version unknown it now installs instead of silently returning "already installed". - The versionChecks toggle is resolved env var > project > global, so a global false holds in projects with their own workspace block and the env var works without an active profile. - run() resolves compatibility once for both checks, so an offline launch pays one lookup instead of two. - kimi-acp is live-tracked like kimi (same package and binary). - Codex/Gemini self-update suppression only applies while checks are on, and Codex only writes into the CodeMie-owned CODEX_HOME. - update/install print a dim note instead of misleading output when checks are off; the below-minimum message no longer prints "vlatest". Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Adds an "Agent Version Checks" section to CONFIGURATION.md (env var, config example, precedence, behavior when off). Revises the EPMCDME-14767 spec so it describes the implemented behavior: an unknown tracked version is reported as unknown instead of falling back to the hardcoded constant, per ticket criteria codemie-ai#4 and codemie-ai#5. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ache `doctor --refresh-versions` deleted the whole version cache, so run offline it threw away entries that were still valid. It now re-checks each live-tracked package in place, bypassing only the 24h TTL, keeps the existing entry when a lookup fails, and reports how many packages were checked. clearVersionCache() had no other callers and is removed. The cache also treats npm output that isn't a version string as a failed lookup (never cached), and ignores malformed cache files or entries so the next successful write repairs them. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
The "already set" check pattern-matched the text before the first line starting with `[`, so a quoted key, or a key after a multi-line array, was missed and a duplicate top-level key made config.toml invalid. It now parses the file with @iarna/toml, checks only the top level, and leaves a file that doesn't parse untouched. Adds tests for those TOML cases, the Windows `shell` option in Codex and Gemini getVersion, and Gemini's auto-update default (checks on, checks off, existing user value kept). Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Asserts that a live-tracked agent whose lookup fails is never offered its hardcoded fallback as an update, that --force-refresh re-checks npm despite a fresh cache entry, and that it is a no-op with a note when version checks are disabled. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Documents that the Codex/Gemini self-update settings CodeMie adds stay after version checks are turned off, and how to restore the agents' own auto-update. Updates spec section 5 and its criterion to the "tracking" wording used throughout, plus the per-package doctor refresh and cache validation behavior. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…mport Adds JSDoc to isLiveTrackedAgent, resolveSupportedVersionDetailed and getCachedLatestVersion, and replaces the wildcard fs import in version-cache.ts with a named readFile import. Refs PR codemie-ai#576 review Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Existing mocks returned the pinned fallback as the "live" value, so a
bug that compared against or installed the fallback would pass. The
notice, Codex compatibility and Codex/Claude installVersion('supported')
tests now use a live version that differs from the fallback, and cover
the not-live case. Adds the first Claude installVersion tests.
Refs PR codemie-ai#576 review
Generated with AI
Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Spawning `npm view` took 2.5-3.8s per package on Windows (about 4s each in parallel), so the 3s lookup limit was routinely hit and live version tracking silently did nothing. The version cache now makes one HTTP GET to <registry>/<name>/latest (about 0.25s), honoring npm's registry and @scope:registry settings and HTTPS_PROXY/HTTP_PROXY/NO_PROXY. Also, per PR review, removes changes this ticket doesn't need: the forced-refresh path, the shared atomic-write helper (a torn cache file already reads as empty), and the exec() command quoting, which moves to its own PR. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Updates CONFIGURATION.md and the spec for the direct registry lookup, the four tracked agents, and the removed refresh flags. Removes the planning run logs and review artifacts from the task folder, keeping spec.md and plan.md. Refs PR codemie-ai#576 review, EPMCDME-14767 Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
An explicit update check bypasses the 24h version cache (the result is still written back), so a release shows up immediately instead of after up to a day. Launch, setup and doctor keep using the cache. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
The tracked-version constants of Claude, Codex, Gemini and Kimi only mark an agent as version-checked now; describe them so and drop the "UPDATE THIS" instructions. The minimum stays hand-maintained. Codex writes its config.toml with fs writeFile instead of importing a CLI connector helper, so the plugin no longer depends on the CLI layer. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Also drop the doctor guard on metadata.supportedVersion, which the versionKnown check already covers. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
With live tracking, an agent's own self-update moves it to npm's latest release, which is the tracked version, so suppressing it no longer serves the feature. It also left a lasting edit in the user's shared ~/.gemini/settings.json. Drop the suppression, its tests and docs, and revert an unrelated Copilot comment edit. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Keep only the wording change ("tracked") in console output; revert the
unrelated warning-glyph and indentation edits.
Generated with AI
Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
The registry lookup runs on every agent launch, so a checked-out repo
could route env secrets (a token in registry=https://host/${TOKEN}/) to
its own host. Expand ${VAR} only in the user .npmrc and ignore project
values that need it. Also strip quotes around .npmrc values.
Generated with AI
Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
A live-tracked agent ahead of the tracked version has usually self-updated since the cached lookup. Skip the launch notice, setup advice and doctor hint there; pinned agents keep the notice. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Update-all dropped agents whose latest-version lookup failed and, when offline, printed "No updatable agents installed". List them as "Could not check". Docs: a launch can wait up to 3s while offline. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
An offline or firewalled machine waited up to 3s on every agent launch, since failed lookups weren't remembered. Record the failure time and skip lookups for that package for 10 minutes; a success clears it and codemie update (bypassCache) always retries. The expired version itself is still never served. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
npm installs are .cmd shims that spawn() can't start without a shell, so getVersion() returned null and no version check ran for npm-installed Kimi or Claude on Windows. Also share the "ahead of live tracking" rule between the launch notice and doctor via isAheadOfLiveTracking(). Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…roxy The live version lookup now gets its proxy from system-proxy's getProxyAgentForUrl, so it also works behind a Windows system proxy or PAC (codemie-ai#571), and drops its own NO_PROXY matching. npm's https-proxy/proxy/noproxy settings still apply and now take precedence over HTTPS_PROXY/HTTP_PROXY, matching npm. Proxy discovery counts against the lookup's existing timeout. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
940bea3 to
b7922bf
Compare
… version
The agent suite's global setup compared the installed Claude with
CLAUDE_SUPPORTED_VERSION, which is now only a marker: installVersion('supported')
installs the live tracked version instead. The check could never match, so
Claude was reinstalled on every run and the log claimed the constant's version.
It now asks resolveSupportedInstallVersion for the same target the installer
uses, keeps an installed Claude when that target is unknown, and logs the
version actually installed.
Generated with AI
Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Since the registry lookup resolves its proxy through system-proxy, these tests read the machine's Windows proxy settings. That registry read could outlast the tests' short timeouts under full parallel load, failing the first fetch test. Set CODEMIE_NO_SYSTEM_PROXY=1 so only the npm/env proxy logic is tested. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
|
@mykolanehrych Thanks — resolved. I rebased onto the latest main; the conflict was only the import block in BaseAgentAdapter.ts (vs. the system-proxy imports from #571), and the PR is mergeable again.
|
| ): Promise<string | null> { | ||
| if (!options.bypassCache) { | ||
| const cache = await loadCache(); | ||
| const entry = cache.packages[packageName]; |
There was a problem hiding this comment.
Security (medium/low): version cache is shared across registries, so a project .npmrc can poison it
getCachedLatestVersion keys the cache by package name only (here and at :155 on write). The registry it queries is resolved from the project .npmrc as well as the user one (src/utils/npm-registry.ts:61). The result is written to the global ~/.codemie/version-cache.json with a 24h TTL.
Scenario
- A repo ships a
.npmrcwithregistry=https://attacker.example/(or@anthropic-ai:registry=...). - The user runs
codemie claudein that repo. The lookup goes to the attacker's server, which returns{"version":"1.0.5"}, an old but real release. It passes theNPM_VERSION_PATTERNandextractVersionchecks. - The value is cached under the package name. In any other project, a cache hit is served without a lookup, and
resolveSupportedInstallVersionreturns1.0.5as the install target forinstall --supportedorupdate.
Impact
- The attacker can steer the install to an older real version, for example one with known vulnerabilities.
isAheadOfLiveTrackingsuppresses update notices when the installed version is newer, so a downgrade is less likely to be noticed.- No code injection: the version is digits-only and the install still comes from the real registry. Pointing a repo at another registry is normal npm behavior. The new part is that the effect outlives the repo through the shared cache.
Related, lower priority: http: registries are accepted (npm-registry.ts:139). That is fine for internal mirrors configured by the user, but it is another reason to trust only user-level registry config here.
The live version lookup read the current project's .npmrc, and its result is cached globally under the package name. A checked-out repo could point the lookup at its own registry or proxy and plant an older release as the tracked version for every project for 24h (or a lookup failure, silencing checks for 10 minutes). The lookup now reads only the user .npmrc and npm_config_* env vars. Also apply NO_PROXY and npm's noproxy before either proxy source, so noproxy covers HTTPS_PROXY/HTTP_PROXY and the system proxy too, and update the spec and docs to match. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ache Under npm run/npx, npm exports the project's .npmrc as npm_config_* env vars, so a repo could still pick the registry the lookup uses. Those env vars, npm_config_userconfig included, are now ignored when CodeMie was launched by npm, and only ~/.npmrc is read. Cache and failure entries are keyed by registry and package, so a value from one registry never reaches lookups against another. An empty CODEMIE_VERSION_CHECKS_ENABLED no longer overrides an explicit config false. Adds a test for the Claude update path and updates the spec and docs. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…registries - run(): a failing shared version check no longer aborts the launch of an agent without a minimum version; both checks fall back to their own lookup. - A live `latest` below the agent's minimum (lagging mirror, bad dist-tag) is treated as unknown instead of becoming the tracked version. - codemie update and install --supported install the exact version they displayed instead of re-resolving 'supported', which could read a different cached value. Adds tests for each, plus doctor's ahead-of-tracking result and a mixed checked/failed codemie update run. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…he key Key cache entries by registry origin plus a SHA-256 of the resolved registry URL, and drop legacy raw-URL keys on load so the next write scrubs them from disk. Update spec section 1 to the real cache shape. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
When the shared compatibility check failed, blockIfBelowMinimum re-ran it unguarded and a second failure aborted run(). Treat a failed lookup as an unknown version, log it at debug and continue the launch. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Mark a live latest below the hard minimum with liveBelowMinimum, and make install --supported target the minimum in that case instead of the latest channel, which would install the release the gate refuses. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Prove an https registry is tunnelled through the user .npmrc https-proxy via CONNECT to the registry host, and that a dead HTTP_PROXY/HTTPS_PROXY is not used. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…atest is below the minimum Instead of installing the minimum, installing the tracked version now fails with an AgentInstallationError naming the registry latest and the minimum. The below-minimum state is surfaced on VersionCompatibilityResult, so plain `install claude|codex` and `install --supported` stop with that error rather than installing the refused release or offering a "latest" reinstall. `install --supported` on an agent with no tracked version now says so instead of blaming disabled checks or npm. Spec section 2 documents the behaviour. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
setup no longer shows a green "installed" check for a Claude below the minimum supported version; it warns that it will not launch and points at `codemie install claude --supported`. Also covers `codemie update` reporting a failed CLI lookup for the built-in agent. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…invalid An explicitly configured npm proxy that cannot be constructed now fails the lookup (debug-logged) instead of silently sending the request direct. Proxy discovery failures for the env/system resolver still go direct. Documents that npm's cafile/ca/strict-ssl settings are not read. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Plan, technical analysis, review verdict and QA results for the round-4 and round-5 review fixes on the live version tracking PR (EPMCDME-14767). Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…minimum A plain `codemie install claude|codex` now only stops with the below-minimum error when an install would actually happen; an already installed agent keeps the "is already installed" no-op. The agent test setup reinstalls Claude when the tracked version is unknown and the installed version is below the minimum. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Summary
Implements EPMCDME-14767: the version CodeMie tracks for Claude, Codex, Gemini and Kimi now follows each agent's latest npm release instead of a hand-edited constant.
codemie setup,codemie updateandcodemie doctor(which already compared versions onmain) all read it through one resolver,resolveSupportedVersionDetailed.codemie updateno longer special-cases Claude, and always fetches fresh (bypassing the cache) since the user asked to check now. The hardcoded*_SUPPORTED_VERSIONconstants now only mark an agent as version-checked and no longer need bumping.<registry>/<package>/latest, instead of spawningnpm view. On a Windows laptopnpm viewtook 2.5–3.8s per package and about 4s each in parallel, so the 3s limit was routinely hit and the feature silently did nothing. The direct request takes about 0.25s (4 packages in parallel: 0.67s). It honors npm'sregistryand@scope:registrysettings, plusHTTPS_PROXY/HTTP_PROXY/NO_PROXYand npm's proxy settings. Registries that require auth aren't supported, and npm'sstrict-ssl/cafilesettings aren't read (Node'sNODE_EXTRA_CA_CERTSstill works for a corporate CA). In those setups the tracked version stays unknown, so no notice is shown; nothing breaks.${VAR}references are expanded only in the user.npmrc, never in a project.npmrc, so a checked-out repo can't route env secrets to its own host on agent launch.--supportedhint, which would otherwise suggest a downgrade.codemie updatereports "Could not check X" for agents whose lookup failed instead of dropping them; while the registry is unreachable a launch can wait up to 3s for the lookup, after which lookups are skipped for 10 minutes (updatealways retries).CODEMIE_VERSION_CHECKS_ENABLED, orworkspace.versionChecks.enabledin the project or global config, resolved in that order. On by default; only an explicitfalsedisables it. Documented indocs/CONFIGURATION.md.install --supportedinstalls the tracked version, or the latest release when it's unknown, never the stale constant. For an already-installed agent it asks first.main.Windows: required for the feature
getVersion()now runs--versionthrough a shell on Windows for Codex and Gemini, and for the PATH fallback of Kimi and Claude (npm installs). npm installs are.cmdshims thatspawn()can't start directly, so without thisgetVersion()failed there and no version check ran for those agents on Windows (criterion #3). Native.exeinstalls worked before and still do. Agents' own self-updaters are left untouched: a self-update moves the agent to npm's latest release, which is exactly the tracked version.Corrections to the previous description
The earlier description said the Codex test failures were "pre-existing … unrelated" and that "CI is green". Both were wrong: this branch's live lookup reached the real npm registry from inside
codex.plugin.version-support.test.ts. The tests now mock the resolver.Split out / follow-ups
exec()quoting of the base command in shell mode is in its own PR (branchfix/exec-shell-command-quoting).codemie update kimiupdates the npm package, not the native Kimi binary. Pre-existing.setupshows a green check for a below-minimum Claude. Both pre-existing.Test plan
npm run license-check,typecheck,lint,buildnpx vitest run --project unit(300 files, 4.5k tests), including a registry client tested against a real local HTTP server (proxy,NO_PROXY, scoped registries, timeouts), plus version cache, resolver, and Codex/Gemini/Claude plugin testsnpx vitest run --project cli: failures in a full parallel run all pass in isolation.upstream/mainshows the same local flakiness, and CI's integration step hasn't failed in its last 100 runs.Generated with AI
Co-Authored-By: codemie-ai codemie.ai@gmail.com