From 2fd61a93eabce92c71c0306ff75ee2cb6e295a50 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Mon, 22 Sep 2025 02:14:59 -0400 Subject: [PATCH] sync --- packages/opencode/src/cli/cmd/tui.ts | 226 ------------------ .../cmd/{opentui => tui}/component/border.tsx | 0 .../component/dialog-command.tsx | 0 .../component/dialog-model.tsx | 0 .../component/dialog-session-list.tsx | 0 .../{opentui => tui}/component/dialog-tag.tsx | 0 .../cmd/{opentui => tui}/component/prompt.tsx | 0 .../cmd/{opentui => tui}/context/local.tsx | 0 .../cmd/{opentui => tui}/context/route.tsx | 0 .../cli/cmd/{opentui => tui}/context/sdk.tsx | 0 .../cli/cmd/{opentui => tui}/context/sync.tsx | 0 .../cmd/{opentui => tui}/context/theme.tsx | 0 .../src/cli/cmd/{opentui => tui}/home.tsx | 0 .../src/cli/cmd/{opentui => tui}/session.tsx | 0 .../cmd/{opentui/opentui.tsx => tui/tui.tsx} | 49 +++- .../cmd/{opentui => tui}/ui/dialog-select.tsx | 0 .../cli/cmd/{opentui => tui}/ui/dialog.tsx | 0 .../cli/cmd/{opentui => tui}/util/format.ts | 0 packages/opencode/src/index.ts | 4 +- 19 files changed, 46 insertions(+), 233 deletions(-) delete mode 100644 packages/opencode/src/cli/cmd/tui.ts rename packages/opencode/src/cli/cmd/{opentui => tui}/component/border.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/component/dialog-command.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/component/dialog-model.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/component/dialog-session-list.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/component/dialog-tag.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/component/prompt.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/context/local.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/context/route.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/context/sdk.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/context/sync.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/context/theme.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/home.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/session.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui/opentui.tsx => tui/tui.tsx} (76%) rename packages/opencode/src/cli/cmd/{opentui => tui}/ui/dialog-select.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/ui/dialog.tsx (100%) rename packages/opencode/src/cli/cmd/{opentui => tui}/util/format.ts (100%) diff --git a/packages/opencode/src/cli/cmd/tui.ts b/packages/opencode/src/cli/cmd/tui.ts deleted file mode 100644 index 168933119..000000000 --- a/packages/opencode/src/cli/cmd/tui.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { Global } from "../../global" -import { Provider } from "../../provider/provider" -import { Server } from "../../server/server" -import { UI } from "../ui" -import { cmd } from "./cmd" -import path from "path" -import fs from "fs/promises" -import { Installation } from "../../installation" -import { Config } from "../../config/config" -import { Bus } from "../../bus" -import { Log } from "../../util/log" -import { FileWatcher } from "../../file/watcher" -import { Ide } from "../../ide" - -import { Flag } from "../../flag/flag" -import { Session } from "../../session" -import { $ } from "bun" -import { bootstrap } from "../bootstrap" - -declare global { - const OPENCODE_TUI_PATH: string -} - -if (typeof OPENCODE_TUI_PATH !== "undefined") { - await import(OPENCODE_TUI_PATH as string, { - with: { type: "file" }, - }) -} - -export const TuiCommand = cmd({ - command: "$0 [project]", - describe: "start opencode tui", - builder: (yargs) => - yargs - .positional("project", { - type: "string", - describe: "path to start opencode in", - }) - .option("model", { - type: "string", - alias: ["m"], - describe: "model to use in the format of provider/model", - }) - .option("continue", { - alias: ["c"], - describe: "continue the last session", - type: "boolean", - }) - .option("session", { - alias: ["s"], - describe: "session id to continue", - type: "string", - }) - .option("prompt", { - alias: ["p"], - type: "string", - describe: "prompt to use", - }) - .option("agent", { - type: "string", - describe: "agent to use", - }) - .option("port", { - type: "number", - describe: "port to listen on", - default: 0, - }) - .option("hostname", { - alias: ["h"], - type: "string", - describe: "hostname to listen on", - default: "127.0.0.1", - }), - handler: async (args) => { - while (true) { - const cwd = args.project ? path.resolve(args.project) : process.cwd() - try { - process.chdir(cwd) - } catch (e) { - UI.error("Failed to change directory to " + cwd) - return - } - const result = await bootstrap(cwd, async () => { - const sessionID = await (async () => { - if (args.continue) { - const it = Session.list() - try { - for await (const s of it) { - if (s.parentID === undefined) { - return s.id - } - } - return - } finally { - await it.return() - } - } - if (args.session) { - return args.session - } - return undefined - })() - const providers = await Provider.list() - if (Object.keys(providers).length === 0) { - return "needs_provider" - } - - const server = Server.listen({ - port: args.port, - hostname: args.hostname, - }) - - let cmd = [] as string[] - const tui = Bun.embeddedFiles.find((item) => (item as File).name.includes("tui")) as File - if (tui) { - let binaryName = tui.name - if (process.platform === "win32" && !binaryName.endsWith(".exe")) { - binaryName += ".exe" - } - const binary = path.join(Global.Path.cache, "tui", binaryName) - const file = Bun.file(binary) - if (!(await file.exists())) { - await Bun.write(file, tui, { mode: 0o755 }) - if (process.platform !== "win32") await fs.chmod(binary, 0o755) - } - cmd = [binary] - } - if (!tui) { - const dir = Bun.fileURLToPath(new URL("../../../../tui/cmd/opencode", import.meta.url)) - let binaryName = `./dist/tui${process.platform === "win32" ? ".exe" : ""}` - await $`go build -o ${binaryName} ./main.go`.cwd(dir) - cmd = [path.join(dir, binaryName)] - } - Log.Default.info("tui", { - cmd, - }) - const proc = Bun.spawn({ - cmd: [ - ...cmd, - ...(args.model ? ["--model", args.model] : []), - ...(args.prompt ? ["--prompt", args.prompt] : []), - ...(args.agent ? ["--agent", args.agent] : []), - ...(sessionID ? ["--session", sessionID] : []), - ], - cwd, - stdout: "inherit", - stderr: "inherit", - stdin: "inherit", - env: { - ...process.env, - CGO_ENABLED: "0", - OPENCODE_SERVER: server.url.toString(), - }, - onExit: () => { - server.stop() - }, - }) - - ;(async () => { - if (Installation.isDev()) return - if (Installation.isSnapshot()) return - const config = await Config.global() - if (config.autoupdate === false || Flag.OPENCODE_DISABLE_AUTOUPDATE) return - const latest = await Installation.latest().catch(() => {}) - if (!latest) return - if (Installation.VERSION === latest) return - const method = await Installation.method() - if (method === "unknown") return - await Installation.upgrade(method, latest) - .then(() => Bus.publish(Installation.Event.Updated, { version: latest })) - .catch(() => {}) - })() - ;(async () => { - if (Ide.alreadyInstalled()) return - const ide = Ide.ide() - if (ide === "unknown") return - await Ide.install(ide) - .then(() => Bus.publish(Ide.Event.Installed, { ide })) - .catch(() => {}) - })() - FileWatcher.init() - - await proc.exited - server.stop() - - return "done" - }) - if (result === "done") break - if (result === "needs_provider") { - UI.empty() - UI.println(UI.logo(" ")) - const result = await Bun.spawn({ - cmd: [...getOpencodeCommand(), "auth", "login"], - cwd: process.cwd(), - stdout: "inherit", - stderr: "inherit", - stdin: "inherit", - }).exited - if (result !== 0) return - UI.empty() - } - } - }, -}) - -/** - * Get the correct command to run opencode CLI - * In development: ["bun", "run", "packages/opencode/src/index.ts"] - * In production: ["/path/to/opencode"] - */ -function getOpencodeCommand(): string[] { - // Check if OPENCODE_BIN_PATH is set (used by shell wrapper scripts) - if (process.env["OPENCODE_BIN_PATH"]) { - return [process.env["OPENCODE_BIN_PATH"]] - } - - const execPath = process.execPath.toLowerCase() - - if (Installation.isDev()) { - // In development, use bun to run the TypeScript entry point - return [execPath, "run", process.argv[1]] - } - - // In production, use the current executable path - return [process.execPath] -} diff --git a/packages/opencode/src/cli/cmd/opentui/component/border.tsx b/packages/opencode/src/cli/cmd/tui/component/border.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/component/border.tsx rename to packages/opencode/src/cli/cmd/tui/component/border.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/component/dialog-command.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/component/dialog-command.tsx rename to packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/component/dialog-model.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/component/dialog-model.tsx rename to packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/component/dialog-session-list.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/component/dialog-session-list.tsx rename to packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/component/dialog-tag.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/component/dialog-tag.tsx rename to packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/component/prompt.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/component/prompt.tsx rename to packages/opencode/src/cli/cmd/tui/component/prompt.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/context/local.tsx rename to packages/opencode/src/cli/cmd/tui/context/local.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/context/route.tsx b/packages/opencode/src/cli/cmd/tui/context/route.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/context/route.tsx rename to packages/opencode/src/cli/cmd/tui/context/route.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/context/sdk.tsx rename to packages/opencode/src/cli/cmd/tui/context/sdk.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/context/sync.tsx rename to packages/opencode/src/cli/cmd/tui/context/sync.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/context/theme.tsx rename to packages/opencode/src/cli/cmd/tui/context/theme.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/home.tsx b/packages/opencode/src/cli/cmd/tui/home.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/home.tsx rename to packages/opencode/src/cli/cmd/tui/home.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/session.tsx b/packages/opencode/src/cli/cmd/tui/session.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/session.tsx rename to packages/opencode/src/cli/cmd/tui/session.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/opentui.tsx b/packages/opencode/src/cli/cmd/tui/tui.tsx similarity index 76% rename from packages/opencode/src/cli/cmd/opentui/opentui.tsx rename to packages/opencode/src/cli/cmd/tui/tui.tsx index 9155fe664..7d38680a6 100644 --- a/packages/opencode/src/cli/cmd/opentui/opentui.tsx +++ b/packages/opencode/src/cli/cmd/tui/tui.tsx @@ -1,5 +1,5 @@ import { cmd } from "../cmd" -import { render, useKeyboard, useKeyHandler, useRenderer, useTerminalDimensions } from "@opentui/solid" +import { render, useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid" import { TextAttributes } from "@opentui/core" import { RouteProvider, useRoute } from "./context/route" import { Home } from "./home" @@ -17,9 +17,50 @@ import { Session } from "./session" import { Instance } from "../../../project/instance" import { EventLoop } from "../../../util/eventloop" -export const OpentuiCommand = cmd({ - command: "opentui", - describe: "print hello", +export const TuiCommand = cmd({ + command: "$0 [project]", + describe: "start opencode tui", + builder: (yargs) => + yargs + .positional("project", { + type: "string", + describe: "path to start opencode in", + }) + .option("model", { + type: "string", + alias: ["m"], + describe: "model to use in the format of provider/model", + }) + .option("continue", { + alias: ["c"], + describe: "continue the last session", + type: "boolean", + }) + .option("session", { + alias: ["s"], + describe: "session id to continue", + type: "string", + }) + .option("prompt", { + alias: ["p"], + type: "string", + describe: "prompt to use", + }) + .option("agent", { + type: "string", + describe: "agent to use", + }) + .option("port", { + type: "number", + describe: "port to listen on", + default: 0, + }) + .option("hostname", { + alias: ["h"], + type: "string", + describe: "hostname to listen on", + default: "127.0.0.1", + }), handler: async () => { await render( () => { diff --git a/packages/opencode/src/cli/cmd/opentui/ui/dialog-select.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/ui/dialog-select.tsx rename to packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/ui/dialog.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog.tsx similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/ui/dialog.tsx rename to packages/opencode/src/cli/cmd/tui/ui/dialog.tsx diff --git a/packages/opencode/src/cli/cmd/opentui/util/format.ts b/packages/opencode/src/cli/cmd/tui/util/format.ts similarity index 100% rename from packages/opencode/src/cli/cmd/opentui/util/format.ts rename to packages/opencode/src/cli/cmd/tui/util/format.ts diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index cf43dd005..c34627e87 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -12,12 +12,11 @@ import { Installation } from "./installation" import { NamedError } from "./util/error" import { FormatError } from "./cli/error" import { ServeCommand } from "./cli/cmd/serve" -import { TuiCommand } from "./cli/cmd/tui" +import { TuiCommand } from "./cli/cmd/tui/tui" 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 { OpentuiCommand } from "./cli/cmd/opentui/opentui" import { ExportCommand } from "./cli/cmd/export" const cancel = new AbortController() @@ -72,7 +71,6 @@ const cli = yargs(hideBin(process.argv)) .usage("\n" + UI.logo()) .command(McpCommand) .command(TuiCommand) - .command(OpentuiCommand) .command(RunCommand) .command(GenerateCommand) .command(DebugCommand)