feat(tui): persist model tier selection and fix formatting
Persist /model tier choice to ~/.local/share/flynn/preferences.json so it survives restarts. Decode HTML entities (e.g. ') in markdown renderer output. Suppress noisy logger.info and punycode deprecation warnings in TUI startup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -109,4 +109,10 @@ describe('renderMarkdown', () => {
|
||||
expect(result).toContain('\x1b[34m');
|
||||
expect(result).toContain('https://example.com');
|
||||
});
|
||||
|
||||
it('decodes HTML entities like apostrophes', () => {
|
||||
const result = renderMarkdown("I'm here. What's up?");
|
||||
expect(result).toContain("I'm here");
|
||||
expect(result).not.toContain(''');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,14 +27,7 @@ function convertHtmlToTerminal(text: string): string {
|
||||
// Horizontal rules
|
||||
.replace(/<hr\s*\/?>/gi, '─'.repeat(40) + '\n')
|
||||
// Strip any remaining HTML tags
|
||||
.replace(/<[^>]+>/g, '')
|
||||
// Decode common HTML entities
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/ /g, ' ');
|
||||
.replace(/<[^>]+>/g, '');
|
||||
}
|
||||
|
||||
// Custom renderer as an object for marked.use()
|
||||
@@ -147,19 +140,29 @@ const terminalRenderer: RendererObject = {
|
||||
},
|
||||
|
||||
html({ text }: Tokens.HTML | Tokens.Tag): string {
|
||||
return convertHtmlToTerminal(text);
|
||||
return decodeHtmlEntities(convertHtmlToTerminal(text));
|
||||
},
|
||||
};
|
||||
|
||||
// Configure marked with our renderer
|
||||
marked.use({ renderer: terminalRenderer });
|
||||
|
||||
function decodeHtmlEntities(text: string): string {
|
||||
return text
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/ /g, ' ');
|
||||
}
|
||||
|
||||
export function renderMarkdown(text: string): string {
|
||||
try {
|
||||
const rendered = marked.parse(text);
|
||||
// marked.parse can return string | Promise<string>, we only use sync
|
||||
if (typeof rendered === 'string') {
|
||||
return rendered.trim();
|
||||
return decodeHtmlEntities(rendered).trim();
|
||||
}
|
||||
return text;
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user