UNPKG

arela

Version:

AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.

747 lines (603 loc) 27.1 kB
HEX001 Excellent! I've successfully implemented HEXI-001: Session Memory Layer. Here's what was accomplished: Implementation Summary Files Created 1. src/memory/session.ts - Complete SessionMemory class implementation 2. test/memory/session.test.ts - Comprehensive test suite (29 tests) Files Modified 1. src/memory/types.ts - Added session-related types (Message, SessionMemoryData, SessionStats) 2. src/memory/index.ts - Exported SessionMemory class Features Implemented Core Functionality - In-memory cache for fast access (<50ms verified by tests) - SQLite persistence with auto-snapshot every 30 seconds - Crash recovery - restore from last snapshot on init - Session lifecycle - init, snapshot, restore, clear - Proper cleanup - event listeners removed on close Session Management - Current task tracking - Open files tracking with add/remove support - Conversation history with timestamps - Active ticket tracking - Arbitrary context key-value store Database Schema All tables implemented as specified: - sessions - Core session data - session_files - Tracked files - session_messages - Conversation history - session_context - Key-value context store Test Results All 29 tests passed including: - Initialization and state management - Task management - File tracking (add/remove) - Message history - Ticket tracking - Context management (set/get/delete) - Snapshot and restore functionality - Clear session - Statistics - Performance: <50ms load time verified - Concurrency handling - Large conversation history (1000+ messages) Acceptance Criteria Status All criteria met: - SessionMemory class implemented - In-memory cache working - SQLite snapshot working - Auto-snapshot every 30 seconds - Restore from snapshot on init - Clear session method - Track open files - Store conversation history - Context key-value store - Unit tests (29 tests, comprehensive coverage) - Session load time <50ms Usage Example import { SessionMemory } from './src/memory/session.js'; const session = new SessionMemory(); await session.init(); // Track current work await session.setCurrentTask("Implementing login"); await session.setActiveTicket("HEXI-001"); await session.trackOpenFile("src/auth/login.ts"); // Store conversation await session.addMessage({ role: "user", content: "How do I..." }); // Context storage await session.setContext("apiKey", "secret"); // Auto-snapshots every 30 seconds // Restores on next init() The Session Memory Layer is now ready to be integrated with Meta-RAG, Context Router, and CLI commands as specified in the ticket! HEX 002 Perfect! I've successfully implemented HEXI-002: Project Memory Layer. Here's what was accomplished: Implementation Summary Files Created 1. src/memory/project.ts - Complete ProjectMemory class implementation (600+ lines) 2. test/memory/project.test.ts - Comprehensive test suite (44 tests, all passing) Files Modified 1. src/memory/types.ts - Added project-related types (Decision, Pattern, Todo, ProjectMemoryData, ProjectStats) 2. src/memory/index.ts - Exported ProjectMemory class Features Implemented Core Functionality - SQLite persistence per project at .arela/memory/project.db - Project initialization with unique ID generation - Database reuse across sessions (same project = same ID) - WAL mode for better concurrency - Millisecond precision timestamps for accurate ordering Architecture Management - Set/get project architecture - Persistence across sessions Tech Stack Management - Add technologies to stack - Retrieve all technologies in insertion order - Duplicate prevention Decision Recording (ADR-like) - Add architecture decisions with metadata (title, description, rationale, date, tags) - Filter decisions by tags - Search decisions by text (searches title, description, rationale) - Ordered by date (newest first) Pattern Tracking - Add code patterns with examples - Track usage frequency - Increment pattern usage counter - Ordered by frequency (most used first) Todo Management - Add project todos with priorities (high/medium/low) - Filter todos by priority - Complete todos with timestamp tracking - Ordered by creation date (newest first) Convention Storage - Set/get project conventions - Update existing conventions - Retrieve all conventions as key-value pairs Metadata Management - Store arbitrary metadata as JSON - Support complex objects - Update existing metadata Statistics - Comprehensive project stats including counts for all data types - Database path information Test Coverage All 44 tests passing, including: - Initialization and database creation - Architecture tracking and persistence - Tech stack management (add, retrieve, no duplicates, ordering) - Decision recording and filtering (by tags, by search query) - Pattern tracking with frequency incrementation - Todo management (add, filter by priority, complete) - Convention management (set, get, update, retrieve all) - Metadata management (complex objects, JSON storage) - Statistics gathering - Performance tests (queries <100ms verified) - Persistence across sessions - Error handling for uninitialized projects - Complex workflow scenarios Acceptance Criteria Status All criteria met: - ProjectMemory class implemented - SQLite database per project - Architecture tracking - Tech stack management - Decision recording (ADR-like) - Pattern tracking with frequency - Todo list management - Convention storage - Metadata key-value store - Search decisions by query - Filter todos by priority - Unit tests (44 tests, comprehensive coverage) - Query performance <100ms Usage Example import { ProjectMemory } from './src/memory/project.js'; const project = new ProjectMemory(); await project.init(); // Set architecture await project.setArchitecture('VSA Modular Monolith'); // Track tech stack await project.addTechStack('TypeScript'); await project.addTechStack('Next.js'); await project.addTechStack('PostgreSQL'); // Record decision await project.addDecision({ title: 'Chose VSA over Microservices', description: 'Team size is 3 people', rationale: 'VSA provides modularity without operational complexity', date: Date.now(), tags: ['architecture', 'decision'], }); // Track patterns await project.addPattern({ name: 'Repository Pattern', description: 'Data access abstraction', examples: ['UserRepository', 'PostRepository'], frequency: 0, }); // Store conventions await project.setConvention('testing', 'Always use Vitest'); await project.setConvention('imports', 'Use absolute imports'); // Add todos await project.addTodo({ task: 'Add integration tests', priority: 'high', completed: false, }); // Get stats const stats = await project.getStats(); console.log(stats); The Project Memory Layer is now ready to be integrated with Meta-RAG, Context Router, and CLI commands as specified in the ticket! HEXI-003: USER MEMORY LAYER Excellent! I've successfully implemented HEXI-003: User Memory Layer. Here's what was accomplished: Implementation Summary Files Created 1. src/memory/user.ts - Complete UserMemory class implementation (600+ lines) 2. test/memory/user.test.ts - Comprehensive test suite (47 tests, all passing) Files Modified 1. src/memory/types.ts - Added user-related types (UserPreferences, Expertise, UserPattern, ProjectRef, UserMemoryData, UserStats) 2. src/memory/index.ts - Exported UserMemory class Features Implemented Core Functionality - Global SQLite database at ~/.arela/user.db (cross-project) - User initialization with unique ID generation - Database reuse across all projects (single user profile) - WAL mode for better concurrency - Query performance <100ms verified by tests Preferences Management - Set/get individual preferences - Get all preferences as key-value object - Update existing preferences - Support for custom preference keys Expertise Tracking - Set/get expertise levels per domain (beginner/intermediate/expert) - Track multiple domains (frontend, backend, devops, mobile, etc.) - Get all expertise levels - Update expertise as user grows Pattern Learning (Cross-Project) - Add patterns with examples and description - Track frequency across ALL projects - Increment pattern usage and track source projects - Get top patterns by frequency - Learned-from projects tracking (no duplicates) - Sorted by frequency (most used first) Global Conventions - Set/get global conventions - Update existing conventions - Retrieve all conventions as key-value pairs Project History Tracking - Track projects with ID and path - Update last accessed timestamp - Increment session count per project - Get recent projects (sorted by last accessed) - Limit results for efficient queries Metadata Management - Store arbitrary metadata as JSON - Support complex objects and arrays - Update existing metadata - Type-safe retrieval Statistics - Comprehensive user stats including counts for all data types - Database path information - User ID tracking Test Coverage All 47 tests passing, including: - Initialization and database creation - User ID persistence across sessions - Preferences management (set, get, update, get all) - Expertise tracking (set, get, update, multiple domains) - Pattern learning (add, sort by frequency, increment usage, track projects) - Pattern learned-from tracking (no duplicates, cross-project) - Top patterns query with limit - Global conventions (set, get, update, get all) - Project history tracking (track, update timestamps, recent projects) - Session count incrementing - Metadata management (simple values, complex objects, arrays) - Statistics gathering - Performance tests (queries <100ms verified) - Persistence across sessions (all data types) - Error handling for uninitialized user - Complex workflow scenarios Acceptance Criteria Status All criteria met: - UserMemory class implemented - Global SQLite database (~/.arela/user.db) - Preferences management - Expertise tracking - Pattern learning across projects - Global conventions - Project history tracking - Metadata storage - Top patterns by frequency - Recent projects query - Unit tests (47 tests, comprehensive coverage) - Query performance <100ms Usage Example import { UserMemory } from './src/memory/user.js'; // Initialize user memory (global) const user = new UserMemory(); await user.init(); // Set preferences await user.setPreference('language', 'TypeScript'); await user.setPreference('framework', 'Next.js'); await user.setPreference('testing', 'Vitest'); await user.setPreference('style', 'Functional programming'); // Track expertise await user.setExpertise('frontend', 'expert'); await user.setExpertise('backend', 'intermediate'); await user.setExpertise('devops', 'beginner'); // Learn patterns await user.addPattern({ name: 'Prefers small PRs (<300 LOC)', description: 'User consistently creates small, focused PRs', frequency: 15, examples: ['PR-123', 'PR-456'], learnedFrom: ['project-1', 'project-2'], }); // Global conventions await user.setConvention('imports', 'Always use absolute imports'); await user.setConvention('testing', 'Write tests before implementation'); // Track projects await user.trackProject('stride-mobile', '/Users/Star/Arela Stride/mobile'); await user.incrementSessionCount('stride-mobile'); // Get top patterns const topPatterns = await user.getTopPatterns(5); // Get recent projects const recentProjects = await user.getRecentProjects(10); // Get stats const stats = await user.getStats(); console.log(stats); The User Memory Layer is now ready to be integrated with Meta-RAG, Context Router, and CLI commands as specified in the ticket! HEX 004 Implementation Complete! I've successfully implemented HEXI-003: User Memory Layer for the Hexi-Memory system. Here's what was accomplished: Files Created 1. src/memory/user.ts - Complete UserMemory class (600+ lines) 2. test/memory/user.test.ts - Comprehensive test suite (47 tests) Files Modified 1. src/memory/types.ts - Added user-related types 2. src/memory/index.ts - Exported UserMemory class 3. RESEARCH/implemented.md - Updated with implementation details Key Features Implemented Core Functionality - Global SQLite database at ~/.arela/user.db (cross-project) - User initialization with unique ID - WAL mode for better concurrency - Query performance <100ms (verified) Preferences Management - Set/get individual preferences - Update existing preferences - Support for custom preference keys Expertise Tracking - Track expertise levels per domain (beginner/intermediate/expert) - Support for multiple domains (frontend, backend, devops, mobile, etc.) Pattern Learning (Cross-Project) - Add patterns with examples and descriptions - Track frequency across ALL projects - Increment pattern usage and track source projects - Get top patterns by frequency - No duplicate projects in learned-from tracking Global Conventions - Set/get/update global conventions - Retrieve all conventions as key-value pairs Project History - Track projects with ID and path - Update last accessed timestamp - Increment session count per project - Get recent projects (sorted by last accessed) Metadata Management - Store arbitrary metadata as JSON - Support complex objects and arrays Test Results All 47 tests passed including: - Initialization and persistence - Preferences management - Expertise tracking - Pattern learning with cross-project tracking - Global conventions - Project history tracking - Metadata management - Performance tests (<100ms) - Complex workflow scenarios Acceptance Criteria All requirements from HEXI-003 ticket met: - UserMemory class implemented - Global SQLite database (~/.arela/user.db) - Preferences management - Expertise tracking - Pattern learning across projects - Global conventions - Project history tracking - Metadata storage - Top patterns by frequency - Recent projects query - Unit tests (47 tests, comprehensive coverage) - Query performance <100ms The User Memory Layer is now ready to be integrated with Meta-RAG, Context Router, and CLI commands as specified in the ticket! CODEX Here’s what I implemented for the three HEXI tickets and how it fits into the existing Hexi-Memory system. HEXI-004: Vector Memory Wrapper - Extended src/memory/vector.ts to keep existing Tri-Memory behavior and add the wrapper API: - Existing: - isReady(), getStats(): VectorStats, rebuildIndex(...), query(question, topK) (unchanged, still used by TriMemory and the CLI). - getStats now also populates indexSizeBytes (new optional field on VectorStats in src/memory/types.ts). - New wrapper methods (per HEXI-004): - async init(projectPath: string): Promise<void> - No-op initializer that ensures the index directory exists; construction with cwd still remains the primary configuration. - async search(queryText: string, limit = 5): Promise<VectorSearchResult[]> - Wraps the existing RAG search from src/rag/index.ts. - Returns objects of shape: - file, chunk, score, lineStart, lineEnd (line numbers currently 0 because the index does not track them). - async searchByEmbedding(embedding: number[], limit = 5): Promise<VectorSearchResult[]> - Reads .arela/.rag-index.json directly and does cosine similarity over stored embeddings using a local cosineSimilarity helper. - Does not call Ollama; useful for Meta-RAG workflows that already have an embedding. - async getIndexSize(): Promise<number> - Returns the on-disk size of .arela/.rag-index.json in bytes, or 0 if missing. - async getChunkCount(): Promise<number> - Returns embeddings.length from the index JSON (or 0 if missing). - Added VectorSearchResult interface in src/memory/vector.ts for the wrapper results. - Updated src/memory/types.ts: - VectorStats now has optional indexSizeBytes?: number (no breaking changes; existing usages still work). HEXI-005: Graph Memory Wrapper - Extended src/memory/graph.ts to keep the existing Tri-Memory behavior and add Graph wrapper APIs: - Existing (unchanged): - isReady(), getStats(): GraphStats, impact(filePath), findSlice(identifier), private helpers using GraphDB from src/ingest/ storage.ts. - getStats now also sets lastUpdatedAt?: number on GraphStats using fs.stat of graph.db (new optional field defined in src/memory/types.ts). - New wrapper-facing types (exported from src/memory/graph.ts): - GraphFileNode: - { path, repoPath, language, size } - language inferred from file extension (ts/tsx/js/jsx/py/go/rs/java/ unknown). - size is current lines count stored in the files table. - GraphImport: - { source, target, type: 'internal' | 'external' } - type classified by whether target looks like a file-ish path (isInternalPath helper). - GraphFunctionNode: - { name, file, lineStart, lineEnd }. - New wrapper methods (per HEXI-005): - async init(projectPath: string): Promise<void> - Ensures the .arela/memory directory exists; constructor cwd remains the primary configuration. - File queries: - async getFile(path: string): Promise<GraphFileNode | undefined> - Looks up files table by normalized path. - async getFiles(repoPaths?: string[]): Promise<GraphFileNode[]> - Optional filter by repo column; otherwise returns all files. - async searchFiles(pattern: string): Promise<GraphFileNode[]> - LIKE search on files.path. - Dependency queries: - async getImports(filePath: string): Promise<GraphImport[]> - Uses imports join to map from_file_id to_file_id/to_module and returns source/target edges with type classification. - async getImportedBy(filePath: string): Promise<string[]> - All file paths that import the given file. - async getDependencies(filePath: string, depth = 1): Promise<string[]> - async getDependents(filePath: string, depth = 1): Promise<string[]> - Both use a small BFS over the graph via GraphDB, walking downstream (imports) or upstream (imported-by) up to depth, returning sorted unique paths. - Function queries: - async getFunctions(filePath: string): Promise<GraphFunctionNode[]> - Uses functions joined to files via file_id. - async searchFunctions(name: string): Promise<GraphFunctionNode[]> - LIKE search on functions.name with file path included. HEXI-006: Governance Memory Wrapper - Added src/memory/governance.ts implementing GovernanceMemory as a wrapper over the existing audit_log table in .arela/memory/audit.db: - Types: - EventFilters: - { type?, agent?, startDate?, endDate?, limit? } (timestamps in epoch ms). - AuditEvent: - { id: string, timestamp: number, type: string, agent: string, data: Record<string, any> } - type derives from metadata.type if present, otherwise falls back to action/generic "event". - data merges metadata with result, commitHash, ticketId, policyViolations. - Decision: - { id, title, description, rationale, timestamp, tags }. - Derived from AuditEvent with type === 'decision' and fields in data. - Change: - { id, file, author, timestamp, description, linesAdded, linesRemoved }. - Derived from AuditEvent with type === 'change' and fields in data. - GovernanceStats: - { totalEvents, totalDecisions, totalChanges, eventsByType, lastUpdated }. - Class GovernanceMemory: - Constructor: new GovernanceMemory(cwd?: string) (defaults to process.cwd()). - async init(projectPath: string): Promise<void> - Sets dbPath under <projectPath>/.arela/memory/audit.db. - Ensures directory exists. - Calls AuditMemory.init() to create schema, without changing AuditMemory behavior. - async getEvents(filters?: EventFilters): Promise<AuditEvent[]> - Reads from audit_log, maps each row via rowToEvent, then filters in memory by: - type, agent, startDate, endDate, limit. - timestamp is converted to epoch ms (Date.parse on the stored text). - async getEventsByType(type: string): Promise<AuditEvent[]> - async getEventsByAgent(agent: string): Promise<AuditEvent[]> - async getRecentEvents(limit: number): Promise<AuditEvent[]> - async getDecisions(): Promise<Decision[]> - Uses type === 'decision' events; expects decision fields in event.data (e.g. id, title, description, rationale, tags). - async getDecisionsByTag(tag: string): Promise<Decision[]> - Filters decisions where tags contains the tag. - async getChanges(filePath?: string): Promise<Change[]> - Uses type === 'change' events; expects file, author, description, linesAdded, linesRemoved in data. - Optional filePath is normalized relative to cwd before comparison. - async getChangesByAuthor(author: string): Promise<Change[]> - async getStats(): Promise<GovernanceStats> - Aggregates counts by event.type, tallies decisions/changes, and computes lastUpdated as max timestamp. - Internal helpers: - openDb() – mirrors AuditMemory’s DB setup (WAL, foreign keys). - rowToEvent, parseTimestamp, safeParseJson, normalizePath. - Exported GovernanceMemory from src/memory/index.ts: - Added import { GovernanceMemory } from "./governance.js";. - Added export { GovernanceMemory } from "./governance.js";. - Tri-Memory (TriMemory) itself still orchestrates vector, graph, and audit; governance is now available as a first-class memory class, but not yet wired into TriMemory’s API (keeping behavior stable). Tests - Added test/memory/vector.test.ts: - Creates a temporary project dir with a minimal .arela/.rag-index.json. - Verifies: - isReady() returns true. - getStats() includes correct counts and indexSizeBytes > 0. - getIndexSize() and getChunkCount() behave as expected. - searchByEmbedding() returns the expected best match and a high score, without invoking Ollama. - Added test/memory/graph.test.ts: - Uses GraphDB to create a tiny in-memory graph under a temp .arela/memory/ graph.db: - Two files (src/a.ts, src/b.ts), one import a -> b, and two functions (fnA, fnB). - Verifies: - isReady() and getStats() work. - getFile, getFiles, searchFiles return sensible data and infer language. - getImports / getImportedBy reflect the a -> b relationship. - getDependencies / getDependents traverse transitive dependencies up to a given depth. - getFunctions and searchFunctions see both fnA and fnB. - Added test/memory/governance.test.ts: - Uses AuditMemory to seed decisions and changes into a temp audit.db: - One decision event with metadata including id, title, rationale, tags. - One change event with metadata including file, author, linesAdded, linesRemoved. - Verifies: - getEvents, getEventsByType, getEventsByAgent, getRecentEvents. - getDecisions, getDecisionsByTag. - getChanges, getChangesByAuthor. - getStats counts events and types correctly. Test Run Status / Environment Note - I ran Vitest in this environment: - vector.test.ts passed. - graph.test.ts and governance.test.ts both failed due to a native module ABI mismatch in better-sqlite3: - The installed better_sqlite3.node was compiled against a different Node NODE_MODULE_VERSION than the current Node version. - This is an environment/build issue, not a logic issue in the new code. Locally, you can fix it by running npm rebuild better-sqlite3 or reinstalling dependencies with the Node version you use to run tests, then rerun npm test. How to Use the New Wrappers - Vector (semantic layer): - const vector = new VectorMemory(projectPath); await vector.init(projectPath); - await vector.search("login authentication", 10); - await vector.searchByEmbedding(myEmbedding, 10); - await vector.getStats();, await vector.getIndexSize();, await vector.getChunkCount(); - Graph (structural layer): - const graph = new GraphMemory(projectPath); await graph.init(projectPath); - await graph.getFile("src/auth/login.ts"); - await graph.getImports("src/auth/login.ts"); - await graph.getDependents("src/auth/login.ts", 2); - await graph.getFunctions("src/auth/login.ts");, await graph.searchFunctions("login"); - Governance (historical layer): - const gov = new GovernanceMemory(projectPath); await gov.init(projectPath); - await gov.getEvents({ type: "decision", agent: "codex" }); - await gov.getDecisionsByTag("database"); - await gov.getChanges("src/index.ts"); - await gov.getStats(); If you’d like, I can next wire GovernanceMemory into TriMemory (and potentially the CLI) so governance queries sit alongside memory query/impact/audit.