refactor(status): share update channel display + one-liner

This commit is contained in:
Peter Steinberger
2026-02-17 00:29:15 +00:00
parent 1dc9bb8d62
commit ed74f48bd5
4 changed files with 40 additions and 96 deletions

View File

@@ -5,9 +5,8 @@ import {
} from "../../commands/status.update.js";
import { readConfigFileSnapshot } from "../../config/config.js";
import {
formatUpdateChannelLabel,
normalizeUpdateChannel,
resolveEffectiveUpdateChannel,
resolveUpdateChannelDisplay,
} from "../../infra/update-channels.js";
import { checkUpdateStatus } from "../../infra/update-check.js";
import { defaultRuntime } from "../../runtime.js";
@@ -52,17 +51,13 @@ export async function updateStatusCommand(opts: UpdateStatusOptions): Promise<vo
includeRegistry: true,
});
const channelInfo = resolveEffectiveUpdateChannel({
const channelInfo = resolveUpdateChannelDisplay({
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 channelLabel = channelInfo.label;
const gitLabel =
update.installKind === "git"

View File

@@ -17,16 +17,8 @@ import { inspectPortUsage } from "../infra/ports.js";
import { readRestartSentinel } from "../infra/restart-sentinel.js";
import { getRemoteSkillEligibility } from "../infra/skills-remote.js";
import { readTailscaleStatusJson } from "../infra/tailscale.js";
import {
formatUpdateChannelLabel,
normalizeUpdateChannel,
resolveEffectiveUpdateChannel,
} from "../infra/update-channels.js";
import {
checkUpdateStatus,
compareSemverStrings,
formatGitInstallLabel,
} from "../infra/update-check.js";
import { normalizeUpdateChannel, resolveUpdateChannelDisplay } from "../infra/update-channels.js";
import { checkUpdateStatus, formatGitInstallLabel } from "../infra/update-check.js";
import { runExec } from "../process/exec.js";
import type { RuntimeEnv } from "../runtime.js";
import { VERSION } from "../version.js";
@@ -36,6 +28,7 @@ import { buildChannelsTable } from "./status-all/channels.js";
import { formatDurationPrecise, formatGatewayAuthUsed } from "./status-all/format.js";
import { pickGatewaySelfPresence } from "./status-all/gateway.js";
import { buildStatusAllReportLines } from "./status-all/report-lines.js";
import { formatUpdateOneLiner } from "./status.update.js";
export async function statusAllCommand(
runtime: RuntimeEnv,
@@ -98,17 +91,13 @@ export async function statusAllCommand(
includeRegistry: true,
});
const configChannel = normalizeUpdateChannel(cfg.update?.channel);
const channelInfo = resolveEffectiveUpdateChannel({
const channelInfo = resolveUpdateChannelDisplay({
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 channelLabel = channelInfo.label;
const gitLabel = formatGitInstallLabel(update);
progress.tick();
@@ -243,65 +232,7 @@ export async function statusAllCommand(
}).httpUrl
: null;
const updateLine = (() => {
const appendRegistryAndDepsStatus = (parts: string[]) => {
const latest = update.registry?.latestVersion;
if (latest) {
const cmp = compareSemverStrings(VERSION, latest);
if (cmp === 0) {
parts.push(`npm latest ${latest}`);
} else if (cmp != null && cmp < 0) {
parts.push(`npm update ${latest}`);
} else {
parts.push(`npm latest ${latest} (local newer)`);
}
} else if (update.registry?.error) {
parts.push("npm latest unknown");
}
if (update.deps?.status === "ok") {
parts.push("deps ok");
}
if (update.deps?.status === "stale") {
parts.push("deps stale");
}
if (update.deps?.status === "missing") {
parts.push("deps missing");
}
};
if (update.installKind === "git" && update.git) {
const parts: string[] = [];
parts.push(update.git.branch ? `git ${update.git.branch}` : "git");
if (update.git.upstream) {
parts.push(`${update.git.upstream}`);
}
if (update.git.dirty) {
parts.push("dirty");
}
if (update.git.behind != null && update.git.ahead != null) {
if (update.git.behind === 0 && update.git.ahead === 0) {
parts.push("up to date");
} else if (update.git.behind > 0 && update.git.ahead === 0) {
parts.push(`behind ${update.git.behind}`);
} else if (update.git.behind === 0 && update.git.ahead > 0) {
parts.push(`ahead ${update.git.ahead}`);
} else {
parts.push(`diverged (ahead ${update.git.ahead}, behind ${update.git.behind})`);
}
}
if (update.git.fetchOk === false) {
parts.push("fetch failed");
}
appendRegistryAndDepsStatus(parts);
return parts.join(" · ");
}
const parts: string[] = [];
parts.push(update.packageManager !== "unknown" ? update.packageManager : "pkg");
appendRegistryAndDepsStatus(parts);
return parts.join(" · ");
})();
const updateLine = formatUpdateOneLiner(update).replace(/^Update:\s*/i, "");
const gatewayTarget = remoteUrlMissing ? `fallback ${connection.url}` : connection.url;
const gatewayStatus = gatewayReachable

View File

@@ -6,11 +6,7 @@ import { info } from "../globals.js";
import { formatTimeAgo } from "../infra/format-time/format-relative.ts";
import type { HeartbeatEventPayload } from "../infra/heartbeat-events.js";
import { formatUsageReportLines, loadProviderUsageSummary } from "../infra/provider-usage.js";
import {
formatUpdateChannelLabel,
normalizeUpdateChannel,
resolveEffectiveUpdateChannel,
} from "../infra/update-channels.js";
import { normalizeUpdateChannel, resolveUpdateChannelDisplay } from "../infra/update-channels.js";
import { formatGitInstallLabel } from "../infra/update-check.js";
import {
resolveMemoryCacheSummary,
@@ -132,10 +128,11 @@ export async function statusCommand(
: null;
const configChannel = normalizeUpdateChannel(cfg.update?.channel);
const channelInfo = resolveEffectiveUpdateChannel({
const channelInfo = resolveUpdateChannelDisplay({
configChannel,
installKind: update.installKind,
git: update.git ? { tag: update.git.tag, branch: update.git.branch } : undefined,
gitTag: update.git?.tag ?? null,
gitBranch: update.git?.branch ?? null,
});
if (opts.json) {
@@ -352,12 +349,7 @@ export async function statusCommand(
const updateAvailability = resolveUpdateAvailability(update);
const updateLine = formatUpdateOneLiner(update).replace(/^Update:\s*/i, "");
const channelLabel = formatUpdateChannelLabel({
channel: channelInfo.channel,
source: channelInfo.source,
gitTag: update.git?.tag ?? null,
gitBranch: update.git?.branch ?? null,
});
const channelLabel = channelInfo.label;
const gitLabel = formatGitInstallLabel(update);
const overviewRows = [

View File

@@ -81,3 +81,29 @@ export function formatUpdateChannelLabel(params: {
}
return `${params.channel} (default)`;
}
export function resolveUpdateChannelDisplay(params: {
configChannel?: UpdateChannel | null;
installKind: "git" | "package" | "unknown";
gitTag?: string | null;
gitBranch?: string | null;
}): { channel: UpdateChannel; source: UpdateChannelSource; label: string } {
const channelInfo = resolveEffectiveUpdateChannel({
configChannel: params.configChannel,
installKind: params.installKind,
git:
params.gitTag || params.gitBranch
? { tag: params.gitTag ?? null, branch: params.gitBranch ?? null }
: undefined,
});
return {
channel: channelInfo.channel,
source: channelInfo.source,
label: formatUpdateChannelLabel({
channel: channelInfo.channel,
source: channelInfo.source,
gitTag: params.gitTag ?? null,
gitBranch: params.gitBranch ?? null,
}),
};
}