@mycontxt/core 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -53,6 +53,8 @@ interface ProjectConfig {
53
53
  maxTokens: number;
54
54
  autoSession: boolean;
55
55
  stackDetection: boolean;
56
+ autoSync: boolean;
57
+ syncIntervalMinutes: number;
56
58
  }
57
59
  /**
58
60
  * Branch information
@@ -365,6 +367,17 @@ interface ILocalDatabase {
365
367
  * Restore an entry to a specific version
366
368
  */
367
369
  restoreVersion(entryId: string, version: number): Promise<MemoryEntry>;
370
+ /**
371
+ * Get cached plan for a user (for offline-first access)
372
+ */
373
+ getCachedPlan(userId: string): {
374
+ planId: string;
375
+ fetchedAt: number;
376
+ } | null;
377
+ /**
378
+ * Cache user's plan locally
379
+ */
380
+ cachePlan(userId: string, planId: string): void;
368
381
  }
369
382
  /**
370
383
  * Remote database interface (Supabase/Cloud)
@@ -415,6 +428,12 @@ interface IRemoteDatabase {
415
428
  * Get branches from remote
416
429
  */
417
430
  listBranches(projectId: string): Promise<Branch[]>;
431
+ /**
432
+ * Get user profile (for plan resolution)
433
+ */
434
+ getUserProfile(userId: string): Promise<{
435
+ plan_id?: string;
436
+ } | null>;
418
437
  }
419
438
 
