diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 41cad4f7..03973318 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -6,6 +6,10 @@ - Exposed `PI_SESSION_ID`, `PI_SESSION_FILE`, `PI_PROVIDER`, `PI_MODEL`, and `PI_REASONING_LEVEL` to commands run by built-in and factory-created bash tools. +### Fixed + +- Fixed explicit self-updates when `PI_SKIP_VERSION_CHECK` is set ([#6977](https://github.com/earendil-works/pi/issues/6977)). + ## [0.81.1] - 2026-07-21 ### New Features diff --git a/packages/coding-agent/src/utils/version-check.ts b/packages/coding-agent/src/utils/version-check.ts index a6a4f469..1a99a869 100644 --- a/packages/coding-agent/src/utils/version-check.ts +++ b/packages/coding-agent/src/utils/version-check.ts @@ -31,7 +31,7 @@ export async function getLatestPiRelease( currentVersion: string, options: { timeoutMs?: number } = {}, ): Promise { - if (process.env.PI_SKIP_VERSION_CHECK || process.env.PI_OFFLINE) return undefined; + if (process.env.PI_OFFLINE) return undefined; const response = await fetch(LATEST_VERSION_URL, { headers: { @@ -68,6 +68,8 @@ export async function getLatestPiVersion( } export async function checkForNewPiVersion(currentVersion: string): Promise { + if (process.env.PI_SKIP_VERSION_CHECK) return undefined; + try { const latestRelease = await getLatestPiRelease(currentVersion); if (latestRelease && isNewerPackageVersion(latestRelease.version, currentVersion)) { diff --git a/packages/coding-agent/test/package-command-paths.test.ts b/packages/coding-agent/test/package-command-paths.test.ts index 4158f3f0..eb6972bf 100644 --- a/packages/coding-agent/test/package-command-paths.test.ts +++ b/packages/coding-agent/test/package-command-paths.test.ts @@ -470,6 +470,32 @@ describe("package commands", () => { } }); + it("allows explicit self-update checks when automatic version checks are disabled", async () => { + const previousSkipVersionCheck = process.env.PI_SKIP_VERSION_CHECK; + process.env.PI_SKIP_VERSION_CHECK = "1"; + const fetchMock = vi.fn(async () => Response.json({ version: VERSION })); + vi.stubGlobal("fetch", fetchMock); + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + try { + await expect(runPackageCommandDirectly(["update", "--self"])).resolves.toBeUndefined(); + + expect(fetchMock).toHaveBeenCalledOnce(); + expect(logSpy.mock.calls.map(([message]) => String(message)).join("\n")).toContain( + `pi is already up to date (v${VERSION})`, + ); + expect(errorSpy).not.toHaveBeenCalled(); + expect(process.exitCode).toBeUndefined(); + } finally { + if (previousSkipVersionCheck === undefined) { + delete process.env.PI_SKIP_VERSION_CHECK; + } else { + process.env.PI_SKIP_VERSION_CHECK = previousSkipVersionCheck; + } + } + }); + it("uses the update check version for forced self updates even when current", async () => { const globalPrefix = join(tempDir, "global-prefix"); const projectPrefix = join(tempDir, "project-prefix"); diff --git a/packages/coding-agent/test/version-check.test.ts b/packages/coding-agent/test/version-check.test.ts index b294c627..6e2f0ac4 100644 --- a/packages/coding-agent/test/version-check.test.ts +++ b/packages/coding-agent/test/version-check.test.ts @@ -80,12 +80,21 @@ describe("version checks", () => { await expect(getLatestPiRelease("1.2.3")).resolves.toEqual({ note: "**Read this**", version: "1.2.4" }); }); - it("skips api calls when version checks are disabled", async () => { + it("skips automatic api calls when version checks are disabled", async () => { process.env.PI_SKIP_VERSION_CHECK = "1"; const fetchMock = vi.fn(); vi.stubGlobal("fetch", fetchMock); - await expect(getLatestPiVersion("1.2.3")).resolves.toBeUndefined(); + await expect(checkForNewPiVersion("1.2.3")).resolves.toBeUndefined(); expect(fetchMock).not.toHaveBeenCalled(); }); + + it("allows direct api calls when automatic version checks are disabled", async () => { + process.env.PI_SKIP_VERSION_CHECK = "1"; + const fetchMock = vi.fn(async () => Response.json({ version: "1.2.4" })); + vi.stubGlobal("fetch", fetchMock); + + await expect(getLatestPiVersion("1.2.3")).resolves.toBe("1.2.4"); + expect(fetchMock).toHaveBeenCalledOnce(); + }); });