Spaces:
Paused
Paused
| import { | |
| formatUpdateAvailableHint, | |
| formatUpdateOneLiner, | |
| resolveUpdateAvailability, | |
| } from "../../commands/status.update.js"; | |
| import { readConfigFileSnapshot } from "../../config/config.js"; | |
| import { | |
| formatUpdateChannelLabel, | |
| normalizeUpdateChannel, | |
| resolveEffectiveUpdateChannel, | |
| } from "../../infra/update-channels.js"; | |
| import { checkUpdateStatus } from "../../infra/update-check.js"; | |
| import { defaultRuntime } from "../../runtime.js"; | |
| import { renderTable } from "../../terminal/table.js"; | |
| import { theme } from "../../terminal/theme.js"; | |
| import { resolveUpdateRoot, type UpdateStatusOptions } from "./shared.js"; | |
| function formatGitStatusLine(params: { | |
| branch: string | null; | |
| tag: string | null; | |
| sha: string | null; | |
| }): string { | |
| const shortSha = params.sha ? params.sha.slice(0, 8) : null; | |
| const branch = params.branch && params.branch !== "HEAD" ? params.branch : null; | |
| const tag = params.tag; | |
| const parts = [ | |
| branch ?? (tag ? "detached" : "git"), | |
| tag ? `tag ${tag}` : null, | |
| shortSha ? `@ ${shortSha}` : null, | |
| ].filter(Boolean); | |
| return parts.join(" 路 "); | |
| } | |
| export async function updateStatusCommand(opts: UpdateStatusOptions): Promise<void> { | |
| const timeoutMs = opts.timeout ? Number.parseInt(opts.timeout, 10) * 1000 : undefined; | |
| if (timeoutMs !== undefined && (Number.isNaN(timeoutMs) || timeoutMs <= 0)) { | |
| defaultRuntime.error("--timeout must be a positive integer (seconds)"); | |
| defaultRuntime.exit(1); | |
| return; | |
| } | |
| const root = await resolveUpdateRoot(); | |
| const configSnapshot = await readConfigFileSnapshot(); | |
| const configChannel = configSnapshot.valid | |
| ? normalizeUpdateChannel(configSnapshot.config.update?.channel) | |
| : null; | |
| const update = await checkUpdateStatus({ | |
| root, | |
| timeoutMs: timeoutMs ?? 3500, | |
| fetchGit: true, | |
| includeRegistry: true, | |
| }); | |
| const channelInfo = resolveEffectiveUpdateChannel({ | |
| configChannel, | |
| installKind: update.installKind, | |
| git: update.git ? { tag: update.git.tag, branch: update.git.branch } : undefined, | |
| }); | |
| const channelLabel = formatUpdateChannelLabel({ | |
| channel: channelInfo.channel, | |
| source: channelInfo.source, | |
| gitTag: update.git?.tag ?? null, | |
| gitBranch: update.git?.branch ?? null, | |
| }); | |
| const gitLabel = | |
| update.installKind === "git" | |
| ? formatGitStatusLine({ | |
| branch: update.git?.branch ?? null, | |
| tag: update.git?.tag ?? null, | |
| sha: update.git?.sha ?? null, | |
| }) | |
| : null; | |
| const updateAvailability = resolveUpdateAvailability(update); | |
| const updateLine = formatUpdateOneLiner(update).replace(/^Update:\s*/i, ""); | |
| if (opts.json) { | |
| defaultRuntime.log( | |
| JSON.stringify( | |
| { | |
| update, | |
| channel: { | |
| value: channelInfo.channel, | |
| source: channelInfo.source, | |
| label: channelLabel, | |
| config: configChannel, | |
| }, | |
| availability: updateAvailability, | |
| }, | |
| null, | |
| 2, | |
| ), | |
| ); | |
| return; | |
| } | |
| const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1); | |
| const installLabel = | |
| update.installKind === "git" | |
| ? `git (${update.root ?? "unknown"})` | |
| : update.installKind === "package" | |
| ? update.packageManager | |
| : "unknown"; | |
| const rows = [ | |
| { Item: "Install", Value: installLabel }, | |
| { Item: "Channel", Value: channelLabel }, | |
| ...(gitLabel ? [{ Item: "Git", Value: gitLabel }] : []), | |
| { | |
| Item: "Update", | |
| Value: updateAvailability.available ? theme.warn(`available 路 ${updateLine}`) : updateLine, | |
| }, | |
| ]; | |
| defaultRuntime.log(theme.heading("OpenClaw update status")); | |
| defaultRuntime.log(""); | |
| defaultRuntime.log( | |
| renderTable({ | |
| width: tableWidth, | |
| columns: [ | |
| { key: "Item", header: "Item", minWidth: 10 }, | |
| { key: "Value", header: "Value", flex: true, minWidth: 24 }, | |
| ], | |
| rows, | |
| }).trimEnd(), | |
| ); | |
| defaultRuntime.log(""); | |
| const updateHint = formatUpdateAvailableHint(update); | |
| if (updateHint) { | |
| defaultRuntime.log(theme.warn(updateHint)); | |
| } | |
| } | |