420
439
  /**
@@ -584,7 +603,9 @@ interface ContextBuilderOptions extends ContextMode {
584
603
  interface ContextResult {
585
604
  context: string;
586
605
  entriesIncluded: number;
606
+ entriesFiltered: number;
587
607
  tokensUsed: number;
608
+ tokensSaved: number;
588
609
  budget: number;
589
610
  }
590
611
  /**
package/dist/index.js CHANGED
@@ -405,6 +405,11 @@ var SyncEngine = class {
405
405
  }
406
406
  if (!options.dryRun) {
407
407
  await this.remote.pushEntries(unsyncedEntries);
408
+ const pushedIds = unsyncedEntries.map((e) => e.id);
409
+ if (typeof this.remote.generateEmbeddings === "function") {
410
+ this.remote.generateEmbeddings(pushedIds).catch(() => {
411
+ });
412
+ }
408
413
  await this.local.markSynced(unsyncedEntries.map((e) => e.id));
409
414
  }
410
415
  result.pushed = unsyncedEntries.length;
@@ -622,13 +627,19 @@ function buildContextPayload(entries, options) {
622
627
  (ranked) => options.includeTypes.includes(ranked.entry.type)
623
628
  );
624
629
  }
630
+ const totalEntryTokens = rankedEntries.reduce(
631
+ (sum, ranked) => sum + countEntryTokens(ranked.entry),
632
+ 0
633
+ );
625
634
  const fitted = fitToBudget(rankedEntries, budget);
626
635
  const context = buildContext(fitted);
627
636
  const tokensUsed = countTokens(context);
628
637
  return {
629
638
  context,
630
639
  entriesIncluded: fitted.length,
640
+ entriesFiltered: rankedEntries.length - fitted.length,
631
641
  tokensUsed,
642
+ tokensSaved: Math.max(0, totalEntryTokens - tokensUsed),
632
643
  budget
633
644
  };
634
645
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/engine/memory.ts","../src/engine/relevance.ts","../src/engine/sync.ts","../src/utils/tokens.ts","../src/engine/context-builder.ts","../src/scanner.ts","../src/rules-parser.ts"],"sourcesContent":["/**\n * Core type definitions for MemoCore\n */\n\n/**\n * Memory entry types\n */\nexport type MemoryEntryType = 'decision' | 'pattern' | 'context' | 'document' | 'session';\n\n/**\n * Memory entry status\n */\nexport type MemoryEntryStatus = 'active' | 'draft' | 'archived' | 'stale';\n\n/**\n * User tier levels\n */\nexport type UserTier = 'free' | 'pro';\n\n/**\n * Core memory entry\n */\nexport interface MemoryEntry {\n id: string;\n projectId: string;\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata: Record<string, any>;\n embedding?: number[];\n branch: string;\n version: number;\n status: MemoryEntryStatus;\n isSynced: boolean;\n isArchived: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * Project configuration\n */\nexport interface Project {\n id: string;\n userId?: string;\n name: string;\n path: string;\n stack?: string[];\n config: ProjectConfig;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * Project configuration options\n */\nexport interface ProjectConfig {\n defaultBranch: string;\n maxTokens: number;\n autoSession: boolean;\n stackDetection: boolean;\n}\n\n/**\n * Branch information\n */\nexport interface Branch {\n id: string;\n projectId: string;\n name: string;\n parentBranch?: string;\n isActive: boolean;\n createdAt: Date;\n}\n\n/**\n * User profile\n */\nexport interface UserProfile {\n id: string;\n email?: string;\n tier: UserTier;\n createdAt: Date;\n}\n\n/**\n * Authentication session\n */\nexport interface AuthSession {\n userId: string;\n accessToken: string;\n refreshToken: string;\n expiresAt: Date;\n}\n\n/**\n * Sync operation result\n */\nexport interface SyncResult {\n pushed: number;\n pulled: number;\n conflicts: number;\n errors: string[];\n}\n\n/**\n * Entry query filters\n */\nexport interface EntryQuery {\n projectId: string;\n type?: MemoryEntryType;\n branch?: string;\n isArchived?: boolean;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\n/**\n * Input for creating a new entry\n */\nexport interface CreateEntryInput {\n id?: string; // Optional - if not provided, will be auto-generated\n projectId: string;\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata?: Record<string, any>;\n branch?: string;\n status?: MemoryEntryStatus; // Optional - defaults to 'active'\n}\n\n/**\n * Decision-specific input\n */\nexport interface DecisionInput {\n title: string;\n rationale: string;\n alternatives?: string[];\n consequences?: string[];\n tags?: string[];\n}\n\n/**\n * Pattern-specific input\n */\nexport interface PatternInput {\n title: string;\n content: string;\n category?: string;\n tags?: string[];\n}\n\n/**\n * Context-specific input\n */\nexport interface ContextInput {\n feature?: string;\n blockers?: string[];\n nextSteps?: string[];\n activeFiles?: string[];\n}\n\n/**\n * Document-specific input\n */\nexport interface DocumentInput {\n title: string;\n content: string;\n url?: string;\n tags?: string[];\n}\n\n/**\n * Session-specific input\n */\nexport interface SessionInput {\n feature: string;\n description?: string;\n}\n\n/**\n * Ranked entry for context retrieval\n */\nexport interface RankedEntry {\n entry: MemoryEntry;\n score: number;\n reasons: string[];\n}\n\n/**\n * Context retrieval options\n */\nexport interface SuggestOptions {\n projectId: string;\n taskDescription?: string;\n taskEmbedding?: number[];\n activeFiles?: string[];\n branch?: string;\n maxResults?: number;\n maxTokens?: number;\n minRelevance?: number;\n}\n\n/**\n * Activity item for the dashboard activity feed.\n * Derived from memory_entries changes — no separate table needed.\n */\nexport interface ActivityItem {\n id: string;\n projectId: string;\n projectName: string;\n entryId?: string;\n type: 'push' | 'session' | 'branch' | 'draft' | 'edit' | 'archive';\n description: string;\n actor: 'user' | 'auto';\n createdAt: Date;\n}\n\n/**\n * Usage statistics for the sidebar usage meters.\n */\nexport interface UsageStats {\n entries: { used: number; limit: number };\n projects: { used: number; limit: number | null };\n searches: { used: number; limit: number };\n}\n\n/**\n * Validation error\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Not found error\n */\nexport class NotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Conflict error\n */\nexport class ConflictError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Authentication error\n */\nexport class AuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'AuthError';\n }\n}\n","/**\n * Memory Engine - Core business logic for memory management\n */\n\nimport { nanoid } from 'nanoid';\nimport type { ILocalDatabase } from '../interfaces/database.js';\nimport type {\n MemoryEntry,\n CreateEntryInput,\n DecisionInput,\n PatternInput,\n ContextInput,\n DocumentInput,\n SessionInput,\n EntryQuery,\n} from '../types.js';\nimport { ValidationError, NotFoundError } from '../types.js';\n\nexport class MemoryEngine {\n constructor(private db: ILocalDatabase) {}\n\n // ==================\n // Decision Management\n // ==================\n\n async addDecision(projectId: string, input: DecisionInput): Promise<MemoryEntry> {\n // Validate input\n if (!input.title?.trim()) {\n throw new ValidationError('Decision title is required');\n }\n if (!input.rationale?.trim()) {\n throw new ValidationError('Decision rationale is required');\n }\n\n // Create entry\n const entry = await this.db.createEntry({\n projectId,\n type: 'decision',\n title: input.title.trim(),\n content: input.rationale.trim(),\n metadata: {\n alternatives: input.alternatives || [],\n consequences: input.consequences || [],\n tags: input.tags || [],\n },\n });\n\n return entry;\n }\n\n async listDecisions(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'decision',\n branch,\n isArchived: false,\n });\n }\n\n async getDecision(id: string): Promise<MemoryEntry> {\n const entry = await this.db.getEntry(id);\n if (!entry || entry.type !== 'decision') {\n throw new NotFoundError(`Decision with id ${id} not found`);\n }\n return entry;\n }\n\n async updateDecision(\n id: string,\n updates: Partial<DecisionInput>\n ): Promise<MemoryEntry> {\n const existing = await this.getDecision(id);\n\n return this.db.updateEntry(id, {\n title: updates.title?.trim() || existing.title,\n content: updates.rationale?.trim() || existing.content,\n metadata: {\n ...existing.metadata,\n alternatives: updates.alternatives || existing.metadata.alternatives,\n consequences: updates.consequences || existing.metadata.consequences,\n tags: updates.tags || existing.metadata.tags,\n },\n });\n }\n\n // ==================\n // Pattern Management\n // ==================\n\n async addPattern(projectId: string, input: PatternInput): Promise<MemoryEntry> {\n if (!input.title?.trim()) {\n throw new ValidationError('Pattern title is required');\n }\n if (!input.content?.trim()) {\n throw new ValidationError('Pattern content is required');\n }\n\n return this.db.createEntry({\n projectId,\n type: 'pattern',\n title: input.title.trim(),\n content: input.content.trim(),\n metadata: {\n category: input.category || 'general',\n tags: input.tags || [],\n },\n });\n }\n\n async listPatterns(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'pattern',\n branch,\n isArchived: false,\n });\n }\n\n async getPattern(id: string): Promise<MemoryEntry> {\n const entry = await this.db.getEntry(id);\n if (!entry || entry.type !== 'pattern') {\n throw new NotFoundError(`Pattern with id ${id} not found`);\n }\n return entry;\n }\n\n async updatePattern(\n id: string,\n updates: Partial<PatternInput>\n ): Promise<MemoryEntry> {\n const existing = await this.getPattern(id);\n\n return this.db.updateEntry(id, {\n title: updates.title?.trim() || existing.title,\n content: updates.content?.trim() || existing.content,\n metadata: {\n ...existing.metadata,\n category: updates.category || existing.metadata.category,\n tags: updates.tags || existing.metadata.tags,\n },\n });\n }\n\n // ==================\n // Context Management\n // ==================\n\n async setContext(projectId: string, input: ContextInput): Promise<MemoryEntry> {\n // Get or create context entry for the project\n const existing = await this.db.listEntries({\n projectId,\n type: 'context',\n isArchived: false,\n });\n\n const contextData = {\n feature: input.feature || '',\n blockers: input.blockers || [],\n nextSteps: input.nextSteps || [],\n activeFiles: input.activeFiles || [],\n };\n\n if (existing.length > 0) {\n // Update existing context\n return this.db.updateEntry(existing[0].id, {\n title: 'Project Context',\n content: JSON.stringify(contextData, null, 2),\n metadata: contextData,\n });\n } else {\n // Create new context\n return this.db.createEntry({\n projectId,\n type: 'context',\n title: 'Project Context',\n content: JSON.stringify(contextData, null, 2),\n metadata: contextData,\n });\n }\n }\n\n async getContext(projectId: string): Promise<MemoryEntry | null> {\n const entries = await this.db.listEntries({\n projectId,\n type: 'context',\n isArchived: false,\n });\n\n return entries[0] || null;\n }\n\n // ==================\n // Document Management\n // ==================\n\n async addDocument(projectId: string, input: DocumentInput): Promise<MemoryEntry> {\n if (!input.title?.trim()) {\n throw new ValidationError('Document title is required');\n }\n if (!input.content?.trim()) {\n throw new ValidationError('Document content is required');\n }\n\n return this.db.createEntry({\n projectId,\n type: 'document',\n title: input.title.trim(),\n content: input.content.trim(),\n metadata: {\n url: input.url,\n tags: input.tags || [],\n },\n });\n }\n\n async listDocuments(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'document',\n branch,\n isArchived: false,\n });\n }\n\n async getDocument(id: string): Promise<MemoryEntry> {\n const entry = await this.db.getEntry(id);\n if (!entry || entry.type !== 'document') {\n throw new NotFoundError(`Document with id ${id} not found`);\n }\n return entry;\n }\n\n // ==================\n // Session Management\n // ==================\n\n async startSession(projectId: string, input: SessionInput): Promise<MemoryEntry> {\n if (!input.feature?.trim()) {\n throw new ValidationError('Session feature is required');\n }\n\n // Check if there's already an active session\n const active = await this.getActiveSession(projectId);\n if (active) {\n throw new ValidationError(\n 'An active session already exists. End it first or use a different branch.'\n );\n }\n\n return this.db.createEntry({\n projectId,\n type: 'session',\n title: `Session: ${input.feature}`,\n content: input.description || '',\n metadata: {\n feature: input.feature,\n startedAt: new Date().toISOString(),\n endedAt: null,\n },\n });\n }\n\n async endSession(projectId: string, summary?: string): Promise<MemoryEntry> {\n const active = await this.getActiveSession(projectId);\n if (!active) {\n throw new NotFoundError('No active session found');\n }\n\n return this.db.updateEntry(active.id, {\n content: summary || active.content,\n metadata: {\n ...active.metadata,\n endedAt: new Date().toISOString(),\n },\n });\n }\n\n async getActiveSession(projectId: string): Promise<MemoryEntry | null> {\n const sessions = await this.db.listEntries({\n projectId,\n type: 'session',\n isArchived: false,\n });\n\n return sessions.find((s) => !s.metadata.endedAt) || null;\n }\n\n async listSessions(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'session',\n branch,\n isArchived: false,\n });\n }\n\n // ==================\n // Generic Operations\n // ==================\n\n async deleteEntry(id: string, hard = false): Promise<void> {\n return this.db.deleteEntry(id, hard);\n }\n\n async searchEntries(\n projectId: string,\n searchTerm: string,\n options?: { branch?: string; type?: string }\n ): Promise<MemoryEntry[]> {\n return this.db.searchEntries(projectId, searchTerm, options);\n }\n\n async getAllEntries(query: EntryQuery): Promise<MemoryEntry[]> {\n return this.db.listEntries(query);\n }\n\n async getEntryCount(projectId: string, branch?: string): Promise<number> {\n return this.db.countEntries({\n projectId,\n branch,\n isArchived: false,\n });\n }\n}\n","/**\n * Relevance Engine - Smart context retrieval scoring\n */\n\nimport type { MemoryEntry, SuggestOptions, RankedEntry } from '../types.js';\n\n/**\n * Calculate relevance score for a memory entry\n *\n * Scoring breakdown (when no embeddings available):\n * - Keyword overlap: 40%\n * - Recency: 25%\n * - Type priority: 20%\n * - File match: 15%\n *\n * Total: 1.0 (100%)\n */\nexport function calculateRelevance(\n entry: MemoryEntry,\n options: SuggestOptions\n): number {\n let score = 0;\n\n // 1. Keyword overlap (40%)\n if (options.taskDescription) {\n score += keywordOverlap(entry, options.taskDescription) * 0.4;\n }\n\n // 2. Recency boost (25%) - exponential decay over 30 days\n const daysOld = (Date.now() - entry.updatedAt.getTime()) / (1000 * 60 * 60 * 24);\n const recencyScore = Math.exp(-daysOld / 30); // Exponential decay\n score += recencyScore * 0.25;\n\n // 3. Type priority (20%)\n const typePriority = getTypePriority(entry.type);\n score += typePriority * 0.2;\n\n // 4. File match boost (15%)\n if (options.activeFiles && options.activeFiles.length > 0) {\n const hasFileMatch = options.activeFiles.some(file =>\n entry.content.toLowerCase().includes(file.toLowerCase()) ||\n entry.title.toLowerCase().includes(file.toLowerCase())\n );\n if (hasFileMatch) {\n score += 0.15;\n }\n }\n\n return Math.min(score, 1.0);\n}\n\n/**\n * Calculate keyword overlap between entry and search query\n */\nfunction keywordOverlap(entry: MemoryEntry, query: string): number {\n const entryText = `${entry.title} ${entry.content}`.toLowerCase();\n const queryWords = query.toLowerCase().split(/\\s+/).filter(w => w.length > 2);\n\n if (queryWords.length === 0) return 0;\n\n const matchCount = queryWords.filter(word => entryText.includes(word)).length;\n return matchCount / queryWords.length;\n}\n\n/**\n * Get priority score for entry type\n */\nfunction getTypePriority(type: string): number {\n const priorities: Record<string, number> = {\n context: 1.0, // Highest priority\n decision: 0.8,\n pattern: 0.8,\n session: 0.5,\n document: 0.3, // Lowest priority\n };\n\n return priorities[type] || 0.5;\n}\n\n/**\n * Generate match reasons for transparency\n */\nexport function getMatchReasons(\n entry: MemoryEntry,\n options: SuggestOptions\n): string[] {\n const reasons: string[] = [];\n\n // Check keyword matches\n if (options.taskDescription) {\n const overlap = keywordOverlap(entry, options.taskDescription);\n if (overlap > 0.3) {\n reasons.push(`${Math.round(overlap * 100)}% keyword match`);\n }\n }\n\n // Check recency\n const daysOld = (Date.now() - entry.updatedAt.getTime()) / (1000 * 60 * 60 * 24);\n if (daysOld < 7) {\n reasons.push('Recently updated');\n }\n\n // Check type\n if (entry.type === 'context') {\n reasons.push('Current context');\n }\n\n // Check file matches\n if (options.activeFiles) {\n const matchedFiles = options.activeFiles.filter(file =>\n entry.content.toLowerCase().includes(file.toLowerCase())\n );\n if (matchedFiles.length > 0) {\n reasons.push(`References ${matchedFiles.join(', ')}`);\n }\n }\n\n return reasons;\n}\n\n/**\n * Rank and filter entries by relevance\n */\nexport function rankEntries(\n entries: MemoryEntry[],\n options: SuggestOptions\n): RankedEntry[] {\n const minRelevance = options.minRelevance || 0.3;\n\n return entries\n .map(entry => ({\n entry,\n score: calculateRelevance(entry, options),\n reasons: getMatchReasons(entry, options),\n }))\n .filter(ranked => ranked.score >= minRelevance)\n .sort((a, b) => b.score - a.score);\n}\n","/**\n * Sync Engine - Handles push/pull synchronization\n * Coordinates between local and remote databases\n */\n\nimport type { ILocalDatabase, IRemoteDatabase } from '../interfaces/database.js';\nimport type { MemoryEntry, Project, SyncResult } from '../types.js';\n\nexport interface SyncOptions {\n /**\n * Force push even if conflicts exist (last-write-wins)\n */\n force?: boolean;\n\n /**\n * Dry run - don't actually sync, just report what would happen\n */\n dryRun?: boolean;\n}\n\nexport class SyncEngine {\n constructor(\n private local: ILocalDatabase,\n private remote: IRemoteDatabase\n ) {}\n\n /**\n * Push local changes to remote\n */\n async push(projectId: string, options: SyncOptions = {}): Promise<SyncResult> {\n const result: SyncResult = {\n pushed: 0,\n pulled: 0,\n conflicts: 0,\n errors: [],\n };\n\n try {\n // Get project from local\n const project = await this.local.getProject(projectId);\n if (!project) {\n throw new Error('Project not found locally');\n }\n\n // Sync project metadata\n if (!options.dryRun) {\n await this.remote.upsertProject(project);\n }\n\n // Get unsynced entries\n const unsyncedEntries = await this.local.getUnsyncedEntries(projectId);\n\n if (unsyncedEntries.length === 0) {\n return result;\n }\n\n // Check for conflicts (entries modified both locally and remotely)\n const conflicts: MemoryEntry[] = [];\n if (!options.force) {\n const lastPull = await this.local.getLastPull(projectId);\n if (lastPull) {\n const remoteChanges = await this.remote.pullEntries(projectId, lastPull);\n const unsyncedIds = new Set(unsyncedEntries.map((e) => e.id));\n\n // Find entries that changed both locally and remotely\n for (const remoteEntry of remoteChanges) {\n if (unsyncedIds.has(remoteEntry.id)) {\n const localEntry = unsyncedEntries.find((e) => e.id === remoteEntry.id);\n if (\n localEntry &&\n localEntry.updatedAt.getTime() !== remoteEntry.updatedAt.getTime()\n ) {\n conflicts.push(localEntry);\n }\n }\n }\n }\n }\n\n if (conflicts.length > 0 && !options.force) {\n result.conflicts = conflicts.length;\n result.errors.push(\n `${conflicts.length} conflict(s) found. Use --force to push anyway (last-write-wins).`\n );\n return result;\n }\n\n // Push entries to remote\n if (!options.dryRun) {\n await this.remote.pushEntries(unsyncedEntries);\n\n // Mark entries as synced locally\n await this.local.markSynced(unsyncedEntries.map((e) => e.id));\n }\n\n result.pushed = unsyncedEntries.length;\n\n // Sync branches\n const branches = await this.local.listBranches(projectId);\n for (const branch of branches) {\n if (!options.dryRun) {\n await this.remote.upsertBranch(branch);\n }\n }\n\n return result;\n } catch (error) {\n result.errors.push(\n error instanceof Error ? error.message : 'Unknown error during push'\n );\n return result;\n }\n }\n\n /**\n * Pull remote changes to local\n */\n async pull(projectId: string, options: SyncOptions = {}): Promise<SyncResult> {\n const result: SyncResult = {\n pushed: 0,\n pulled: 0,\n conflicts: 0,\n errors: [],\n };\n\n try {\n // Get project from local\n const project = await this.local.getProject(projectId);\n if (!project) {\n throw new Error('Project not found locally');\n }\n\n // Get last pull timestamp\n const lastPull = await this.local.getLastPull(projectId);\n const since = lastPull || new Date(0); // Pull all if first time\n\n // Pull entries from remote\n const remoteEntries = await this.remote.pullEntries(projectId, since);\n\n if (remoteEntries.length === 0) {\n return result;\n }\n\n // Check for conflicts (entries modified locally that also changed remotely)\n const unsyncedEntries = await this.local.getUnsyncedEntries(projectId);\n const unsyncedIds = new Set(unsyncedEntries.map((e) => e.id));\n\n const conflicts: MemoryEntry[] = [];\n for (const remoteEntry of remoteEntries) {\n if (unsyncedIds.has(remoteEntry.id)) {\n const localEntry = unsyncedEntries.find((e) => e.id === remoteEntry.id);\n if (\n localEntry &&\n localEntry.updatedAt.getTime() !== remoteEntry.updatedAt.getTime()\n ) {\n conflicts.push(remoteEntry);\n }\n }\n }\n\n if (conflicts.length > 0 && !options.force) {\n result.conflicts = conflicts.length;\n result.errors.push(\n `${conflicts.length} conflict(s) found. Use --force to pull anyway (last-write-wins).`\n );\n return result;\n }\n\n // Upsert remote entries into local database\n // Last-write-wins: remote entries with newer updatedAt override local\n if (!options.dryRun) {\n for (const entry of remoteEntries) {\n const localEntry = await this.local.getEntry(entry.id);\n\n if (!localEntry) {\n // New entry - create it\n await this.local.createEntry({\n id: entry.id,\n projectId: entry.projectId,\n type: entry.type,\n title: entry.title,\n content: entry.content,\n metadata: entry.metadata,\n branch: entry.branch,\n });\n } else if (entry.updatedAt > localEntry.updatedAt || options.force) {\n // Remote is newer or force flag - update local\n await this.local.updateEntry(entry.id, {\n title: entry.title,\n content: entry.content,\n metadata: entry.metadata,\n updatedAt: entry.updatedAt,\n isSynced: true,\n });\n }\n }\n\n // Update last pull timestamp\n await this.local.updateLastPull(projectId, new Date());\n }\n\n result.pulled = remoteEntries.length;\n\n return result;\n } catch (error) {\n result.errors.push(\n error instanceof Error ? error.message : 'Unknown error during pull'\n );\n return result;\n }\n }\n\n /**\n * Full bidirectional sync (pull then push)\n */\n async sync(projectId: string, options: SyncOptions = {}): Promise<SyncResult> {\n // First pull remote changes\n const pullResult = await this.pull(projectId, options);\n\n if (pullResult.errors.length > 0) {\n return pullResult;\n }\n\n // Then push local changes\n const pushResult = await this.push(projectId, options);\n\n // Combine results\n return {\n pushed: pushResult.pushed,\n pulled: pullResult.pulled,\n conflicts: pullResult.conflicts + pushResult.conflicts,\n errors: [...pullResult.errors, ...pushResult.errors],\n };\n }\n}\n","/**\n * Token counting utilities using tiktoken\n */\n\nimport { get_encoding } from 'tiktoken';\nimport type { MemoryEntry, RankedEntry } from '../types.js';\n\n// Use cl100k_base encoding (GPT-4/Claude compatible)\nconst encoding = get_encoding('cl100k_base');\n\n/**\n * Count tokens in a text string\n */\nexport function countTokens(text: string): number {\n const tokens = encoding.encode(text);\n return tokens.length;\n}\n\n/**\n * Count tokens in a memory entry\n */\nexport function countEntryTokens(entry: MemoryEntry): number {\n const text = formatEntryForContext(entry);\n return countTokens(text);\n}\n\n/**\n * Format entry for context (how it will appear in the prompt)\n */\nexport function formatEntryForContext(entry: MemoryEntry): string {\n const lines: string[] = [];\n\n lines.push(`## ${entry.type.toUpperCase()}: ${entry.title}`);\n lines.push('');\n lines.push(entry.content);\n\n // Add relevant metadata\n if (entry.metadata && Object.keys(entry.metadata).length > 0) {\n lines.push('');\n lines.push('**Metadata:**');\n for (const [key, value] of Object.entries(entry.metadata)) {\n if (Array.isArray(value) && value.length > 0) {\n lines.push(`- ${key}: ${value.join(', ')}`);\n } else if (value && typeof value === 'string') {\n lines.push(`- ${key}: ${value}`);\n }\n }\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Fit ranked entries within a token budget\n */\nexport function fitToBudget(\n rankedEntries: RankedEntry[],\n maxTokens: number\n): RankedEntry[] {\n const result: RankedEntry[] = [];\n let currentTokens = 0;\n\n // Reserve tokens for header/footer\n const headerTokens = countTokens('# MemoCore Context\\n\\n');\n currentTokens += headerTokens;\n\n for (const ranked of rankedEntries) {\n const entryTokens = countEntryTokens(ranked.entry);\n\n if (currentTokens + entryTokens <= maxTokens) {\n result.push(ranked);\n currentTokens += entryTokens;\n } else {\n // Budget exceeded, stop adding\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Build formatted context from ranked entries\n */\nexport function buildContext(\n rankedEntries: RankedEntry[],\n options?: {\n includeReasons?: boolean;\n includeStats?: boolean;\n }\n): string {\n const lines: string[] = [];\n\n lines.push('# MemoCore Context');\n lines.push('');\n\n if (options?.includeStats) {\n lines.push(`Found ${rankedEntries.length} relevant entries:`);\n lines.push('');\n }\n\n for (const ranked of rankedEntries) {\n if (options?.includeReasons && ranked.reasons.length > 0) {\n lines.push(`<!-- Match reasons: ${ranked.reasons.join(', ')} -->`);\n }\n\n lines.push(formatEntryForContext(ranked.entry));\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Free tiktoken resources (call on cleanup)\n */\nexport function cleanup(): void {\n encoding.free();\n}\n","/**\n * Context Builder Engine\n * Intelligently assembles project context for AI agents\n */\n\nimport type { MemoryEntry, SuggestOptions, RankedEntry } from '../types.js';\nimport { rankEntries } from './relevance.js';\nimport { countTokens, fitToBudget, buildContext } from '../utils/tokens.js';\n\nexport interface ContextMode {\n type: 'task' | 'files' | 'all';\n taskDescription?: string;\n activeFiles?: string[];\n includeTypes?: string[];\n}\n\nexport interface ContextBuilderOptions extends ContextMode {\n projectId: string;\n maxTokens?: number;\n minRelevance?: number;\n}\n\nexport interface ContextResult {\n context: string;\n entriesIncluded: number;\n tokensUsed: number;\n budget: number;\n}\n\n/**\n * Convert MemoryEntry[] to RankedEntry[] with default scores\n */\nfunction toRankedEntries(entries: MemoryEntry[]): RankedEntry[] {\n return entries.map((entry) => ({\n entry,\n score: 1.0,\n reasons: [],\n }));\n}\n\n/**\n * Build intelligent context payload for AI agents\n */\nexport function buildContextPayload(\n entries: MemoryEntry[],\n options: ContextBuilderOptions\n): ContextResult {\n const budget = options.maxTokens || 4000;\n let rankedEntries: RankedEntry[] = [];\n\n if (options.type === 'task' && options.taskDescription) {\n // Task-based context: rank by relevance\n const suggestOpts: SuggestOptions = {\n projectId: options.projectId,\n taskDescription: options.taskDescription,\n activeFiles: options.activeFiles,\n maxTokens: budget,\n };\n\n rankedEntries = rankEntries(entries, suggestOpts);\n } else if (options.type === 'files' && options.activeFiles && options.activeFiles.length > 0) {\n // File-based context: filter by file mentions\n const filtered = entries.filter((entry) =>\n options.activeFiles!.some(\n (file) =>\n entry.content.includes(file) || entry.metadata?.files?.includes(file)\n )\n );\n\n // Sort by recency\n filtered.sort(\n (a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()\n );\n\n rankedEntries = toRankedEntries(filtered);\n } else {\n // All context: include everything, sorted by recency\n const sorted = [...entries];\n sorted.sort(\n (a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()\n );\n\n rankedEntries = toRankedEntries(sorted);\n }\n\n // Filter by type if specified\n if (options.includeTypes && options.includeTypes.length > 0) {\n rankedEntries = rankedEntries.filter((ranked) =>\n options.includeTypes!.includes(ranked.entry.type)\n );\n }\n\n // Fit to token budget\n const fitted = fitToBudget(rankedEntries, budget);\n\n // Build formatted context\n const context = buildContext(fitted);\n const tokensUsed = countTokens(context);\n\n return {\n context,\n entriesIncluded: fitted.length,\n tokensUsed,\n budget,\n };\n}\n\n/**\n * Build a summary of what context is available\n */\nexport function buildContextSummary(entries: MemoryEntry[]): {\n totalEntries: number;\n byType: Record<string, number>;\n recentActivity: string[];\n oldestEntry: Date | null;\n newestEntry: Date | null;\n} {\n const byType: Record<string, number> = {};\n const recentActivity: string[] = [];\n\n let oldest: Date | null = null;\n let newest: Date | null = null;\n\n for (const entry of entries) {\n // Count by type\n byType[entry.type] = (byType[entry.type] || 0) + 1;\n\n // Track date range\n if (!oldest || entry.createdAt < oldest) {\n oldest = entry.createdAt;\n }\n if (!newest || entry.updatedAt > newest) {\n newest = entry.updatedAt;\n }\n }\n\n // Get recent activity (last 5 entries)\n const recent = [...entries]\n .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())\n .slice(0, 5);\n\n for (const entry of recent) {\n const age = Date.now() - entry.updatedAt.getTime();\n const daysAgo = Math.floor(age / (1000 * 60 * 60 * 24));\n\n let timeStr = '';\n if (daysAgo === 0) {\n timeStr = 'today';\n } else if (daysAgo === 1) {\n timeStr = 'yesterday';\n } else if (daysAgo < 7) {\n timeStr = `${daysAgo} days ago`;\n } else {\n timeStr = `${Math.floor(daysAgo / 7)} weeks ago`;\n }\n\n recentActivity.push(`${entry.type}: ${entry.title} (${timeStr})`);\n }\n\n return {\n totalEntries: entries.length,\n byType,\n recentActivity,\n oldestEntry: oldest,\n newestEntry: newest,\n };\n}\n","/**\n * Code Comment Scanner\n * Extracts @decision, @pattern, and @context tags from code comments\n */\n\nimport { createHash } from 'crypto';\nimport type { MemoryEntryType } from './types.js';\n\nexport interface ScanComment {\n tag: 'decision' | 'pattern' | 'context';\n category?: string;\n title: string;\n content: string;\n fields: Record<string, string>;\n file: string;\n line: number;\n hash: string;\n}\n\nexport interface ScanResult {\n found: ScanComment[];\n errors: Array<{ file: string; line: number; error: string }>;\n}\n\n/**\n * Comment patterns for different languages\n */\nconst COMMENT_PATTERNS = [\n // Single line comments: // @tag\n { pattern: /^(\\s*)\\/\\/\\s*/, continuation: /^(\\s*)\\/\\/\\s+(?!@)/ },\n // Python/Ruby/Shell: # @tag\n { pattern: /^(\\s*)#\\s*/, continuation: /^(\\s*)#\\s+(?!@)/ },\n // SQL: -- @tag\n { pattern: /^(\\s*)--\\s*/, continuation: /^(\\s*)--\\s+(?!@)/ },\n];\n\n/**\n * Tag detection pattern\n */\nconst TAG_PATTERN = /@(decision|pattern|context)\\s*/i;\n\n/**\n * Category pattern: [@decision [category] title]\n */\nconst CATEGORY_PATTERN = /^\\[([^\\]]+)\\]\\s*/;\n\n/**\n * Field pattern: | key: value\n */\nconst FIELD_PATTERN = /\\|\\s*(\\w+):\\s*([^|]+)/g;\n\n/**\n * Parse a single file for tagged comments\n */\nexport function parseFile(content: string, filePath: string): ScanComment[] {\n const lines = content.split('\\n');\n const comments: ScanComment[] = [];\n let currentComment: Partial<ScanComment> | null = null;\n let currentIndent: string = '';\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + 1;\n\n // Check for tag start\n const tagMatch = detectTag(line);\n if (tagMatch) {\n // Save previous comment if exists\n if (currentComment && currentComment.title) {\n comments.push(finalizeComment(currentComment, filePath));\n }\n\n // Start new comment\n const { tag, content, category } = tagMatch;\n const { title, fields } = extractTitleAndFields(content);\n\n currentComment = {\n tag,\n category,\n title,\n content: title,\n fields,\n file: filePath,\n line: lineNum,\n };\n\n currentIndent = getIndent(line);\n continue;\n }\n\n // Check for continuation line\n if (currentComment && isContinuationLine(line, currentIndent)) {\n const continuationText = extractContinuationText(line);\n if (continuationText) {\n currentComment.content += ' ' + continuationText;\n\n // Check for fields in continuation\n const moreFields = extractFields(continuationText);\n Object.assign(currentComment.fields!, moreFields);\n }\n continue;\n }\n\n // If we hit a non-continuation line, finalize current comment\n if (currentComment && currentComment.title) {\n comments.push(finalizeComment(currentComment, filePath));\n currentComment = null;\n }\n }\n\n // Finalize last comment if exists\n if (currentComment && currentComment.title) {\n comments.push(finalizeComment(currentComment, filePath));\n }\n\n return comments;\n}\n\n/**\n * Detect if a line contains a tag\n */\nfunction detectTag(line: string): { tag: 'decision' | 'pattern' | 'context'; content: string; category?: string } | null {\n // Check if line has a comment marker\n let commentContent: string | null = null;\n for (const { pattern } of COMMENT_PATTERNS) {\n const match = line.match(pattern);\n if (match) {\n commentContent = line.substring(match[0].length);\n break;\n }\n }\n\n if (!commentContent) return null;\n\n // Check for tag\n const tagMatch = commentContent.match(TAG_PATTERN);\n if (!tagMatch) return null;\n\n const tag = tagMatch[1].toLowerCase() as 'decision' | 'pattern' | 'context';\n let content = commentContent.substring(tagMatch[0].length).trim();\n\n // Extract category if present\n let category: string | undefined;\n const categoryMatch = content.match(CATEGORY_PATTERN);\n if (categoryMatch) {\n category = categoryMatch[1];\n content = content.substring(categoryMatch[0].length).trim();\n }\n\n return { tag, content, category };\n}\n\n/**\n * Check if line is a continuation of current comment\n */\nfunction isContinuationLine(line: string, expectedIndent: string): boolean {\n for (const { continuation } of COMMENT_PATTERNS) {\n const match = line.match(continuation);\n if (match && match[1] === expectedIndent) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Extract text from continuation line\n */\nfunction extractContinuationText(line: string): string | null {\n for (const { continuation } of COMMENT_PATTERNS) {\n const match = line.match(continuation);\n if (match) {\n return line.substring(match[0].length).trim();\n }\n }\n return null;\n}\n\n/**\n * Get indentation of a line\n */\nfunction getIndent(line: string): string {\n const match = line.match(/^(\\s*)/);\n return match ? match[1] : '';\n}\n\n/**\n * Extract title and fields from content\n */\nfunction extractTitleAndFields(content: string): { title: string; fields: Record<string, string> } {\n const fields = extractFields(content);\n\n // Title is everything before the first |\n const pipeIndex = content.indexOf('|');\n const title = pipeIndex >= 0 ? content.substring(0, pipeIndex).trim() : content.trim();\n\n return { title, fields };\n}\n\n/**\n * Extract key:value fields from content\n */\nfunction extractFields(content: string): Record<string, string> {\n const fields: Record<string, string> = {};\n let match;\n\n FIELD_PATTERN.lastIndex = 0; // Reset regex state\n while ((match = FIELD_PATTERN.exec(content)) !== null) {\n const key = match[1];\n const value = match[2].trim();\n fields[key] = value;\n }\n\n return fields;\n}\n\n/**\n * Finalize a comment by adding hash\n */\nfunction finalizeComment(partial: Partial<ScanComment>, filePath: string): ScanComment {\n const content = partial.content || partial.title || '';\n const hash = createContentHash(partial.tag!, partial.title!, content);\n\n return {\n tag: partial.tag!,\n category: partial.category,\n title: partial.title!,\n content,\n fields: partial.fields || {},\n file: filePath,\n line: partial.line!,\n hash,\n };\n}\n\n/**\n * Create a stable hash for deduplication\n */\nfunction createContentHash(tag: string, title: string, content: string): string {\n const normalized = `${tag}:${title}:${content}`.toLowerCase().replace(/\\s+/g, ' ');\n return createHash('sha256').update(normalized).digest('hex').substring(0, 16);\n}\n\n/**\n * Convert scan comment to memory entry type\n */\nexport function scanCommentToEntry(comment: ScanComment, projectId: string): {\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata: Record<string, any>;\n} {\n const metadata: Record<string, any> = {\n source: 'scan',\n file: comment.file,\n line: comment.line,\n hash: comment.hash,\n category: comment.category,\n ...comment.fields,\n };\n\n // Map decision fields\n if (comment.tag === 'decision') {\n return {\n type: 'decision',\n title: comment.title,\n content: comment.fields.rationale || comment.content,\n metadata: {\n ...metadata,\n alternatives: comment.fields.alternatives,\n consequences: comment.fields.consequences,\n status: comment.fields.status || 'active',\n },\n };\n }\n\n // Map pattern fields\n if (comment.tag === 'pattern') {\n return {\n type: 'pattern',\n title: comment.title,\n content: comment.fields.template || comment.content,\n metadata: {\n ...metadata,\n when: comment.fields.when,\n },\n };\n }\n\n // Context is free-form\n return {\n type: 'context',\n title: 'Active Context',\n content: comment.content,\n metadata,\n };\n}\n","/**\n * Rules File Parser\n * Parses .contxt/rules.md file into structured memory entries\n */\n\nimport type { MemoryEntryType } from './types.js';\n\nexport interface RulesEntry {\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata: Record<string, any>;\n}\n\nexport interface ParsedRules {\n stack: string[];\n decisions: RulesEntry[];\n patterns: RulesEntry[];\n context: RulesEntry | null;\n documents: RulesEntry[];\n}\n\n/**\n * Parse rules.md file into structured entries\n */\nexport function parseRulesFile(content: string): ParsedRules {\n const lines = content.split('\\n');\n const result: ParsedRules = {\n stack: [],\n decisions: [],\n patterns: [],\n context: null,\n documents: [],\n };\n\n let currentSection: string | null = null;\n let currentContent: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Check for heading\n const headingMatch = line.match(/^#+\\s+(.+)/);\n if (headingMatch) {\n // Process previous section\n if (currentSection && currentContent.length > 0) {\n processSection(currentSection, currentContent.join('\\n'), result);\n }\n\n // Start new section\n currentSection = headingMatch[1].trim();\n currentContent = [];\n continue;\n }\n\n // Add line to current section\n if (currentSection && line.trim()) {\n currentContent.push(line);\n }\n }\n\n // Process final section\n if (currentSection && currentContent.length > 0) {\n processSection(currentSection, currentContent.join('\\n'), result);\n }\n\n return result;\n}\n\n/**\n * Process a section based on its heading\n */\nfunction processSection(heading: string, content: string, result: ParsedRules): void {\n const headingLower = heading.toLowerCase();\n\n if (headingLower === 'stack' || headingLower === 'tech stack') {\n result.stack = parseListItems(content);\n } else if (headingLower === 'decisions') {\n result.decisions = parseDecisions(content);\n } else if (headingLower === 'patterns') {\n result.patterns = parsePatterns(content);\n } else if (headingLower === 'context') {\n result.context = parseContext(content);\n } else {\n // Any other heading becomes a document\n result.documents.push({\n type: 'document',\n title: heading,\n content: content.trim(),\n metadata: { source: 'rules', section: heading },\n });\n }\n}\n\n/**\n * Parse list items from markdown content\n */\nfunction parseListItems(content: string): string[] {\n const items: string[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const match = line.match(/^[-*]\\s+(.+)/);\n if (match) {\n items.push(match[1].trim());\n }\n }\n\n return items;\n}\n\n/**\n * Parse decisions from list items\n * Format: - Title (rationale text)\n */\nfunction parseDecisions(content: string): RulesEntry[] {\n const decisions: RulesEntry[] = [];\n const items = parseListItems(content);\n\n for (const item of items) {\n // Try to extract rationale in parentheses\n const match = item.match(/^(.+?)\\s*\\(([^)]+)\\)\\s*$/);\n\n if (match) {\n const title = match[1].trim();\n const rationale = match[2].trim();\n decisions.push({\n type: 'decision',\n title,\n content: rationale,\n metadata: {\n source: 'rules',\n rationale,\n },\n });\n } else {\n // No parentheses, use the whole item as title and content\n decisions.push({\n type: 'decision',\n title: item,\n content: item,\n metadata: { source: 'rules' },\n });\n }\n }\n\n return decisions;\n}\n\n/**\n * Parse patterns from list items\n * Format: - Name: description/template\n */\nfunction parsePatterns(content: string): RulesEntry[] {\n const patterns: RulesEntry[] = [];\n const items = parseListItems(content);\n\n for (const item of items) {\n // Try to extract pattern name and description\n const colonIndex = item.indexOf(':');\n\n if (colonIndex >= 0) {\n const name = item.substring(0, colonIndex).trim();\n const description = item.substring(colonIndex + 1).trim();\n patterns.push({\n type: 'pattern',\n title: name,\n content: description,\n metadata: { source: 'rules' },\n });\n } else {\n // No colon, use the whole item\n patterns.push({\n type: 'pattern',\n title: item,\n content: item,\n metadata: { source: 'rules' },\n });\n }\n }\n\n return patterns;\n}\n\n/**\n * Parse context from free-form text\n */\nfunction parseContext(content: string): RulesEntry {\n return {\n type: 'context',\n title: 'Active Context',\n content: content.trim(),\n metadata: { source: 'rules' },\n };\n}\n\n/**\n * Generate rules.md file from memory entries\n */\nexport function generateRulesFile(entries: {\n stack: string[];\n decisions: Array<{ title: string; content: string; metadata: any }>;\n patterns: Array<{ title: string; content: string; metadata: any }>;\n context: Array<{ content: string }>;\n documents: Array<{ title: string; content: string }>;\n}): string {\n const sections: string[] = [];\n\n // Stack section\n if (entries.stack.length > 0) {\n sections.push('# Stack\\n');\n for (const item of entries.stack) {\n sections.push(`- ${item}`);\n }\n sections.push('');\n }\n\n // Decisions section\n if (entries.decisions.length > 0) {\n sections.push('# Decisions\\n');\n for (const decision of entries.decisions) {\n const rationale = decision.metadata.rationale || decision.content;\n sections.push(`- ${decision.title} (${rationale})`);\n }\n sections.push('');\n }\n\n // Patterns section\n if (entries.patterns.length > 0) {\n sections.push('# Patterns\\n');\n for (const pattern of entries.patterns) {\n sections.push(`- ${pattern.title}: ${pattern.content}`);\n }\n sections.push('');\n }\n\n // Context section\n if (entries.context.length > 0) {\n sections.push('# Context\\n');\n sections.push(entries.context[0].content);\n sections.push('');\n }\n\n // Document sections\n for (const doc of entries.documents) {\n sections.push(`# ${doc.title}\\n`);\n sections.push(doc.content);\n sections.push('');\n }\n\n return sections.join('\\n');\n}\n"],"mappings":"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","names":["content"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/engine/memory.ts","../src/engine/relevance.ts","../src/engine/sync.ts","../src/utils/tokens.ts","../src/engine/context-builder.ts","../src/scanner.ts","../src/rules-parser.ts"],"sourcesContent":["/**\n * Core type definitions for MemoCore\n */\n\n/**\n * Memory entry types\n */\nexport type MemoryEntryType = 'decision' | 'pattern' | 'context' | 'document' | 'session';\n\n/**\n * Memory entry status\n */\nexport type MemoryEntryStatus = 'active' | 'draft' | 'archived' | 'stale';\n\n/**\n * User tier levels\n */\nexport type UserTier = 'free' | 'pro';\n\n/**\n * Core memory entry\n */\nexport interface MemoryEntry {\n id: string;\n projectId: string;\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata: Record<string, any>;\n embedding?: number[];\n branch: string;\n version: number;\n status: MemoryEntryStatus;\n isSynced: boolean;\n isArchived: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * Project configuration\n */\nexport interface Project {\n id: string;\n userId?: string;\n name: string;\n path: string;\n stack?: string[];\n config: ProjectConfig;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/**\n * Project configuration options\n */\nexport interface ProjectConfig {\n defaultBranch: string;\n maxTokens: number;\n autoSession: boolean;\n stackDetection: boolean;\n autoSync: boolean;\n syncIntervalMinutes: number;\n}\n\n/**\n * Branch information\n */\nexport interface Branch {\n id: string;\n projectId: string;\n name: string;\n parentBranch?: string;\n isActive: boolean;\n createdAt: Date;\n}\n\n/**\n * User profile\n */\nexport interface UserProfile {\n id: string;\n email?: string;\n tier: UserTier;\n createdAt: Date;\n}\n\n/**\n * Authentication session\n */\nexport interface AuthSession {\n userId: string;\n accessToken: string;\n refreshToken: string;\n expiresAt: Date;\n}\n\n/**\n * Sync operation result\n */\nexport interface SyncResult {\n pushed: number;\n pulled: number;\n conflicts: number;\n errors: string[];\n}\n\n/**\n * Entry query filters\n */\nexport interface EntryQuery {\n projectId: string;\n type?: MemoryEntryType;\n branch?: string;\n isArchived?: boolean;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\n/**\n * Input for creating a new entry\n */\nexport interface CreateEntryInput {\n id?: string; // Optional - if not provided, will be auto-generated\n projectId: string;\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata?: Record<string, any>;\n branch?: string;\n status?: MemoryEntryStatus; // Optional - defaults to 'active'\n}\n\n/**\n * Decision-specific input\n */\nexport interface DecisionInput {\n title: string;\n rationale: string;\n alternatives?: string[];\n consequences?: string[];\n tags?: string[];\n}\n\n/**\n * Pattern-specific input\n */\nexport interface PatternInput {\n title: string;\n content: string;\n category?: string;\n tags?: string[];\n}\n\n/**\n * Context-specific input\n */\nexport interface ContextInput {\n feature?: string;\n blockers?: string[];\n nextSteps?: string[];\n activeFiles?: string[];\n}\n\n/**\n * Document-specific input\n */\nexport interface DocumentInput {\n title: string;\n content: string;\n url?: string;\n tags?: string[];\n}\n\n/**\n * Session-specific input\n */\nexport interface SessionInput {\n feature: string;\n description?: string;\n}\n\n/**\n * Ranked entry for context retrieval\n */\nexport interface RankedEntry {\n entry: MemoryEntry;\n score: number;\n reasons: string[];\n}\n\n/**\n * Context retrieval options\n */\nexport interface SuggestOptions {\n projectId: string;\n taskDescription?: string;\n taskEmbedding?: number[];\n activeFiles?: string[];\n branch?: string;\n maxResults?: number;\n maxTokens?: number;\n minRelevance?: number;\n}\n\n/**\n * Activity item for the dashboard activity feed.\n * Derived from memory_entries changes — no separate table needed.\n */\nexport interface ActivityItem {\n id: string;\n projectId: string;\n projectName: string;\n entryId?: string;\n type: 'push' | 'session' | 'branch' | 'draft' | 'edit' | 'archive';\n description: string;\n actor: 'user' | 'auto';\n createdAt: Date;\n}\n\n/**\n * Usage statistics for the sidebar usage meters.\n */\nexport interface UsageStats {\n entries: { used: number; limit: number };\n projects: { used: number; limit: number | null };\n searches: { used: number; limit: number };\n}\n\n/**\n * Validation error\n */\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Not found error\n */\nexport class NotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotFoundError';\n }\n}\n\n/**\n * Conflict error\n */\nexport class ConflictError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Authentication error\n */\nexport class AuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'AuthError';\n }\n}\n","/**\n * Memory Engine - Core business logic for memory management\n */\n\nimport { nanoid } from 'nanoid';\nimport type { ILocalDatabase } from '../interfaces/database.js';\nimport type {\n MemoryEntry,\n CreateEntryInput,\n DecisionInput,\n PatternInput,\n ContextInput,\n DocumentInput,\n SessionInput,\n EntryQuery,\n} from '../types.js';\nimport { ValidationError, NotFoundError } from '../types.js';\n\nexport class MemoryEngine {\n constructor(private db: ILocalDatabase) {}\n\n // ==================\n // Decision Management\n // ==================\n\n async addDecision(projectId: string, input: DecisionInput): Promise<MemoryEntry> {\n // Validate input\n if (!input.title?.trim()) {\n throw new ValidationError('Decision title is required');\n }\n if (!input.rationale?.trim()) {\n throw new ValidationError('Decision rationale is required');\n }\n\n // Create entry\n const entry = await this.db.createEntry({\n projectId,\n type: 'decision',\n title: input.title.trim(),\n content: input.rationale.trim(),\n metadata: {\n alternatives: input.alternatives || [],\n consequences: input.consequences || [],\n tags: input.tags || [],\n },\n });\n\n return entry;\n }\n\n async listDecisions(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'decision',\n branch,\n isArchived: false,\n });\n }\n\n async getDecision(id: string): Promise<MemoryEntry> {\n const entry = await this.db.getEntry(id);\n if (!entry || entry.type !== 'decision') {\n throw new NotFoundError(`Decision with id ${id} not found`);\n }\n return entry;\n }\n\n async updateDecision(\n id: string,\n updates: Partial<DecisionInput>\n ): Promise<MemoryEntry> {\n const existing = await this.getDecision(id);\n\n return this.db.updateEntry(id, {\n title: updates.title?.trim() || existing.title,\n content: updates.rationale?.trim() || existing.content,\n metadata: {\n ...existing.metadata,\n alternatives: updates.alternatives || existing.metadata.alternatives,\n consequences: updates.consequences || existing.metadata.consequences,\n tags: updates.tags || existing.metadata.tags,\n },\n });\n }\n\n // ==================\n // Pattern Management\n // ==================\n\n async addPattern(projectId: string, input: PatternInput): Promise<MemoryEntry> {\n if (!input.title?.trim()) {\n throw new ValidationError('Pattern title is required');\n }\n if (!input.content?.trim()) {\n throw new ValidationError('Pattern content is required');\n }\n\n return this.db.createEntry({\n projectId,\n type: 'pattern',\n title: input.title.trim(),\n content: input.content.trim(),\n metadata: {\n category: input.category || 'general',\n tags: input.tags || [],\n },\n });\n }\n\n async listPatterns(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'pattern',\n branch,\n isArchived: false,\n });\n }\n\n async getPattern(id: string): Promise<MemoryEntry> {\n const entry = await this.db.getEntry(id);\n if (!entry || entry.type !== 'pattern') {\n throw new NotFoundError(`Pattern with id ${id} not found`);\n }\n return entry;\n }\n\n async updatePattern(\n id: string,\n updates: Partial<PatternInput>\n ): Promise<MemoryEntry> {\n const existing = await this.getPattern(id);\n\n return this.db.updateEntry(id, {\n title: updates.title?.trim() || existing.title,\n content: updates.content?.trim() || existing.content,\n metadata: {\n ...existing.metadata,\n category: updates.category || existing.metadata.category,\n tags: updates.tags || existing.metadata.tags,\n },\n });\n }\n\n // ==================\n // Context Management\n // ==================\n\n async setContext(projectId: string, input: ContextInput): Promise<MemoryEntry> {\n // Get or create context entry for the project\n const existing = await this.db.listEntries({\n projectId,\n type: 'context',\n isArchived: false,\n });\n\n const contextData = {\n feature: input.feature || '',\n blockers: input.blockers || [],\n nextSteps: input.nextSteps || [],\n activeFiles: input.activeFiles || [],\n };\n\n if (existing.length > 0) {\n // Update existing context\n return this.db.updateEntry(existing[0].id, {\n title: 'Project Context',\n content: JSON.stringify(contextData, null, 2),\n metadata: contextData,\n });\n } else {\n // Create new context\n return this.db.createEntry({\n projectId,\n type: 'context',\n title: 'Project Context',\n content: JSON.stringify(contextData, null, 2),\n metadata: contextData,\n });\n }\n }\n\n async getContext(projectId: string): Promise<MemoryEntry | null> {\n const entries = await this.db.listEntries({\n projectId,\n type: 'context',\n isArchived: false,\n });\n\n return entries[0] || null;\n }\n\n // ==================\n // Document Management\n // ==================\n\n async addDocument(projectId: string, input: DocumentInput): Promise<MemoryEntry> {\n if (!input.title?.trim()) {\n throw new ValidationError('Document title is required');\n }\n if (!input.content?.trim()) {\n throw new ValidationError('Document content is required');\n }\n\n return this.db.createEntry({\n projectId,\n type: 'document',\n title: input.title.trim(),\n content: input.content.trim(),\n metadata: {\n url: input.url,\n tags: input.tags || [],\n },\n });\n }\n\n async listDocuments(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'document',\n branch,\n isArchived: false,\n });\n }\n\n async getDocument(id: string): Promise<MemoryEntry> {\n const entry = await this.db.getEntry(id);\n if (!entry || entry.type !== 'document') {\n throw new NotFoundError(`Document with id ${id} not found`);\n }\n return entry;\n }\n\n // ==================\n // Session Management\n // ==================\n\n async startSession(projectId: string, input: SessionInput): Promise<MemoryEntry> {\n if (!input.feature?.trim()) {\n throw new ValidationError('Session feature is required');\n }\n\n // Check if there's already an active session\n const active = await this.getActiveSession(projectId);\n if (active) {\n throw new ValidationError(\n 'An active session already exists. End it first or use a different branch.'\n );\n }\n\n return this.db.createEntry({\n projectId,\n type: 'session',\n title: `Session: ${input.feature}`,\n content: input.description || '',\n metadata: {\n feature: input.feature,\n startedAt: new Date().toISOString(),\n endedAt: null,\n },\n });\n }\n\n async endSession(projectId: string, summary?: string): Promise<MemoryEntry> {\n const active = await this.getActiveSession(projectId);\n if (!active) {\n throw new NotFoundError('No active session found');\n }\n\n return this.db.updateEntry(active.id, {\n content: summary || active.content,\n metadata: {\n ...active.metadata,\n endedAt: new Date().toISOString(),\n },\n });\n }\n\n async getActiveSession(projectId: string): Promise<MemoryEntry | null> {\n const sessions = await this.db.listEntries({\n projectId,\n type: 'session',\n isArchived: false,\n });\n\n return sessions.find((s) => !s.metadata.endedAt) || null;\n }\n\n async listSessions(projectId: string, branch?: string): Promise<MemoryEntry[]> {\n return this.db.listEntries({\n projectId,\n type: 'session',\n branch,\n isArchived: false,\n });\n }\n\n // ==================\n // Generic Operations\n // ==================\n\n async deleteEntry(id: string, hard = false): Promise<void> {\n return this.db.deleteEntry(id, hard);\n }\n\n async searchEntries(\n projectId: string,\n searchTerm: string,\n options?: { branch?: string; type?: string }\n ): Promise<MemoryEntry[]> {\n return this.db.searchEntries(projectId, searchTerm, options);\n }\n\n async getAllEntries(query: EntryQuery): Promise<MemoryEntry[]> {\n return this.db.listEntries(query);\n }\n\n async getEntryCount(projectId: string, branch?: string): Promise<number> {\n return this.db.countEntries({\n projectId,\n branch,\n isArchived: false,\n });\n }\n}\n","/**\n * Relevance Engine - Smart context retrieval scoring\n */\n\nimport type { MemoryEntry, SuggestOptions, RankedEntry } from '../types.js';\n\n/**\n * Calculate relevance score for a memory entry\n *\n * Scoring breakdown (when no embeddings available):\n * - Keyword overlap: 40%\n * - Recency: 25%\n * - Type priority: 20%\n * - File match: 15%\n *\n * Total: 1.0 (100%)\n */\nexport function calculateRelevance(\n entry: MemoryEntry,\n options: SuggestOptions\n): number {\n let score = 0;\n\n // 1. Keyword overlap (40%)\n if (options.taskDescription) {\n score += keywordOverlap(entry, options.taskDescription) * 0.4;\n }\n\n // 2. Recency boost (25%) - exponential decay over 30 days\n const daysOld = (Date.now() - entry.updatedAt.getTime()) / (1000 * 60 * 60 * 24);\n const recencyScore = Math.exp(-daysOld / 30); // Exponential decay\n score += recencyScore * 0.25;\n\n // 3. Type priority (20%)\n const typePriority = getTypePriority(entry.type);\n score += typePriority * 0.2;\n\n // 4. File match boost (15%)\n if (options.activeFiles && options.activeFiles.length > 0) {\n const hasFileMatch = options.activeFiles.some(file =>\n entry.content.toLowerCase().includes(file.toLowerCase()) ||\n entry.title.toLowerCase().includes(file.toLowerCase())\n );\n if (hasFileMatch) {\n score += 0.15;\n }\n }\n\n return Math.min(score, 1.0);\n}\n\n/**\n * Calculate keyword overlap between entry and search query\n */\nfunction keywordOverlap(entry: MemoryEntry, query: string): number {\n const entryText = `${entry.title} ${entry.content}`.toLowerCase();\n const queryWords = query.toLowerCase().split(/\\s+/).filter(w => w.length > 2);\n\n if (queryWords.length === 0) return 0;\n\n const matchCount = queryWords.filter(word => entryText.includes(word)).length;\n return matchCount / queryWords.length;\n}\n\n/**\n * Get priority score for entry type\n */\nfunction getTypePriority(type: string): number {\n const priorities: Record<string, number> = {\n context: 1.0, // Highest priority\n decision: 0.8,\n pattern: 0.8,\n session: 0.5,\n document: 0.3, // Lowest priority\n };\n\n return priorities[type] || 0.5;\n}\n\n/**\n * Generate match reasons for transparency\n */\nexport function getMatchReasons(\n entry: MemoryEntry,\n options: SuggestOptions\n): string[] {\n const reasons: string[] = [];\n\n // Check keyword matches\n if (options.taskDescription) {\n const overlap = keywordOverlap(entry, options.taskDescription);\n if (overlap > 0.3) {\n reasons.push(`${Math.round(overlap * 100)}% keyword match`);\n }\n }\n\n // Check recency\n const daysOld = (Date.now() - entry.updatedAt.getTime()) / (1000 * 60 * 60 * 24);\n if (daysOld < 7) {\n reasons.push('Recently updated');\n }\n\n // Check type\n if (entry.type === 'context') {\n reasons.push('Current context');\n }\n\n // Check file matches\n if (options.activeFiles) {\n const matchedFiles = options.activeFiles.filter(file =>\n entry.content.toLowerCase().includes(file.toLowerCase())\n );\n if (matchedFiles.length > 0) {\n reasons.push(`References ${matchedFiles.join(', ')}`);\n }\n }\n\n return reasons;\n}\n\n/**\n * Rank and filter entries by relevance\n */\nexport function rankEntries(\n entries: MemoryEntry[],\n options: SuggestOptions\n): RankedEntry[] {\n const minRelevance = options.minRelevance || 0.3;\n\n return entries\n .map(entry => ({\n entry,\n score: calculateRelevance(entry, options),\n reasons: getMatchReasons(entry, options),\n }))\n .filter(ranked => ranked.score >= minRelevance)\n .sort((a, b) => b.score - a.score);\n}\n","/**\n * Sync Engine - Handles push/pull synchronization\n * Coordinates between local and remote databases\n */\n\nimport type { ILocalDatabase, IRemoteDatabase } from '../interfaces/database.js';\nimport type { MemoryEntry, Project, SyncResult } from '../types.js';\n\nexport interface SyncOptions {\n /**\n * Force push even if conflicts exist (last-write-wins)\n */\n force?: boolean;\n\n /**\n * Dry run - don't actually sync, just report what would happen\n */\n dryRun?: boolean;\n}\n\nexport class SyncEngine {\n constructor(\n private local: ILocalDatabase,\n private remote: IRemoteDatabase\n ) {}\n\n /**\n * Push local changes to remote\n */\n async push(projectId: string, options: SyncOptions = {}): Promise<SyncResult> {\n const result: SyncResult = {\n pushed: 0,\n pulled: 0,\n conflicts: 0,\n errors: [],\n };\n\n try {\n // Get project from local\n const project = await this.local.getProject(projectId);\n if (!project) {\n throw new Error('Project not found locally');\n }\n\n // Sync project metadata\n if (!options.dryRun) {\n await this.remote.upsertProject(project);\n }\n\n // Get unsynced entries\n const unsyncedEntries = await this.local.getUnsyncedEntries(projectId);\n\n if (unsyncedEntries.length === 0) {\n return result;\n }\n\n // Check for conflicts (entries modified both locally and remotely)\n const conflicts: MemoryEntry[] = [];\n if (!options.force) {\n const lastPull = await this.local.getLastPull(projectId);\n if (lastPull) {\n const remoteChanges = await this.remote.pullEntries(projectId, lastPull);\n const unsyncedIds = new Set(unsyncedEntries.map((e) => e.id));\n\n // Find entries that changed both locally and remotely\n for (const remoteEntry of remoteChanges) {\n if (unsyncedIds.has(remoteEntry.id)) {\n const localEntry = unsyncedEntries.find((e) => e.id === remoteEntry.id);\n if (\n localEntry &&\n localEntry.updatedAt.getTime() !== remoteEntry.updatedAt.getTime()\n ) {\n conflicts.push(localEntry);\n }\n }\n }\n }\n }\n\n if (conflicts.length > 0 && !options.force) {\n result.conflicts = conflicts.length;\n result.errors.push(\n `${conflicts.length} conflict(s) found. Use --force to push anyway (last-write-wins).`\n );\n return result;\n }\n\n // Push entries to remote\n if (!options.dryRun) {\n await this.remote.pushEntries(unsyncedEntries);\n\n // Trigger embedding generation for pushed entries (non-blocking)\n const pushedIds = unsyncedEntries.map((e) => e.id);\n if (typeof (this.remote as any).generateEmbeddings === 'function') {\n (this.remote as any).generateEmbeddings(pushedIds).catch(() => {});\n }\n\n // Mark entries as synced locally\n await this.local.markSynced(unsyncedEntries.map((e) => e.id));\n }\n\n result.pushed = unsyncedEntries.length;\n\n // Sync branches\n const branches = await this.local.listBranches(projectId);\n for (const branch of branches) {\n if (!options.dryRun) {\n await this.remote.upsertBranch(branch);\n }\n }\n\n return result;\n } catch (error) {\n result.errors.push(\n error instanceof Error ? error.message : 'Unknown error during push'\n );\n return result;\n }\n }\n\n /**\n * Pull remote changes to local\n */\n async pull(projectId: string, options: SyncOptions = {}): Promise<SyncResult> {\n const result: SyncResult = {\n pushed: 0,\n pulled: 0,\n conflicts: 0,\n errors: [],\n };\n\n try {\n // Get project from local\n const project = await this.local.getProject(projectId);\n if (!project) {\n throw new Error('Project not found locally');\n }\n\n // Get last pull timestamp\n const lastPull = await this.local.getLastPull(projectId);\n const since = lastPull || new Date(0); // Pull all if first time\n\n // Pull entries from remote\n const remoteEntries = await this.remote.pullEntries(projectId, since);\n\n if (remoteEntries.length === 0) {\n return result;\n }\n\n // Check for conflicts (entries modified locally that also changed remotely)\n const unsyncedEntries = await this.local.getUnsyncedEntries(projectId);\n const unsyncedIds = new Set(unsyncedEntries.map((e) => e.id));\n\n const conflicts: MemoryEntry[] = [];\n for (const remoteEntry of remoteEntries) {\n if (unsyncedIds.has(remoteEntry.id)) {\n const localEntry = unsyncedEntries.find((e) => e.id === remoteEntry.id);\n if (\n localEntry &&\n localEntry.updatedAt.getTime() !== remoteEntry.updatedAt.getTime()\n ) {\n conflicts.push(remoteEntry);\n }\n }\n }\n\n if (conflicts.length > 0 && !options.force) {\n result.conflicts = conflicts.length;\n result.errors.push(\n `${conflicts.length} conflict(s) found. Use --force to pull anyway (last-write-wins).`\n );\n return result;\n }\n\n // Upsert remote entries into local database\n // Last-write-wins: remote entries with newer updatedAt override local\n if (!options.dryRun) {\n for (const entry of remoteEntries) {\n const localEntry = await this.local.getEntry(entry.id);\n\n if (!localEntry) {\n // New entry - create it\n await this.local.createEntry({\n id: entry.id,\n projectId: entry.projectId,\n type: entry.type,\n title: entry.title,\n content: entry.content,\n metadata: entry.metadata,\n branch: entry.branch,\n });\n } else if (entry.updatedAt > localEntry.updatedAt || options.force) {\n // Remote is newer or force flag - update local\n await this.local.updateEntry(entry.id, {\n title: entry.title,\n content: entry.content,\n metadata: entry.metadata,\n updatedAt: entry.updatedAt,\n isSynced: true,\n });\n }\n }\n\n // Update last pull timestamp\n await this.local.updateLastPull(projectId, new Date());\n }\n\n result.pulled = remoteEntries.length;\n\n return result;\n } catch (error) {\n result.errors.push(\n error instanceof Error ? error.message : 'Unknown error during pull'\n );\n return result;\n }\n }\n\n /**\n * Full bidirectional sync (pull then push)\n */\n async sync(projectId: string, options: SyncOptions = {}): Promise<SyncResult> {\n // First pull remote changes\n const pullResult = await this.pull(projectId, options);\n\n if (pullResult.errors.length > 0) {\n return pullResult;\n }\n\n // Then push local changes\n const pushResult = await this.push(projectId, options);\n\n // Combine results\n return {\n pushed: pushResult.pushed,\n pulled: pullResult.pulled,\n conflicts: pullResult.conflicts + pushResult.conflicts,\n errors: [...pullResult.errors, ...pushResult.errors],\n };\n }\n}\n","/**\n * Token counting utilities using tiktoken\n */\n\nimport { get_encoding } from 'tiktoken';\nimport type { MemoryEntry, RankedEntry } from '../types.js';\n\n// Use cl100k_base encoding (GPT-4/Claude compatible)\nconst encoding = get_encoding('cl100k_base');\n\n/**\n * Count tokens in a text string\n */\nexport function countTokens(text: string): number {\n const tokens = encoding.encode(text);\n return tokens.length;\n}\n\n/**\n * Count tokens in a memory entry\n */\nexport function countEntryTokens(entry: MemoryEntry): number {\n const text = formatEntryForContext(entry);\n return countTokens(text);\n}\n\n/**\n * Format entry for context (how it will appear in the prompt)\n */\nexport function formatEntryForContext(entry: MemoryEntry): string {\n const lines: string[] = [];\n\n lines.push(`## ${entry.type.toUpperCase()}: ${entry.title}`);\n lines.push('');\n lines.push(entry.content);\n\n // Add relevant metadata\n if (entry.metadata && Object.keys(entry.metadata).length > 0) {\n lines.push('');\n lines.push('**Metadata:**');\n for (const [key, value] of Object.entries(entry.metadata)) {\n if (Array.isArray(value) && value.length > 0) {\n lines.push(`- ${key}: ${value.join(', ')}`);\n } else if (value && typeof value === 'string') {\n lines.push(`- ${key}: ${value}`);\n }\n }\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Fit ranked entries within a token budget\n */\nexport function fitToBudget(\n rankedEntries: RankedEntry[],\n maxTokens: number\n): RankedEntry[] {\n const result: RankedEntry[] = [];\n let currentTokens = 0;\n\n // Reserve tokens for header/footer\n const headerTokens = countTokens('# MemoCore Context\\n\\n');\n currentTokens += headerTokens;\n\n for (const ranked of rankedEntries) {\n const entryTokens = countEntryTokens(ranked.entry);\n\n if (currentTokens + entryTokens <= maxTokens) {\n result.push(ranked);\n currentTokens += entryTokens;\n } else {\n // Budget exceeded, stop adding\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Build formatted context from ranked entries\n */\nexport function buildContext(\n rankedEntries: RankedEntry[],\n options?: {\n includeReasons?: boolean;\n includeStats?: boolean;\n }\n): string {\n const lines: string[] = [];\n\n lines.push('# MemoCore Context');\n lines.push('');\n\n if (options?.includeStats) {\n lines.push(`Found ${rankedEntries.length} relevant entries:`);\n lines.push('');\n }\n\n for (const ranked of rankedEntries) {\n if (options?.includeReasons && ranked.reasons.length > 0) {\n lines.push(`<!-- Match reasons: ${ranked.reasons.join(', ')} -->`);\n }\n\n lines.push(formatEntryForContext(ranked.entry));\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Free tiktoken resources (call on cleanup)\n */\nexport function cleanup(): void {\n encoding.free();\n}\n","/**\n * Context Builder Engine\n * Intelligently assembles project context for AI agents\n */\n\nimport type { MemoryEntry, SuggestOptions, RankedEntry } from '../types.js';\nimport { rankEntries } from './relevance.js';\nimport { countTokens, countEntryTokens, fitToBudget, buildContext } from '../utils/tokens.js';\n\nexport interface ContextMode {\n type: 'task' | 'files' | 'all';\n taskDescription?: string;\n activeFiles?: string[];\n includeTypes?: string[];\n}\n\nexport interface ContextBuilderOptions extends ContextMode {\n projectId: string;\n maxTokens?: number;\n minRelevance?: number;\n}\n\nexport interface ContextResult {\n context: string;\n entriesIncluded: number;\n entriesFiltered: number;\n tokensUsed: number;\n tokensSaved: number;\n budget: number;\n}\n\n/**\n * Convert MemoryEntry[] to RankedEntry[] with default scores\n */\nfunction toRankedEntries(entries: MemoryEntry[]): RankedEntry[] {\n return entries.map((entry) => ({\n entry,\n score: 1.0,\n reasons: [],\n }));\n}\n\n/**\n * Build intelligent context payload for AI agents\n */\nexport function buildContextPayload(\n entries: MemoryEntry[],\n options: ContextBuilderOptions\n): ContextResult {\n const budget = options.maxTokens || 4000;\n let rankedEntries: RankedEntry[] = [];\n\n if (options.type === 'task' && options.taskDescription) {\n // Task-based context: rank by relevance\n const suggestOpts: SuggestOptions = {\n projectId: options.projectId,\n taskDescription: options.taskDescription,\n activeFiles: options.activeFiles,\n maxTokens: budget,\n };\n\n rankedEntries = rankEntries(entries, suggestOpts);\n } else if (options.type === 'files' && options.activeFiles && options.activeFiles.length > 0) {\n // File-based context: filter by file mentions\n const filtered = entries.filter((entry) =>\n options.activeFiles!.some(\n (file) =>\n entry.content.includes(file) || entry.metadata?.files?.includes(file)\n )\n );\n\n // Sort by recency\n filtered.sort(\n (a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()\n );\n\n rankedEntries = toRankedEntries(filtered);\n } else {\n // All context: include everything, sorted by recency\n const sorted = [...entries];\n sorted.sort(\n (a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()\n );\n\n rankedEntries = toRankedEntries(sorted);\n }\n\n // Filter by type if specified\n if (options.includeTypes && options.includeTypes.length > 0) {\n rankedEntries = rankedEntries.filter((ranked) =>\n options.includeTypes!.includes(ranked.entry.type)\n );\n }\n\n // Compute total tokens of all candidate entries (before budget fitting)\n const totalEntryTokens = rankedEntries.reduce(\n (sum, ranked) => sum + countEntryTokens(ranked.entry),\n 0\n );\n\n // Fit to token budget\n const fitted = fitToBudget(rankedEntries, budget);\n\n // Build formatted context\n const context = buildContext(fitted);\n const tokensUsed = countTokens(context);\n\n return {\n context,\n entriesIncluded: fitted.length,\n entriesFiltered: rankedEntries.length - fitted.length,\n tokensUsed,\n tokensSaved: Math.max(0, totalEntryTokens - tokensUsed),\n budget,\n };\n}\n\n/**\n * Build a summary of what context is available\n */\nexport function buildContextSummary(entries: MemoryEntry[]): {\n totalEntries: number;\n byType: Record<string, number>;\n recentActivity: string[];\n oldestEntry: Date | null;\n newestEntry: Date | null;\n} {\n const byType: Record<string, number> = {};\n const recentActivity: string[] = [];\n\n let oldest: Date | null = null;\n let newest: Date | null = null;\n\n for (const entry of entries) {\n // Count by type\n byType[entry.type] = (byType[entry.type] || 0) + 1;\n\n // Track date range\n if (!oldest || entry.createdAt < oldest) {\n oldest = entry.createdAt;\n }\n if (!newest || entry.updatedAt > newest) {\n newest = entry.updatedAt;\n }\n }\n\n // Get recent activity (last 5 entries)\n const recent = [...entries]\n .sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())\n .slice(0, 5);\n\n for (const entry of recent) {\n const age = Date.now() - entry.updatedAt.getTime();\n const daysAgo = Math.floor(age / (1000 * 60 * 60 * 24));\n\n let timeStr = '';\n if (daysAgo === 0) {\n timeStr = 'today';\n } else if (daysAgo === 1) {\n timeStr = 'yesterday';\n } else if (daysAgo < 7) {\n timeStr = `${daysAgo} days ago`;\n } else {\n timeStr = `${Math.floor(daysAgo / 7)} weeks ago`;\n }\n\n recentActivity.push(`${entry.type}: ${entry.title} (${timeStr})`);\n }\n\n return {\n totalEntries: entries.length,\n byType,\n recentActivity,\n oldestEntry: oldest,\n newestEntry: newest,\n };\n}\n","/**\n * Code Comment Scanner\n * Extracts @decision, @pattern, and @context tags from code comments\n */\n\nimport { createHash } from 'crypto';\nimport type { MemoryEntryType } from './types.js';\n\nexport interface ScanComment {\n tag: 'decision' | 'pattern' | 'context';\n category?: string;\n title: string;\n content: string;\n fields: Record<string, string>;\n file: string;\n line: number;\n hash: string;\n}\n\nexport interface ScanResult {\n found: ScanComment[];\n errors: Array<{ file: string; line: number; error: string }>;\n}\n\n/**\n * Comment patterns for different languages\n */\nconst COMMENT_PATTERNS = [\n // Single line comments: // @tag\n { pattern: /^(\\s*)\\/\\/\\s*/, continuation: /^(\\s*)\\/\\/\\s+(?!@)/ },\n // Python/Ruby/Shell: # @tag\n { pattern: /^(\\s*)#\\s*/, continuation: /^(\\s*)#\\s+(?!@)/ },\n // SQL: -- @tag\n { pattern: /^(\\s*)--\\s*/, continuation: /^(\\s*)--\\s+(?!@)/ },\n];\n\n/**\n * Tag detection pattern\n */\nconst TAG_PATTERN = /@(decision|pattern|context)\\s*/i;\n\n/**\n * Category pattern: [@decision [category] title]\n */\nconst CATEGORY_PATTERN = /^\\[([^\\]]+)\\]\\s*/;\n\n/**\n * Field pattern: | key: value\n */\nconst FIELD_PATTERN = /\\|\\s*(\\w+):\\s*([^|]+)/g;\n\n/**\n * Parse a single file for tagged comments\n */\nexport function parseFile(content: string, filePath: string): ScanComment[] {\n const lines = content.split('\\n');\n const comments: ScanComment[] = [];\n let currentComment: Partial<ScanComment> | null = null;\n let currentIndent: string = '';\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + 1;\n\n // Check for tag start\n const tagMatch = detectTag(line);\n if (tagMatch) {\n // Save previous comment if exists\n if (currentComment && currentComment.title) {\n comments.push(finalizeComment(currentComment, filePath));\n }\n\n // Start new comment\n const { tag, content, category } = tagMatch;\n const { title, fields } = extractTitleAndFields(content);\n\n currentComment = {\n tag,\n category,\n title,\n content: title,\n fields,\n file: filePath,\n line: lineNum,\n };\n\n currentIndent = getIndent(line);\n continue;\n }\n\n // Check for continuation line\n if (currentComment && isContinuationLine(line, currentIndent)) {\n const continuationText = extractContinuationText(line);\n if (continuationText) {\n currentComment.content += ' ' + continuationText;\n\n // Check for fields in continuation\n const moreFields = extractFields(continuationText);\n Object.assign(currentComment.fields!, moreFields);\n }\n continue;\n }\n\n // If we hit a non-continuation line, finalize current comment\n if (currentComment && currentComment.title) {\n comments.push(finalizeComment(currentComment, filePath));\n currentComment = null;\n }\n }\n\n // Finalize last comment if exists\n if (currentComment && currentComment.title) {\n comments.push(finalizeComment(currentComment, filePath));\n }\n\n return comments;\n}\n\n/**\n * Detect if a line contains a tag\n */\nfunction detectTag(line: string): { tag: 'decision' | 'pattern' | 'context'; content: string; category?: string } | null {\n // Check if line has a comment marker\n let commentContent: string | null = null;\n for (const { pattern } of COMMENT_PATTERNS) {\n const match = line.match(pattern);\n if (match) {\n commentContent = line.substring(match[0].length);\n break;\n }\n }\n\n if (!commentContent) return null;\n\n // Check for tag\n const tagMatch = commentContent.match(TAG_PATTERN);\n if (!tagMatch) return null;\n\n const tag = tagMatch[1].toLowerCase() as 'decision' | 'pattern' | 'context';\n let content = commentContent.substring(tagMatch[0].length).trim();\n\n // Extract category if present\n let category: string | undefined;\n const categoryMatch = content.match(CATEGORY_PATTERN);\n if (categoryMatch) {\n category = categoryMatch[1];\n content = content.substring(categoryMatch[0].length).trim();\n }\n\n return { tag, content, category };\n}\n\n/**\n * Check if line is a continuation of current comment\n */\nfunction isContinuationLine(line: string, expectedIndent: string): boolean {\n for (const { continuation } of COMMENT_PATTERNS) {\n const match = line.match(continuation);\n if (match && match[1] === expectedIndent) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Extract text from continuation line\n */\nfunction extractContinuationText(line: string): string | null {\n for (const { continuation } of COMMENT_PATTERNS) {\n const match = line.match(continuation);\n if (match) {\n return line.substring(match[0].length).trim();\n }\n }\n return null;\n}\n\n/**\n * Get indentation of a line\n */\nfunction getIndent(line: string): string {\n const match = line.match(/^(\\s*)/);\n return match ? match[1] : '';\n}\n\n/**\n * Extract title and fields from content\n */\nfunction extractTitleAndFields(content: string): { title: string; fields: Record<string, string> } {\n const fields = extractFields(content);\n\n // Title is everything before the first |\n const pipeIndex = content.indexOf('|');\n const title = pipeIndex >= 0 ? content.substring(0, pipeIndex).trim() : content.trim();\n\n return { title, fields };\n}\n\n/**\n * Extract key:value fields from content\n */\nfunction extractFields(content: string): Record<string, string> {\n const fields: Record<string, string> = {};\n let match;\n\n FIELD_PATTERN.lastIndex = 0; // Reset regex state\n while ((match = FIELD_PATTERN.exec(content)) !== null) {\n const key = match[1];\n const value = match[2].trim();\n fields[key] = value;\n }\n\n return fields;\n}\n\n/**\n * Finalize a comment by adding hash\n */\nfunction finalizeComment(partial: Partial<ScanComment>, filePath: string): ScanComment {\n const content = partial.content || partial.title || '';\n const hash = createContentHash(partial.tag!, partial.title!, content);\n\n return {\n tag: partial.tag!,\n category: partial.category,\n title: partial.title!,\n content,\n fields: partial.fields || {},\n file: filePath,\n line: partial.line!,\n hash,\n };\n}\n\n/**\n * Create a stable hash for deduplication\n */\nfunction createContentHash(tag: string, title: string, content: string): string {\n const normalized = `${tag}:${title}:${content}`.toLowerCase().replace(/\\s+/g, ' ');\n return createHash('sha256').update(normalized).digest('hex').substring(0, 16);\n}\n\n/**\n * Convert scan comment to memory entry type\n */\nexport function scanCommentToEntry(comment: ScanComment, projectId: string): {\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata: Record<string, any>;\n} {\n const metadata: Record<string, any> = {\n source: 'scan',\n file: comment.file,\n line: comment.line,\n hash: comment.hash,\n category: comment.category,\n ...comment.fields,\n };\n\n // Map decision fields\n if (comment.tag === 'decision') {\n return {\n type: 'decision',\n title: comment.title,\n content: comment.fields.rationale || comment.content,\n metadata: {\n ...metadata,\n alternatives: comment.fields.alternatives,\n consequences: comment.fields.consequences,\n status: comment.fields.status || 'active',\n },\n };\n }\n\n // Map pattern fields\n if (comment.tag === 'pattern') {\n return {\n type: 'pattern',\n title: comment.title,\n content: comment.fields.template || comment.content,\n metadata: {\n ...metadata,\n when: comment.fields.when,\n },\n };\n }\n\n // Context is free-form\n return {\n type: 'context',\n title: 'Active Context',\n content: comment.content,\n metadata,\n };\n}\n","/**\n * Rules File Parser\n * Parses .contxt/rules.md file into structured memory entries\n */\n\nimport type { MemoryEntryType } from './types.js';\n\nexport interface RulesEntry {\n type: MemoryEntryType;\n title: string;\n content: string;\n metadata: Record<string, any>;\n}\n\nexport interface ParsedRules {\n stack: string[];\n decisions: RulesEntry[];\n patterns: RulesEntry[];\n context: RulesEntry | null;\n documents: RulesEntry[];\n}\n\n/**\n * Parse rules.md file into structured entries\n */\nexport function parseRulesFile(content: string): ParsedRules {\n const lines = content.split('\\n');\n const result: ParsedRules = {\n stack: [],\n decisions: [],\n patterns: [],\n context: null,\n documents: [],\n };\n\n let currentSection: string | null = null;\n let currentContent: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Check for heading\n const headingMatch = line.match(/^#+\\s+(.+)/);\n if (headingMatch) {\n // Process previous section\n if (currentSection && currentContent.length > 0) {\n processSection(currentSection, currentContent.join('\\n'), result);\n }\n\n // Start new section\n currentSection = headingMatch[1].trim();\n currentContent = [];\n continue;\n }\n\n // Add line to current section\n if (currentSection && line.trim()) {\n currentContent.push(line);\n }\n }\n\n // Process final section\n if (currentSection && currentContent.length > 0) {\n processSection(currentSection, currentContent.join('\\n'), result);\n }\n\n return result;\n}\n\n/**\n * Process a section based on its heading\n */\nfunction processSection(heading: string, content: string, result: ParsedRules): void {\n const headingLower = heading.toLowerCase();\n\n if (headingLower === 'stack' || headingLower === 'tech stack') {\n result.stack = parseListItems(content);\n } else if (headingLower === 'decisions') {\n result.decisions = parseDecisions(content);\n } else if (headingLower === 'patterns') {\n result.patterns = parsePatterns(content);\n } else if (headingLower === 'context') {\n result.context = parseContext(content);\n } else {\n // Any other heading becomes a document\n result.documents.push({\n type: 'document',\n title: heading,\n content: content.trim(),\n metadata: { source: 'rules', section: heading },\n });\n }\n}\n\n/**\n * Parse list items from markdown content\n */\nfunction parseListItems(content: string): string[] {\n const items: string[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const match = line.match(/^[-*]\\s+(.+)/);\n if (match) {\n items.push(match[1].trim());\n }\n }\n\n return items;\n}\n\n/**\n * Parse decisions from list items\n * Format: - Title (rationale text)\n */\nfunction parseDecisions(content: string): RulesEntry[] {\n const decisions: RulesEntry[] = [];\n const items = parseListItems(content);\n\n for (const item of items) {\n // Try to extract rationale in parentheses\n const match = item.match(/^(.+?)\\s*\\(([^)]+)\\)\\s*$/);\n\n if (match) {\n const title = match[1].trim();\n const rationale = match[2].trim();\n decisions.push({\n type: 'decision',\n title,\n content: rationale,\n metadata: {\n source: 'rules',\n rationale,\n },\n });\n } else {\n // No parentheses, use the whole item as title and content\n decisions.push({\n type: 'decision',\n title: item,\n content: item,\n metadata: { source: 'rules' },\n });\n }\n }\n\n return decisions;\n}\n\n/**\n * Parse patterns from list items\n * Format: - Name: description/template\n */\nfunction parsePatterns(content: string): RulesEntry[] {\n const patterns: RulesEntry[] = [];\n const items = parseListItems(content);\n\n for (const item of items) {\n // Try to extract pattern name and description\n const colonIndex = item.indexOf(':');\n\n if (colonIndex >= 0) {\n const name = item.substring(0, colonIndex).trim();\n const description = item.substring(colonIndex + 1).trim();\n patterns.push({\n type: 'pattern',\n title: name,\n content: description,\n metadata: { source: 'rules' },\n });\n } else {\n // No colon, use the whole item\n patterns.push({\n type: 'pattern',\n title: item,\n content: item,\n metadata: { source: 'rules' },\n });\n }\n }\n\n return patterns;\n}\n\n/**\n * Parse context from free-form text\n */\nfunction parseContext(content: string): RulesEntry {\n return {\n type: 'context',\n title: 'Active Context',\n content: content.trim(),\n metadata: { source: 'rules' },\n };\n}\n\n/**\n * Generate rules.md file from memory entries\n */\nexport function generateRulesFile(entries: {\n stack: string[];\n decisions: Array<{ title: string; content: string; metadata: any }>;\n patterns: Array<{ title: string; content: string; metadata: any }>;\n context: Array<{ content: string }>;\n documents: Array<{ title: string; content: string }>;\n}): string {\n const sections: string[] = [];\n\n // Stack section\n if (entries.stack.length > 0) {\n sections.push('# Stack\\n');\n for (const item of entries.stack) {\n sections.push(`- ${item}`);\n }\n sections.push('');\n }\n\n // Decisions section\n if (entries.decisions.length > 0) {\n sections.push('# Decisions\\n');\n for (const decision of entries.decisions) {\n const rationale = decision.metadata.rationale || decision.content;\n sections.push(`- ${decision.title} (${rationale})`);\n }\n sections.push('');\n }\n\n // Patterns section\n if (entries.patterns.length > 0) {\n sections.push('# Patterns\\n');\n for (const pattern of entries.patterns) {\n sections.push(`- ${pattern.title}: ${pattern.content}`);\n }\n sections.push('');\n }\n\n // Context section\n if (entries.context.length > 0) {\n sections.push('# Context\\n');\n sections.push(entries.context[0].content);\n sections.push('');\n }\n\n // Document sections\n for (const doc of entries.documents) {\n sections.push(`# ${doc.title}\\n`);\n sections.push(doc.content);\n sections.push('');\n }\n\n return sections.join('\\n');\n}\n"],"mappings":"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","names":["content"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mycontxt/core",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",