| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- import "zod-openapi/extend"
- import { App } from "./app/app"
- import { Server } from "./server/server"
- import fs from "fs/promises"
- import path from "path"
- import { Share } from "./share/share"
- import { Global } from "./global"
- import yargs from "yargs"
- import { hideBin } from "yargs/helpers"
- import { RunCommand } from "./cli/cmd/run"
- import { GenerateCommand } from "./cli/cmd/generate"
- import { VERSION } from "./cli/version"
- import { ScrapCommand } from "./cli/cmd/scrap"
- import { Log } from "./util/log"
- import { AuthCommand, AuthLoginCommand } from "./cli/cmd/auth"
- import { Provider } from "./provider/provider"
- import { UI } from "./cli/ui"
- const cli = yargs(hideBin(process.argv))
- .scriptName("opencode")
- .version(VERSION)
- .option("print-logs", {
- describe: "Print logs to stderr",
- type: "boolean",
- })
- .middleware(async () => {
- await Log.init({ print: process.argv.includes("--print-logs") })
- Log.Default.info("opencode", {
- version: VERSION,
- args: process.argv.slice(2),
- })
- })
- .usage("\n" + UI.logo())
- .command({
- command: "$0 [project]",
- describe: "Start OpenCode TUI",
- builder: (yargs) =>
- yargs.positional("project", {
- type: "string",
- describe: "path to start opencode in",
- }),
- handler: async (args) => {
- while (true) {
- const cwd = args.project ? path.resolve(args.project) : process.cwd()
- process.chdir(cwd)
- const result = await App.provide(
- { cwd, version: VERSION },
- async () => {
- const providers = await Provider.list()
- if (Object.keys(providers).length === 0) {
- return "needs_provider"
- }
- await Share.init()
- const server = Server.listen()
- let cmd = ["go", "run", "./main.go"]
- let cwd = new URL("../../tui/cmd/opencode", import.meta.url)
- .pathname
- if (Bun.embeddedFiles.length > 0) {
- const blob = Bun.embeddedFiles[0] as File
- const binary = path.join(Global.Path.cache, "tui", blob.name)
- const file = Bun.file(binary)
- if (!(await file.exists())) {
- await Bun.write(file, blob, { mode: 0o755 })
- await fs.chmod(binary, 0o755)
- }
- cwd = process.cwd()
- cmd = [binary]
- }
- const proc = Bun.spawn({
- cmd: [...cmd, ...process.argv.slice(2)],
- cwd,
- stdout: "inherit",
- stderr: "inherit",
- stdin: "inherit",
- env: {
- ...process.env,
- OPENCODE_SERVER: server.url.toString(),
- },
- onExit: () => {
- server.stop()
- },
- })
- await proc.exited
- await server.stop()
- return "done"
- },
- )
- if (result === "done") break
- if (result === "needs_provider") {
- UI.empty()
- UI.println(UI.logo(" "))
- UI.empty()
- await AuthLoginCommand.handler(args)
- }
- }
- },
- })
- .command(RunCommand)
- .command(GenerateCommand)
- .command(ScrapCommand)
- .command(AuthCommand)
- .fail((msg, err) => {
- if (
- msg.startsWith("Unknown argument") ||
- msg.startsWith("Not enough non-option arguments")
- ) {
- cli.showHelp("log")
- }
- Log.Default.error(msg, {
- err,
- })
- })
- .strict()
- try {
- await cli.parse()
- } catch (e) {
- Log.Default.error(e)
- }
|