import palette from '../../vendor/pi-coding-agent/theme/dark.json'; // Upstream Pi dark palette; browser styling replaces the theme file watcher // and Node's syntax highlighter. Code blocks use Pi's plain-code fallback. // Lift secondary text so small terminal text stays legible on tool backgrounds. const readable = { muted: '#b0b0bd', toolOutput: '#b0b0bd', thinkingText: '#b0b0bd', dim: '#aaaab7', mdLinkUrl: '#aaaab7', mdCodeBlockBorder: '#aaaab7', mdQuote: '#b0b0bd' }; function color(name, text, background = false) { const value = readable[name] ?? palette.vars[palette.colors[name]] ?? palette.colors[name] ?? palette.vars.text; const rgb = value.slice(1).match(/../g).map(part => parseInt(part, 16)).join(';'); const open = `\x1b[${background ? 48 : 38};2;${rgb}m`, close = `\x1b[${background ? 49 : 39}m`; return open + String(text).replaceAll(close, open) + close; } export const terminalTheme = { background: palette.export.pageBg, foreground: palette.vars.text, cursor: palette.vars.accent, cursorAccent: palette.export.pageBg, selectionBackground: palette.vars.selectedBg, selectionForeground: palette.vars.text, black: '#18181e', brightBlack: '#9696a4', white: '#d4d4d4', brightWhite: '#f2f2f4', }; export const theme = { fg: (name, text) => color(name, text), bg: (name, text) => color(name, text, true), bold: text => `\x1b[1m${text}\x1b[22m`, italic: text => `\x1b[3m${text}\x1b[23m`, underline: text => `\x1b[4m${text}\x1b[24m`, }; export function getMarkdownTheme() { return { ...Object.fromEntries(Object.entries({ heading: 'mdHeading', link: 'mdLink', linkUrl: 'mdLinkUrl', code: 'mdCode', codeBlock: 'mdCodeBlock', codeBlockBorder: 'mdCodeBlockBorder', quote: 'mdQuote', quoteBorder: 'mdQuoteBorder', hr: 'mdHr', listBullet: 'mdListBullet' }).map(([key, value]) => [key, text => theme.fg(value, text)])), bold: theme.bold, italic: theme.italic, underline: theme.underline, strikethrough: text => `\x1b[9m${text}\x1b[29m`, highlightCode: code => code.split('\n').map(line => theme.fg('mdCodeBlock', line)), }; } export function getEditorTheme() { return { borderColor: text => theme.fg('borderMuted', text), selectList: { selectedPrefix: text => theme.fg('accent', text), selectedText: text => theme.fg('accent', text), description: text => theme.fg('muted', text), scrollInfo: text => theme.fg('muted', text), noMatch: text => theme.fg('muted', text), } }; }