chore: commit unrelated local changes

This commit is contained in:
William Valentin
2026-02-15 21:51:22 -08:00
parent 7f563b4bb1
commit 50dcff5ea6
7 changed files with 60 additions and 21 deletions
+9 -12
View File
@@ -13,18 +13,15 @@ export interface MessageListProps {
// Helper to format timestamp in human-readable way
function formatTimestamp(timestamp: number): string {
const now = Date.now();
const diff = now - timestamp;
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const date = new Date(timestamp);
const now = new Date();
const isSameDay = date.toDateString() === now.toDateString();
if (seconds < 60) {return 'just now';}
if (minutes < 60) {return `${minutes}m ago`;}
if (hours < 24) {return `${hours}h ago`;}
if (days < 7) {return `${days}d ago`;}
return new Date(timestamp).toLocaleDateString([], { month: 'short', day: 'numeric' });
if (isSameDay) {
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}
return date.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
}
// Individual message component
@@ -37,7 +34,7 @@ const MessageItem = memo(function MessageItem({
}): React.ReactElement {
const isUser = message.role === 'user';
const accentColor = isUser ? 'blue' : '#ff8c00';
const timestampText = message.timestamp ? formatTimestamp(message.timestamp) : '';
const timestampText = message.timestamp ? formatTimestamp(message.timestamp) : 'unknown time';
return (
<Box
+11 -1
View File
@@ -46,6 +46,14 @@ export function formatPrompt(state: 'default' | 'thinking'): string {
return `${colors.orange}${colors.bold}flynn>${colors.reset} `;
}
function formatMessageTime(timestamp: number): string {
return new Date(timestamp).toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
}
export interface MinimalTuiConfig {
session: ManagedSession;
modelClient: ModelClient;
@@ -771,7 +779,9 @@ export class MinimalTui {
private async handleMessage(content: string): Promise<void> {
// Print Flynn label before response
process.stdout.write(`\n${colors.orange}${colors.bold}Flynn:${colors.reset}\n`);
process.stdout.write(
`\n${colors.orange}${colors.bold}Flynn${colors.reset} ${colors.gray}[${formatMessageTime(Date.now())}]${colors.reset}\n`,
);
try {
// Use agent if available (supports tool loop)
+6
View File
@@ -23,16 +23,22 @@ describe('SessionStore', () => {
it('saves and retrieves messages', () => {
const sessionId = 'test-session';
const before = Date.now();
store.addMessage(sessionId, { role: 'user', content: 'Hello' });
store.addMessage(sessionId, { role: 'assistant', content: 'Hi there!' });
const after = Date.now();
const messages = store.getMessages(sessionId);
expect(messages).toHaveLength(2);
expect(messages[0].role).toBe('user');
expect(messages[0].content).toBe('Hello');
expect(messages[0].timestamp).toBeTypeOf('number');
expect(messages[0].timestamp!).toBeGreaterThanOrEqual(before - 1000);
expect(messages[0].timestamp!).toBeLessThanOrEqual(after + 1000);
expect(messages[1].role).toBe('assistant');
expect(messages[1].content).toBe('Hi there!');
expect(messages[1].timestamp).toBeTypeOf('number');
});
it('clears session messages', () => {
+9 -6
View File
@@ -53,20 +53,22 @@ export class SessionStore {
}
addMessage(sessionId: string, message: Message, metadata?: HistoryMetadata): void {
const createdAtSeconds = Math.floor((message.timestamp ?? Date.now()) / 1000);
const stmt = this.db.prepare(
'INSERT INTO messages (session_id, role, content, metadata) VALUES (?, ?, ?, ?)',
'INSERT INTO messages (session_id, role, content, created_at, metadata) VALUES (?, ?, ?, ?, ?)',
);
stmt.run(sessionId, message.role, message.content, metadata ? JSON.stringify(metadata) : null);
stmt.run(sessionId, message.role, message.content, createdAtSeconds, metadata ? JSON.stringify(metadata) : null);
}
getMessages(sessionId: string): Message[] {
const stmt = this.db.prepare(
'SELECT role, content FROM messages WHERE session_id = ? ORDER BY id ASC',
'SELECT role, content, created_at FROM messages WHERE session_id = ? ORDER BY id ASC',
);
const rows = stmt.all(sessionId) as Array<{ role: string; content: string }>;
const rows = stmt.all(sessionId) as Array<{ role: string; content: string; created_at: number }>;
return rows.map(row => ({
role: row.role as 'user' | 'assistant',
content: row.content,
timestamp: row.created_at * 1000,
}));
}
@@ -81,10 +83,11 @@ export class SessionStore {
this.db.prepare('DELETE FROM messages WHERE session_id = ?').run(sessionId);
// Re-insert in order
const insert = this.db.prepare(
'INSERT INTO messages (session_id, role, content, metadata) VALUES (?, ?, ?, ?)',
'INSERT INTO messages (session_id, role, content, created_at, metadata) VALUES (?, ?, ?, ?, ?)',
);
for (const msg of messages) {
insert.run(sessionId, msg.role, msg.content, null);
const createdAtSeconds = Math.floor((msg.timestamp ?? Date.now()) / 1000);
insert.run(sessionId, msg.role, msg.content, createdAtSeconds, null);
}
});
transaction();