@ulrichc1/sparn 1.2.2 → 1.4.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.
Files changed (42) hide show
  1. package/PRIVACY.md +1 -1
  2. package/README.md +136 -642
  3. package/SECURITY.md +1 -1
  4. package/dist/cli/dashboard.cjs +3977 -0
  5. package/dist/cli/dashboard.cjs.map +1 -0
  6. package/dist/cli/dashboard.d.cts +17 -0
  7. package/dist/cli/dashboard.d.ts +17 -0
  8. package/dist/cli/dashboard.js +3932 -0
  9. package/dist/cli/dashboard.js.map +1 -0
  10. package/dist/cli/index.cjs +3853 -484
  11. package/dist/cli/index.cjs.map +1 -1
  12. package/dist/cli/index.js +3810 -457
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/daemon/index.cjs +411 -99
  15. package/dist/daemon/index.cjs.map +1 -1
  16. package/dist/daemon/index.js +423 -103
  17. package/dist/daemon/index.js.map +1 -1
  18. package/dist/hooks/post-tool-result.cjs +115 -266
  19. package/dist/hooks/post-tool-result.cjs.map +1 -1
  20. package/dist/hooks/post-tool-result.js +115 -266
  21. package/dist/hooks/post-tool-result.js.map +1 -1
  22. package/dist/hooks/pre-prompt.cjs +197 -268
  23. package/dist/hooks/pre-prompt.cjs.map +1 -1
  24. package/dist/hooks/pre-prompt.js +182 -268
  25. package/dist/hooks/pre-prompt.js.map +1 -1
  26. package/dist/hooks/stop-docs-refresh.cjs +123 -0
  27. package/dist/hooks/stop-docs-refresh.cjs.map +1 -0
  28. package/dist/hooks/stop-docs-refresh.d.cts +1 -0
  29. package/dist/hooks/stop-docs-refresh.d.ts +1 -0
  30. package/dist/hooks/stop-docs-refresh.js +126 -0
  31. package/dist/hooks/stop-docs-refresh.js.map +1 -0
  32. package/dist/index.cjs +1754 -337
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +539 -40
  35. package/dist/index.d.ts +539 -40
  36. package/dist/index.js +1737 -329
  37. package/dist/index.js.map +1 -1
  38. package/dist/mcp/index.cjs +304 -71
  39. package/dist/mcp/index.cjs.map +1 -1
  40. package/dist/mcp/index.js +308 -71
  41. package/dist/mcp/index.js.map +1 -1
  42. package/package.json +10 -3
package/dist/index.d.ts CHANGED
@@ -2,15 +2,15 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
 
3
3
  /**
4
4
  * Core memory entry types for Sparn's context optimization engine.
5
- * Maps to neuroscience-inspired memory model with decay and state transitions.
5
+ * Memory model with time-based decay and state transitions.
6
6
  */
7
7
  /**
8
8
  * Confidence state for memory entries.
9
- * Based on multi-state synapse model from neuroscience.
9
+ * Entries are classified as silent, ready, or active based on score.
10
10
  */
11
11
  type ConfidenceState = 'silent' | 'ready' | 'active';
12
12
  /**
13
- * Represents a single context memory entry with neuroscience-inspired metadata.
13
+ * Represents a single context memory entry with optimization metadata.
14
14
  *
15
15
  * State transitions:
16
16
  * - score ≤ 0.3 → silent (not included in context)
@@ -66,8 +66,8 @@ interface StateDistribution {
66
66
 
67
67
  /**
68
68
  * KV Memory Store Module
69
- * Implements hippocampal key-value storage with dual index/value tables.
70
- * Maps to: Hippocampal Key-Value — the hippocampus separates what to store from how to retrieve it.
69
+ * Key-value storage with dual index/value tables.
70
+ * Separates what to store (content) from how to retrieve it (index with scores and state).
71
71
  */
72
72
 
73
73
  /**
@@ -84,6 +84,13 @@ interface OptimizationStats {
84
84
  /**
85
85
  * KV Memory interface.
86
86
  */
87
+ /**
88
+ * FTS5 search result with rank score.
89
+ */
90
+ interface FTSResult {
91
+ entry: MemoryEntry;
92
+ rank: number;
93
+ }
87
94
  interface KVMemory {
88
95
  /** Store a memory entry */
89
96
  put(entry: MemoryEntry): Promise<void>;
@@ -105,6 +112,8 @@ interface KVMemory {
105
112
  getOptimizationStats(): Promise<OptimizationStats[]>;
106
113
  /** Clear all optimization statistics */
107
114
  clearOptimizationStats(): Promise<void>;
115
+ /** Full-text search using FTS5 */
116
+ searchFTS(query: string, limit?: number): Promise<FTSResult[]>;
108
117
  }
109
118
  /**
110
119
  * Create KV Memory store with SQLite backend.
@@ -202,6 +211,10 @@ interface DecayConfig {
202
211
  defaultTTL: number;
203
212
  /** Decay threshold for pruning (0.0-1.0, default: 0.95) */
204
213
  decayThreshold: number;
214
+ /** Minutes within which entries get a recency boost (default: 30) */
215
+ recencyBoostMinutes?: number;
216
+ /** Multiplier for recency boost at age 0 (default: 1.3) */
217
+ recencyBoostMultiplier?: number;
205
218
  }
