mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-31 06:12:26 +00:00
114 lines
2.9 KiB
TypeScript
114 lines
2.9 KiB
TypeScript
import z from "zod"
|
|
import { EOL } from "os"
|
|
import { NamedError } from "@opencode-ai/util/error"
|
|
import { logo as glyphs } from "./logo"
|
|
|
|
export namespace UI {
|
|
export const CancelledError = NamedError.create("UICancelledError", z.void())
|
|
|
|
export const Style = {
|
|
TEXT_HIGHLIGHT: "\x1b[96m",
|
|
TEXT_HIGHLIGHT_BOLD: "\x1b[96m\x1b[1m",
|
|
TEXT_DIM: "\x1b[90m",
|
|
TEXT_DIM_BOLD: "\x1b[90m\x1b[1m",
|
|
TEXT_NORMAL: "\x1b[0m",
|
|
TEXT_NORMAL_BOLD: "\x1b[1m",
|
|
TEXT_WARNING: "\x1b[93m",
|
|
TEXT_WARNING_BOLD: "\x1b[93m\x1b[1m",
|
|
TEXT_DANGER: "\x1b[91m",
|
|
TEXT_DANGER_BOLD: "\x1b[91m\x1b[1m",
|
|
TEXT_SUCCESS: "\x1b[92m",
|
|
TEXT_SUCCESS_BOLD: "\x1b[92m\x1b[1m",
|
|
TEXT_INFO: "\x1b[94m",
|
|
TEXT_INFO_BOLD: "\x1b[94m\x1b[1m",
|
|
}
|
|
|
|
export function println(...message: string[]) {
|
|
print(...message)
|
|
Bun.stderr.write(EOL)
|
|
}
|
|
|
|
export function print(...message: string[]) {
|
|
blank = false
|
|
Bun.stderr.write(message.join(" "))
|
|
}
|
|
|
|
let blank = false
|
|
export function empty() {
|
|
if (blank) return
|
|
println("" + Style.TEXT_NORMAL)
|
|
blank = true
|
|
}
|
|
|
|
export function logo(pad?: string) {
|
|
const result: string[] = []
|
|
const reset = "\x1b[0m"
|
|
const left = {
|
|
fg: Bun.color("gray", "ansi") ?? "",
|
|
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({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
})
|
|
|
|
return new Promise((resolve) => {
|
|
rl.question(prompt, (answer: string) => {
|
|
rl.close()
|
|
resolve(answer.trim())
|
|
})
|
|
})
|
|
}
|
|
|
|
export function error(message: string) {
|
|
println(Style.TEXT_DANGER_BOLD + "Error: " + Style.TEXT_NORMAL + message)
|
|
}
|
|
|
|
export function markdown(text: string): string {
|
|
return text
|
|
}
|
|
}
|