chore: uptick

This commit is contained in:
Brooklyn Nicholson 2026-04-03 19:55:15 -05:00
parent fab4d8d470
commit 56a69e519b
3 changed files with 21 additions and 16 deletions

View file

@ -14,6 +14,7 @@ import { Thinking } from './components/thinking.js'
import { COMMANDS, HOTKEYS, INTERPOLATION_RE, MAX_CTX, PLACEHOLDERS, TOOL_VERBS, ZERO } from './constants.js' import { COMMANDS, HOTKEYS, INTERPOLATION_RE, MAX_CTX, PLACEHOLDERS, TOOL_VERBS, ZERO } from './constants.js'
import { type GatewayClient, type GatewayEvent } from './gatewayClient.js' import { type GatewayClient, type GatewayEvent } from './gatewayClient.js'
import * as inputHistory from './lib/history.js' import * as inputHistory from './lib/history.js'
import { writeOsc52Clipboard } from './lib/osc52.js'
import { upsert } from './lib/messages.js' import { upsert } from './lib/messages.js'
import { estimateRows, flat, fmtK, hasInterpolation, pick, userDisplay } from './lib/text.js' import { estimateRows, flat, fmtK, hasInterpolation, pick, userDisplay } from './lib/text.js'
import { DEFAULT_THEME, fromSkin, type Theme } from './theme.js' import { DEFAULT_THEME, fromSkin, type Theme } from './theme.js'
@ -661,7 +662,7 @@ export function App({ gw }: { gw: GatewayClient }) {
return true return true
} }
process.stdout.write(`\x1b]52;c;${Buffer.from(target.text).toString('base64')}\x07`) writeOsc52Clipboard(target.text)
sys('copied to clipboard') sys('copied to clipboard')
return true return true

View file

@ -8,50 +8,51 @@ function MdInline({ t, text }: { t: Theme; text: string }) {
const re = /(\[(.+?)\]\((https?:\/\/[^\s)]+)\)|\*\*(.+?)\*\*|`([^`]+)`|\*(.+?)\*|(https?:\/\/[^\s]+))/g const re = /(\[(.+?)\]\((https?:\/\/[^\s)]+)\)|\*\*(.+?)\*\*|`([^`]+)`|\*(.+?)\*|(https?:\/\/[^\s]+))/g
let last = 0 let last = 0
let match: RegExpExecArray | null
while ((match = re.exec(text)) !== null) { for (const m of text.matchAll(re)) {
if (match.index > last) { const i = m.index ?? 0
if (i > last) {
parts.push( parts.push(
<Text color={t.color.cornsilk} key={parts.length}> <Text color={t.color.cornsilk} key={parts.length}>
{text.slice(last, match.index)} {text.slice(last, i)}
</Text> </Text>
) )
} }
if (match[2] && match[3]) { if (m[2] && m[3]) {
parts.push( parts.push(
<Text color={t.color.amber} key={parts.length} underline> <Text color={t.color.amber} key={parts.length} underline>
{match[2]} {m[2]}
</Text> </Text>
) )
} else if (match[4]) { } else if (m[4]) {
parts.push( parts.push(
<Text bold color={t.color.cornsilk} key={parts.length}> <Text bold color={t.color.cornsilk} key={parts.length}>
{match[4]} {m[4]}
</Text> </Text>
) )
} else if (match[5]) { } else if (m[5]) {
parts.push( parts.push(
<Text color={t.color.amber} dimColor key={parts.length}> <Text color={t.color.amber} dimColor key={parts.length}>
{match[5]} {m[5]}
</Text> </Text>
) )
} else if (match[6]) { } else if (m[6]) {
parts.push( parts.push(
<Text color={t.color.cornsilk} italic key={parts.length}> <Text color={t.color.cornsilk} italic key={parts.length}>
{match[6]} {m[6]}
</Text> </Text>
) )
} else if (match[7]) { } else if (m[7]) {
parts.push( parts.push(
<Text color={t.color.amber} key={parts.length} underline> <Text color={t.color.amber} key={parts.length} underline>
{match[7]} {m[7]}
</Text> </Text>
) )
} }
last = match.index + match[0].length last = i + m[0].length
} }
if (last < text.length) { if (last < text.length) {

3
ui-tui/src/lib/osc52.ts Normal file
View file

@ -0,0 +1,3 @@
export function writeOsc52Clipboard(s: string): void {
process.stdout.write('\x1b]52;c;' + Buffer.from(s, 'utf8').toString('base64') + '\x07')
}