206
219
  /**
207
220
  * Confidence state threshold configuration.
@@ -245,6 +258,8 @@ interface RealtimeConfig {
245
258
  windowSize: number;
246
259
  /** Consolidation interval in hours, or null for disabled (default: null) */
247
260
  consolidationInterval: number | null;
261
+ /** Use precise GPT tokenizer for token counting (default: false) */
262
+ preciseTokenCounting?: boolean;
248
263
  }
249
264
  /**
250
265
  * Complete Sparn configuration.
@@ -259,6 +274,8 @@ interface SparnConfig {
259
274
  autoConsolidate: number | null;
260
275
  /** Real-time optimization settings */
261
276
  realtime: RealtimeConfig;
277
+ /** Additional BTSP pattern regex strings (default: []) */
278
+ btspPatterns?: string[];
262
279
  }
263
280
  /**
264
281
  * Default configuration values.
@@ -283,7 +300,7 @@ declare function createClaudeCodeAdapter(memory: KVMemory, config: SparnConfig):
283
300
  /**
284
301
  * Generic Adapter - Agent-agnostic optimization pipeline
285
302
  *
286
- * Orchestrates all 6 neuroscience modules to optimize context memory.
303
+ * Orchestrates all optimization modules to process context memory.
287
304
  */
288
305
 
289
306
  /**
@@ -297,7 +314,6 @@ declare function createGenericAdapter(memory: KVMemory, config: SparnConfig): Ag
297
314
  /**
298
315
  * BTSP Embedder - Implements behavioral timescale synaptic plasticity
299
316
  *
300
- * Neuroscience: One-shot learning from critical events (errors, conflicts).
301
317
  * Application: Detect high-importance patterns and mark for permanent retention.
302
318
  */
303
319
 
@@ -321,11 +337,15 @@ interface BTSPEmbedder {
321
337
  * Create a BTSP embedder instance
322
338
  * @returns BTSPEmbedder instance
323
339
  */
324
- declare function createBTSPEmbedder(): BTSPEmbedder;
340
+ interface BTSPEmbedderConfig {
341
+ /** Additional regex pattern strings to detect BTSP events */
342
+ customPatterns?: string[];
343
+ }
344
+ declare function createBTSPEmbedder(config?: BTSPEmbedderConfig): BTSPEmbedder;
325
345
 
326
346
  /**
327
347
  * Sparse pruner types.
328
- * Implements sparse coding principle from neuroscience.
348
+ * Relevance filtering: keep only the most important entries.
329
349
  */
330
350
 
331
351
  /**
@@ -342,13 +362,64 @@ interface PruneResult {
342
362
  prunedTokens: number;
343
363
  }
344
364
 
365
+ /**
366
+ * Shared TF-IDF utilities
367
+ *
368
+ * Centralized text tokenization and TF-IDF scoring used by
369
+ * sparse-pruner, budget-pruner, incremental-optimizer, and sleep-compressor.
370
+ */
371
+
372
+ /**
373
+ * Tokenize text into lowercase words
374
+ */
375
+ declare function tokenize(text: string): string[];
376
+ /**
377
+ * Calculate term frequency with sqrt capping
378
+ */
379
+ declare function calculateTF(term: string, tokens: string[]): number;
380
+ /**
381
+ * Calculate inverse document frequency across entries
382
+ */
383
+ declare function calculateIDF(term: string, allEntries: MemoryEntry[]): number;
384
+ /**
385
+ * Calculate TF-IDF score for an entry relative to a corpus
386
+ */
387
+ declare function calculateTFIDF(entry: MemoryEntry, allEntries: MemoryEntry[]): number;
388
+ /**
389
+ * Pre-computed TF-IDF index for O(1) document frequency lookups.
390
+ * Eliminates O(n^2) bottleneck when scoring multiple entries.
391
+ */
392
+ interface TFIDFIndex {
393
+ /** Map of term -> number of documents containing the term */
394
+ documentFrequency: Map<string, number>;
395
+ /** Total number of documents in the corpus */
396
+ totalDocuments: number;
397
+ }
398
+ /**
399
+ * Build a pre-computed TF-IDF index from a set of entries.
400
+ * Iterates all entries once to build document frequency map.
401
+ *
402
+ * @param entries - Corpus of memory entries
403
+ * @returns Pre-computed index for use with scoreTFIDF()
404
+ */
405
+ declare function createTFIDFIndex(entries: MemoryEntry[]): TFIDFIndex;
406
+ /**
407
+ * Score an entry using a pre-computed TF-IDF index.
408
+ * Uses pre-computed document frequencies instead of re-tokenizing all entries.
409
+ *
410
+ * @param entry - Entry to score
411
+ * @param index - Pre-computed TF-IDF index from createTFIDFIndex()
412
+ * @returns TF-IDF score (higher = more distinctive)
413
+ */
414
+ declare function scoreTFIDF(entry: MemoryEntry, index: TFIDFIndex): number;
415
+
345
416
  /**
346
417
  * Budget-Aware Pruner - Token budget optimization
347
418
  *
348
419
  * Unlike SparsePruner which keeps top N% entries, BudgetPruner fits entries
349
420
  * within a target token budget using priority scoring that combines:
350
421
  * - TF-IDF relevance
351
- * - Engram decay
422
+ * - Time-based decay
352
423
  * - Confidence state multipliers
353
424
  * - BTSP bypass (always included)
354
425
  *
@@ -383,9 +454,10 @@ interface BudgetPruner {
383
454
  * Calculate priority score for an entry
384
455
  * @param entry - Entry to score
385
456
  * @param allEntries - All entries for TF-IDF calculation
457
+ * @param index - Optional pre-computed TF-IDF index
386
458
  * @returns Priority score (higher = more important)
387
459
  */
388
- priorityScore(entry: MemoryEntry, allEntries: MemoryEntry[]): number;
460
+ priorityScore(entry: MemoryEntry, allEntries: MemoryEntry[], index?: TFIDFIndex): number;
389
461
  }
