7. 用户体验
7.1 终端 UI
typescript
import { spinner, confirm, text } from '@clack/prompts';
class ClaudeCodeUI {
async displayThinking() {
const s = spinner();
s.start('Thinking...');
return s;
}
async displayToolCall(name: string, input: any) {
console.log(chalk.dim(`\n → ${name}`));
if (input.command) {
console.log(chalk.cyan(` $ ${input.command}`));
} else if (input.path || input.file_path) {
console.log(chalk.cyan(` 📄 ${input.path || input.file_path}`));
}
}
async displayToolResult(name: string, result: any) {
if (result.error) {
console.log(chalk.red(` ✗ ${result.error}`));
} else {
console.log(chalk.green(` ✓ Done`));
}
}
async displayMarkdown(content: string) {
const rendered = marked.parse(content);
console.log(rendered);
}
async displayDiff(oldContent: string, newContent: string) {
const diff = createPatch('file', oldContent, newContent);
console.log(
diff.split('\n').map(line => {
if (line.startsWith('+')) return chalk.green(line);
if (line.startsWith('-')) return chalk.red(line);
return line;
}).join('\n')
);
}
}7.2 快捷命令
typescript
const shortcuts = {
'/help': 'Show available commands',
'/clear': 'Clear conversation history',
'/undo': 'Undo last file change',
'/diff': 'Show recent changes',
'/memory': 'Manage memories',
'/model': 'Switch model',
'/exit': 'Exit Claude Code'
};
class CommandHandler {
async handle(input: string) {
if (!input.startsWith('/')) {
return null; // 不是命令
}
const [cmd, ...args] = input.split(' ');
switch (cmd) {
case '/help':
return this.showHelp();
case '/clear':
return this.clearHistory();
case '/undo':
return this.undoLastChange();
case '/diff':
return this.showDiff(args[0]);
case '/memory':
return this.manageMemory(args);
default:
return `Unknown command: ${cmd}`;
}
}
}