@mycontxt/core 0.1.0

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.
@@ -0,0 +1,720 @@
1
+ /**
2
+ * Core type definitions for MemoCore
3
+ */
4
+ /**
5
+ * Memory entry types
6
+ */
7
+ type MemoryEntryType = 'decision' | 'pattern' | 'context' | 'document' | 'session';
8
+ /**
9
+ * Memory entry status
10
+ */
11
+ type MemoryEntryStatus = 'active' | 'draft' | 'archived' | 'stale';
12
+ /**
13
+ * User tier levels
14
+ */
15
+ type UserTier = 'free' | 'pro';
16
+ /**
17
+ * Core memory entry
18
+ */
19
+ interface MemoryEntry {
20
+ id: string;
21
+ projectId: string;
22
+ type: MemoryEntryType;
23
+ title: string;
24
+ content: string;
25
+ metadata: Record<string, any>;
26
+ embedding?: number[];
27
+ branch: string;
28
+ version: number;
29
+ status: MemoryEntryStatus;
30
+ isSynced: boolean;
31
+ isArchived: boolean;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ }
35
+ /**
36
+ * Project configuration
37
+ */
38
+ interface Project {
39
+ id: string;
40
+ userId?: string;
41
+ name: string;
42
+ path: string;
43
+ stack?: string[];
44
+ config: ProjectConfig;
45
+ createdAt: Date;
46
+ updatedAt: Date;
47
+ }
48
+ /**
49
+ * Project configuration options
50
+ */
51
+ interface ProjectConfig {
52
+ defaultBranch: string;
53
+ maxTokens: number;
54
+ autoSession: boolean;
55
+ stackDetection: boolean;
56
+ }
57
+ /**
58
+ * Branch information
59
+ */
60
+ interface Branch {
61
+ id: string;
62
+ projectId: string;
63
+ name: string;
64
+ parentBranch?: string;
65
+ isActive: boolean;
66
+ createdAt: Date;
67
+ }
68
+ /**
69
+ * User profile
70
+ */
71
+ interface UserProfile {
72
+ id: string;
73
+ email?: string;
74
+ tier: UserTier;
75
+ createdAt: Date;
76
+ }
77
+ /**
78
+ * Authentication session
79
+ */
80
+ interface AuthSession {
81
+ userId: string;
82
+ accessToken: string;
83
+ refreshToken: string;
84
+ expiresAt: Date;
85
+ }
86
+ /**
87
+ * Sync operation result
88
+ */
89
+ interface SyncResult {
90
+ pushed: number;
91
+ pulled: number;
92
+ conflicts: number;
93
+ errors: string[];
94
+ }
95
+ /**
96
+ * Entry query filters
97
+ */
98
+ interface EntryQuery {
99
+ projectId: string;
100
+ type?: MemoryEntryType;
101
+ branch?: string;
102
+ isArchived?: boolean;
103
+ search?: string;
104
+ limit?: number;
105
+ offset?: number;
106
+ }
107
+ /**
108
+ * Input for creating a new entry
109
+ */
110
+ interface CreateEntryInput {
111
+ id?: string;
112
+ projectId: string;
113
+ type: MemoryEntryType;
114
+ title: string;
115
+ content: string;
116
+ metadata?: Record<string, any>;
117
+ branch?: string;
118
+ status?: MemoryEntryStatus;
119
+ }
120
+ /**
121
+ * Decision-specific input
122
+ */
123
+ interface DecisionInput {
124
+ title: string;
125
+ rationale: string;
126
+ alternatives?: string[];
127
+ consequences?: string[];
128
+ tags?: string[];
129
+ }
130
+ /**
131
+ * Pattern-specific input
132
+ */
133
+ interface PatternInput {
134
+ title: string;
135
+ content: string;
136
+ category?: string;
137
+ tags?: string[];
138
+ }
139
+ /**
140
+ * Context-specific input
141
+ */
142
+ interface ContextInput {
143
+ feature?: string;
144
+ blockers?: string[];
145
+ nextSteps?: string[];
146
+ activeFiles?: string[];
147
+ }
148
+ /**
149
+ * Document-specific input
150
+ */
151
+ interface DocumentInput {
152
+ title: string;
153
+ content: string;
154
+ url?: string;
155
+ tags?: string[];
156
+ }
157
+ /**
158
+ * Session-specific input
159
+ */
160
+ interface SessionInput {
161
+ feature: string;
162
+ description?: string;
163
+ }
164
+ /**
165
+ * Ranked entry for context retrieval
166
+ */
167
+ interface RankedEntry {
168
+ entry: MemoryEntry;
169
+ score: number;
170
+ reasons: string[];
171
+ }
172
+ /**
173
+ * Context retrieval options
174
+ */
175
+ interface SuggestOptions {
176
+ projectId: string;
177
+ taskDescription?: string;
178
+ taskEmbedding?: number[];
179
+ activeFiles?: string[];
180
+ branch?: string;
181
+ maxResults?: number;
182
+ maxTokens?: number;
183
+ minRelevance?: number;
184
+ }
185
+ /**
186
+ * Activity item for the dashboard activity feed.
187
+ * Derived from memory_entries changes — no separate table needed.
188
+ */
189
+ interface ActivityItem {
190
+ id: string;
191
+ projectId: string;
192
+ projectName: string;
193
+ entryId?: string;
194
+ type: 'push' | 'session' | 'branch' | 'draft' | 'edit' | 'archive';
195
+ description: string;
196
+ actor: 'user' | 'auto';
197
+ createdAt: Date;
198
+ }
199
+ /**
200
+ * Usage statistics for the sidebar usage meters.
201
+ */
202
+ interface UsageStats {
203
+ entries: {
204
+ used: number;
205
+ limit: number;
206
+ };
207
+ projects: {
208
+ used: number;
209
+ limit: number | null;
210
+ };
211
+ searches: {
212
+ used: number;
213
+ limit: number;
214
+ };
215
+ }
216
+ /**
217
+ * Validation error
218
+ */
219
+ declare class ValidationError extends Error {
220
+ constructor(message: string);
221
+ }
222
+ /**
223
+ * Not found error
224
+ */
225
+ declare class NotFoundError extends Error {
226
+ constructor(message: string);
227
+ }
228
+ /**
229
+ * Conflict error
230
+ */
231
+ declare class ConflictError extends Error {
232
+ constructor(message: string);
233
+ }
234
+ /**
235
+ * Authentication error
236
+ */
237
+ declare class AuthError extends Error {
238
+ constructor(message: string);
239
+ }
240
+
241
+ /**
242
+ * Database interface definitions
243
+ * These interfaces define the contract between business logic and storage adapters
244
+ */
245
+
246
+ /**
247
+ * Local database interface (SQLite)
248
+ * This is the source of truth for offline-first architecture
249
+ */
250
+ interface ILocalDatabase {
251
+ /**
252
+ * Initialize the database schema
253
+ */
254
+ initialize(): Promise<void>;
255
+ /**
256
+ * Close the database connection
257
+ */
258
+ close(): Promise<void>;
259
+ /**
260
+ * Create or initialize a project
261
+ */
262
+ initProject(config: {
263
+ name: string;
264
+ path: string;
265
+ stack?: string[];
266
+ config?: Partial<ProjectConfig>;
267
+ }): Promise<Project>;
268
+ /**
269
+ * Get a project by ID
270
+ */
271
+ getProject(projectId: string): Promise<Project | null>;
272
+ /**
273
+ * Get project by path
274
+ */
275
+ getProjectByPath(path: string): Promise<Project | null>;
276
+ /**
277
+ * Update project configuration
278
+ */
279
+ updateProject(projectId: string, updates: Partial<Omit<Project, 'id' | 'createdAt'>>): Promise<Project>;
280
+ /**
281
+ * Create a new memory entry
282
+ */
283
+ createEntry(input: CreateEntryInput): Promise<MemoryEntry>;
284
+ /**
285
+ * Get a single entry by ID
286
+ */
287
+ getEntry(id: string): Promise<MemoryEntry | null>;
288
+ /**
289
+ * Update an existing entry
290
+ */
291
+ updateEntry(id: string, updates: Partial<Omit<MemoryEntry, 'id' | 'projectId' | 'createdAt'>>): Promise<MemoryEntry>;
292
+ /**
293
+ * Delete an entry (soft delete by default)
294
+ */
295
+ deleteEntry(id: string, hard?: boolean): Promise<void>;
296
+ /**
297
+ * List entries with optional filters
298
+ */
299
+ listEntries(query: EntryQuery): Promise<MemoryEntry[]>;
300
+ /**
301
+ * Count entries matching query
302
+ */
303
+ countEntries(query: Omit<EntryQuery, 'limit' | 'offset'>): Promise<number>;
304
+ /**
305
+ * Search entries (full-text search)
306
+ */
307
+ searchEntries(projectId: string, searchTerm: string, options?: {
308
+ branch?: string;
309
+ type?: string;
310
+ limit?: number;
311
+ }): Promise<MemoryEntry[]>;
312
+ /**
313
+ * Get all unsynced entries for a project
314
+ */
315
+ getUnsyncedEntries(projectId: string): Promise<MemoryEntry[]>;
316
+ /**
317
+ * Mark entries as synced
318
+ */
319
+ markSynced(ids: string[]): Promise<void>;
320
+ /**
321
+ * Get entries updated since a timestamp
322
+ */
323
+ getEntriesUpdatedSince(projectId: string, timestamp: Date): Promise<MemoryEntry[]>;
324
+ /**
325
+ * Update last pull timestamp
326
+ */
327
+ updateLastPull(projectId: string, timestamp: Date): Promise<void>;
328
+ /**
329
+ * Get last pull timestamp
330
+ */
331
+ getLastPull(projectId: string): Promise<Date | null>;
332
+ /**
333
+ * Create a new branch
334
+ */
335
+ createBranch(projectId: string, name: string, fromBranch: string): Promise<Branch>;
336
+ /**
337
+ * Get a branch by name
338
+ */
339
+ getBranch(projectId: string, name: string): Promise<Branch | null>;
340
+ /**
341
+ * List all branches for a project
342
+ */
343
+ listBranches(projectId: string): Promise<Branch[]>;
344
+ /**
345
+ * Delete a branch
346
+ */
347
+ deleteBranch(projectId: string, name: string): Promise<void>;
348
+ /**
349
+ * Get current active branch
350
+ */
351
+ getActiveBranch(projectId: string): Promise<string>;
352
+ /**
353
+ * Switch to a different branch
354
+ */
355
+ switchBranch(projectId: string, branchName: string): Promise<void>;
356
+ /**
357
+ * Create a version snapshot of an entry
358
+ */
359
+ createVersion(entryId: string, snapshot: MemoryEntry): Promise<void>;
360
+ /**
361
+ * Get version history for an entry
362
+ */
363
+ getVersionHistory(entryId: string): Promise<MemoryEntry[]>;
364
+ /**
365
+ * Restore an entry to a specific version
366
+ */
367
+ restoreVersion(entryId: string, version: number): Promise<MemoryEntry>;
368
+ }
369
+ /**
370
+ * Remote database interface (Supabase/Cloud)
371
+ * Mirrors ILocalDatabase but for cloud operations
372
+ */
373
+ interface IRemoteDatabase {
374
+ /**
375
+ * Initialize connection to remote database
376
+ */
377
+ initialize(): Promise<void>;
378
+ /**
379
+ * Close connection
380
+ */
381
+ close(): Promise<void>;
382
+ /**
383
+ * Sync project to remote
384
+ */
385
+ upsertProject(project: Project): Promise<Project>;
386
+ /**
387
+ * Get project from remote
388
+ */
389
+ getProject(projectId: string): Promise<Project | null>;
390
+ /**
391
+ * Push entries to remote
392
+ */
393
+ pushEntries(entries: MemoryEntry[]): Promise<void>;
394
+ /**
395
+ * Pull entries from remote updated since timestamp
396
+ */
397
+ pullEntries(projectId: string, since: Date): Promise<MemoryEntry[]>;
398
+ /**
399
+ * Get all entries for a project
400
+ */
401
+ listEntries(query: EntryQuery): Promise<MemoryEntry[]>;
402
+ /**
403
+ * Perform semantic search using embeddings
404
+ */
405
+ semanticSearch(projectId: string, queryEmbedding: number[], options?: {
406
+ branch?: string;
407
+ limit?: number;
408
+ minSimilarity?: number;
409
+ }): Promise<MemoryEntry[]>;
410
+ /**
411
+ * Sync branch to remote
412
+ */
413
+ upsertBranch(branch: Branch): Promise<Branch>;
414
+ /**
415
+ * Get branches from remote
416
+ */
417
+ listBranches(projectId: string): Promise<Branch[]>;
418
+ }
419
+
420
+ /**
421
+ * Authentication provider interface
422
+ */
423
+
424
+ interface IAuthProvider {
425
+ /**
426
+ * Initialize authentication provider
427
+ */
428
+ initialize(): Promise<void>;
429
+ /**
430
+ * Login with browser OAuth flow
431
+ */
432
+ login(): Promise<AuthSession>;
433
+ /**
434
+ * Logout and clear session
435
+ */
436
+ logout(): Promise<void>;
437
+ /**
438
+ * Get current session
439
+ */
440
+ getSession(): Promise<AuthSession | null>;
441
+ /**
442
+ * Refresh access token
443
+ */
444
+ refreshSession(refreshToken: string): Promise<AuthSession>;
445
+ /**
446
+ * Get user profile
447
+ */
448
+ getUserProfile(userId: string): Promise<UserProfile | null>;
449
+ /**
450
+ * Check if user is authenticated
451
+ */
452
+ isAuthenticated(): Promise<boolean>;
453
+ }
454
+
455
+ /**
456
+ * Embeddings provider interface
457
+ */
458
+ interface IEmbeddingProvider {
459
+ /**
460
+ * Initialize embeddings provider
461
+ */
462
+ initialize(): Promise<void>;
463
+ /**
464
+ * Generate embedding for a single text
465
+ */
466
+ generateEmbedding(text: string): Promise<number[]>;
467
+ /**
468
+ * Generate embeddings for multiple texts (batch)
469
+ */
470
+ generateEmbeddings(texts: string[]): Promise<number[][]>;
471
+ /**
472
+ * Calculate cosine similarity between two embeddings
473
+ */
474
+ cosineSimilarity(embedding1: number[], embedding2: number[]): number;
475
+ }
476
+
477
+ /**
478
+ * Memory Engine - Core business logic for memory management
479
+ */
480
+
481
+ declare class MemoryEngine {
482
+ private db;
483
+ constructor(db: ILocalDatabase);
484
+ addDecision(projectId: string, input: DecisionInput): Promise<MemoryEntry>;
485
+ listDecisions(projectId: string, branch?: string): Promise<MemoryEntry[]>;
486
+ getDecision(id: string): Promise<MemoryEntry>;
487
+ updateDecision(id: string, updates: Partial<DecisionInput>): Promise<MemoryEntry>;
488
+ addPattern(projectId: string, input: PatternInput): Promise<MemoryEntry>;
489
+ listPatterns(projectId: string, branch?: string): Promise<MemoryEntry[]>;
490
+ getPattern(id: string): Promise<MemoryEntry>;
491
+ updatePattern(id: string, updates: Partial<PatternInput>): Promise<MemoryEntry>;
492
+ setContext(projectId: string, input: ContextInput): Promise<MemoryEntry>;
493
+ getContext(projectId: string): Promise<MemoryEntry | null>;
494
+ addDocument(projectId: string, input: DocumentInput): Promise<MemoryEntry>;
495
+ listDocuments(projectId: string, branch?: string): Promise<MemoryEntry[]>;
496
+ getDocument(id: string): Promise<MemoryEntry>;
497
+ startSession(projectId: string, input: SessionInput): Promise<MemoryEntry>;
498
+ endSession(projectId: string, summary?: string): Promise<MemoryEntry>;
499
+ getActiveSession(projectId: string): Promise<MemoryEntry | null>;
500
+ listSessions(projectId: string, branch?: string): Promise<MemoryEntry[]>;
501
+ deleteEntry(id: string, hard?: boolean): Promise<void>;
502
+ searchEntries(projectId: string, searchTerm: string, options?: {
503
+ branch?: string;
504
+ type?: string;
505
+ }): Promise<MemoryEntry[]>;
506
+ getAllEntries(query: EntryQuery): Promise<MemoryEntry[]>;
507
+ getEntryCount(projectId: string, branch?: string): Promise<number>;
508
+ }
509
+
510
+ /**
511
+ * Relevance Engine - Smart context retrieval scoring
512
+ */
513
+
514
+ /**
515
+ * Calculate relevance score for a memory entry
516
+ *
517
+ * Scoring breakdown (when no embeddings available):
518
+ * - Keyword overlap: 40%
519
+ * - Recency: 25%
520
+ * - Type priority: 20%
521
+ * - File match: 15%
522
+ *
523
+ * Total: 1.0 (100%)
524
+ */
525
+ declare function calculateRelevance(entry: MemoryEntry, options: SuggestOptions): number;
526
+ /**
527
+ * Generate match reasons for transparency
528
+ */
529
+ declare function getMatchReasons(entry: MemoryEntry, options: SuggestOptions): string[];
530
+ /**
531
+ * Rank and filter entries by relevance
532
+ */
533
+ declare function rankEntries(entries: MemoryEntry[], options: SuggestOptions): RankedEntry[];
534
+
535
+ /**
536
+ * Sync Engine - Handles push/pull synchronization
537
+ * Coordinates between local and remote databases
538
+ */
539
+
540
+ interface SyncOptions {
541
+ /**
542
+ * Force push even if conflicts exist (last-write-wins)
543
+ */
544
+ force?: boolean;
545
+ /**
546
+ * Dry run - don't actually sync, just report what would happen
547
+ */
548
+ dryRun?: boolean;
549
+ }
550
+ declare class SyncEngine {
551
+ private local;
552
+ private remote;
553
+ constructor(local: ILocalDatabase, remote: IRemoteDatabase);
554
+ /**
555
+ * Push local changes to remote
556
+ */
557
+ push(projectId: string, options?: SyncOptions): Promise<SyncResult>;
558
+ /**
559
+ * Pull remote changes to local
560
+ */
561
+ pull(projectId: string, options?: SyncOptions): Promise<SyncResult>;
562
+ /**
563
+ * Full bidirectional sync (pull then push)
564
+ */
565
+ sync(projectId: string, options?: SyncOptions): Promise<SyncResult>;
566
+ }
567
+
568
+ /**
569
+ * Context Builder Engine
570
+ * Intelligently assembles project context for AI agents
571
+ */
572
+
573
+ interface ContextMode {
574
+ type: 'task' | 'files' | 'all';
575
+ taskDescription?: string;
576
+ activeFiles?: string[];
577
+ includeTypes?: string[];
578
+ }
579
+ interface ContextBuilderOptions extends ContextMode {
580
+ projectId: string;
581
+ maxTokens?: number;
582
+ minRelevance?: number;
583
+ }
584
+ interface ContextResult {
585
+ context: string;
586
+ entriesIncluded: number;
587
+ tokensUsed: number;
588
+ budget: number;
589
+ }
590
+ /**
591
+ * Build intelligent context payload for AI agents
592
+ */
593
+ declare function buildContextPayload(entries: MemoryEntry[], options: ContextBuilderOptions): ContextResult;
594
+ /**
595
+ * Build a summary of what context is available
596
+ */
597
+ declare function buildContextSummary(entries: MemoryEntry[]): {
598
+ totalEntries: number;
599
+ byType: Record<string, number>;
600
+ recentActivity: string[];
601
+ oldestEntry: Date | null;
602
+ newestEntry: Date | null;
603
+ };
604
+
605
+ /**
606
+ * Token counting utilities using tiktoken
607
+ */
608
+
609
+ /**
610
+ * Count tokens in a text string
611
+ */
612
+ declare function countTokens(text: string): number;
613
+ /**
614
+ * Count tokens in a memory entry
615
+ */
616
+ declare function countEntryTokens(entry: MemoryEntry): number;
617
+ /**
618
+ * Format entry for context (how it will appear in the prompt)
619
+ */
620
+ declare function formatEntryForContext(entry: MemoryEntry): string;
621
+ /**
622
+ * Fit ranked entries within a token budget
623
+ */
624
+ declare function fitToBudget(rankedEntries: RankedEntry[], maxTokens: number): RankedEntry[];
625
+ /**
626
+ * Build formatted context from ranked entries
627
+ */
628
+ declare function buildContext(rankedEntries: RankedEntry[], options?: {
629
+ includeReasons?: boolean;
630
+ includeStats?: boolean;
631
+ }): string;
632
+ /**
633
+ * Free tiktoken resources (call on cleanup)
634
+ */
635
+ declare function cleanup(): void;
636
+
637
+ /**
638
+ * Code Comment Scanner
639
+ * Extracts @decision, @pattern, and @context tags from code comments
640
+ */
641
+
642
+ interface ScanComment {
643
+ tag: 'decision' | 'pattern' | 'context';
644
+ category?: string;
645
+ title: string;
646
+ content: string;
647
+ fields: Record<string, string>;
648
+ file: string;
649
+ line: number;
650
+ hash: string;
651
+ }
652
+ interface ScanResult {
653
+ found: ScanComment[];
654
+ errors: Array<{
655
+ file: string;
656
+ line: number;
657
+ error: string;
658
+ }>;
659
+ }
660
+ /**
661
+ * Parse a single file for tagged comments
662
+ */
663
+ declare function parseFile(content: string, filePath: string): ScanComment[];
664
+ /**
665
+ * Convert scan comment to memory entry type
666
+ */
667
+ declare function scanCommentToEntry(comment: ScanComment, projectId: string): {
668
+ type: MemoryEntryType;
669
+ title: string;
670
+ content: string;
671
+ metadata: Record<string, any>;
672
+ };
673
+
674
+ /**
675
+ * Rules File Parser
676
+ * Parses .contxt/rules.md file into structured memory entries
677
+ */
678
+
679
+ interface RulesEntry {
680
+ type: MemoryEntryType;
681
+ title: string;
682
+ content: string;
683
+ metadata: Record<string, any>;
684
+ }
685
+ interface ParsedRules {
686
+ stack: string[];
687
+ decisions: RulesEntry[];
688
+ patterns: RulesEntry[];
689
+ context: RulesEntry | null;
690
+ documents: RulesEntry[];
691
+ }
692
+ /**
693
+ * Parse rules.md file into structured entries
694
+ */
695
+ declare function parseRulesFile(content: string): ParsedRules;
696
+ /**
697
+ * Generate rules.md file from memory entries
698
+ */
699
+ declare function generateRulesFile(entries: {
700
+ stack: string[];
701
+ decisions: Array<{
702
+ title: string;
703
+ content: string;
704
+ metadata: any;
705
+ }>;
706
+ patterns: Array<{
707
+ title: string;
708
+ content: string;
709
+ metadata: any;
710
+ }>;
711
+ context: Array<{
712
+ content: string;
713
+ }>;
714
+ documents: Array<{
715
+ title: string;
716
+ content: string;
717
+ }>;
718
+ }): string;
719
+
720
+ export { type ActivityItem, AuthError, type AuthSession, type Branch, ConflictError, type ContextBuilderOptions, type ContextInput, type ContextMode, type ContextResult, type CreateEntryInput, type DecisionInput, type DocumentInput, type EntryQuery, type IAuthProvider, type IEmbeddingProvider, type ILocalDatabase, type IRemoteDatabase, MemoryEngine, type MemoryEntry, type MemoryEntryStatus, type MemoryEntryType, NotFoundError, type ParsedRules, type PatternInput, type Project, type ProjectConfig, type RankedEntry, type RulesEntry, type ScanComment, type ScanResult, type SessionInput, type SuggestOptions, SyncEngine, type SyncOptions, type SyncResult, type UsageStats, type UserProfile, type UserTier, ValidationError, buildContext, buildContextPayload, buildContextSummary, calculateRelevance, cleanup, countEntryTokens, countTokens, fitToBudget, formatEntryForContext, generateRulesFile, getMatchReasons, parseFile, parseRulesFile, rankEntries, scanCommentToEntry };