390
462
  /**
391
463
  * Create a budget-aware pruner instance
@@ -409,10 +481,10 @@ declare function createBudgetPrunerFromConfig(realtimeConfig: RealtimeConfig, de
409
481
  }): BudgetPruner;
410
482
 
411
483
  /**
412
- * Confidence States - Implements multi-state synapses
484
+ * Confidence States - Entry classification by score
413
485
  *
414
- * Neuroscience: Synapses exist in three states: silent, ready (potentiated), active.
415
- * Application: Classify memory entries by score into silent/ready/active states.
486
+ * Entries exist in three states: silent, ready, active.
487
+ * Classifies memory entries by score into silent/ready/active states.
416
488
  */
417
489
 
418
490
  interface ConfidenceStatesConfig {
@@ -524,6 +596,17 @@ interface IncrementalOptimizer {
524
596
  updateCount: number;
525
597
  lastFullOptimization: number;
526
598
  };
599
+ /**
600
+ * Serialize optimizer state to JSON string for persistence
601
+ * @returns JSON string of the state
602
+ */
603
+ serializeState(): string;
604
+ /**
605
+ * Deserialize optimizer state from JSON string
606
+ * @param json - JSON string to restore from
607
+ * @returns true if successful, false on error
608
+ */
609
+ deserializeState(json: string): boolean;
527
610
  }
