feat: show update availability in status
This commit is contained in:
@@ -8,6 +8,7 @@ Docs: https://docs.clawd.bot
|
|||||||
- Telegram: enrich forwarded message context with normalized origin details + legacy fallback. (#1090) — thanks @sleontenko.
|
- Telegram: enrich forwarded message context with normalized origin details + legacy fallback. (#1090) — thanks @sleontenko.
|
||||||
- macOS: strip prerelease/build suffixes when parsing gateway semver patches. (#1110) — thanks @zerone0x.
|
- macOS: strip prerelease/build suffixes when parsing gateway semver patches. (#1110) — thanks @zerone0x.
|
||||||
- macOS: keep CLI install pinned to the full build suffix. (#1111) — thanks @artuskg.
|
- macOS: keep CLI install pinned to the full build suffix. (#1111) — thanks @artuskg.
|
||||||
|
- CLI: surface update availability in `clawdbot status`.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Doctor: avoid re-adding WhatsApp ack reaction config when only legacy auth files exist. (#1087) — thanks @YuriNachos.
|
- Doctor: avoid re-adding WhatsApp ack reaction config when only legacy auth files exist. (#1087) — thanks @YuriNachos.
|
||||||
|
|||||||
@@ -19,3 +19,4 @@ clawdbot status --usage
|
|||||||
Notes:
|
Notes:
|
||||||
- `--deep` runs live probes (WhatsApp Web + Telegram + Discord + Slack + Signal).
|
- `--deep` runs live probes (WhatsApp Web + Telegram + Discord + Slack + Signal).
|
||||||
- Output includes per-agent session stores when multiple agents are configured.
|
- Output includes per-agent session stores when multiple agents are configured.
|
||||||
|
- Update info surfaces in the Overview; if an update is available, status prints a hint to run `clawdbot update` (see [Updating](/install/updating)).
|
||||||
|
|||||||
@@ -19,7 +19,11 @@ import {
|
|||||||
} from "./status.format.js";
|
} from "./status.format.js";
|
||||||
import { resolveGatewayProbeAuth } from "./status.gateway-probe.js";
|
import { resolveGatewayProbeAuth } from "./status.gateway-probe.js";
|
||||||
import { scanStatus } from "./status.scan.js";
|
import { scanStatus } from "./status.scan.js";
|
||||||
import { formatUpdateOneLiner } from "./status.update.js";
|
import {
|
||||||
|
formatUpdateAvailableHint,
|
||||||
|
formatUpdateOneLiner,
|
||||||
|
resolveUpdateAvailability,
|
||||||
|
} from "./status.update.js";
|
||||||
import { formatGatewayAuthUsed } from "./status-all/format.js";
|
import { formatGatewayAuthUsed } from "./status-all/format.js";
|
||||||
import { statusAllCommand } from "./status-all.js";
|
import { statusAllCommand } from "./status-all.js";
|
||||||
|
|
||||||
@@ -228,6 +232,9 @@ export async function statusCommand(
|
|||||||
? `${summary.sessions.paths.length} stores`
|
? `${summary.sessions.paths.length} stores`
|
||||||
: (summary.sessions.paths[0] ?? "unknown");
|
: (summary.sessions.paths[0] ?? "unknown");
|
||||||
|
|
||||||
|
const updateAvailability = resolveUpdateAvailability(update);
|
||||||
|
const updateLine = formatUpdateOneLiner(update).replace(/^Update:\s*/i, "");
|
||||||
|
|
||||||
const overviewRows = [
|
const overviewRows = [
|
||||||
{ Item: "Dashboard", Value: dashboard },
|
{ Item: "Dashboard", Value: dashboard },
|
||||||
{ Item: "OS", Value: `${osSummary.label} · node ${process.versions.node}` },
|
{ Item: "OS", Value: `${osSummary.label} · node ${process.versions.node}` },
|
||||||
@@ -242,7 +249,7 @@ export async function statusCommand(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Item: "Update",
|
Item: "Update",
|
||||||
Value: formatUpdateOneLiner(update).replace(/^Update:\s*/i, ""),
|
Value: updateAvailability.available ? warn(`available · ${updateLine}`) : updateLine,
|
||||||
},
|
},
|
||||||
{ Item: "Gateway", Value: gatewayValue },
|
{ Item: "Gateway", Value: gatewayValue },
|
||||||
{ Item: "Daemon", Value: daemonValue },
|
{ Item: "Daemon", Value: daemonValue },
|
||||||
@@ -456,6 +463,11 @@ export async function statusCommand(
|
|||||||
runtime.log("FAQ: https://docs.clawd.bot/faq");
|
runtime.log("FAQ: https://docs.clawd.bot/faq");
|
||||||
runtime.log("Troubleshooting: https://docs.clawd.bot/troubleshooting");
|
runtime.log("Troubleshooting: https://docs.clawd.bot/troubleshooting");
|
||||||
runtime.log("");
|
runtime.log("");
|
||||||
|
const updateHint = formatUpdateAvailableHint(update);
|
||||||
|
if (updateHint) {
|
||||||
|
runtime.log(theme.warn(updateHint));
|
||||||
|
runtime.log("");
|
||||||
|
}
|
||||||
runtime.log("Next steps:");
|
runtime.log("Next steps:");
|
||||||
runtime.log(" Need to share? clawdbot status --all");
|
runtime.log(" Need to share? clawdbot status --all");
|
||||||
runtime.log(" Need to debug live? clawdbot logs --follow");
|
runtime.log(" Need to debug live? clawdbot logs --follow");
|
||||||
|
|||||||
@@ -24,6 +24,48 @@ export async function getUpdateCheckResult(params: {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UpdateAvailability = {
|
||||||
|
available: boolean;
|
||||||
|
hasGitUpdate: boolean;
|
||||||
|
hasRegistryUpdate: boolean;
|
||||||
|
latestVersion: string | null;
|
||||||
|
gitBehind: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function resolveUpdateAvailability(update: UpdateCheckResult): UpdateAvailability {
|
||||||
|
const latestVersion = update.registry?.latestVersion ?? null;
|
||||||
|
const registryCmp = latestVersion ? compareSemverStrings(VERSION, latestVersion) : null;
|
||||||
|
const hasRegistryUpdate = registryCmp != null && registryCmp < 0;
|
||||||
|
const gitBehind =
|
||||||
|
update.installKind === "git" && typeof update.git?.behind === "number"
|
||||||
|
? update.git.behind
|
||||||
|
: null;
|
||||||
|
const hasGitUpdate = gitBehind != null && gitBehind > 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
available: hasGitUpdate || hasRegistryUpdate,
|
||||||
|
hasGitUpdate,
|
||||||
|
hasRegistryUpdate,
|
||||||
|
latestVersion: hasRegistryUpdate ? latestVersion : null,
|
||||||
|
gitBehind,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatUpdateAvailableHint(update: UpdateCheckResult): string | null {
|
||||||
|
const availability = resolveUpdateAvailability(update);
|
||||||
|
if (!availability.available) return null;
|
||||||
|
|
||||||
|
const details: string[] = [];
|
||||||
|
if (availability.hasGitUpdate && availability.gitBehind != null) {
|
||||||
|
details.push(`git behind ${availability.gitBehind}`);
|
||||||
|
}
|
||||||
|
if (availability.hasRegistryUpdate && availability.latestVersion) {
|
||||||
|
details.push(`npm ${availability.latestVersion}`);
|
||||||
|
}
|
||||||
|
const suffix = details.length > 0 ? ` (${details.join(" · ")})` : "";
|
||||||
|
return `Update available${suffix}. Run: clawdbot update`;
|
||||||
|
}
|
||||||
|
|
||||||
export function formatUpdateOneLiner(update: UpdateCheckResult): string {
|
export function formatUpdateOneLiner(update: UpdateCheckResult): string {
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
if (update.installKind === "git" && update.git) {
|
if (update.installKind === "git" && update.git) {
|
||||||
|
|||||||
Reference in New Issue
Block a user