- Add SessionManager class to handle PTY sessions with WebSocket connections. - Implement methods for creating, retrieving, and destroying sessions. - Handle PTY output and WebSocket messages for terminal interaction. - Ensure graceful session destruction and cleanup. feat: initialize web application with Next.js and Tailwind CSS - Create initial Next.js application structure with TypeScript support. - Set up Tailwind CSS for styling with custom theme configurations. - Add ESLint configuration for code quality and consistency. feat: implement chat API and UI components - Create chat API route to handle chat requests and responses. - Develop chat layout with sidebar, header, chat window, and input components. - Integrate Zustand for state management of conversations and messages. - Add utility functions for formatting dates and managing class names. chore: add environment variables and configuration files - Create .env.example for environment variable setup. - Add configuration files for PostCSS, Tailwind CSS, and TypeScript. - Set up package.json with necessary dependencies and scripts for development.
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { clsx, type ClassValue } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
export function formatDate(timestamp: number): string {
|
|
const date = new Date(timestamp);
|
|
const now = new Date();
|
|
const diffMs = now.getTime() - date.getTime();
|
|
const diffMins = Math.floor(diffMs / 60000);
|
|
const diffHours = Math.floor(diffMs / 3600000);
|
|
const diffDays = Math.floor(diffMs / 86400000);
|
|
|
|
if (diffMins < 1) return "just now";
|
|
if (diffMins < 60) return `${diffMins}m ago`;
|
|
if (diffHours < 24) return `${diffHours}h ago`;
|
|
if (diffDays < 7) return `${diffDays}d ago`;
|
|
|
|
return date.toLocaleDateString("en-US", {
|
|
month: "short",
|
|
day: "numeric",
|
|
year: date.getFullYear() !== now.getFullYear() ? "numeric" : undefined,
|
|
});
|
|
}
|
|
|
|
export function truncate(str: string, maxLength: number): string {
|
|
if (str.length <= maxLength) return str;
|
|
return str.slice(0, maxLength - 3) + "...";
|
|
}
|
|
|
|
export function extractTextContent(content: unknown): string {
|
|
if (typeof content === "string") return content;
|
|
if (Array.isArray(content)) {
|
|
return content
|
|
.filter((b): b is { type: "text"; text: string } => b?.type === "text")
|
|
.map((b) => b.text)
|
|
.join("");
|
|
}
|
|
return "";
|
|
}
|