| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- import { cmd } from "@/cli/cmd/cmd"
- import { tui } from "./app"
- import { Rpc } from "@/util/rpc"
- import { type rpc } from "./worker"
- import path from "path"
- import { UI } from "@/cli/ui"
- import { iife } from "@/util/iife"
- import { Log } from "@/util/log"
- import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network"
- import { Config } from "@/config/config"
- declare global {
- const OPENCODE_WORKER_PATH: string
- }
- export const TuiThreadCommand = cmd({
- command: "$0 [project]",
- describe: "start opencode tui",
- builder: (yargs) =>
- withNetworkOptions(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"],
- type: "string",
- describe: "session id to continue",
- })
- .option("prompt", {
- type: "string",
- describe: "prompt to use",
- })
- .option("agent", {
- type: "string",
- describe: "agent to use",
- }),
- handler: async (args) => {
- // Resolve relative paths against PWD to preserve behavior when using --cwd flag
- const baseCwd = process.env.PWD ?? process.cwd()
- const cwd = args.project ? path.resolve(baseCwd, args.project) : process.cwd()
- const localWorker = new URL("./worker.ts", import.meta.url)
- const distWorker = new URL("./cli/cmd/tui/worker.js", import.meta.url)
- const workerPath = await iife(async () => {
- if (typeof OPENCODE_WORKER_PATH !== "undefined") return OPENCODE_WORKER_PATH
- if (await Bun.file(distWorker).exists()) return distWorker
- return localWorker
- })
- try {
- process.chdir(cwd)
- } catch (e) {
- UI.error("Failed to change directory to " + cwd)
- return
- }
- const worker = new Worker(workerPath, {
- env: Object.fromEntries(
- Object.entries(process.env).filter((entry): entry is [string, string] => entry[1] !== undefined),
- ),
- })
- worker.onerror = (e) => {
- Log.Default.error(e)
- }
- const client = Rpc.client<typeof rpc>(worker)
- process.on("uncaughtException", (e) => {
- Log.Default.error(e)
- })
- process.on("unhandledRejection", (e) => {
- Log.Default.error(e)
- })
- const config = await Config.get()
- const networkOpts = resolveNetworkOptions(args, config)
- const server = await client.call("server", networkOpts)
- const prompt = await iife(async () => {
- const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined
- if (!args.prompt) return piped
- return piped ? piped + "\n" + args.prompt : args.prompt
- })
- const tuiPromise = tui({
- url: server.url,
- args: {
- continue: args.continue,
- sessionID: args.session,
- agent: args.agent,
- model: args.model,
- prompt,
- },
- onExit: async () => {
- await client.call("shutdown", undefined)
- },
- })
- setTimeout(() => {
- client.call("checkUpgrade", { directory: cwd }).catch(() => {})
- }, 1000)
- await tuiPromise
- },
- })
|