| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- import yargs from "yargs"
- import { hideBin } from "yargs/helpers"
- import { RunCommand } from "./cli/cmd/run"
- import { GenerateCommand } from "./cli/cmd/generate"
- import { Log } from "./util/log"
- import { AuthCommand } from "./cli/cmd/auth"
- import { AgentCommand } from "./cli/cmd/agent"
- import { UpgradeCommand } from "./cli/cmd/upgrade"
- import { ModelsCommand } from "./cli/cmd/models"
- import { UI } from "./cli/ui"
- import { Installation } from "./installation"
- import { NamedError } from "@opencode-ai/util/error"
- import { FormatError } from "./cli/error"
- import { ServeCommand } from "./cli/cmd/serve"
- import { DebugCommand } from "./cli/cmd/debug"
- import { StatsCommand } from "./cli/cmd/stats"
- import { McpCommand } from "./cli/cmd/mcp"
- import { GithubCommand } from "./cli/cmd/github"
- import { ExportCommand } from "./cli/cmd/export"
- import { ImportCommand } from "./cli/cmd/import"
- import { AttachCommand } from "./cli/cmd/tui/attach"
- import { TuiThreadCommand } from "./cli/cmd/tui/thread"
- import { TuiSpawnCommand } from "./cli/cmd/tui/spawn"
- import { AcpCommand } from "./cli/cmd/acp"
- import { EOL } from "os"
- import { WebCommand } from "./cli/cmd/web"
- import { PrCommand } from "./cli/cmd/pr"
- process.on("unhandledRejection", (e) => {
- Log.Default.error("rejection", {
- e: e instanceof Error ? e.message : e,
- })
- })
- process.on("uncaughtException", (e) => {
- Log.Default.error("exception", {
- e: e instanceof Error ? e.message : e,
- })
- })
- const cli = yargs(hideBin(process.argv))
- .parserConfiguration({ "populate--": true })
- .scriptName("opencode")
- .help("help", "show help")
- .alias("help", "h")
- .version("version", "show version number", Installation.VERSION)
- .alias("version", "v")
- .option("print-logs", {
- describe: "print logs to stderr",
- type: "boolean",
- })
- .option("log-level", {
- describe: "log level",
- type: "string",
- choices: ["DEBUG", "INFO", "WARN", "ERROR"],
- })
- .middleware(async (opts) => {
- await Log.init({
- print: process.argv.includes("--print-logs"),
- dev: Installation.isLocal(),
- level: (() => {
- if (opts.logLevel) return opts.logLevel as Log.Level
- if (Installation.isLocal()) return "DEBUG"
- return "INFO"
- })(),
- })
- process.env.AGENT = "1"
- process.env.OPENCODE = "1"
- Log.Default.info("opencode", {
- version: Installation.VERSION,
- args: process.argv.slice(2),
- })
- })
- .usage("\n" + UI.logo())
- .command(AcpCommand)
- .command(McpCommand)
- .command(TuiThreadCommand)
- .command(TuiSpawnCommand)
- .command(AttachCommand)
- .command(RunCommand)
- .command(GenerateCommand)
- .command(DebugCommand)
- .command(AuthCommand)
- .command(AgentCommand)
- .command(UpgradeCommand)
- .command(ServeCommand)
- .command(WebCommand)
- .command(ModelsCommand)
- .command(StatsCommand)
- .command(ExportCommand)
- .command(ImportCommand)
- .command(GithubCommand)
- .command(PrCommand)
- .fail((msg) => {
- if (
- msg.startsWith("Unknown argument") ||
- msg.startsWith("Not enough non-option arguments") ||
- msg.startsWith("Invalid values:")
- ) {
- cli.showHelp("log")
- }
- process.exit(1)
- })
- .strict()
- try {
- await cli.parse()
- } catch (e) {
- let data: Record<string, any> = {}
- if (e instanceof NamedError) {
- const obj = e.toObject()
- Object.assign(data, {
- ...obj.data,
- })
- }
- if (e instanceof Error) {
- Object.assign(data, {
- name: e.name,
- message: e.message,
- cause: e.cause?.toString(),
- stack: e.stack,
- })
- }
- if (e instanceof ResolveMessage) {
- Object.assign(data, {
- name: e.name,
- message: e.message,
- code: e.code,
- specifier: e.specifier,
- referrer: e.referrer,
- position: e.position,
- importKind: e.importKind,
- })
- }
- Log.Default.error("fatal", data)
- const formatted = FormatError(e)
- if (formatted) UI.error(formatted)
- if (formatted === undefined) {
- UI.error("Unexpected error, check log file at " + Log.file() + " for more details" + EOL)
- console.error(e)
- }
- process.exitCode = 1
- } finally {
- // Some subprocesses don't react properly to SIGTERM and similar signals.
- // Most notably, some docker-container-based MCP servers don't handle such signals unless
- // run using `docker run --init`.
- // Explicitly exit to avoid any hanging subprocesses.
- process.exit()
- }
|