mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 23:40:45 +00:00
133 lines
5.4 KiB
TypeScript
133 lines
5.4 KiB
TypeScript
import type { Command } from "commander";
|
|
import { defaultRuntime } from "../runtime.js";
|
|
import { formatDocsLink } from "../terminal/links.js";
|
|
import { theme } from "../terminal/theme.js";
|
|
import { formatHelpExamples } from "./help-format.js";
|
|
import {
|
|
type UpdateCommandOptions,
|
|
type UpdateStatusOptions,
|
|
type UpdateWizardOptions,
|
|
} from "./update-cli/shared.js";
|
|
import { updateStatusCommand } from "./update-cli/status.js";
|
|
import { updateCommand } from "./update-cli/update-command.js";
|
|
import { updateWizardCommand } from "./update-cli/wizard.js";
|
|
|
|
export { updateCommand, updateStatusCommand, updateWizardCommand };
|
|
export type { UpdateCommandOptions, UpdateStatusOptions, UpdateWizardOptions };
|
|
|
|
export function registerUpdateCli(program: Command) {
|
|
const update = program
|
|
.command("update")
|
|
.description("Update OpenClaw to the latest version")
|
|
.option("--json", "Output result as JSON", false)
|
|
.option("--no-restart", "Skip restarting the gateway service after a successful update")
|
|
.option("--channel <stable|beta|dev>", "Persist update channel (git + npm)")
|
|
.option("--tag <dist-tag|version>", "Override npm dist-tag or version for this update")
|
|
.option("--timeout <seconds>", "Timeout for each update step in seconds (default: 1200)")
|
|
.option("--yes", "Skip confirmation prompts (non-interactive)", false)
|
|
.addHelpText("after", () => {
|
|
const examples = [
|
|
["openclaw update", "Update a source checkout (git)"],
|
|
["openclaw update --channel beta", "Switch to beta channel (git + npm)"],
|
|
["openclaw update --channel dev", "Switch to dev channel (git + npm)"],
|
|
["openclaw update --tag beta", "One-off update to a dist-tag or version"],
|
|
["openclaw update --no-restart", "Update without restarting the service"],
|
|
["openclaw update --json", "Output result as JSON"],
|
|
["openclaw update --yes", "Non-interactive (accept downgrade prompts)"],
|
|
["openclaw update wizard", "Interactive update wizard"],
|
|
["openclaw --update", "Shorthand for openclaw update"],
|
|
] as const;
|
|
const fmtExamples = examples
|
|
.map(([cmd, desc]) => ` ${theme.command(cmd)} ${theme.muted(`# ${desc}`)}`)
|
|
.join("\n");
|
|
return `
|
|
${theme.heading("What this does:")}
|
|
- Git checkouts: fetches, rebases, installs deps, builds, and runs doctor
|
|
- npm installs: updates via detected package manager
|
|
|
|
${theme.heading("Switch channels:")}
|
|
- Use --channel stable|beta|dev to persist the update channel in config
|
|
- Run openclaw update status to see the active channel and source
|
|
- Use --tag <dist-tag|version> for a one-off npm update without persisting
|
|
|
|
${theme.heading("Non-interactive:")}
|
|
- Use --yes to accept downgrade prompts
|
|
- Combine with --channel/--tag/--restart/--json/--timeout as needed
|
|
|
|
${theme.heading("Examples:")}
|
|
${fmtExamples}
|
|
|
|
${theme.heading("Notes:")}
|
|
- Switch channels with --channel stable|beta|dev
|
|
- For global installs: auto-updates via detected package manager when possible (see docs/install/updating.md)
|
|
- Downgrades require confirmation (can break configuration)
|
|
- Skips update if the working directory has uncommitted changes
|
|
|
|
${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.openclaw.ai/cli/update")}`;
|
|
})
|
|
.action(async (opts) => {
|
|
try {
|
|
await updateCommand({
|
|
json: Boolean(opts.json),
|
|
restart: Boolean(opts.restart),
|
|
channel: opts.channel as string | undefined,
|
|
tag: opts.tag as string | undefined,
|
|
timeout: opts.timeout as string | undefined,
|
|
yes: Boolean(opts.yes),
|
|
});
|
|
} catch (err) {
|
|
defaultRuntime.error(String(err));
|
|
defaultRuntime.exit(1);
|
|
}
|
|
});
|
|
|
|
update
|
|
.command("wizard")
|
|
.description("Interactive update wizard")
|
|
.option("--timeout <seconds>", "Timeout for each update step in seconds (default: 1200)")
|
|
.addHelpText(
|
|
"after",
|
|
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.openclaw.ai/cli/update")}\n`,
|
|
)
|
|
.action(async (opts) => {
|
|
try {
|
|
await updateWizardCommand({
|
|
timeout: opts.timeout as string | undefined,
|
|
});
|
|
} catch (err) {
|
|
defaultRuntime.error(String(err));
|
|
defaultRuntime.exit(1);
|
|
}
|
|
});
|
|
|
|
update
|
|
.command("status")
|
|
.description("Show update channel and version status")
|
|
.option("--json", "Output result as JSON", false)
|
|
.option("--timeout <seconds>", "Timeout for update checks in seconds (default: 3)")
|
|
.addHelpText(
|
|
"after",
|
|
() =>
|
|
`\n${theme.heading("Examples:")}\n${formatHelpExamples([
|
|
["openclaw update status", "Show channel + version status."],
|
|
["openclaw update status --json", "JSON output."],
|
|
["openclaw update status --timeout 10", "Custom timeout."],
|
|
])}\n\n${theme.heading("Notes:")}\n${theme.muted(
|
|
"- Shows current update channel (stable/beta/dev) and source",
|
|
)}\n${theme.muted("- Includes git tag/branch/SHA for source checkouts")}\n\n${theme.muted(
|
|
"Docs:",
|
|
)} ${formatDocsLink("/cli/update", "docs.openclaw.ai/cli/update")}`,
|
|
)
|
|
.action(async (opts) => {
|
|
try {
|
|
await updateStatusCommand({
|
|
json: Boolean(opts.json),
|
|
timeout: opts.timeout as string | undefined,
|
|
});
|
|
} catch (err) {
|
|
defaultRuntime.error(String(err));
|
|
defaultRuntime.exit(1);
|
|
}
|
|
});
|
|
}
|