528
611
  /**
529
612
  * Create an incremental optimizer instance
@@ -566,6 +649,17 @@ interface ContextPipelineStats {
566
649
  };
567
650
  }
568
651
  interface ContextPipeline {
652
+ /**
653
+ * Serialize optimizer state for persistence
654
+ * @returns JSON string of the optimizer state
655
+ */
656
+ serializeOptimizerState(): string;
657
+ /**
658
+ * Restore optimizer state from persistence
659
+ * @param json - JSON string to restore from
660
+ * @returns true if successful
661
+ */
662
+ deserializeOptimizerState(json: string): boolean;
569
663
  /**
570
664
  * Ingest new content into the pipeline
571
665
  * @param content - Raw content string
@@ -601,10 +695,153 @@ interface ContextPipeline {
601
695
  declare function createContextPipeline(config: ContextPipelineConfig): ContextPipeline;
602
696
 
603
697
  /**
604
- * Engram Scorer - Implements engram theory (memory decay)
698
+ * Debt Tracker - Technical debt management
605
699
  *
606
- * Neuroscience: Memories fade over time without reinforcement.
607
- * Application: Apply exponential decay formula to memory scores based on age and access count.
700
+ * Tracks technical debt with mandatory repayment dates,
701
+ * severity levels, and token cost estimates.
702
+ * Stored in SQLite alongside the main memory.db.
703
+ */
704
+ type DebtSeverity = 'P0' | 'P1' | 'P2';
705
+ type DebtStatus = 'open' | 'in_progress' | 'resolved';
706
+ interface TechDebt {
707
+ id: string;
708
+ description: string;
709
+ created_at: number;
710
+ repayment_date: number;
711
+ severity: DebtSeverity;
712
+ token_cost: number;
713
+ files_affected: string[];
714
+ status: DebtStatus;
715
+ resolution_tokens?: number;
716
+ resolved_at?: number;
717
+ }
718
+ interface DebtStats {
719
+ total: number;
720
+ open: number;
721
+ in_progress: number;
722
+ resolved: number;
723
+ overdue: number;
724
+ totalTokenCost: number;
725
+ resolvedTokenCost: number;
726
+ repaymentRate: number;
727
+ }
728
+ interface DebtTracker {
729
+ /** Add a new tech debt item */
730
+ add(debt: Omit<TechDebt, 'id' | 'created_at' | 'status'>): Promise<TechDebt>;
731
+ /** List all debts, optionally filtered */
732
+ list(filter?: {
733
+ status?: DebtStatus;
734
+ severity?: DebtSeverity;
735
+ overdue?: boolean;
736
+ }): Promise<TechDebt[]>;
737
+ /** Get a specific debt by ID */
738
+ get(id: string): Promise<TechDebt | null>;
739
+ /** Update debt status */
740
+ resolve(id: string, resolutionTokens?: number): Promise<void>;
741
+ /** Update debt status to in_progress */
742
+ start(id: string): Promise<void>;
743
+ /** Delete a debt item */
744
+ remove(id: string): Promise<void>;
745
+ /** Get debt statistics */
746
+ stats(): Promise<DebtStats>;
747
+ /** Get P0 debts for CLAUDE.md inclusion */
748
+ getCritical(): Promise<TechDebt[]>;
749
+ /** Close database */
750
+ close(): Promise<void>;
751
+ }
752
+ /**
753
+ * Create a debt tracker instance
754
+ */
755
+ declare function createDebtTracker(dbPath: string): DebtTracker;
756
+
757
+ /**
758
+ * Dependency Graph Analyzer
759
+ *
760
+ * Analyzes TypeScript/JavaScript import/export relationships to build
761
+ * a dependency graph. Uses regex-based parsing (no AST dependency needed)
762
+ * for lightweight, fast analysis.
763
+ *
764
+ * Integrates with engram scoring to identify hot paths and prioritize
765
+ * files for context loading.
766
+ */
767
+ interface DependencyNode {
768
+ filePath: string;
769
+ exports: string[];
770
+ imports: DependencyEdge[];
771
+ callers: string[];
772
+ engram_score: number;
773
+ lastModified: number;
774
+ tokenEstimate: number;
775
+ }
776
+ interface DependencyEdge {
777
+ source: string;
778
+ target: string;
779
+ symbols: string[];
780
+ }
781
+ interface GraphAnalysis {
782
+ entryPoints: string[];
783
+ hotPaths: string[];
784
+ orphans: string[];
785
+ totalTokens: number;
786
+ optimizedTokens: number;
787
+ }
788
+ interface DependencyGraphConfig {
789
+ /** Project root directory */
790
+ projectRoot: string;
791
+ /** Maximum depth for traversal (default: Infinity) */
792
+ maxDepth?: number;
793
+ /** File extensions to analyze (default: ['.ts', '.tsx', '.js', '.jsx']) */
794
+ extensions?: string[];
795
+ /** Directories to ignore (default: ['node_modules', 'dist', '.git', '.sparn']) */
796
+ ignoreDirs?: string[];
797
+ }
798
+ interface DependencyGraph {
799
+ /** Build the full dependency graph */
800
+ build(): Promise<Map<string, DependencyNode>>;
801
+ /** Get graph analysis with entry points, hot paths, orphans */
802
+ analyze(): Promise<GraphAnalysis>;
803
+ /** Get subgraph focused on a specific module/pattern */
804
+ focus(pattern: string): Promise<Map<string, DependencyNode>>;
805
+ /** Get files needed starting from an entry point, up to maxDepth */
806
+ getFilesFromEntry(entryPoint: string, maxDepth?: number): Promise<string[]>;
807
+ /** Get the full node map (after build) */
808
+ getNodes(): Map<string, DependencyNode>;
809
+ }
810
+ /**
811
+ * Create a dependency graph analyzer
812
+ */
813
+ declare function createDependencyGraph(config: DependencyGraphConfig): DependencyGraph;
814
+
815
+ /**
816
+ * Docs Generator - Auto-generate CLAUDE.md
817
+ *
818
+ * Scans repo structure, uses dependency graph data, and generates
819
+ * a compact CLAUDE.md optimized for AI agent context loading.
820
+ */
821
+
822
+ interface DocsGeneratorConfig {
823
+ projectRoot: string;
824
+ /** Include dependency graph summary */
825
+ includeGraph?: boolean;
826
+ /** Include debt tracker info */
827
+ includeDebt?: boolean;
828
+ /** Custom sections to append */
829
+ customSections?: string[];
830
+ }
831
+ interface DocsGenerator {
832
+ /** Generate CLAUDE.md content */
833
+ generate(graph?: DependencyGraph): Promise<string>;
834
+ }
835
+ /**
836
+ * Create a docs generator
837
+ */
838
+ declare function createDocsGenerator(config: DocsGeneratorConfig): DocsGenerator;
839
+
840
+ /**
841
+ * Engram Scorer - Implements time-based memory decay
842
+ *
843
+ * Older entries fade over time unless reinforced by access.
844
+ * Applies exponential decay formula to memory scores based on age and access count.
608
845
  *
609
846
  * Formula: decay = 1 - e^(-age/TTL)
610
847
  * Score adjustment: score_new = score_old * (1 - decay) + (accessCount bonus)
@@ -643,11 +880,139 @@ interface EngramScorer {
643
880
  * @param config - Scorer configuration
644
881
  * @returns EngramScorer instance
645
882
  */
