feat(cli): add self-update service

Check the npm registry (at most once per 24h, file-locked) for newer
@opencode-ai/cli releases and act on a host-level autoupdate policy read
from config. Apply patch updates automatically, confirm minor updates
interactively, and never auto-update across majors. Skip local installs
and honor the disable flag. Wired into the default TUI command
(interactive) and serve (background).
This commit is contained in:
Dax Raad 2026-06-27 00:51:45 -04:00
commit 5df049d081
8 changed files with 256 additions and 3 deletions

View file

@ -3,11 +3,14 @@ import { Runtime } from "../../framework/runtime"
import { Effect, Option } from "effect"
import { Daemon } from "../../services/daemon"
import { Standalone } from "../../services/standalone"
import { Updater } from "../../services/updater"
export default Runtime.handler(Commands, (input) =>
Effect.gen(function* () {
const directory = Option.getOrUndefined(input.directory)
if (directory !== undefined) process.chdir(directory)
const updater = yield* Updater.Service
yield* updater.check({ interactive: true })
const daemon = yield* Daemon.Service
const transport = yield* (input.standalone ? Standalone.transport() : daemon.transport())
const { runTui } = yield* Effect.promise(() => import("../../tui"))

View file

@ -11,6 +11,7 @@ import { createOpencodeClient } from "@opencode-ai/sdk/v2/client"
import { Commands } from "../commands"
import { Runtime } from "../../framework/runtime"
import { Daemon } from "../../services/daemon"
import { Updater } from "../../services/updater"
export default Runtime.handler(
Commands.commands.serve,
@ -32,6 +33,8 @@ export default Runtime.handler(
if (input.register) yield* daemon.register(address)
const url = HttpServer.formatAddress(address)
console.log(input.stdio ? JSON.stringify({ url }) : `server listening on ${url}`)
const updater = yield* Updater.Service
yield* updater.check({ interactive: false }).pipe(Effect.forkScoped)
return yield* (input.stdio ? waitForStdinClose() : Effect.never)
}).pipe(Effect.annotateLogs({ role: "server" })),
)