1a734adb4d
Moves effect logging, observability, runtime utilities, flags, installation version info, and process utilities from opencode to core package. This enables better code sharing across packages and establishes core as the single source of truth for foundational utilities. All internal imports updated to use @opencode-ai/core paths for consistency.
80 lines
2.8 KiB
TypeScript
80 lines
2.8 KiB
TypeScript
import type { Argv } from "yargs"
|
|
import { UI } from "../ui"
|
|
import * as prompts from "@clack/prompts"
|
|
import { AppRuntime } from "@/effect/app-runtime"
|
|
import { Installation } from "../../installation"
|
|
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
|
|
|
export const UpgradeCommand = {
|
|
command: "upgrade [target]",
|
|
describe: "upgrade opencode to the latest or a specific version",
|
|
builder: (yargs: Argv) => {
|
|
return yargs
|
|
.positional("target", {
|
|
describe: "version to upgrade to, for ex '0.1.48' or 'v0.1.48'",
|
|
type: "string",
|
|
})
|
|
.option("method", {
|
|
alias: "m",
|
|
describe: "installation method to use",
|
|
type: "string",
|
|
choices: ["curl", "npm", "pnpm", "bun", "brew", "choco", "scoop"],
|
|
})
|
|
},
|
|
handler: async (args: { target?: string; method?: string }) => {
|
|
UI.empty()
|
|
UI.println(UI.logo(" "))
|
|
UI.empty()
|
|
prompts.intro("Upgrade")
|
|
const detectedMethod = await AppRuntime.runPromise(Installation.Service.use((svc) => svc.method()))
|
|
const method = (args.method as Installation.Method) ?? detectedMethod
|
|
if (method === "unknown") {
|
|
prompts.log.error(`opencode is installed to ${process.execPath} and may be managed by a package manager`)
|
|
const install = await prompts.select({
|
|
message: "Install anyways?",
|
|
options: [
|
|
{ label: "Yes", value: true },
|
|
{ label: "No", value: false },
|
|
],
|
|
initialValue: false,
|
|
})
|
|
if (!install) {
|
|
prompts.outro("Done")
|
|
return
|
|
}
|
|
}
|
|
prompts.log.info("Using method: " + method)
|
|
const target = args.target
|
|
? args.target.replace(/^v/, "")
|
|
: await AppRuntime.runPromise(Installation.Service.use((svc) => svc.latest()))
|
|
|
|
if (InstallationVersion === target) {
|
|
prompts.log.warn(`opencode upgrade skipped: ${target} is already installed`)
|
|
prompts.outro("Done")
|
|
return
|
|
}
|
|
|
|
prompts.log.info(`From ${InstallationVersion} → ${target}`)
|
|
const spinner = prompts.spinner()
|
|
spinner.start("Upgrading...")
|
|
const err = await AppRuntime.runPromise(Installation.Service.use((svc) => svc.upgrade(method, target))).catch(
|
|
(err) => err,
|
|
)
|
|
if (err) {
|
|
spinner.stop("Upgrade failed", 1)
|
|
if (err instanceof Installation.UpgradeFailedError) {
|
|
// necessary because choco only allows install/upgrade in elevated terminals
|
|
if (method === "choco" && err.stderr.includes("not running from an elevated command shell")) {
|
|
prompts.log.error("Please run the terminal as Administrator and try again")
|
|
} else {
|
|
prompts.log.error(err.stderr)
|
|
}
|
|
} else if (err instanceof Error) prompts.log.error(err.message)
|
|
prompts.outro("Done")
|
|
return
|
|
}
|
|
spinner.stop("Upgrade complete")
|
|
prompts.outro("Done")
|
|
},
|
|
}
|