646
- declare function createEngramScorer(config: EngramScorerConfig): EngramScorer;
883
+ declare function createEngramScorer(config: EngramScorerConfig & {
884
+ recencyBoostMinutes?: number;
885
+ recencyBoostMultiplier?: number;
886
+ }): EngramScorer;
887
+
888
+ /**
889
+ * Metrics and Telemetry System
890
+ *
891
+ * Tracks performance metrics and optimization statistics:
892
+ * - Optimization duration and throughput
893
+ * - Token savings and reduction rates
894
+ * - Memory usage and cache hit rates
895
+ * - Daemon uptime and session counts
896
+ */
897
+ interface OptimizationMetric {
898
+ timestamp: number;
899
+ duration: number;
900
+ tokensBefore: number;
901
+ tokensAfter: number;
902
+ entriesProcessed: number;
903
+ entriesKept: number;
904
+ cacheHitRate: number;
905
+ memoryUsage: number;
906
+ }
907
+ interface DaemonMetric {
908
+ startTime: number;
909
+ sessionsWatched: number;
910
+ totalOptimizations: number;
911
+ totalTokensSaved: number;
912
+ averageLatency: number;
913
+ memoryUsage: number;
914
+ }
915
+ interface MetricsSnapshot {
916
+ timestamp: number;
917
+ optimization: {
918
+ totalRuns: number;
919
+ totalDuration: number;
920
+ totalTokensSaved: number;
921
+ averageReduction: number;
922
+ p50Latency: number;
923
+ p95Latency: number;
924
+ p99Latency: number;
925
+ };
926
+ cache: {
927
+ hitRate: number;
928
+ totalHits: number;
929
+ totalMisses: number;
930
+ size: number;
931
+ };
932
+ daemon: {
933
+ uptime: number;
934
+ sessionsWatched: number;
935
+ memoryUsage: number;
936
+ };
937
+ }
938
+ interface MetricsCollector {
939
+ /**
940
+ * Record an optimization metric
941
+ */
942
+ recordOptimization(metric: OptimizationMetric): void;
943
+ /**
944
+ * Update daemon metrics
945
+ */
946
+ updateDaemon(metric: Partial<DaemonMetric>): void;
947
+ /**
948
+ * Get current metrics snapshot
949
+ */
950
+ getSnapshot(): MetricsSnapshot;
951
+ /**
952
+ * Export metrics as JSON
953
+ */
954
+ export(): string;
955
+ /**
956
+ * Reset all metrics
957
+ */
958
+ reset(): void;
959
+ }
960
+ /**
961
+ * Create a metrics collector instance
962
+ */
963
+ declare function createMetricsCollector(): MetricsCollector;
964
+ /**
965
+ * Get or create the global metrics collector
966
+ */
967
+ declare function getMetrics(): MetricsCollector;
968
+
969
+ /**
970
+ * Search Engine - Hybrid FTS5 + ripgrep search
971
+ *
972
+ * Deterministic search without embeddings:
973
+ * 1. FTS5 for full-text search with stemming (porter tokenizer)
974
+ * 2. ripgrep fallback for exact pattern/regex matching
975
+ * 3. Fusion scoring with dedup across both sources
976
+ */
977
+ interface SearchResult {
978
+ filePath: string;
979
+ lineNumber: number;
980
+ content: string;
981
+ score: number;
982
+ context: string[];
983
+ engram_score: number;
984
+ }
985
+ interface SearchOpts {
986
+ maxResults?: number;
987
+ fileGlob?: string;
988
+ useRipgrep?: boolean;
989
+ includeContext?: boolean;
990
+ }
991
+ interface IndexStats {
992
+ filesIndexed: number;
993
+ totalLines: number;
994
+ duration: number;
995
+ }
996
+ interface SearchEngine {
997
+ /** Initialize the search database */
998
+ init(projectRoot: string): Promise<void>;
999
+ /** Index files into FTS5 */
1000
+ index(paths?: string[]): Promise<IndexStats>;
1001
+ /** Search using hybrid FTS5 + ripgrep */
1002
+ search(query: string, opts?: SearchOpts): Promise<SearchResult[]>;
1003
+ /** Re-index all files */
1004
+ refresh(): Promise<IndexStats>;
1005
+ /** Close the database */
1006
+ close(): Promise<void>;
1007
+ }
1008
+ /**
1009
+ * Create a search engine instance
1010
+ */
1011
+ declare function createSearchEngine(dbPath: string): SearchEngine;
647
1012
 
