chore: initialize EverOS 1.0.0

md-first memory extraction framework for AI agents.

Markdown is the single source of truth; SQLite holds state and LanceDB
provides the rebuildable vector + BM25 + scalar index. The codebase follows
a single-direction DDD layering (entrypoints -> service -> memory -> infra,
with component / core / config cross-cutting) enforced by import-linter.

Engineering surface:
- Coding conventions in .claude/rules/ (path-scoped) and workflows in
  .claude/skills/ (/commit, /new-branch, /pr).
- GitHub Actions CI runs make lint + test + integration; pre-commit mirrors
  the gates locally (ruff, hygiene hooks, gitlint commit-msg).
- Commit messages follow Conventional Commits, enforced by gitlint.
- make lint also enforces datetime two-zone discipline and OpenAPI drift.
This commit is contained in:
Elliot Chen
2026-06-05 22:35:51 +08:00
commit 518b8eca85
636 changed files with 160553 additions and 0 deletions

View File

@ -0,0 +1,143 @@
import { useState, useEffect, useCallback } from 'react';
import { Message, Memory } from '../types';
import { sendChatMessage } from '../services/api';
const STORAGE_KEY = 'chat_history';
const MEMORIES_STORAGE_KEY = 'chat_memories';
export function useChat() {
const [messages, setMessages] = useState<Message[]>([]);
const [currentMemories, setCurrentMemories] = useState<Memory[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [isRetrievingMemories, setIsRetrievingMemories] = useState(false);
const [isLoadingFollowUps, setIsLoadingFollowUps] = useState(false);
const [error, setError] = useState<string | null>(null);
const [streamingContent, setStreamingContent] = useState('');
// Load chat history and memories from localStorage on mount
useEffect(() => {
const storedMessages = localStorage.getItem(STORAGE_KEY);
if (storedMessages) {
try {
setMessages(JSON.parse(storedMessages));
} catch (e) {
console.error('Error loading chat history:', e);
}
}
const storedMemories = localStorage.getItem(MEMORIES_STORAGE_KEY);
if (storedMemories) {
try {
setCurrentMemories(JSON.parse(storedMemories));
} catch (e) {
console.error('Error loading memories:', e);
}
}
}, []);
// Save chat history to localStorage
const saveChatHistory = useCallback((msgs: Message[]) => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(msgs));
}, []);
// Save memories to localStorage
const saveMemories = useCallback((memories: Memory[]) => {
localStorage.setItem(MEMORIES_STORAGE_KEY, JSON.stringify(memories));
}, []);
const sendMessage = useCallback(
async (content: string) => {
if (!content.trim() || isLoading) return;
setError(null);
setIsLoading(true);
setIsRetrievingMemories(true);
setStreamingContent('');
setCurrentMemories([]); // Clear memories to show loading state
// Add user message
const userMessage: Message = { role: 'user', content };
const updatedMessages = [...messages, userMessage];
setMessages(updatedMessages);
saveChatHistory(updatedMessages);
try {
let assistantContent = '';
await sendChatMessage(content, messages, {
onMemories: (memories) => {
setCurrentMemories(memories);
saveMemories(memories);
setIsRetrievingMemories(false);
},
onToken: (token) => {
assistantContent += token;
setStreamingContent(assistantContent);
},
onDone: () => {
// Add complete assistant message (follow-ups will be added when received)
const assistantMessage: Message = {
role: 'assistant',
content: assistantContent,
};
const finalMessages = [...updatedMessages, assistantMessage];
setMessages(finalMessages);
saveChatHistory(finalMessages);
setStreamingContent('');
setIsLoading(false);
setIsLoadingFollowUps(true); // Start loading follow-ups
},
onFollowUps: (followUps) => {
setIsLoadingFollowUps(false);
// Update the last assistant message with follow-ups
setMessages(prev => {
if (prev.length === 0) return prev;
const updated = [...prev];
const lastIndex = updated.length - 1;
if (updated[lastIndex].role === 'assistant') {
updated[lastIndex] = { ...updated[lastIndex], followUps };
saveChatHistory(updated);
}
return updated;
});
},
onError: (errorMessage) => {
setError(errorMessage);
setIsLoading(false);
setIsRetrievingMemories(false);
setIsLoadingFollowUps(false);
setStreamingContent('');
},
});
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
setIsLoading(false);
setIsRetrievingMemories(false);
setIsLoadingFollowUps(false);
setStreamingContent('');
}
},
[messages, isLoading, saveChatHistory, saveMemories]
);
const clearChat = useCallback(() => {
setMessages([]);
setCurrentMemories([]);
setError(null);
setStreamingContent('');
localStorage.removeItem(STORAGE_KEY);
localStorage.removeItem(MEMORIES_STORAGE_KEY);
}, []);
return {
messages,
currentMemories,
isLoading,
isRetrievingMemories,
isLoadingFollowUps,
error,
streamingContent,
sendMessage,
clearChat,
};
}

