fix(update): make up-to-date package status explicit (#51409)

Merged via squash.

Prepared head SHA: 75aba35882
Co-authored-by: dongzhenye <5765843+dongzhenye@users.noreply.github.com>
Co-authored-by: mcaxtr <7562095+mcaxtr@users.noreply.github.com>
Reviewed-by: @mcaxtr
This commit is contained in:
Zhenye Dong
2026-03-22 04:17:14 +08:00
committed by GitHub
parent bfcfc17a8b
commit 80959219ce
3 changed files with 53 additions and 2 deletions

View File

@@ -207,8 +207,9 @@ Docs: https://docs.openclaw.ai
- Web search: align onboarding, configure, and finalize with plugin-owned provider contracts, including disabled-provider recovery, config-aware credential hooks, and runtime-visible summaries. (#50935) Thanks @gumadeiras.
- Agents/replay: sanitize malformed assistant tool-call replay blocks before provider replay so follow-up Anthropic requests do not inherit the downstream `replace` crash. (#50005) Thanks @jalehman.
- Plugins/context engines: retry strict legacy `assemble()` calls without the new `prompt` field when older engines reject it, preserving prompt-aware retrieval compatibility for pre-prompt plugins. (#50848) thanks @danhdoan.
- make `openclaw update status` explicitly say `up to date` when the local version already matches npm latest, while keeping the availability logic unchanged. (#51409) Thanks @dongzhenye.
- Agents/embedded transport errors: distinguish common network failures like connection refused, DNS lookup failure, and interrupted sockets from true timeouts in embedded-run user messaging and lifecycle diagnostics. (#51419) Thanks @scoootscooob.
- Discord/startup logging: report client initialization while the gateway is still connecting instead of claiming Discord is logged in before readiness is reached. (#51425) Thanks @scoootscooob.
- Discord/startup logging: report client initialization while the gateway is still connecting instead of claiming Discord is logged in before readiness is reached. (#51425) Thanks @scoootscoob.
- Gateway/probe: honor caller `--timeout` for active local loopback probes in `gateway status`, keep inactive remote-mode loopback probes fast, and clamp probe timers to JS-safe bounds so slow local/container gateways stop reporting false timeouts. (#47533) Thanks @MonkeyLeeT.
- Config/startup: keep bundled web-search allowlist compatibility on a lightweight manifest path so config validation no longer pulls bundled web-search registry imports into startup, while still avoiding accidental auto-allow of config-loaded override plugins. (#51574) Thanks @RichardCao.
- Gateway/chat.send: persist uploaded image references across reloads and compaction without delaying first-turn dispatch or double-submitting the same image to vision models. (#51324) Thanks @fuller-stack-dev.
@@ -216,6 +217,7 @@ Docs: https://docs.openclaw.ai
- Agents/compaction safeguard: preserve split-turn context and preserved recent turns when capped retry fallback reuses the last successful summary. (#27727) thanks @Pandadadadazxf.
- Discord/pickers: keep `/codex_resume --browse-projects` picker callbacks alive in Discord by sharing component callback state across duplicate module graphs, preserving callback fallbacks, and acknowledging matched plugin interactions before dispatch. (#51260) Thanks @huntharo.
- Agents/memory flush: keep transcript-hash dedup active across memory-flush fallback retries so a write-then-throw flush attempt cannot append duplicate `MEMORY.md` entries before the fallback cycle completes. (#34222) Thanks @lml2468.
- make `openclaw update status` explicitly say `up to date` when the local version already matches npm latest, while keeping the availability logic unchanged. (#51409) Thanks @dongzhenye.
### Breaking

View File

@@ -66,7 +66,7 @@ describe("resolveUpdateAvailability", () => {
});
describe("formatUpdateOneLiner", () => {
it("renders git status and registry latest summary", () => {
it("renders git status and registry summary without duplicating up to date", () => {
const update = buildUpdate({
installKind: "git",
git: {
@@ -94,6 +94,52 @@ describe("formatUpdateOneLiner", () => {
);
});
it("renders synced git installs with a single up to date label", () => {
const update = buildUpdate({
installKind: "git",
git: {
root: "/tmp/repo",
sha: "abc123456789",
tag: null,
branch: "main",
upstream: "origin/main",
dirty: false,
ahead: 0,
behind: 0,
fetchOk: true,
},
registry: { latestVersion: VERSION },
deps: {
manager: "pnpm",
status: "ok",
lockfilePath: "pnpm-lock.yaml",
markerPath: "node_modules/.modules.yaml",
},
});
expect(formatUpdateOneLiner(update)).toBe(
`Update: git main · ↔ origin/main · up to date · npm latest ${VERSION} · deps ok`,
);
});
it("renders package-manager mode with explicit up-to-date state", () => {
const update = buildUpdate({
installKind: "package",
packageManager: "npm",
registry: { latestVersion: VERSION },
deps: {
manager: "npm",
status: "ok",
lockfilePath: "package-lock.json",
markerPath: "node_modules",
},
});
expect(formatUpdateOneLiner(update)).toBe(
`Update: npm · up to date · npm latest ${VERSION} · deps ok`,
);
});
it("renders package-manager mode with registry error", () => {
const update = buildUpdate({
installKind: "package",

View File

@@ -76,6 +76,9 @@ export function formatUpdateOneLiner(update: UpdateCheckResult): string {
if (update.registry?.latestVersion) {
const cmp = compareSemverStrings(VERSION, update.registry.latestVersion);
if (cmp === 0) {
if (update.installKind !== "git") {
parts.push("up to date");
}
parts.push(`npm latest ${update.registry.latestVersion}`);
} else if (cmp != null && cmp < 0) {
parts.push(`npm update ${update.registry.latestVersion}`);