fix(cli): restore colored help logo (#20592)

pull/20170/head^2
Kit Langton 2026-04-01 23:21:07 -04:00 committed by GitHub
parent 916afb5220
commit 336d28f112
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 78 additions and 9 deletions

View File

@ -1,6 +1,7 @@
import z from "zod"
import { EOL } from "os"
import { NamedError } from "@opencode-ai/util/error"
import { logo as glyphs } from "./logo"
export namespace UI {
const wordmark = [
@ -47,6 +48,7 @@ export namespace UI {
}
export function logo(pad?: string) {
if (!process.stdout.isTTY && !process.stderr.isTTY) {
const result = []
for (const row of wordmark) {
if (pad) result.push(pad)
@ -56,6 +58,53 @@ export namespace UI {
return result.join("").trimEnd()
}
const result: string[] = []
const reset = "\x1b[0m"
const left = {
fg: "\x1b[90m",
shadow: "\x1b[38;5;235m",
bg: "\x1b[48;5;235m",
}
const right = {
fg: reset,
shadow: "\x1b[38;5;238m",
bg: "\x1b[48;5;238m",
}
const gap = " "
const draw = (line: string, fg: string, shadow: string, bg: string) => {
const parts: string[] = []
for (const char of line) {
if (char === "_") {
parts.push(bg, " ", reset)
continue
}
if (char === "^") {
parts.push(fg, bg, "▀", reset)
continue
}
if (char === "~") {
parts.push(shadow, "▀", reset)
continue
}
if (char === " ") {
parts.push(" ")
continue
}
parts.push(fg, char, reset)
}
return parts.join("")
}
glyphs.left.forEach((row, index) => {
if (pad) result.push(pad)
result.push(draw(row, left.fg, left.shadow, left.bg))
result.push(gap)
const other = glyphs.right[index] ?? ""
result.push(draw(other, right.fg, right.shadow, right.bg))
result.push(EOL)
})
return result.join("").trimEnd()
}
export async function input(prompt: string): Promise<string> {
const readline = require("readline")
const rl = readline.createInterface({

View File

@ -48,7 +48,19 @@ process.on("uncaughtException", (e) => {
})
})
const cli = yargs(hideBin(process.argv))
const args = hideBin(process.argv)
function show(out: string) {
const text = out.trimStart()
if (!text.startsWith("opencode ")) {
process.stderr.write(UI.logo() + EOL + EOL)
process.stderr.write(text)
return
}
process.stderr.write(out)
}
const cli = yargs(args)
.parserConfiguration({ "populate--": true })
.scriptName("opencode")
.wrap(100)
@ -130,7 +142,7 @@ const cli = yargs(hideBin(process.argv))
process.stderr.write("Database migration complete." + EOL)
}
})
.usage("\n" + UI.logo())
.usage("")
.completion("completion", "generate shell completion script")
.command(AcpCommand)
.command(McpCommand)
@ -162,7 +174,7 @@ const cli = yargs(hideBin(process.argv))
msg?.startsWith("Invalid values:")
) {
if (err) throw err
cli.showHelp("log")
cli.showHelp(show)
}
if (err) throw err
process.exit(1)
@ -170,7 +182,15 @@ const cli = yargs(hideBin(process.argv))
.strict()
try {
if (args.includes("-h") || args.includes("--help")) {
await cli.parse(args, (err: Error | undefined, _argv: unknown, out: string) => {
if (err) throw err
if (!out) return
show(out)
})
} else {
await cli.parse()
}
} catch (e) {
let data: Record<string, any> = {}
if (e instanceof NamedError) {