View File

@ -0,0 +1,170 @@
import { useState, useEffect, useCallback } from 'react';
import { Message, Memory, ComparisonState } from '../types';
import { sendCompareMessage } from '../services/api';
const STORAGE_KEY = 'compare_chat_history';
const MEMORIES_STORAGE_KEY = 'compare_chat_memories';
const initialComparisonState: ComparisonState = {
withMemory: { content: '', isStreaming: false, isDone: false },
withoutMemory: { content: '', isStreaming: false, isDone: false },
};
export function useCompareChat() {
const [messages, setMessages] = useState<Message[]>([]);
const [currentMemories, setCurrentMemories] = useState<Memory[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [isRetrievingMemories, setIsRetrievingMemories] = useState(false);
const [isLoadingFollowUps, setIsLoadingFollowUps] = useState(false);
const [error, setError] = useState<string | null>(null);
const [comparison, setComparison] = useState<ComparisonState>(initialComparisonState);
// Load chat history and memories from localStorage on mount
useEffect(() => {
const storedMessages = localStorage.getItem(STORAGE_KEY);
if (storedMessages) {
try {
setMessages(JSON.parse(storedMessages));
} catch (e) {
console.error('Error loading chat history:', e);
}
}
const storedMemories = localStorage.getItem(MEMORIES_STORAGE_KEY);
if (storedMemories) {
try {
setCurrentMemories(JSON.parse(storedMemories));
} catch (e) {
console.error('Error loading memories:', e);
}
}
}, []);
// Save chat history to localStorage
const saveChatHistory = useCallback((msgs: Message[]) => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(msgs));
}, []);
// Save memories to localStorage
const saveMemories = useCallback((memories: Memory[]) => {
localStorage.setItem(MEMORIES_STORAGE_KEY, JSON.stringify(memories));
}, []);
const sendMessage = useCallback(
async (content: string) => {
if (!content.trim() || isLoading) return;
setError(null);
setIsLoading(true);
setIsRetrievingMemories(true);
setCurrentMemories([]); // Clear memories to show loading state
// Reset comparison state for new message
setComparison({
withMemory: { content: '', isStreaming: true, isDone: false },
withoutMemory: { content: '', isStreaming: true, isDone: false },
});
// Add user message
const userMessage: Message = { role: 'user', content };
const updatedMessages = [...messages, userMessage];
setMessages(updatedMessages);
saveChatHistory(updatedMessages);
try {
let withMemoryContent = '';
let withoutMemoryContent = '';
let pendingFollowUps: string[] | undefined;
await sendCompareMessage(content, messages, {
onMemories: (memories) => {
setCurrentMemories(memories);
saveMemories(memories);
setIsRetrievingMemories(false);
},
onToken: (stream, token) => {
if (stream === 'withMemory') {
withMemoryContent += token;
setComparison(prev => ({
...prev,
withMemory: { ...prev.withMemory, content: withMemoryContent },
}));
} else {
withoutMemoryContent += token;
setComparison(prev => ({
...prev,
withoutMemory: { ...prev.withoutMemory, content: withoutMemoryContent },
}));
}
},
onStreamDone: (stream) => {
setComparison(prev => {
const updated = {
...prev,
[stream]: { ...prev[stream], isStreaming: false, isDone: true },
};
// When withMemory stream is done, start loading follow-ups indicator
if (stream === 'withMemory') {
setIsLoadingFollowUps(true);
}
return updated;
});
},
onFollowUps: (followUps) => {
// Store follow-ups to be added when assistant message is created
pendingFollowUps = followUps;
setIsLoadingFollowUps(false);
},
onComplete: () => {
// Add complete assistant message with follow-ups
const assistantMessage: Message = {
role: 'assistant',
content: withMemoryContent,
followUps: pendingFollowUps,
};
const finalMessages = [...updatedMessages, assistantMessage];
setMessages(finalMessages);
saveChatHistory(finalMessages);
setIsLoading(false);
setIsLoadingFollowUps(false);
},
onError: (errorMessage) => {
setError(errorMessage);
setIsLoading(false);
setIsRetrievingMemories(false);
setIsLoadingFollowUps(false);
setComparison(initialComparisonState);
},
});
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
setIsLoading(false);
setIsRetrievingMemories(false);
setIsLoadingFollowUps(false);
setComparison(initialComparisonState);
}
},
[messages, isLoading, saveChatHistory, saveMemories]
);
const clearChat = useCallback(() => {
setMessages([]);
setCurrentMemories([]);
setError(null);
setComparison(initialComparisonState);
localStorage.removeItem(STORAGE_KEY);
localStorage.removeItem(MEMORIES_STORAGE_KEY);
}, []);
return {
messages,
currentMemories,
isLoading,
isRetrievingMemories,
isLoadingFollowUps,
error,
comparison,
sendMessage,
clearChat,
};
}