research-cli
Version:
AI-powered research assistant with web search capabilities and beautiful terminal UI
153 lines • 5.35 kB
JavaScript
/**
* Message formatters for research-cli
* Provides consistent, professional formatting for all output types
*/
import { icons, styles } from "./styles.js";
// Message formatting utilities
export class MessageFormatter {
// Status messages with icons
success(message) {
return `${styles.success(icons.success)} ${styles.success(message)}`;
}
error(message) {
return `${styles.error(icons.error)} ${styles.error(message)}`;
}
warning(message) {
return `${styles.warning(icons.warning)} ${styles.warning(message)}`;
}
info(message) {
return `${styles.info(icons.info)} ${styles.info(message)}`;
}
// Headings and structure
heading(text) {
return `\n${styles.heading(text)}\n`;
}
subheading(text) {
return `${styles.subheading(text)}`;
}
// Lists and bullets
bullet(text) {
return ` ${styles.muted(icons.bullet)} ${styles.body(text)}`;
}
numberedItem(number, text) {
return ` ${styles.brand.primary(number.toString())}. ${styles.body(text)}`;
}
// Technical content
code(code) {
return styles.code(` ${code} `);
}
command(command) {
return styles.command(command);
}
path(path) {
return styles.path(path);
}
// Interactive elements
link(text, url) {
if (url) {
return `${styles.link(text)} (${styles.muted(url)})`;
}
return styles.link(text);
}
// Key-value pairs
keyValue(key, value) {
return `${styles.secondary(key)}: ${styles.body(value)}`;
}
// Progress and status
loading(message) {
return `${styles.info(icons.loading)} ${styles.info(message)}`;
}
progress(current, total, message) {
const percentage = Math.round((current / total) * 100);
const bar = "█".repeat(Math.floor(percentage / 5)) +
"░".repeat(20 - Math.floor(percentage / 5));
const progress = `[${bar}] ${percentage}%`;
if (message) {
return `${styles.info(progress)} ${styles.secondary(message)}`;
}
return styles.info(progress);
}
}
// Specialized formatters for different contexts
export class AuthFormatter extends MessageFormatter {
keyStatus(provider, hasKey) {
if (hasKey) {
return ` ${this.success("Configured")}: ${styles.body(provider)}`;
}
return ` ${this.error("Not configured")}: ${styles.body(provider)}`;
}
providerHeading(provider) {
return `\n${styles.heading(`${icons.key} ${provider.toUpperCase()} API Key Setup`)}`;
}
instructions(text) {
return styles.secondary(text);
}
}
export class QueryFormatter extends MessageFormatter {
queryStart(provider, model) {
return `${styles.info(icons.search)} ${styles.info(`Querying ${provider} (${model})...`)}`;
}
toolUsage(toolName) {
return `${styles.info(icons.tool)} ${styles.info(`Using tool: ${toolName}`)}`;
}
toolComplete(toolName) {
return `${this.success(`Tool ${toolName} completed`)}`;
}
usageStats(stats) {
const lines = [
`\n${styles.heading(`${icons.stats} Usage Stats:`)}`,
` Input tokens: ${styles.body(stats.input_tokens.toLocaleString())}`,
` Output tokens: ${styles.body(stats.output_tokens.toLocaleString())}`,
];
if (stats.reasoning_tokens && stats.reasoning_tokens > 0) {
lines.push(` Reasoning tokens: ${styles.body(stats.reasoning_tokens.toLocaleString())}`);
}
lines.push(` Total tokens: ${styles.body(stats.total_tokens.toLocaleString())}`);
return lines.join("\n");
}
citation(index, title, url) {
return `${styles.body(index.toString())}. ${this.link(title, url)}`;
}
sourcesHeading() {
return `\n${styles.heading("## Sources")}\n`;
}
}
export class ConfigFormatter extends MessageFormatter {
configHeading() {
return `${styles.heading(`${icons.config} Current Configuration:`)}`;
}
configItem(key, value) {
return ` ${this.bullet(`${styles.secondary(key)}: ${styles.body(value)}`)}`;
}
placeholder(message) {
return styles.muted(message);
}
}
// Utility functions for quick formatting
export const format = {
// Quick status messages
success: (msg) => new MessageFormatter().success(msg),
error: (msg) => new MessageFormatter().error(msg),
warning: (msg) => new MessageFormatter().warning(msg),
info: (msg) => new MessageFormatter().info(msg),
// Quick text styling
heading: (text) => styles.heading(text),
code: (code) => styles.code(` ${code} `),
command: (cmd) => styles.command(cmd),
path: (path) => styles.path(path),
link: (text, url) => {
const formatter = new MessageFormatter();
return formatter.link(text, url);
},
// Quick key-value
kv: (key, value) => {
const formatter = new MessageFormatter();
return formatter.keyValue(key, value);
},
};
// Export default instances for common use
export const auth = new AuthFormatter();
export const query = new QueryFormatter();
export const config = new ConfigFormatter();
export const message = new MessageFormatter();
//# sourceMappingURL=formatters.js.map