Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
290 changes: 46 additions & 244 deletions packages/opencode/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
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 { ConsoleCommand } from "./cli/cmd/account"
import { ProvidersCommand } from "./cli/cmd/providers"
import { AgentCommand } from "./cli/cmd/agent"
import { UpgradeCommand } from "./cli/cmd/upgrade"
import { UninstallCommand } from "./cli/cmd/uninstall"
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 { Filesystem } from "./util/filesystem"
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 { AcpCommand } from "./cli/cmd/acp"
import { EOL } from "os"
import { WebCommand } from "./cli/cmd/web"
import { PrCommand } from "./cli/cmd/pr"
import { SessionCommand } from "./cli/cmd/session"
import { DbCommand } from "./cli/cmd/db"
import path from "path"
import { Global } from "./global"
import { JsonMigration } from "./storage/json-migration"
import { Database } from "./storage/db"
import { errorMessage } from "./util/error"
import { PluginCommand } from "./cli/cmd/plug"
import { Heap } from "./cli/heap"
import { drizzle } from "drizzle-orm/bun-sqlite"

Expand All @@ -29,156 +52,6 @@ process.on("uncaughtException", (e) => {

const args = hideBin(process.argv)

type Mode =
| "all"
| "none"
| "tui"
| "attach"
| "run"
| "acp"
| "mcp"
| "generate"
| "debug"
| "console"
| "providers"
| "agent"
| "upgrade"
| "uninstall"
| "serve"
| "web"
| "models"
| "stats"
| "export"
| "import"
| "github"
| "pr"
| "session"
| "plugin"
| "db"

const map = new Map<string, Mode>([
["attach", "attach"],
["run", "run"],
["acp", "acp"],
["mcp", "mcp"],
["generate", "generate"],
["debug", "debug"],
["console", "console"],
["providers", "providers"],
["auth", "providers"],
["agent", "agent"],
["upgrade", "upgrade"],
["uninstall", "uninstall"],
["serve", "serve"],
["web", "web"],
["models", "models"],
["stats", "stats"],
["export", "export"],
["import", "import"],
["github", "github"],
["pr", "pr"],
["session", "session"],
["plugin", "plugin"],
["plug", "plugin"],
["db", "db"],
])

function flag(arg: string, name: string) {
return arg === `--${name}` || arg === `--no-${name}` || arg.startsWith(`--${name}=`)
}

function value(arg: string, name: string) {
return arg === `--${name}` || arg.startsWith(`--${name}=`)
}

// Match the root parser closely enough to decide which top-level module to load.
function pick(argv: string[]): Mode {
for (let i = 0; i < argv.length; i++) {
const arg = argv[i]
if (!arg) continue
if (arg === "--") return "tui"
if (arg === "completion") return "all"
if (arg === "--help" || arg === "-h") return "all"
if (arg === "--version" || arg === "-v") return "none"
if (flag(arg, "print-logs") || flag(arg, "pure")) continue
if (value(arg, "log-level")) {
if (arg === "--log-level") i += 1
continue
}
if (arg.startsWith("-") && !arg.startsWith("--")) {
if (arg.includes("h")) return "all"
if (arg.includes("v")) return "none"
return "tui"
}
if (arg.startsWith("-")) return "tui"
return map.get(arg) ?? "tui"
}

return "tui"
}

const mode = pick(args)
const all = mode === "all"
const none = mode === "none"

function load<T>(on: boolean, get: () => Promise<T>): Promise<T | undefined> {
if (!on) {
return Promise.resolve(undefined)
}

return get()
}

const [
TuiThreadCommand,
AttachCommand,
RunCommand,
AcpCommand,
McpCommand,
GenerateCommand,
DebugCommand,
ConsoleCommand,
ProvidersCommand,
AgentCommand,
UpgradeCommand,
UninstallCommand,
ServeCommand,
WebCommand,
ModelsCommand,
StatsCommand,
ExportCommand,
ImportCommand,
GithubCommand,
PrCommand,
SessionCommand,
PluginCommand,
DbCommand,
] = await Promise.all([
load(!none && (all || mode === "tui"), () => import("./cli/cmd/tui/thread").then((x) => x.TuiThreadCommand)),
load(!none && (all || mode === "attach"), () => import("./cli/cmd/tui/attach").then((x) => x.AttachCommand)),
load(!none && (all || mode === "run"), () => import("./cli/cmd/run").then((x) => x.RunCommand)),
load(!none && (all || mode === "acp"), () => import("./cli/cmd/acp").then((x) => x.AcpCommand)),
load(!none && (all || mode === "mcp"), () => import("./cli/cmd/mcp").then((x) => x.McpCommand)),
load(!none && (all || mode === "generate"), () => import("./cli/cmd/generate").then((x) => x.GenerateCommand)),
load(!none && (all || mode === "debug"), () => import("./cli/cmd/debug").then((x) => x.DebugCommand)),
load(!none && (all || mode === "console"), () => import("./cli/cmd/account").then((x) => x.ConsoleCommand)),
load(!none && (all || mode === "providers"), () => import("./cli/cmd/providers").then((x) => x.ProvidersCommand)),
load(!none && (all || mode === "agent"), () => import("./cli/cmd/agent").then((x) => x.AgentCommand)),
load(!none && (all || mode === "upgrade"), () => import("./cli/cmd/upgrade").then((x) => x.UpgradeCommand)),
load(!none && (all || mode === "uninstall"), () => import("./cli/cmd/uninstall").then((x) => x.UninstallCommand)),
load(!none && (all || mode === "serve"), () => import("./cli/cmd/serve").then((x) => x.ServeCommand)),
load(!none && (all || mode === "web"), () => import("./cli/cmd/web").then((x) => x.WebCommand)),
load(!none && (all || mode === "models"), () => import("./cli/cmd/models").then((x) => x.ModelsCommand)),
load(!none && (all || mode === "stats"), () => import("./cli/cmd/stats").then((x) => x.StatsCommand)),
load(!none && (all || mode === "export"), () => import("./cli/cmd/export").then((x) => x.ExportCommand)),
load(!none && (all || mode === "import"), () => import("./cli/cmd/import").then((x) => x.ImportCommand)),
load(!none && (all || mode === "github"), () => import("./cli/cmd/github").then((x) => x.GithubCommand)),
load(!none && (all || mode === "pr"), () => import("./cli/cmd/pr").then((x) => x.PrCommand)),
load(!none && (all || mode === "session"), () => import("./cli/cmd/session").then((x) => x.SessionCommand)),
load(!none && (all || mode === "plugin"), () => import("./cli/cmd/plug").then((x) => x.PluginCommand)),
load(!none && (all || mode === "db"), () => import("./cli/cmd/db").then((x) => x.DbCommand)),
])

function show(out: string) {
const text = out.trimStart()
if (!text.startsWith("opencode ")) {
Expand Down Expand Up @@ -275,100 +148,29 @@ const cli = yargs(args)
})
.usage("")
.completion("completion", "generate shell completion script")

if (TuiThreadCommand) {
cli.command(TuiThreadCommand)
}

if (AttachCommand) {
cli.command(AttachCommand)
}

if (AcpCommand) {
cli.command(AcpCommand)
}

if (McpCommand) {
cli.command(McpCommand)
}

if (RunCommand) {
cli.command(RunCommand)
}

if (GenerateCommand) {
cli.command(GenerateCommand)
}

if (DebugCommand) {
cli.command(DebugCommand)
}

if (ConsoleCommand) {
cli.command(ConsoleCommand)
}

if (ProvidersCommand) {
cli.command(ProvidersCommand)
}

if (AgentCommand) {
cli.command(AgentCommand)
}

if (UpgradeCommand) {
cli.command(UpgradeCommand)
}

if (UninstallCommand) {
cli.command(UninstallCommand)
}

if (ServeCommand) {
cli.command(ServeCommand)
}

if (WebCommand) {
cli.command(WebCommand)
}

if (ModelsCommand) {
cli.command(ModelsCommand)
}

if (StatsCommand) {
cli.command(StatsCommand)
}

if (ExportCommand) {
cli.command(ExportCommand)
}

if (ImportCommand) {
cli.command(ImportCommand)
}

if (GithubCommand) {
cli.command(GithubCommand)
}

if (PrCommand) {
cli.command(PrCommand)
}

if (SessionCommand) {
cli.command(SessionCommand)
}

if (PluginCommand) {
cli.command(PluginCommand)
}

if (DbCommand) {
cli.command(DbCommand)
}

cli
.command(AcpCommand)
.command(McpCommand)
.command(TuiThreadCommand)
.command(AttachCommand)
.command(RunCommand)
.command(GenerateCommand)
.command(DebugCommand)
.command(ConsoleCommand)
.command(ProvidersCommand)
.command(AgentCommand)
.command(UpgradeCommand)
.command(UninstallCommand)
.command(ServeCommand)
.command(WebCommand)
.command(ModelsCommand)
.command(StatsCommand)
.command(ExportCommand)
.command(ImportCommand)
.command(GithubCommand)
.command(PrCommand)
.command(SessionCommand)
.command(PluginCommand)
.command(DbCommand)
.fail((msg, err) => {
if (
msg?.startsWith("Unknown argument") ||
Expand Down
Loading