fix(cli): mon update moves PGAI_TAG to the CLI version

What

mon update moves PGAI_TAG in .env to the CLI's version, as mon local-install already does, so an upgrade no longer needs a manual .env edit.

  • Never to an older version (a newer deployed tag stays; a prerelease of the same x.y.z moves to the release), and a development build of the CLI moves nothing.
  • Only a plain assignment is rewritten (optional export, spaces around =, optional quotes, a trailing # comment). Interpolation, KEY: value or a comment glued to a quote is left alone, with a note.
  • A PGAI_TAG exported in the environment that differs from the tag the stack will use is reported: compose prefers it over .env.
  • After the pull it suggests postgresai mon stop && postgresai mon start (a restart keeps the old containers).
  • readEnvTag replaces readDeployedTag, so .env has one PGAI_TAG reader (the compose backup suffix still goes through sanitizeTagForBackup).

Split out of !440 (closed), whose title it did not match (round-2 review, 2026-09-29). Stacked on !436 (closed)'s branch, like !440 (closed); the two do not touch the same lines and merge in either order.

Tests (red, then green)

  • cli/test/mon-update-tag.test.ts: planUpdateTag table (upgrade, unset, branch tag, equal, newer release, newer prerelease, prerelease of the same version, dev build); readEnvTag/writeEnvTag on export, quotes, comments, CRLF and duplicate lines; mon update end to end on a project whose .env has a non-plain value and on one with an exported PGAI_TAG.
  • cli/test/upgrade.test.ts (backup suffix from .env, hostile tag) passes unchanged.
  • Red commits 2a63c1f, 35197b4; green 88ee318, 3b41e3b, 832fb7f. Full CLI suite: 2006 pass, 1 fail that also fails on main (a checkup-api timeout test).

Code +74/−12, tests +117/−3.

What we did not check

  • A real upgrade across released versions: the CLI in this repo is a development build, so mon update end to end exercises the "not a release" branch; the move itself is covered by the planUpdateTag table and the .env read/write tests.
  • A PGAI_TAG= line inside another variable's multi-line quoted value is read as an assignment.

Part of postgres-ai/internal#354.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GRNbWXUQJebE3vqWjAgTFh

Merge request reports

Loading
Loading