Skip to content

feat(update): port CLI self-updater command to refactor architecture - #2151

Open
jariy17 wants to merge 1 commit into
refactorfrom
feat/update-command
Open

feat(update): port CLI self-updater command to refactor architecture#2151
jariy17 wants to merge 1 commit into
refactorfrom
feat/update-command

Conversation

@jariy17

@jariy17 jariy17 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

What

Ports the agentcore update command from the old CLI (main) into the refactored Handler/Router (Bun) architecture. update checks the npm registry for a newer @aws/agentcore and runs npm install -g; update --check reports availability without installing.

The refactor branch had resource-level update subcommands (gateway, harness, eval…) but no top-level self-updater — this adds it.

Changes

  • src/handlers/update/action.ts (new) — fetchLatestVersion, compareVersions, installArgv, handleUpdate. The install runs through an injectable ProcessRunner (defaults to the shared runProcess from src/io/exec.ts), so the install path is testable without spawning a real npm.
  • src/handlers/update/index.tsx (new) — createUpdateHandler; always renders the UpdateResult as JSON (matching the resource-command convention); npm progress streams to io.stderr so stdout stays a clean, pipeable JSON result; SilentCLIError for a non-zero exit on failed install.
  • src/handlers/index.tsx — mounts the handler at the root (2 lines).
  • src/handlers/update/update.test.ts (new) — compareVersions table, fetchLatestVersion fetch spy (200/404), and handleUpdate branches (up-to-date / newer-local / update-available / updated / update-failed) via an injected fake runner.

CLI surface

agentcore update           # check and install
agentcore update --check   # report availability only

Verification

  • bun test src/handlers/update/21 pass / 0 fail
  • bunx tsc --noEmit → clean
  • Live: update --help, update --check, update --check --json all correct

Notes

Faithful port of the old command's behavior (bare update installs; --check only checks). A separate adversarial bug bash surfaced pre-existing gaps carried over from the old CLI (dist-tag check/install channel mismatch, no CI/TTY install guard, unvalidated registry JSON) — not addressed here to keep this a clean port; happy to follow up.

@github-actions github-actions Bot added the size/m PR size: M label Aug 31, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@codecov-commenter

codecov-commenter commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.24731% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.14%. Comparing base (f431dce) to head (3003400).
⚠️ Report is 21 commits behind head on refactor.

Files with missing lines Patch % Lines
src/handlers/update/index.tsx 57.14% 9 Missing ⚠️
src/handlers/update/action.ts 98.57% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           refactor    #2151      +/-   ##
============================================
- Coverage     97.16%   97.14%   -0.03%     
============================================
  Files           495      497       +2     
  Lines         32676    32769      +93     
============================================
+ Hits          31751    31834      +83     
- Misses          925      935      +10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Clean port of agentcore update into the refactored Handler/Router architecture. Nicely scoped:

  • Business logic (fetchLatestVersion, compareVersions, handleUpdate) is separated from the handler shell.
  • ProcessRunner is injected so the install path is covered without spawning real npm — mocking is at the true I/O boundary (matches the repo's guidance).
  • fetch is spied via spyOn(globalThis, "fetch") and restored in afterEach — appropriately hermetic.
  • renderJson is called before the SilentCLIError throw, so the JSON result reaches stdout even on a failed install, and the non-zero exit still surfaces to scripts.
  • Telemetry is auto-instrumented at the router (cli.command_run with command_path), so no per-handler wiring is needed.

Known follow-ups already called out in the PR description (which I agree are out of scope for a "clean port"):

  • installArgv() uses distTag() (@preview vs @latest), but fetchLatestVersion() always queries the /latest endpoint. For a preview build the check and the install target disagree — the check compares against stable, then installs from preview.
  • No guard against running npm install -g in non-interactive/CI contexts, and the registry JSON isn't schema-validated.

Non-blocking observations for a future pass:

  • PACKAGE_NAME = "@aws/agentcore" is hardcoded while the current package.json name on refactor is agentcore. Fine if this reflects the intended published name, but worth confirming before the branch actually ships.
  • Test file is update.test.ts while the rest of src/handlers/ uses co-located index.test.ts. Minor.
  • In the "newer-local" test (handleUpdate(false) with no injected runner), the branch returns before invoking the runner, so it's safe today, but passing a mock runner would make the test robust to future refactors of handleUpdate.

Nothing here needs to block merge.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 31, 2026
@jariy17
jariy17 force-pushed the feat/update-command branch from c07c1ce to 26875ea Compare August 31, 2026 20:12
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Aug 31, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Ports the `agentcore update` command from the old CLI into the refactored
Handler/Router (Bun) architecture. It checks the npm registry for a newer
@aws/agentcore and runs `npm install -g` (`--check` reports without installing).

- src/handlers/update/action.ts: fetchLatestVersion + compareVersions +
  handleUpdate, with an injectable ProcessRunner (defaults to the shared
  runProcess) so the install path is testable without spawning npm.
- src/handlers/update/index.tsx: createUpdateHandler, always renders the
  UpdateResult as JSON (resource-command convention); npm progress streams to
  stderr so stdout stays pipeable.
- Mounted in src/handlers/index.tsx.
- 21 bun tests (compareVersions table, fetch spy, injected runner); tsc clean.
@jariy17
jariy17 force-pushed the feat/update-command branch from 26875ea to 3003400 Compare August 31, 2026 21:37
@github-actions github-actions Bot added size/m PR size: M and removed size/m PR size: M labels Aug 31, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
export async function fetchLatestVersion(): Promise<string> {
const response = await fetch(`${REGISTRY_URL}/${PACKAGE_NAME}/latest`);
if (!response.ok) {
throw new Error(`Failed to fetch latest version: ${response.statusText}`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an AgentCoreCLIError. I think we should create a NetworkingError to cover this and other cases.

}

return 0;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking a little gnarly! Can we not use semver?

ctx.require(JsonRendererKey).renderJson(result);

if (result.status === "update-failed") {
throw new SilentCLIError("failed to install update", { exitCode: 1 });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should this error be silent?

description: "Check for and install CLI updates",
flags: [flag("check", "check for updates without installing", z.boolean().default(false))],
handle: async (ctx, flags) => {
const result = await handleUpdate(flags.check, {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably just put all of the functionality here. I don't see an upshot of pulling this out. I think code could still be tested easily enough if it were inlined here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants