Files
oh-my-openagent/src/cli/run/output-renderer.ts
YeonGyu-Kim 90aa3a306c perf(hooks,tools): optimize string operations and reduce redundant iterations
- output-renderer, hashline-edit-diff: replace str += with array join (H2)
- auto-slash-command: single-pass Map grouping instead of 6x filter (M1)
- comment-checker: hoist Zod schema to module scope (M2)
- session-last-agent: reverse iterate sorted array instead of sort+reverse (L2)
2026-03-18 14:19:12 +09:00

91 lines
2.2 KiB
TypeScript

import pc from "picocolors"
export function renderAgentHeader(
agent: string | null,
model: string | null,
variant: string | null,
agentColorsByName: Record<string, string>,
): void {
if (!agent && !model) return
const agentLabel = agent
? pc.bold(colorizeWithProfileColor(agent, agentColorsByName[agent]))
: ""
const modelBase = model ?? ""
const variantSuffix = variant ? ` (${variant})` : ""
const modelLabel = model ? pc.dim(`${modelBase}${variantSuffix}`) : ""
process.stdout.write("\n")
if (modelLabel) {
process.stdout.write(` ${modelLabel} \n`)
}
if (agentLabel) {
process.stdout.write(` ${pc.dim("└─")} ${agentLabel} \n`)
}
process.stdout.write("\n")
}
export function openThinkBlock(): void {
process.stdout.write(`\n ${pc.dim("┃ Thinking:")} `)
}
export function closeThinkBlock(): void {
process.stdout.write(" \n\n")
}
export function writePaddedText(
text: string,
atLineStart: boolean,
): { output: string; atLineStart: boolean } {
const isGitHubActions = process.env.GITHUB_ACTIONS === "true"
if (isGitHubActions) {
return { output: text, atLineStart: text.endsWith("\n") }
}
const parts: string[] = []
let lineStart = atLineStart
for (let i = 0; i < text.length; i++) {
const ch = text[i]
if (lineStart) {
parts.push(" ")
lineStart = false
}
if (ch === "\n") {
parts.push(" \n")
lineStart = true
continue
}
parts.push(ch)
}
return { output: parts.join(""), atLineStart: lineStart }
}
function colorizeWithProfileColor(text: string, hexColor?: string): string {
if (!hexColor) return pc.magenta(text)
const rgb = parseHexColor(hexColor)
if (!rgb) return pc.magenta(text)
const [r, g, b] = rgb
return `\u001b[38;2;${r};${g};${b}m${text}\u001b[39m`
}
function parseHexColor(hexColor: string): [number, number, number] | null {
const cleaned = hexColor.trim()
const match = cleaned.match(/^#?([A-Fa-f0-9]{6})$/)
if (!match) return null
const hex = match[1]
const r = Number.parseInt(hex.slice(0, 2), 16)
const g = Number.parseInt(hex.slice(2, 4), 16)
const b = Number.parseInt(hex.slice(4, 6), 16)
return [r, g, b]
}