Skip to content

feat(cli): Auto-update when version mismatch detected #1125

@christso

Description

@christso

Problem

When required_version in .agentv/config.yaml doesn't satisfy the installed version, agentv eval shows a warning and asks "Continue anyway?" — but doesn't offer to run the update. The user has to manually run agentv self update in a separate step.

Current behavior

Warning: This project requires agentv >=4.15.0 but you have 4.14.2.
  Run `agentv self update` to upgrade.
? Continue anyway? (y/N)

User must abort, manually run agentv self update, then re-run their command.

Desired behavior

Warning: This project requires agentv >=4.15.0 but you have 4.14.2.
? Update now? (Y/n)
  • Y (default): Runs agentv self update inline, then exits with message to re-run the command.
  • N: Continues the command as-is (no second prompt).
  • Non-interactive / --strict: Behavior unchanged (warn + continue, or abort).

Proposed design

1. Modify enforceRequiredVersion() in apps/cli/src/version-check.ts

Replace the "Continue anyway?" prompt with a single "Update now?" prompt:

[warn] → "Update now? (Y/n)" → [Y] → run self-update → exit with "re-run your command"
                               → [N] → continue (proceed with the command)

The update step reuses the existing runCommand() + detectPackageManager() logic from apps/cli/src/commands/self/index.ts. Extract these into a shared module (e.g., apps/cli/src/self-update.ts) so both the self update command and the version-check prompt can call the same code.

2. After update completes

  • Print the before/after version.
  • Print: Update complete. Please re-run your command.
  • Exit with code 0.

Why not re-exec? Re-executing the original process.argv after an in-place global install is fragile — the new binary may have different argument parsing, and the current process's module cache is stale. A clean exit + re-run message is the safe approach (same pattern Codex uses).

3. Non-interactive / CI

No change. Non-interactive environments get the existing stderr warning and continue. --strict still aborts.

Reference

Similar to how openai/codex handles self-update: detect version mismatch → prompt "Update now?" → run install command inline if accepted.

Files to change

  • apps/cli/src/version-check.ts — replace "Continue anyway?" with "Update now?" prompt + inline update
  • apps/cli/src/commands/self/index.ts — extract runCommand(), detectPackageManager() into shared module
  • New: apps/cli/src/self-update.ts — shared update execution logic
  • apps/cli/test/version-check.test.ts — update tests for new prompt flow

Manual E2E test steps

Setup

Add a required_version to .agentv/config.yaml that is higher than the current installed version:

required_version: ">=99.0.0"

Use any eval file for testing, e.g.:

bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run

Red tests (before changes)

  1. Interactive — decline to continue:

    bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run
    • Expect: warning + "Continue anyway?" prompt
    • Type N → exits with code 1
    • Confirm: no "Update now?" option exists
  2. Interactive — continue anyway:

    • Same command, type Y
    • Expect: eval runs despite version mismatch
    • Confirm: no update was offered
  3. Strict mode:

    bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run --strict
    • Expect: warning + immediate abort (no prompt)
  4. Non-interactive:

    echo "" | bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run
    • Expect: warning to stderr, eval continues

Green tests (after changes)

  1. Interactive — accept update (Y):

    bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run
    • Expect: warning + "Update now? (Y/n)"
    • Type Y (or press Enter, since Y is default)
    • Expect: runs npm install -g agentv@latest or bun add -g agentv@latest (auto-detected)
    • Expect: prints version change (e.g., 4.19.0 → 4.20.0) and "Update complete. Please re-run your command."
    • Expect: exits with code 0 (does NOT continue the eval)
  2. Interactive — decline update (N):

    • Same command, type N
    • Expect: no update runs, eval proceeds immediately (no second prompt)
  3. Strict mode unchanged:

    bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run --strict
    • Expect: warning + immediate abort, no "Update now?" prompt
  4. Non-interactive unchanged:

    echo "" | bun apps/cli/src/cli.ts eval examples/features/trials/evals/dataset.eval.yaml --dry-run
    • Expect: warning to stderr, eval continues, no prompt
  5. agentv self update still works independently:

    bun apps/cli/src/cli.ts self update
    • Expect: same behavior as before (no regression)

Cleanup

Remove required_version from .agentv/config.yaml after testing.

Acceptance criteria

  • Interactive TTY: version mismatch prompts "Update now? (Y/n)" (single prompt, no "Continue anyway?")
  • Selecting Y runs the update inline (npm or bun, auto-detected)
  • After successful update, prints version change and exits cleanly
  • Selecting N continues the command without interruption
  • Non-interactive and --strict behavior unchanged
  • agentv self update command still works independently
  • Unit tests cover the new prompt flow

Metadata

Metadata

Assignees

No one assigned

    Labels

    in-progressClaimed by an agent — do not duplicate work

    Type

    No type

    Projects

    Status

    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions