Files
can1357 e9888367d1 refactor: migrated packages to internal utility modules and removed external dependencies
- Implemented in-house, zero-dependency utility modules in `pi-utils` covering DOM manipulation, markdown parsing, templating, browser automation helpers, and terminal buffers.
- Migrated packages across the repository to consume the new internal utilities and `omptype` schema validators instead of external dependencies.
- Removed multiple external runtime and development dependencies including Zod, Marked, LRU cache, Turndown, and Puppeteer browser packages.
2026-08-05 13:39:09 +02:00

130 lines
3.5 KiB
TypeScript

/**
* Simple chat interface demo using tui.ts
*/
import { CombinedAutocompleteProvider } from "@oh-my-pi/pi-tui/autocomplete";
import { Editor } from "@oh-my-pi/pi-tui/components/editor";
import { Loader } from "@oh-my-pi/pi-tui/components/loader";
import { Markdown } from "@oh-my-pi/pi-tui/components/markdown";
import { Text } from "@oh-my-pi/pi-tui/components/text";
import { ProcessTerminal } from "@oh-my-pi/pi-tui/terminal";
import { TUI } from "@oh-my-pi/pi-tui/tui";
import { getProjectDir } from "@oh-my-pi/pi-utils";
import chalk from "@oh-my-pi/pi-utils/chalk";
import { defaultEditorTheme, defaultMarkdownTheme } from "./test-themes";
// Create terminal
const terminal = new ProcessTerminal();
// Create TUI
const tui = new TUI(terminal);
// Create chat container with some initial messages
tui.addChild(
new Text("Welcome to Simple Chat!\n\nType your messages below. Type '/' for commands. Press Ctrl+C to exit."),
);
// Create editor with autocomplete
const editor = new Editor(defaultEditorTheme);
// Set up autocomplete provider with slash commands and file completion
const autocompleteProvider = new CombinedAutocompleteProvider(
[
{ name: "delete", description: "Delete the last message" },
{ name: "clear", description: "Clear all messages" },
],
getProjectDir(),
);
editor.setAutocompleteProvider(autocompleteProvider);
tui.addChild(editor);
// Focus the editor
tui.setFocus(editor);
// Track if we're waiting for bot response
let isResponding = false;
// Handle message submission
editor.onSubmit = (value: string) => {
// Prevent submission if already responding
if (isResponding) {
return;
}
const trimmed = value.trim();
// Handle slash commands
if (trimmed === "/delete") {
const children = tui.children;
// Remove component before editor (if there are any besides the initial text)
if (children.length > 3) {
// children[0] = "Welcome to Simple Chat!"
// children[1] = "Type your messages below..."
// children[2...n-1] = messages
// children[n] = editor
children.splice(children.length - 2, 1);
}
tui.requestRender();
return;
}
if (trimmed === "/clear") {
const children = tui.children;
// Remove all messages but keep the welcome text and editor
children.splice(2, children.length - 3);
tui.requestRender();
return;
}
if (trimmed) {
isResponding = true;
editor.disableSubmit = true;
const userMessage = new Markdown(value, 1, 1, defaultMarkdownTheme);
const children = tui.children;
children.splice(children.length - 1, 0, userMessage);
const loader = new Loader(
tui,
s => chalk.cyan(s),
s => chalk.dim(s),
"Thinking...",
);
children.splice(children.length - 1, 0, loader);
tui.requestRender();
setTimeout(() => {
tui.removeChild(loader);
// Simulate a response
const responses = [
"That's interesting! Tell me more.",
"I see what you mean.",
"Fascinating perspective!",
"Could you elaborate on that?",
"That makes sense to me.",
"I hadn't thought of it that way.",
"Great point!",
"Thanks for sharing that.",
];
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
// Add assistant message with no background (transparent)
const botMessage = new Markdown(randomResponse, 1, 1, defaultMarkdownTheme);
children.splice(children.length - 1, 0, botMessage);
// Re-enable submit
isResponding = false;
editor.disableSubmit = false;
// Request render
tui.requestRender();
}, 1000);
}
};
// Start the TUI
tui.start();