Skip to content

feat(cli): show an update-available notice after every command - #39

Merged
cmglezpdev merged 1 commit into
mainfrom
claude/cli-update-notification-5d947f
Aug 20, 2026
Merged

cmglezpdev merged 1 commit into
mainfrom
claude/cli-update-notification-5d947f

Conversation

@cmglezpdev

Copy link
Copy Markdown
Owner

What this changes

After any veta command finishes, a pnpm-style box on stderr announces a newer published version, its changelog URL, and the exact command to update — inferred from how the binary was installed (npm, pnpm, yarn, bun, npx, or Homebrew; npm as the fallback).

Why

Users of a globally installed CLI have no signal that a newer version exists; they stay on old releases until something breaks. The box surfaces the update the moment they use the tool, without ever performing the update itself — which installer owns the binary is the user's business, so veta suggests the command instead of running one.

How to verify

pnpm typecheck
pnpm test

Live, with a seeded cache pretending 0.12.0 is out:

pnpm build
node -e 'const fs=require("fs");fs.mkdirSync("/tmp/veta-demo",{recursive:true});fs.writeFileSync("/tmp/veta-demo/update-check.json",JSON.stringify({checkedAt:Date.now(),latest:"0.12.0"}))'
VETA_DATA_DIR=/tmp/veta-demo node bin/cli.js --version

The box renders after the version line. CI=1 in front silences it; 2>/dev/null shows stdout stays a pure 0.10.0.

  • The registry lookup starts before the command runs so the round-trip overlaps real work; the result prints after the command, on success and error paths alike.
  • It is allowed to lose: 1.5 s abort, offline, malformed cache, or a broken registry answer all collapse to silence, and the whole notice step is wrapped so it can never change an exit code.
  • 24-hour cache at <dataDir>/update-check.json via the existing atomic-json helpers; a future checkedAt (clock skew) counts as stale.
  • Opt-outs follow the update-notifier convention (NO_UPDATE_NOTIFIER, CI) plus VETA_NO_UPDATE_CHECK; non-TTY stderr and the completion path never check at all, keeping D17's fast completion promise.
  • All logic lives in src/cli/update/ behind injected deps (fetchLatest, cache, now), so tests cover timeout, TTL, and failure without network or real time.

Checklist

  • pnpm typecheck and pnpm test pass (468 passed, 1 skipped live test)
  • Commits follow Conventional Commits — feat → minor, intended
  • domain/ imports nothing outside domain/ — untouched by this PR
  • YouTube wire-level names stay inside src/adapters/ytdlp/ — none added
  • Documentation updated: README "Update notifications" section
  • No vi.mock, module-level vi.spyOn, or vi.useFakeTimers was added — the timeout test uses a real 5 ms abort, caches use temp dirs

Anything unresolved

  • fetchLatestFromNpm itself is not unit-tested (it would need network or fetch mocking); everything around it is, behind the injected fetchLatest.
  • Two pre-existing tests (run-extraction thumbnail, extract flat-package) are flaky under full-suite load and pass in isolation — unrelated to this change, being fixed separately.

After any command finishes, a pnpm-style box on stderr announces a newer
published version, its changelog URL, and the exact command to update —
detected from how the binary was installed (npm, pnpm, yarn, bun, npx,
or Homebrew; npm as the fallback).

The registry lookup starts before the command runs so the round-trip
overlaps real work, is cached for 24 hours in the data directory, gives
up silently after 1.5 s, and can never change an exit code or touch
stdout. NO_UPDATE_NOTIFIER, CI, VETA_NO_UPDATE_CHECK, a non-TTY stderr,
and the completion path all disable it.
@cmglezpdev
cmglezpdev force-pushed the claude/cli-update-notification-5d947f branch from 850879e to b24a712 Compare August 20, 2026 00:31
@cmglezpdev
cmglezpdev merged commit 709ff25 into main Aug 20, 2026
3 checks passed
@cmglezpdev
cmglezpdev deleted the claude/cli-update-notification-5d947f branch August 25, 2026 17:13
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