648
1013
  /**
649
1014
  * Sleep compressor (consolidation) types.
650
- * Implements sleep replay principle from neuroscience.
1015
+ * Periodic consolidation removes decayed entries and merges duplicates.
651
1016
  */
652
1017
 
653
1018
  /**
@@ -682,11 +1047,10 @@ interface DuplicateGroup {
682
1047
  }
683
1048
 
684
1049
  /**
685
- * Sleep Compressor - Implements sleep replay principle
1050
+ * Sleep Compressor - Periodic consolidation
686
1051
  *
687
- * Neuroscience: During sleep, the brain consolidates memories by replaying important ones
688
- * and discarding irrelevant information.
689
- * Application: Periodic consolidation removes decayed entries and merges duplicates.
1052
+ * Removes decayed entries and merges duplicates to keep the memory store lean.
1053
+ * Runs on demand or on a scheduled interval via the daemon.
690
1054
  */
691
1055
 
692
1056
  interface SleepCompressor {
@@ -716,10 +1080,10 @@ interface SleepCompressor {
716
1080
  declare function createSleepCompressor(): SleepCompressor;
717
1081
 
718
1082
  /**
719
- * Sparse Pruner - Implements sparse coding principle
1083
+ * Sparse Pruner - Relevance filtering
720
1084
  *
721
- * Neuroscience: Only 2-5% of neurons fire at any given time.
722
- * Application: Keep only top 5% most relevant context entries by TF-IDF score.
1085
+ * Keeps only the top 2-5% most relevant context entries by TF-IDF score.
1086
+ * Low-scoring entries are pruned to reduce token usage.
723
1087
  */
724
1088
 
725
1089
  interface SparsePrunerConfig {
@@ -748,6 +1112,91 @@ interface SparsePruner {
748
1112
  */
749
1113
  declare function createSparsePruner(config: SparsePrunerConfig): SparsePruner;
750
1114
 
1115
+ /**
1116
+ * Workflow Planner - Plan/Exec/Verify separation
1117
+ *
1118
+ * Separates AI agent workflows into discrete phases:
1119
+ * - Planning: Identify files needed, search queries, and steps
1120
+ * - Execution: Apply constraints (max reads, token budget)
1121
+ * - Verification: Check step completion and run tests
1122
+ *
1123
+ * Reduces token waste by preventing re-planning loops.
1124
+ */
1125
+ interface SparnPlan {
1126
+ id: string;
1127
+ created_at: number;
1128
+ task_description: string;
1129
+ steps: PlanStep[];
1130
+ token_budget: {
1131
+ planning: number;
1132
+ estimated_execution: number;
1133
+ max_file_reads: number;
1134
+ };
1135
+ files_needed: string[];
1136
+ search_queries: string[];
1137
+ status: 'draft' | 'ready' | 'executing' | 'completed' | 'failed';
1138
+ }
1139
+ interface PlanStep {
1140
+ order: number;
1141
+ action: 'read' | 'write' | 'search' | 'test' | 'verify';
1142
+ target: string;
1143
+ description: string;
1144
+ dependencies: number[];
1145
+ estimated_tokens: number;
1146
+ status: 'pending' | 'in_progress' | 'completed' | 'skipped' | 'failed';
1147
+ result?: string;
1148
+ }
1149
+ interface PlanExecConstraints {
1150
+ maxFileReads: number;
1151
+ tokenBudget: number;
1152
+ allowReplan: boolean;
1153
+ }
1154
+ interface PlanVerifyResult {
1155
+ planId: string;
1156
+ stepsCompleted: number;
1157
+ stepsFailed: number;
1158
+ stepsSkipped: number;
1159
+ totalSteps: number;
1160
+ tokensBudgeted: number;
1161
+ tokensUsed: number;
1162
+ success: boolean;
1163
+ details: Array<{
1164
+ step: number;
1165
+ action: string;
1166
+ target: string;
1167
+ status: string;
1168
+ }>;
1169
+ }
1170
+ interface WorkflowPlanner {
1171
+ /** Create a new plan */
1172
+ createPlan(taskDescription: string, filesNeeded: string[], searchQueries: string[], steps: Omit<PlanStep, 'status' | 'result'>[], tokenBudget?: {
1173
+ planning: number;
1174
+ estimated_execution: number;
1175
+ max_file_reads: number;
1176
+ }): Promise<SparnPlan>;
1177
+ /** Load an existing plan */
1178
+ loadPlan(planId: string): Promise<SparnPlan | null>;
1179
+ /** List all plans */
1180
+ listPlans(): Promise<Array<{
1181
+ id: string;
1182
+ task: string;
1183
+ status: string;
1184
+ created: number;
1185
+ }>>;
1186
+ /** Update a plan step status */
1187
+ updateStep(planId: string, stepOrder: number, status: PlanStep['status'], result?: string): Promise<void>;
1188
+ /** Start execution of a plan */
1189
+ startExec(planId: string): Promise<PlanExecConstraints>;
1190
+ /** Verify plan completion */
1191
+ verify(planId: string): Promise<PlanVerifyResult>;
1192
+ /** Get the plans directory */
1193
+ getPlansDir(): string;
1194
+ }
1195
+ /**
1196
+ * Create a workflow planner
1197
+ */
1198
+ declare function createWorkflowPlanner(projectRoot: string): WorkflowPlanner;
1199
+
751
1200
  /**
752
1201
  * Daemon Process Manager - Background process lifecycle management
753
1202
  *
@@ -913,13 +1362,13 @@ declare function createSessionWatcher(config: SessionWatcherConfig): SessionWatc
913
1362
  /**
914
1363
  * Sparn MCP Server - Model Context Protocol server implementation
915
1364
  *
916
- * Exposes Sparn's neuroscience-inspired context optimization as MCP tools,
917
- * enabling integration with Claude Desktop, VS Code, and other MCP clients.
1365
+ * Exposes Sparn context optimization as MCP tools, enabling integration
1366
+ * with Claude Desktop, VS Code, and other MCP clients.
918
1367
  *
919
1368
  * Tools:
920
1369
  * - sparn_optimize: Optimize context with configurable options
921
1370
  * - sparn_stats: Get optimization statistics
922
- * - sparn_consolidate: Run memory consolidation (sleep replay)
1371
+ * - sparn_consolidate: Run memory consolidation
923
1372
  */
924
1373
 
925
1374
  /**
@@ -967,6 +1416,47 @@ declare function parseClaudeCodeContext(context: string): MemoryEntry[];
967
1416
  * @returns Memory entry
968
1417
  */
969
1418
  declare function createEntry(content: string, type: BlockType, baseTime: number): MemoryEntry;
1419
+ /**
1420
+ * Parsed JSONL message structure
1421
+ */
1422
+ interface JSONLMessage {
1423
+ role?: string;
1424
+ content?: string | Array<{
1425
+ type: string;
1426
+ text?: string;
1427
+ name?: string;
1428
+ input?: unknown;
1429
+ content?: string | Array<{
1430
+ type: string;
1431
+ text?: string;
1432
+ }>;
1433
+ }>;
1434
+ type?: string;
1435
+ tool_use?: {
1436
+ name: string;
1437
+ input: unknown;
1438
+ };
1439
+ tool_result?: {
1440
+ content: string | Array<{
1441
+ type: string;
1442
+ text?: string;
1443
+ }>;
1444
+ };
1445
+ }
1446
+ /**
1447
+ * Parse a single JSONL line into a message
1448
+ * @param line - Single JSON line
1449
+ * @returns Parsed message or null on failure
1450
+ */
1451
+ declare function parseJSONLLine(line: string): JSONLMessage | null;
1452
+ /**
1453
+ * Parse JSONL context into memory entries
1454
+ * Handles Claude Code transcript format (one JSON object per line)
1455
+ *
1456
+ * @param context - Raw JSONL context string
1457
+ * @returns Array of memory entries, or empty array if parsing fails
1458
+ */
1459
+ declare function parseJSONLContext(context: string): MemoryEntry[];
970
1460
  /**
971
1461
  * Parse generic context (fallback for non-Claude-Code agents)
972
1462
  * Splits on double newlines, treats as paragraphs
@@ -1017,23 +1507,32 @@ declare function createLogger(verbose?: boolean): Logger;
1017
1507
 
1018
1508
  /**
1019
1509
  * Token estimation utilities.
1020
- * Uses whitespace heuristic (~90% accuracy vs GPT tokenizer).
1510
+ * Supports both heuristic (~90% accuracy) and precise (GPT tokenizer, ~95%+ accuracy) modes.
1021
1511
  */
1022
1512
  /**
1023
- * Estimate token count for text using heuristic.
1513
+ * Enable or disable precise token counting using GPT tokenizer.
1514
+ * When enabled, estimateTokens() uses gpt-tokenizer for ~95%+ accuracy on code.
1515
+ * When disabled (default), uses fast whitespace heuristic.
1024
1516
  *
1025
- * Approximation: 1 token 4 chars or 0.75 words
1026
- * Provides ~90% accuracy compared to GPT tokenizer, sufficient for optimization heuristics.
1517
+ * @param enabled - Whether to use precise counting
1518
+ */
1519
+ declare function setPreciseTokenCounting(enabled: boolean): void;
1520
+ /**
1521
+ * Count tokens precisely using GPT tokenizer.
1027
1522
  *
1028
1523
  * @param text - Text to count
1029
- * @returns Estimated token count
1524
+ * @returns Exact token count
1525
+ */
1526
+ declare function countTokensPrecise(text: string): number;
1527
+ /**
1528
+ * Estimate token count for text.
1030
1529
  *
1031
- * @example
1032
- * ```typescript
1033
- * const tokens = estimateTokens('Hello world');
1034
- * console.log(tokens); // ~2
1035
- * ```
1530
+ * In default (heuristic) mode: ~90% accuracy, very fast.
1531
+ * In precise mode: ~95%+ accuracy using GPT tokenizer.
1532
+ *
1533
+ * @param text - Text to count
1534
+ * @returns Estimated token count
1036
1535
  */
1037
1536
  declare function estimateTokens(text: string): number;
1038
1537
 
1039
- export { type AgentAdapter, type AgentType, type BTSPEmbedder, type BlockType, type BudgetPruner, type BudgetPrunerConfig, type ConfidenceState, type ConfidenceStates, type ConfidenceStatesConfig, type ConsolidateResult, type ContextPipeline, type ContextPipelineConfig, type ContextPipelineStats, DEFAULT_CONFIG, type DaemonCommand, type DaemonStartResult, type DaemonStatusResult, type DaemonStopResult, type DecayConfig, type DuplicateGroup, type EngramScorer, type EngramScorerConfig, type FilePosition, type FileTracker, type IncrementalOptimizer, type IncrementalOptimizerConfig, type IncrementalOptimizerState, type KVMemory, type LogLevel, type Logger, type MemoryEntry, type MemoryQueryFilters, type OptimizationResult, type OptimizeOptions, type PruneResult, type PruningConfig, type RealtimeConfig, type SessionStats, type SessionWatcher, type SessionWatcherConfig, type SleepCompressor, type SparnConfig, type SparnMcpServerOptions, type SparsePruner, type SparsePrunerConfig, type StateDistribution, type StatesConfig, type UIConfig, createBTSPEmbedder, createBudgetPruner, createBudgetPrunerFromConfig, createClaudeCodeAdapter, createConfidenceStates, createContextPipeline, createDaemonCommand, createEngramScorer, createEntry, createFileTracker, createGenericAdapter, createIncrementalOptimizer, createKVMemory, createLogger, createSessionWatcher, createSleepCompressor, createSparnMcpServer, createSparsePruner, estimateTokens, hashContent, parseClaudeCodeContext, parseGenericContext };
1538
+ export { type AgentAdapter, type AgentType, type BTSPEmbedder, type BTSPEmbedderConfig, type BlockType, type BudgetPruner, type BudgetPrunerConfig, type ConfidenceState, type ConfidenceStates, type ConfidenceStatesConfig, type ConsolidateResult, type ContextPipeline, type ContextPipelineConfig, type ContextPipelineStats, DEFAULT_CONFIG, type DaemonCommand, type DaemonStartResult, type DaemonStatusResult, type DaemonStopResult, type DebtSeverity, type DebtStats, type DebtStatus, type DebtTracker, type DecayConfig, type DependencyEdge, type DependencyGraph, type DependencyGraphConfig, type DependencyNode, type DocsGenerator, type DocsGeneratorConfig, type DuplicateGroup, type EngramScorer, type EngramScorerConfig, type FTSResult, type FilePosition, type FileTracker, type GraphAnalysis, type IncrementalOptimizer, type IncrementalOptimizerConfig, type IncrementalOptimizerState, type IndexStats, type JSONLMessage, type KVMemory, type LogLevel, type Logger, type MemoryEntry, type MemoryQueryFilters, type MetricsCollector, type MetricsSnapshot, type OptimizationResult, type OptimizeOptions, type PlanExecConstraints, type PlanStep, type PlanVerifyResult, type PruneResult, type PruningConfig, type RealtimeConfig, type SearchEngine, type SearchOpts, type SearchResult, type SessionStats, type SessionWatcher, type SessionWatcherConfig, type SleepCompressor, type SparnConfig, type SparnMcpServerOptions, type SparnPlan, type SparsePruner, type SparsePrunerConfig, type StateDistribution, type StatesConfig, type TFIDFIndex, type TechDebt, type UIConfig, type WorkflowPlanner, calculateIDF, calculateTF, calculateTFIDF, countTokensPrecise, createBTSPEmbedder, createBudgetPruner, createBudgetPrunerFromConfig, createClaudeCodeAdapter, createConfidenceStates, createContextPipeline, createDaemonCommand, createDebtTracker, createDependencyGraph, createDocsGenerator, createEngramScorer, createEntry, createFileTracker, createGenericAdapter, createIncrementalOptimizer, createKVMemory, createLogger, createMetricsCollector, createSearchEngine, createSessionWatcher, createSleepCompressor, createSparnMcpServer, createSparsePruner, createTFIDFIndex, createWorkflowPlanner, estimateTokens, getMetrics, hashContent, parseClaudeCodeContext, parseGenericContext, parseJSONLContext, parseJSONLLine, scoreTFIDF, setPreciseTokenCounting, tokenize };