@danielsimonjr/memory-mcp 0.7.2 → 0.47.1

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 (70) hide show
  1. package/dist/__tests__/edge-cases/edge-cases.test.js +406 -0
  2. package/dist/__tests__/file-path.test.js +5 -5
  3. package/dist/__tests__/integration/workflows.test.js +449 -0
  4. package/dist/__tests__/knowledge-graph.test.js +8 -3
  5. package/dist/__tests__/performance/benchmarks.test.js +413 -0
  6. package/dist/__tests__/unit/core/EntityManager.test.js +334 -0
  7. package/dist/__tests__/unit/core/GraphStorage.test.js +205 -0
  8. package/dist/__tests__/unit/core/RelationManager.test.js +274 -0
  9. package/dist/__tests__/unit/features/CompressionManager.test.js +350 -0
  10. package/dist/__tests__/unit/search/BasicSearch.test.js +311 -0
  11. package/dist/__tests__/unit/search/BooleanSearch.test.js +432 -0
  12. package/dist/__tests__/unit/search/FuzzySearch.test.js +448 -0
  13. package/dist/__tests__/unit/search/RankedSearch.test.js +379 -0
  14. package/dist/__tests__/unit/utils/levenshtein.test.js +77 -0
  15. package/dist/core/EntityManager.js +554 -0
  16. package/dist/core/GraphStorage.js +172 -0
  17. package/dist/core/KnowledgeGraphManager.js +423 -0
  18. package/dist/core/ObservationManager.js +129 -0
  19. package/dist/core/RelationManager.js +186 -0
  20. package/dist/core/TransactionManager.js +389 -0
  21. package/dist/core/index.js +9 -0
  22. package/dist/features/AnalyticsManager.js +222 -0
  23. package/dist/features/ArchiveManager.js +74 -0
  24. package/dist/features/BackupManager.js +311 -0
  25. package/dist/features/CompressionManager.js +291 -0
  26. package/dist/features/ExportManager.js +305 -0
  27. package/dist/features/HierarchyManager.js +219 -0
  28. package/dist/features/ImportExportManager.js +50 -0
  29. package/dist/features/ImportManager.js +328 -0
  30. package/dist/features/TagManager.js +210 -0
  31. package/dist/features/index.js +12 -0
  32. package/dist/index.js +13 -996
  33. package/dist/memory.jsonl +18 -0
  34. package/dist/search/BasicSearch.js +131 -0
  35. package/dist/search/BooleanSearch.js +283 -0
  36. package/dist/search/FuzzySearch.js +96 -0
  37. package/dist/search/RankedSearch.js +190 -0
  38. package/dist/search/SavedSearchManager.js +145 -0
  39. package/dist/search/SearchFilterChain.js +187 -0
  40. package/dist/search/SearchManager.js +305 -0
  41. package/dist/search/SearchSuggestions.js +57 -0
  42. package/dist/search/TFIDFIndexManager.js +217 -0
  43. package/dist/search/index.js +14 -0
  44. package/dist/server/MCPServer.js +52 -0
  45. package/dist/server/toolDefinitions.js +732 -0
  46. package/dist/server/toolHandlers.js +117 -0
  47. package/dist/types/analytics.types.js +6 -0
  48. package/dist/types/entity.types.js +7 -0
  49. package/dist/types/import-export.types.js +7 -0
  50. package/dist/types/index.js +12 -0
  51. package/dist/types/search.types.js +7 -0
  52. package/dist/types/tag.types.js +6 -0
  53. package/dist/utils/constants.js +128 -0
  54. package/dist/utils/dateUtils.js +89 -0
  55. package/dist/utils/entityUtils.js +108 -0
  56. package/dist/utils/errors.js +121 -0
  57. package/dist/utils/filterUtils.js +155 -0
  58. package/dist/utils/index.js +39 -0
  59. package/dist/utils/levenshtein.js +62 -0
  60. package/dist/utils/logger.js +33 -0
  61. package/dist/utils/paginationUtils.js +81 -0
  62. package/dist/utils/pathUtils.js +115 -0
  63. package/dist/utils/responseFormatter.js +55 -0
  64. package/dist/utils/schemas.js +184 -0
  65. package/dist/utils/searchCache.js +209 -0
  66. package/dist/utils/tagUtils.js +107 -0
  67. package/dist/utils/tfidf.js +90 -0
  68. package/dist/utils/validationHelper.js +99 -0
  69. package/dist/utils/validationUtils.js +109 -0
  70. package/package.json +82 -48
@@ -0,0 +1,18 @@
1
+ {"type":"entity","name":"Claude Code","entityType":"Software","observations":["An official CLI tool by Anthropic for interacting with Claude","Supports MCP servers for extended functionality","Supports multiple MCP servers simultaneously","Has built-in tools for file operations and bash commands"],"createdAt":"2025-11-12T05:32:42.880Z","lastModified":"2025-11-12T05:36:07.196Z","tags":["cli","anthropic","ai-assistant"],"importance":9}
2
+ {"type":"entity","name":"MCP","entityType":"Protocol","observations":["Model Context Protocol","Allows Claude to integrate with external tools and services","Supports resources, tools, and prompts"],"createdAt":"2025-11-12T05:32:42.880Z","lastModified":"2025-11-12T05:36:25.202Z"}
3
+ {"type":"entity","name":"Memory System","entityType":"Feature","observations":["Knowledge graph-based memory system","Stores entities, relations, and observations","Supports tagging and importance levels"],"createdAt":"2025-11-12T05:32:42.880Z","lastModified":"2025-11-12T05:36:25.202Z","tags":["knowledge-graph"],"importance":7}
4
+ {"type":"entity","name":"Memory MCP Project","entityType":"software_project","observations":["Enhanced MCP memory server with 45+ tools (vs 11 in official version)","Version: 0.41.0 (workspace) / 0.11.6 (npm published)","Author: Daniel Simon Jr.","Repository: https://github.com/danielsimonjr/memory-mcp","npm package: @danielsimonjr/memory-mcp","License: MIT","Enterprise-grade knowledge graph storage with hierarchical organization","TypeScript with strict mode, ES modules","Build: tsc, Test: Vitest 4.0.13","Dependencies: @modelcontextprotocol/sdk ^1.21.1, zod ^4.1.13","Session 2025-11-26: Published v0.41.0 to npm","Session 2025-11-26: Pushed CLAUDE.md with memory usage reminder to GitHub","Session 2025-11-26: All 47 tools defined and exposed in MCPServer.ts","Session 2025-11-26: Claude Code client only sees ~15 tools due to client-side limitation (not server issue)","Session 2025-11-26: Tools verified working: search_nodes, fuzzy_search, boolean_search, search_nodes_ranked via unit tests (394/396 passing)","Architecture: 3-tier (MCP Protocol → Managers → Storage), KnowledgeGraphManager facade with 10 specialized managers","Storage: JSONL format with in-memory caching and write-through invalidation","45+ tools in 10 categories: Core CRUD, Hierarchy, Compression, Archiving, Advanced Search, Saved Searches, Tags, Analytics, Import/Export","Search: BasicSearch, RankedSearch (TF-IDF), BooleanSearch (AND/OR/NOT), FuzzySearch (Levenshtein)","Performance: 50x faster duplicate detection via two-level bucketing, batch operations, deep copy strategy","Validation: 14 Zod schemas, query limits (10 depth, 50 terms, 20 operators), graph limits (100K entities, 1M relations)","Data model: Entity (name, type, observations[], parentId?, tags[], importance 0-10), Relation (from, to, type)","Code stats: 46 files, ~15K LOC source, 398 tests across 14 test files","Architecture: 3-tier (Protocol → Managers → Storage), KnowledgeGraphManager facade with 10 specialized managers","Managers: Entity, Relation, Search, Compression, Hierarchy, Export, Import, Analytics, Tag, Archive","Search: Basic, TF-IDF ranked, Boolean (AND/OR/NOT), Fuzzy (Levenshtein)","Performance: 50x faster duplicate detection, in-memory caching, batch operations","Validation: 14 Zod schemas, query limits (10 depth, 50 terms), graph limits (100K entities)","Data model: Entity (name, type, observations[], parentId?, tags[], importance), Relation (from, to, type)","Export: 7 formats (JSON, CSV, GraphML, GEXF, DOT, Markdown, Mermaid)","Import: 3 formats with merge strategies (replace, skip, merge, fail)","v0.48.0: Added dependency graph tool (2025-12-01)","69 TypeScript files across 7 modules","47 tools total (was documented as 45)","MCPServer.ts refactored: 907→67 lines (92.6% reduction)","toolDefinitions.ts and toolHandlers.ts extracted","26 documentation files in docs/","Lazy manager initialization for 10 managers","MCPServer.ts refactored: 907 to 67 lines (92.6% reduction)","CLAUDE.md updated 2025-12-01 with complete v0.48.0 details"],"createdAt":"2025-11-26T06:45:42.789Z","lastModified":"2025-12-02T05:47:12.411Z","tags":["mcp","knowledge-graph","typescript","enterprise","memory-server"],"importance":10}
5
+ {"type":"entity","name":"DeepThinking MCP","entityType":"software_project","observations":["Model Context Protocol server for advanced multi-modal reasoning","GitHub: https://github.com/danielsimonjr/deepthinking-mcp","npm: deepthinking-mcp (published)","Architecture: TypeScript, MCP SDK, modular validators, session management","Key files: src/index.ts (entry), src/tools/thinking.ts (tool schema), src/validation/ (validators)","Export formats: Markdown, LaTeX, JSON, HTML, Jupyter, Mermaid, DOT, ASCII","Production features: Caching, webhooks, backup/restore, rate limiting, batch processing, templates","96.8% implementation complete (30/31 tasks)","146 TypeScript files, 37,807 lines of code in src/","Zero TypeScript suppressions (100% reduction from 231 baseline)","Service layer architecture: ThoughtFactory, ExportService, ModeRouter","Repository pattern: ISessionRepository with File and Memory implementations","SessionManager refactored: 700 → 542 lines with extracted SessionMetricsCalculator","Taxonomy system: 110+ reasoning types across 12 categories","Search engine: full-text indexing, faceted search, TF-IDF ranking","Batch processing: 6 operations (export, index, backup, analyze, validate, cleanup)","Caching: LRU, LFU, FIFO strategies with factory pattern","Backup system: provider abstraction (local, S3, GCS, Azure prepared)","Enterprise security: Zod validation, rate limiting, PII redaction, path sanitization","Visualization: interactive dashboards, Mermaid diagrams, mindmaps, state charts","Webhooks: EventBus pub/sub, WebhookManager HTTP dispatch","v5.0.0 MILESTONE (2025-11-30): Released to npm and GitHub. Phase 5 Sprint 2 COMPLETED. New deepthinking_core tool with inductive, deductive, and abductive reasoning modes. Breaking change: abductive moved from deepthinking_causal to deepthinking_core.","Architecture: 10 tools (was 9), 20 modes (was 18). New deepthinking_core provides three fundamental reasoning modes: inductive (pattern recognition), deductive (logical derivation), abductive (best explanation). Quality: 745/745 tests passing, typecheck clean.","Publication: deepthinking-mcp@5.0.0 live on npm, commit 2e2f4107248ca34fee7a495c4fa9bee846ada090 on GitHub origin/master. CHANGELOG.md updated with comprehensive release notes and migration guide.","Breaking change migration: Users calling abductive mode through deepthinking_causal must update to deepthinking_core. Migration guide in CHANGELOG.md with code examples.","Phase 5 progress: Sprint 1 (v4.8.0) and Sprint 2 (v5.0.0) complete. Sprint 3 pending (advanced modes expansion). On track for Phase 5 completion.","Version history: v4.3.7 (schema fixes) → v4.4.0 (hand-written schemas) → v4.8.0 (core→standard rename) → v5.0.0 (new fundamental reasoning modes). All intermediate versions consolidated.","Phase 5 Sprint evolution: Sprint 1 (v4.8.0) renamed deepthinking_core to deepthinking_standard. Sprint 2 (v5.0.0) created new deepthinking_core with inductive/deductive/abductive modes. All Sprint 2 implementation details consolidated into v5.0.0 milestone.","Quality metrics consolidated: 745/745 tests passing, full TypeScript compliance, zero suppressions, 96.8% implementation complete. Build workflow: typecheck → test → build → commit → publish → push.","Performance optimization history: Replaced npx-based servers with global installs, investigated client slowness (not caused by deepthinking-mcp). 225 KB compiled size, ~35-55 MB runtime footprint.","Implementation completion: All 31 tasks across 4 sprints completed (Quick Wins, Code Quality, Architecture, Advanced Features). Template system for new modes created. Production-ready with enterprise security.","20 reasoning modes across 10 tools: deepthinking_core (inductive, deductive, abductive), deepthinking_standard (sequential, shannon, hybrid), deepthinking_math (mathematics, physics), deepthinking_temporal (temporal), deepthinking_probabilistic (bayesian, evidential), deepthinking_causal (causal, counterfactual), deepthinking_strategic (gametheory, optimization), deepthinking_analytical (analogical, firstprinciples), deepthinking_scientific (scientificmethod, systemsthinking, formallogic), deepthinking_session (session management).","Goal: Restructure deepthinking modes where 'core' means fundamental reasoning types","Rename deepthinking_core → deepthinking_standard (sequential, shannon, hybrid)","Create NEW deepthinking_core (inductive, deductive, abductive)","Move abductive mode from deepthinking_causal to new deepthinking_core","3 sprints total: 2-3 weeks, 40-60 developer hours","Sprint 1 (9 tasks, 12-16h): Rename core → standard with all scaffolding","Sprint 2 (16 tasks, 16-24h): Create new core mode by cloning existing files","Sprint 3 (12 tasks, 12-20h): Testing, documentation, v5.0.0 release","Two npm releases: v4.8.0 after Sprint 1, v5.0.0 after Sprint 3","Typecheck and commit after each sprint completion","Full unit testing before each npm publish","Plan files: PHASE_5_IMPLEMENTATION_PLAN.md and 3 sprint TODO JSONs","Commits: b9a847c (initial), df22848 (simplified)","Operator approved simplified approach - no beta versions needed","Started: 2025-11-30","Sprint 1 COMPLETED (2025-11-30)","Successfully renamed deepthinking_core → deepthinking_standard","Updated: json-schemas.ts, definitions.ts, 3 test files","All 744 tests passing after rename","Typecheck passed, build successful","Files modified: src/tools/json-schemas.ts, src/tools/definitions.ts, tests/unit/tools/schemas/schema-validation.test.ts, tests/integration/mcp-compliance.test.ts, tests/unit/tools/schemas/tool-definitions.test.ts","Sequential/shannon/hybrid now route to deepthinking_standard","Ready for v4.8.0 release","v4.8.0 published to npm - Sprint 1 release complete","npm package size: 225.28 KB dist/index.js, 506.80 KB source map","Publish process: prepublishOnly hook ran build + test:publish successfully","All Sprint 1 tasks completed and published","Sprint 2 ready to begin: Create new deepthinking_core tool","Sprint 1 COMPLETED and v4.8.0 PUBLISHED (2025-11-30)","All commits pushed to GitHub: 3faa822 (Sprint 1), 384fb85 (version bump)","Working tree clean, ready for Sprint 2","Sprint 2 goal: Create new deepthinking_core tool with inductive/deductive/abductive modes","Sprint 2 tasks: 16 tasks, 16-24 hours estimated","Sprint 2 will introduce 2 new fundamental reasoning modes: inductive and deductive","v5.0.1 released 2025-11-30: Fixed mode recommendation algorithm to properly suggest core reasoning modes for philosophical/metaphysical problems","Mode recommendation system now detects philosophical domains (metaphysics, theology, philosophy, epistemology, ethics) and prioritizes Hybrid (0.92), Inductive (0.85), Deductive (0.90), and Abductive (0.90) modes","Added Inductive+Deductive+Abductive hybrid combination for maximum evidential strength through multi-modal synthesis","Updated quickRecommend() mappings: 'pattern'→INDUCTIVE, 'logic'→DEDUCTIVE, 'proof'→DEDUCTIVE, 'philosophical'→HYBRID, 'metaphysical'→HYBRID","Lowered Evidential mode score from 0.88 to 0.82 and excluded for philosophical domains to prevent over-weighting uncertainty handling","All 740 tests passing after v5.0.1 fixes, published to npm and GitHub","Philosophical reasoning testing validated: Hybrid mode achieved 91.5% confidence through weighted integration of Inductive (85%), Deductive (40%), and Abductive (90%) modes","Phase 6 planning complete 2025-11-30: Meta-Reasoning mode implementation plan created with 2-sprint structure (24-36 hours total effort)","Meta-Reasoning mode will provide strategic oversight, monitoring reasoning quality, recommending mode switches, and orchestrating multiple modes intelligently","Sprint 1 (14-20h): Core infrastructure - type system, validation, MetaMonitor service, basic meta-reasoning logic","Sprint 2 (10-16h): Integration with existing modes, SessionAnalytics service, enhanced recommendations, comprehensive testing, v6.0.0 release","Meta-reasoning key capabilities: strategy monitoring, effectiveness evaluation, mode switching recommendations, quality assessment, resource allocation decisions","v6.0.0 will be purely additive (no breaking changes), adding 20+ new tests (740→760+ total)","Meta-reasoning addresses user pain points: 'How do I know if I'm using the right mode?', 'When should I switch strategies?', 'Can the system help me choose better?'","Meta-reasoning complements existing 20 modes by providing executive function to orchestrate them intelligently - it monitors and guides reasoning rather than doing reasoning itself","Phase 6 Sprint 1 progress 2025-11-30: Completed first 4 tasks (type system, validation, registry) - 8 hours work","Created MetaReasoningThought type with 7 interfaces: CurrentStrategy, StrategyEvaluation, AlternativeStrategy, StrategyRecommendation, ResourceAllocation, QualityMetrics, SessionContext","Created comprehensive MetaReasoningValidator with 401 lines, validates all meta-reasoning fields with appropriate warnings and errors","Registered metareasoning validator in validator registry for lazy loading, exported in index.ts","All typechecks passing after Sprint 1 progress - meta-reasoning type system fully integrated into core.ts","Remaining Sprint 1 tasks: tool routing (3h), meta-reasoning logic (4h), MetaMonitor service (3h), ThoughtFactory update (1h), unit tests (2h)","Phase 6 Sprint 1 COMPLETE 2025-11-30: All 8 tasks finished, ~14 hours of estimated 20.5 hours actual work","Created MetaMonitor service (330 lines) with session tracking, strategy evaluation, alternative suggestions, quality metrics calculation","Updated ThoughtFactory to create MetaReasoningThought instances with sensible defaults for all 7 meta-reasoning fields","All 745 tests passing after Sprint 1 completion, typecheck clean, meta-reasoning fully integrated into tool routing","Sprint 1 deliverables: MetaReasoningThought type (7 interfaces), MetaReasoningValidator (401 lines), MetaMonitor service, ThoughtFactory integration, tool routing complete","Next: Sprint 2 will add integration with existing modes, SessionAnalytics service, enhanced recommendations, export formatters, comprehensive testing, and v6.0.0 release","Phase 6 Sprint 1 deliverables summary: 3 new files (844 total lines), 7 modified files, all integration points complete","MetaMonitor service capabilities: evaluateStrategy(), suggestAlternatives(), calculateQualityMetrics(), getSessionContext() - full session monitoring API","Meta-reasoning infrastructure ready for Sprint 2: type system complete, validation working, ThoughtFactory creates instances, tool routing functional","Sprint 1 efficiency: 146% (14 hours actual vs 20.5 estimated) - faster due to well-defined types and existing architectural patterns","Meta-reasoning mode uses deepthinking_analytical tool alongside analogical and firstprinciples modes","All 745 existing tests continue passing - zero regressions from meta-reasoning additions","Phase 6 Sprint 2 progress 2025-12-01: ModeRouter enhanced with evaluateAndSuggestSwitch() and autoSwitchIfNeeded() methods using MetaMonitor for adaptive mode switching (commit 521bc5a)","SessionManager integrated with MetaMonitor - records all thoughts, starts strategy tracking on session creation, clears monitoring data on session eviction (commit 739c932)","Sprint 2 critical infrastructure complete: All 745 tests passing after ModeRouter and SessionManager meta-reasoning integration","Remaining Sprint 2 tasks: Update exporters (Markdown, Mermaid), create meta-reasoning tests, write comprehensive documentation, update README/CHANGELOG, final validation, v6.0.0 release","Auto-switch thresholds: evaluateAndSuggestSwitch suggests at effectiveness < 0.4, autoSwitchIfNeeded triggers at < 0.3 to prevent mode thrashing","Meta-reasoning evaluation metrics: effectiveness (progress/effort), efficiency (progress/time), confidence (1.0 - issues*0.15), quality score (weighted combination)","Phase 6 Sprint 2: Markdown exporter enhanced with comprehensive meta-reasoning insights display (commit cf015c8)","Markdown export now shows: current strategy, strategy evaluation (4 metrics), recommendations, alternative strategies, quality metrics (6 dimensions)","All core Sprint 2 infrastructure complete: ModeRouter adaptive switching, SessionManager tracking, Markdown export enhancement","Remaining for v6.0.0: meta-reasoning tests, comprehensive documentation (METAREASONING.md), README/CHANGELOG updates, final validation, npm publish","v6.0.0 RELEASED 2025-12-01: Meta-Reasoning mode (21st mode) published to npm and GitHub - Phase 6 Sprint 2 COMPLETE","Meta-Reasoning mode provides strategic oversight: monitors effectiveness, recommends mode switches, assesses quality across 6 dimensions","Architecture enhancements v6.0.0: MetaMonitor service (330 lines), ModeRouter adaptive switching (evaluateAndSuggestSwitch, autoSwitchIfNeeded), SessionManager auto-tracking","Auto-switch thresholds: effectiveness < 0.4 suggests alternatives, < 0.3 triggers automatic mode switch to prevent thrashing","Quality metrics (6 dimensions): logical consistency, evidence quality, completeness, originality, clarity, overall quality (0-1 scale)","Strategy evaluation metrics: effectiveness (progress/effort), efficiency (progress/time), confidence (1.0 - issues*0.15), quality score (weighted 0.4/0.2/0.4)","Markdown exporter enhanced: displays comprehensive meta-reasoning insights (strategy, evaluation, recommendations, alternatives, quality metrics)","Documentation v6.0.0: docs/modes/METAREASONING.md (complete usage guide), updated README.md (21 modes), updated CHANGELOG.md (release notes)","Zero breaking changes in v6.0.0 - purely additive release, all 740 tests passing, typecheck clean, published successfully","Meta-reasoning integration: MetaMonitor tracks all thoughts via SessionManager, provides strategy evaluation API, suggests mode alternatives","Publication v6.0.0: deepthinking-mcp@6.0.0 live on npm, commits pushed to GitHub (521bc5a, 739c932, cf015c8, f35b8a9, f12a2e3)","Meta-reasoning capabilities: strategy monitoring, effectiveness evaluation, mode switching recommendations, quality assessment, resource allocation decisions","21 reasoning modes total: 20 existing modes + new meta-reasoning mode for executive oversight and strategic coordination","Tools count: 10 tools (deepthinking_core, deepthinking_standard, deepthinking_math, deepthinking_temporal, deepthinking_probabilistic, deepthinking_causal, deepthinking_strategic, deepthinking_analytical, deepthinking_scientific, deepthinking_session)","Meta-reasoning accessible via deepthinking_analytical tool alongside analogical and firstprinciples modes","Phase 6 completion metrics: Sprint 1 (14h, type system + MetaMonitor), Sprint 2 (10h, integration + docs), total 24 hours actual vs 30-36 estimated (80% efficiency)","v6.0.0 deliverables: 7 new interfaces (CurrentStrategy, StrategyEvaluation, AlternativeStrategy, StrategyRecommendation, ResourceAllocation, QualityMetrics, SessionContext), MetaMonitor service, adaptive ModeRouter, enhanced SessionManager, comprehensive documentation"],"createdAt":"2025-11-26T07:11:27.559Z","lastModified":"2025-12-01T04:17:29.868Z","tags":["mcp","reasoning","typescript","ai-tools","active-project","bug-fix","json-schema","deepthinking-mcp","compatibility","2025-11-28"],"importance":10}
6
+ {"type":"entity","name":"Math MCP Server","entityType":"software_project","observations":["v3.2.1 | @danielsimonjr/math-mcp | ISC | Node 18+ | github.com/danielsimonjr/math-mcp","Entry: dist/index-wasm.js (accelerated) or dist/index.js (basic)","Acceleration: mathjs → WASM 14x (10x10+) → Workers 32x (100x100+) → WebGPU future","7 tools: evaluate, simplify, derivative, solve, matrix_operations, statistics, unit_conversion","721 tests (99.7%): 11 integration, 569 unit, 117 security","Security: rate limiting, expression sandboxing, WASM SHA-256 integrity","Observability: Prometheus :9090, Kubernetes health probes","Build: npm run build:all | Test: npm run test:all","v3.2.2 published 2025-11-26 - fixed Windows path separator in WASM hash manifest","Session 2025-11-26: Added CLAUDE.md with build commands, architecture, memory usage instructions","Session 2025-11-26: Added .claude/settings.local.json and .mcp.json (10 MCP servers configured)","Session 2025-11-26: Updated .gitignore to exclude .claude/ and .mcp.json","Session 2025-11-26: Commits pushed - 1ba79fb (v3.2.2 release), b5bd10e (gitignore update)","Currently wraps the original josdejong/mathjs library with WASM acceleration layer","Future migration: Will switch to danielsimonjr/mathjs fork once TypeScript+WASM refactoring is stable","Migration enables: Native WASM implementation instead of wrapper, unified codebase, better performance"],"createdAt":"2025-11-26T16:23:12.606Z","lastModified":"2025-11-28T22:35:24.653Z","tags":["mcp","mathematics","wasm","typescript","active-project"],"importance":10}
7
+ {"type":"entity","name":"MCP Protocol JSON Schema Requirements","entityType":"technical-standard","observations":["MCP (Model Context Protocol) requires JSON Schema Draft 7 format for tool input schemas","Does NOT support OpenAPI 3 schemas despite similarity","Does NOT support $schema property in tool input schemas","zodToJsonSchema library supports multiple targets: 'jsonSchema7', 'jsonSchema2019-09', 'openApi3'","For MCP compatibility, must use: target: 'jsonSchema7' and strip $schema property","Common error: Using 'openApi3' target causes MCP server connection failures","Best practice: Use helper function to generate MCP-compatible schemas from Zod definitions"],"createdAt":"2025-11-28T22:31:01.588Z","lastModified":"2025-11-28T22:31:13.695Z","tags":["mcp","json-schema","technical-standard","protocol","specification"],"importance":8}
8
+ {"type":"entity","name":"Math.js Library","entityType":"software-project","observations":["Extensive math library for JavaScript and Node.js - 673 total source files","GitHub fork: danielsimonjr/mathjs (modernization fork of josdejong/mathjs)","License: Apache 2.0, Requires: Node.js >= 18, Supports: ES2020+ JavaScript engines","Main branch: master, ES modules codebase requiring .js extensions in all imports","=== ARCHITECTURE ===","Factory function + dependency injection pattern with typed-function library","Immutable factory functions (createAdd, createMultiply, etc.) with declared dependencies","math.create(factories, config) creates MathJS instances from factory functions","Factory registration: src/factoriesAny.js (full) and src/factoriesNumber.js (lightweight)","Enables dynamic extension - new data types automatically work in dependent functions","Example: extending multiply with MyDecimal type automatically works in prod function","=== DATA TYPES ===","Supports: numbers, BigNumber, bigint, Complex, Fraction, Unit, Matrix (Dense/Sparse)","Typed-function provides multi-type dispatch and automatic type conversions","=== MODERNIZATION GOALS ===","Primary: Modernize with TypeScript for type safety and better developer tooling","WASM: Use AssemblyScript to compile TypeScript to WebAssembly (2-25x performance gains)","Parallelization: WebWorkers for multi-core CPU utilization (2-4x additional speedup)","WebGPU: Future GPU-accelerated matrix operations (10-100x potential speedup)","100% backward compatibility maintained throughout refactoring","Target: Large matrices (>1000×1000), linear algebra, FFT, statistical computations","Reference docs: PARALLEL_COMPUTING_IMPROVEMENT_PLAN.md, SCIENTIFIC_COMPUTING_IMPROVEMENT_PLAN.md","=== PERFORMANCE TIERS ===","Tier 1: JavaScript fallback (always available, baseline performance)","Tier 2: WASM acceleration (2-10x faster for large operations)","Tier 3: Parallel/multicore with WebWorkers (2-4x additional speedup on multi-core)","=== TYPESCRIPT REFACTORING STATUS ===","Status: 61/673 files converted (9% complete) as of 2025-11-28","Phase 1 COMPLETE: Infrastructure (18 files) - build system, WASM modules, parallel computing","Phase 2 IN PROGRESS: Functions (170 files planned) - arithmetic, trig, algebra, matrix ops","Migration tool: tools/migrate-to-ts.js for automated conversion assistance","Priority targets: plain number implementations, sparse algorithms, combinatorics, numeric solvers","Compilation: tsconfig.build.json for TypeScript, tsconfig.wasm.json for AssemblyScript","Output: lib/typescript/ for compiled TS, lib/wasm/ for WASM modules","=== BUILD SYSTEM ===","Gulp-based build pipeline compiling to multiple formats","Outputs: lib/esm/ (ES modules), lib/cjs/ (CommonJS), lib/browser/ (UMD bundle)","Build commands: npm run build (full), npm run build:wasm, npm run compile:ts, npm run watch:ts","Test commands: npm test (unit+lint), npm run test:all, npm run test:types, npm run coverage","=== DOCUMENTATION STRUCTURE ===","Root: README.md, CHANGELOG.md, CLAUDE.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md","Root: PARALLEL_COMPUTING_IMPROVEMENT_PLAN.md, SCIENTIFIC_COMPUTING_IMPROVEMENT_PLAN.md","docs/architecture/: README_TYPESCRIPT_WASM.md, TYPESCRIPT_WASM_ARCHITECTURE.md","docs/refactoring/: REFACTORING_PLAN.md, REFACTORING_SUMMARY.md, REFACTORING_TASKS.md, TYPESCRIPT_CONVERSION_SUMMARY.md","docs/migration/: MIGRATION_GUIDE.md, HISTORY.md","docs/: Also contains core/, datatypes/, expressions/, reference/ subdirectories (user-facing docs)","Total: 43 markdown files across 8 directories","README.md includes complete documentation organization with quick navigation table","=== MCP DEVELOPMENT ENVIRONMENT ===","MCP servers configured (.mcp.json): sequential-thinking, deepthinking, math-mcp, fermat-mcp, memory-mcp, everything-mcp, fzf-mcp, playwright, time, substack (10 total)","Permissions (.claude/settings.local.json): git, npm, memory-mcp, deepthinking-mcp, math-mcp tools","CLAUDE.md: Complete build/test commands, architecture overview, implementation patterns, MCP usage guidelines","=== SESSION 2025-11-28 ===","Created comprehensive CLAUDE.md guidance document for Claude Code","Set up MCP server configuration (.mcp.json with 10 servers)","Created .claude/settings.local.json with tool permissions","Reorganized documentation: moved 8 files to docs/architecture/, docs/refactoring/, docs/migration/","Added documentation organization section to README.md with navigation table","Fixed deepthinking-mcp JSON schema compatibility (openApi3 → jsonSchema7, removed $schema)","Updated memory with comprehensive project context (8 entities, relations)","=== RELATED PROJECTS ===","Math MCP Server: WASM-accelerated MCP server using mathjs (validates refactoring)","Uses math-mcp for cross-validation of mathematical implementations","=== INTEGRATION WITH MATH MCP SERVER ===","Math MCP Server currently wraps the original mathjs library with WASM acceleration","Future plan: Replace Math MCP Server's dependency with this optimized Math.js fork once stable","This fork provides native TypeScript + WASM + WebWorkers implementation vs external wrapper","Integration milestone: When refactoring reaches sufficient stability and test coverage","Benefits: Unified codebase, better performance, native WASM instead of wrapper layer","=== AUTOMATED CONVERSION TOOLS (2025-11-28) ===","Created comprehensive codemod tooling for TypeScript conversion automation:","1. transform-to-ts.js - Basic JavaScript→TypeScript transformation","2. transform-mathjs-to-ts.js - Advanced Math.js-specific patterns (factory functions, typed-function, dependencies)","3. batch-convert.sh - Bash script for batch conversion with progress tracking","4. batch-convert.ps1 - PowerShell script for Windows batch conversion","5. AUTOMATED_CONVERSION_GUIDE.md - Complete guide on using codemods for conversion","6. CONVERSION_EXAMPLES.md - Real-world examples of JS→TS conversion patterns","","=== CODEMOD CAPABILITIES ===","✅ Automated: Import path updates (.js→.ts), factory parameter typing, typed-function signatures, JSDoc conversion","⚠️ Semi-automated: Complex generics, return types, type guards (70-80% automation)","❌ Manual: Business logic, algorithm refactoring, documentation, tests, WASM implementation","","=== CONVERSION WORKFLOW ===","Step 1: Choose files (by category, phase, or list)","Step 2: Dry run preview (jscodeshift --dry --print)","Step 3: Run transformation (automatic import/type conversion)","Step 4: Manual refinement (generics, complex types, type guards)","Step 5: Compile & test (npm run compile:ts && npm test)","Step 6: Update factory indexes (factoriesAny.ts, factoriesNumber.ts)","Step 7: Update type definitions (types/index.d.ts)","","=== PERFORMANCE BENCHMARKS ===","1 file: 0.5h manual vs 0.5min codemod (1x speedup)","10 files: 5h manual vs 2min codemod (2.5x speedup)","50 files: 25h manual vs 5min codemod (5x speedup)","170 files: 85h manual vs 15min codemod (5.7x speedup)","612 files: 306h manual vs 45min codemod (6.8x speedup)","Total time savings: ~70% (accounting for 30% manual refinement)","","=== MATH.JS-SPECIFIC TYPE INFERENCE ===","Dependency mapping: typed→TypedFunction, matrix→MatrixConstructor, addScalar→(a:number,b:number)=>number","Type detection: Matrix, DenseMatrix, SparseMatrix, BigNumber, Complex, Fraction, Unit","Algorithm detection: algorithm01-14 for sparse matrix operations","Signature parsing: 'number,number'→(x:number,y:number):number","","=== TOOLS LOCATION ===","All tools in tools/ directory: transform-to-ts.js, transform-mathjs-to-ts.js, batch-convert.sh, batch-convert.ps1","Documentation: AUTOMATED_CONVERSION_GUIDE.md (comprehensive guide), CONVERSION_EXAMPLES.md (5 real examples)","=== CODEMOD TESTING RESULTS (2025-11-28) ===","Tested transform-mathjs-to-ts.js on isInteger.js - SUCCESS!","Conversion time: 1.5 seconds automated + 5-10 minutes manual refinement","12 modifications applied: 2 import updates, 2 factory types, 5 signature types, 3 type imports","Automation level: 70-75% automated, 25-30% manual","=== BUGS FOUND & FIXED ===","1. Missing type annotations on factory parameters - FIXED (object-level annotation)","2. Generic <any> in return type - FIXED (removed type parameter)","3. Identifier keys not recognized (number: vs \"number\":) - FIXED (handle both)","4. Union types not handled (Array | Matrix) - FIXED (split and create union)","5. Missing bigint keyword - FIXED (added to primitives)","6. Arrow params missing parentheses (n: number => invalid) - FIXED (post-process regex)","7. Factory name showing undefined - FIXED (handle literal and identifier)","8. Over-eager return type inference - FIXED (don't infer single-param functions)","=== TESTING OUTPUT ===","BEFORE: 51 lines of JavaScript","AFTER: 57 lines of TypeScript (70% complete, needs 5-10 min refinement)","Manual work: Add import type, refine any types, add return types, update factory indexes","=== PERFORMANCE ===","Estimated time savings: 3-6x speedup per file","Manual: 30 min/file × 612 files = 306 hours","Codemod: 10 min/file × 612 files = 102 hours","Time saved: 204 hours (67% reduction)","=== RECOMMENDATION ===","✅ Codemod is production-ready for Math.js TypeScript conversion","✅ Proceed with pilot conversion of 10 diverse files","✅ Quality: High (with manual refinement)","✅ Reliability: 95%+ success rate expected","TypeScript Conversion Status (2025-11-30): 53.5% source coverage (685 TS / 1,281 total)","Remaining conversions: 596 source JS files, 343 test JS files (939 total)","Test coverage: 0.3% TypeScript (1 TS / 344 total tests)","TypeScript errors: 1,234 remaining (reduced from 1,330, 96 fixed this session)","Dependency graph generated: 596 JS files analyzed, 283 factory functions identified","High-dependency files: utils/factory.js (282 deps), utils/is.js (73 deps), plain/number/index.js (51 deps)","Error fixes applied: TS2683 (43 fixes - error classes), TS7031 (28 fixes - constants), TS7018 (25 fixes - docs)","Conversion approach: Prioritizing high-dependency files with fewer errors first","Both .js and .ts files coexist (originals kept as reference until build system updated)"],"createdAt":"2025-11-28T22:33:24.118Z","lastModified":"2025-12-01T00:23:12.537Z","tags":["mathjs","mathematics","library","typescript","wasm","assemblyscript","webworkers","webgpu","active-project","javascript","nodejs","performance","refactoring","modernization"],"importance":10}
9
+ {"type":"entity","name":"zod-v4-compatibility-issue","entityType":"technical_issue","observations":["Zod v4 native toJSONSchema() has bugs with complex types like tuples: z.tuple([z.number(), z.number()])","Error: TypeError: Cannot read properties of undefined (reading '_zod')","zod-to-json-schema v3.25.0 generates empty schemas when used with default Zod v4 import","Solution: Use 'import { z } from zod/v3' compatibility layer with zod-to-json-schema","Target: jsonSchema2020-12 for MCP draft 2020-12 compliance","Requires updating ALL files that import zod, not just generator functions","Tests can pass while runtime fails - need manual MCP server testing to verify"],"createdAt":"2025-11-29T18:38:28.415Z","lastModified":"2025-11-29T18:38:28.415Z"}
10
+ {"type":"entity","name":"development-best-practices","entityType":"workflow_guideline","observations":["CRITICAL: Always clean up debug/test artifacts before committing and publishing","Remove temporary test scripts created for debugging (e.g., test-mcp-server.mjs, test-schema-output.js)","Check for junk files with git status before committing","Common temporary files to remove: test-*.js, test-*.mjs, debug-*.js, temp-*.js, .error.txt","Use .gitignore for test artifacts that should never be committed","Before npm publish: Review dist/ contents, check for test files in package","Before git commit: Run 'git status' and verify only intended files are staged","Clean workflow: Create temp files → Debug/test → Delete temp files → Commit clean code","Example cleanup command: rm test-*.mjs test-*.js before committing","Memory trigger: When session ends or publishing, ask 'Did I create any temp/debug files?'"],"createdAt":"2025-11-29T19:04:25.307Z","lastModified":"2025-11-29T19:04:25.307Z"}
11
+ {"type":"entity","name":"Math.js TypeScript Conversion","entityType":"project","observations":["Active TypeScript conversion of Math.js library","Status as of 2025-11-30: 686 TS files, 939 JS files (42.2% coverage)","Source: 685 TS / 1,281 total (53.5% coverage)","Tests: 1 TS / 344 total (0.3% coverage)","TypeScript errors: 1,137 in 234 files, 452 error-free files","Session 2025-11-30: Fixed 50 errors - TS7018 (12), TS7022 (10), TS7023 (11)","Fixed implicit type annotations in constants, operators, utilities, matrix functions","Remaining top error categories: TS2339 (360 property access), TS7006 (234 implicit any params), TS2322 (76 type mismatches)","Strategy: Fix errors from least to most, prioritize high-dependency files","Dependency analysis complete: utils/factory.js has 282 dependents (highest)"],"createdAt":"2025-11-30T23:24:14.053Z","lastModified":"2025-11-30T23:24:14.053Z"}
12
+ {"type":"entity","name":"Windows-MCP Server","entityType":"software-project","observations":["Lightweight MCP (Model Context Protocol) server for Windows OS interaction and automation","Version 0.1.0 published to PyPI as 'windows-mcp-server' on 2025-11-30","PyPI URL: https://pypi.org/project/windows-mcp-server/0.1.0/","GitHub repository: https://github.com/danielsimonjr/Windows-MCP (forked from CursorTouch/Windows-MCP)","Platform: Windows 7-11 only, requires Python 3.13+","Entry point: main.py using FastMCP framework","Provides 14 MCP tools for Windows automation: State-Tool, Launch-Tool, Click-Tool, Type-Tool, Switch-Tool, Scroll-Tool, Drag-Tool, Move-Tool, Shortcut-Tool, Key-Tool, Wait-Tool, Clipboard-Tool, Powershell-Tool, Scrape-Tool","Architecture: Desktop layer (src/desktop) handles Windows UI Automation API, Tree layer (src/tree) handles accessibility tree traversal with parallel processing","Key dependencies: fastmcp>=2.8.1, uiautomation>=2.0.24, pyautogui>=0.9.54, humancursor>=1.1.5, pillow>=11.2.1","Installation: pip install windows-mcp-server, then run with 'windows-mcp' command or 'python -m windows_mcp'","MCP server configuration uses uv: uv --directory C:/mcp-servers/Windows-MCP run main.py","Built distributions: windows_mcp_server-0.1.0-py3-none-any.whl (28.1 kB) and windows_mcp_server-0.1.0.tar.gz (29.4 kB)","All 14 tools tested successfully on 2025-11-30","Project includes comprehensive CLAUDE.md with architecture documentation, build commands, development best practices","Uses parallel processing via ThreadPoolExecutor for UI element extraction across multiple applications","Screenshot annotation feature with bounding boxes and labels (0.7 scale factor)","Fuzzy app name matching using fuzzywuzzy library for Launch-Tool","Configuration files: .mcp.json (project MCP registry), .claude/settings.local.json (permissions - not tracked in git)","Gitignore follows Python best practices: excludes dist/, __pycache__, .venv/, .claude/, .mcp.json but commits uv.lock and CLAUDE.md","Package renamed from 'windows-mcp' to 'windows-mcp-server' due to PyPI namespace conflict","Original author: Jeomon George (CursorTouch), forked and published by danielsimonjr","Console script entry point: windows-mcp = '__main__:main'","DXT extension packaging support via manifest.json for Claude Desktop integration","State-Tool can capture desktop state with optional vision (screenshot) support, returns apps + UI elements + coordinates","PyPI publication used API token authentication (stored in C:/mcp-servers/PyPi_Key.txt)","Latest git commits: e3923ca (package rename), d5ab135 (gitignore Claude files), e477ea1 (Python gitignore best practices)"],"createdAt":"2025-12-01T03:45:50.433Z","lastModified":"2025-12-01T03:46:02.822Z","tags":["mcp","windows","automation","python","fastmcp","active-project","published","pypi","ui-automation","desktop-control"],"importance":10}
13
+ {"type":"relation","from":"Claude Code","to":"MCP","relationType":"supports","createdAt":"2025-11-12T05:32:56.996Z","lastModified":"2025-11-12T05:32:56.996Z"}
14
+ {"type":"relation","from":"Claude Code","to":"Memory System","relationType":"includes","createdAt":"2025-11-12T05:32:56.996Z","lastModified":"2025-11-12T05:32:56.996Z"}
15
+ {"type":"relation","from":"DeepThinking MCP","to":"MCP Protocol JSON Schema Requirements","relationType":"implements","createdAt":"2025-11-28T22:31:20.896Z","lastModified":"2025-11-28T22:31:20.896Z"}
16
+ {"type":"relation","from":"Math MCP Server","to":"Math.js Library","relationType":"uses_library","createdAt":"2025-11-28T22:33:37.193Z","lastModified":"2025-11-28T22:33:37.193Z"}
17
+ {"type":"relation","from":"DeepThinking MCP","to":"zod-v4-compatibility-issue","relationType":"fixes","createdAt":"2025-11-29T18:38:28.720Z","lastModified":"2025-11-29T18:38:28.720Z"}
18
+ {"type":"relation","from":"development-best-practices","to":"DeepThinking MCP","relationType":"applies_to","createdAt":"2025-11-29T19:04:25.602Z","lastModified":"2025-11-29T19:04:25.602Z"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Basic Search
3
+ *
4
+ * Simple text-based search with tag, importance, and date filters with result caching.
5
+ *
6
+ * @module search/BasicSearch
7
+ */
8
+ import { isWithinDateRange } from '../utils/dateUtils.js';
9
+ import { SEARCH_LIMITS } from '../utils/constants.js';
10
+ import { searchCaches } from '../utils/searchCache.js';
11
+ import { SearchFilterChain } from './SearchFilterChain.js';
12
+ /**
13
+ * Performs basic text search with optional filters and caching.
14
+ */
15
+ export class BasicSearch {
16
+ storage;
17
+ enableCache;
18
+ constructor(storage, enableCache = true) {
19
+ this.storage = storage;
20
+ this.enableCache = enableCache;
21
+ }
22
+ /**
23
+ * Search nodes by text query with optional filters and pagination.
24
+ *
25
+ * Searches across entity names, types, and observations.
26
+ *
27
+ * @param query - Text to search for (case-insensitive)
28
+ * @param tags - Optional tags to filter by
29
+ * @param minImportance - Optional minimum importance (0-10)
30
+ * @param maxImportance - Optional maximum importance (0-10)
31
+ * @param offset - Number of results to skip (default: 0)
32
+ * @param limit - Maximum number of results (default: 50, max: 200)
33
+ * @returns Filtered knowledge graph with pagination applied
34
+ */
35
+ async searchNodes(query, tags, minImportance, maxImportance, offset = 0, limit = SEARCH_LIMITS.DEFAULT) {
36
+ // Check cache first
37
+ if (this.enableCache) {
38
+ const cacheKey = { query, tags, minImportance, maxImportance, offset, limit };
39
+ const cached = searchCaches.basic.get(cacheKey);
40
+ if (cached) {
41
+ return cached;
42
+ }
43
+ }
44
+ const graph = await this.storage.loadGraph();
45
+ const queryLower = query.toLowerCase();
46
+ // First filter by text match (search-specific)
47
+ const textMatched = graph.entities.filter(e => {
48
+ return (e.name.toLowerCase().includes(queryLower) ||
49
+ e.entityType.toLowerCase().includes(queryLower) ||
50
+ e.observations.some(o => o.toLowerCase().includes(queryLower)));
51
+ });
52
+ // Apply tag and importance filters using SearchFilterChain
53
+ const filters = { tags, minImportance, maxImportance };
54
+ const filteredEntities = SearchFilterChain.applyFilters(textMatched, filters);
55
+ // Apply pagination using SearchFilterChain
56
+ const pagination = SearchFilterChain.validatePagination(offset, limit);
57
+ const paginatedEntities = SearchFilterChain.paginate(filteredEntities, pagination);
58
+ const filteredEntityNames = new Set(paginatedEntities.map(e => e.name));
59
+ const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
60
+ const result = { entities: paginatedEntities, relations: filteredRelations };
61
+ // Cache the result
62
+ if (this.enableCache) {
63
+ const cacheKey = { query, tags, minImportance, maxImportance, offset, limit };
64
+ searchCaches.basic.set(cacheKey, result);
65
+ }
66
+ return result;
67
+ }
68
+ /**
69
+ * Open specific nodes by name.
70
+ *
71
+ * @param names - Array of entity names to retrieve
72
+ * @returns Knowledge graph with specified entities and their relations
73
+ */
74
+ async openNodes(names) {
75
+ const graph = await this.storage.loadGraph();
76
+ const filteredEntities = graph.entities.filter(e => names.includes(e.name));
77
+ const filteredEntityNames = new Set(filteredEntities.map(e => e.name));
78
+ const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
79
+ return { entities: filteredEntities, relations: filteredRelations };
80
+ }
81
+ /**
82
+ * Search by date range with optional filters and pagination.
83
+ *
84
+ * @param startDate - Optional start date (ISO 8601)
85
+ * @param endDate - Optional end date (ISO 8601)
86
+ * @param entityType - Optional entity type filter
87
+ * @param tags - Optional tags filter
88
+ * @param offset - Number of results to skip (default: 0)
89
+ * @param limit - Maximum number of results (default: 50, max: 200)
90
+ * @returns Filtered knowledge graph with pagination applied
91
+ */
92
+ async searchByDateRange(startDate, endDate, entityType, tags, offset = 0, limit = SEARCH_LIMITS.DEFAULT) {
93
+ // Check cache first
94
+ if (this.enableCache) {
95
+ const cacheKey = { method: 'dateRange', startDate, endDate, entityType, tags, offset, limit };
96
+ const cached = searchCaches.basic.get(cacheKey);
97
+ if (cached) {
98
+ return cached;
99
+ }
100
+ }
101
+ const graph = await this.storage.loadGraph();
102
+ // First filter by date range (search-specific - uses createdAt OR lastModified)
103
+ const dateFiltered = graph.entities.filter(e => {
104
+ const dateToCheck = e.createdAt || e.lastModified;
105
+ if (dateToCheck && !isWithinDateRange(dateToCheck, startDate, endDate)) {
106
+ return false;
107
+ }
108
+ return true;
109
+ });
110
+ // Apply entity type and tag filters using SearchFilterChain
111
+ const filters = { tags, entityType };
112
+ const filteredEntities = SearchFilterChain.applyFilters(dateFiltered, filters);
113
+ // Apply pagination using SearchFilterChain
114
+ const pagination = SearchFilterChain.validatePagination(offset, limit);
115
+ const paginatedEntities = SearchFilterChain.paginate(filteredEntities, pagination);
116
+ const filteredEntityNames = new Set(paginatedEntities.map(e => e.name));
117
+ const filteredRelations = graph.relations.filter(r => {
118
+ const dateToCheck = r.createdAt || r.lastModified;
119
+ const inDateRange = !dateToCheck || isWithinDateRange(dateToCheck, startDate, endDate);
120
+ const involvesFilteredEntities = filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to);
121
+ return inDateRange && involvesFilteredEntities;
122
+ });
123
+ const result = { entities: paginatedEntities, relations: filteredRelations };
124
+ // Cache the result
125
+ if (this.enableCache) {
126
+ const cacheKey = { method: 'dateRange', startDate, endDate, entityType, tags, offset, limit };
127
+ searchCaches.basic.set(cacheKey, result);
128
+ }
129
+ return result;
130
+ }
131
+ }
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Boolean Search
3
+ *
4
+ * Advanced search with boolean operators (AND, OR, NOT) and field-specific queries.
5
+ *
6
+ * @module search/BooleanSearch
7
+ */
8
+ import { SEARCH_LIMITS, QUERY_LIMITS } from '../utils/constants.js';
9
+ import { ValidationError } from '../utils/errors.js';
10
+ import { SearchFilterChain } from './SearchFilterChain.js';
11
+ /**
12
+ * Performs boolean search with query parsing and AST evaluation.
13
+ */
14
+ export class BooleanSearch {
15
+ storage;
16
+ constructor(storage) {
17
+ this.storage = storage;
18
+ }
19
+ /**
20
+ * Boolean search with support for AND, OR, NOT operators, field-specific queries, and pagination.
21
+ *
22
+ * Query syntax examples:
23
+ * - "alice AND programming" - Both terms must match
24
+ * - "type:person OR type:organization" - Either type matches
25
+ * - "NOT archived" - Exclude archived items
26
+ * - "name:alice AND (observation:coding OR observation:teaching)"
27
+ *
28
+ * @param query - Boolean query string
29
+ * @param tags - Optional tags filter
30
+ * @param minImportance - Optional minimum importance
31
+ * @param maxImportance - Optional maximum importance
32
+ * @param offset - Number of results to skip (default: 0)
33
+ * @param limit - Maximum number of results (default: 50, max: 200)
34
+ * @returns Filtered knowledge graph matching the boolean query with pagination applied
35
+ */
36
+ async booleanSearch(query, tags, minImportance, maxImportance, offset = 0, limit = SEARCH_LIMITS.DEFAULT) {
37
+ // Validate query length
38
+ if (query.length > QUERY_LIMITS.MAX_QUERY_LENGTH) {
39
+ throw new ValidationError('Query too long', [`Query length ${query.length} exceeds maximum of ${QUERY_LIMITS.MAX_QUERY_LENGTH} characters`]);
40
+ }
41
+ const graph = await this.storage.loadGraph();
42
+ // Parse the query into an AST
43
+ let queryAst;
44
+ try {
45
+ queryAst = this.parseBooleanQuery(query);
46
+ }
47
+ catch (error) {
48
+ throw new Error(`Failed to parse boolean query: ${error instanceof Error ? error.message : String(error)}`);
49
+ }
50
+ // Validate query complexity
51
+ this.validateQueryComplexity(queryAst);
52
+ // First filter by boolean query evaluation (search-specific)
53
+ const booleanMatched = graph.entities.filter(e => this.evaluateBooleanQuery(queryAst, e));
54
+ // Apply tag and importance filters using SearchFilterChain
55
+ const filters = { tags, minImportance, maxImportance };
56
+ const filteredEntities = SearchFilterChain.applyFilters(booleanMatched, filters);
57
+ // Apply pagination using SearchFilterChain
58
+ const pagination = SearchFilterChain.validatePagination(offset, limit);
59
+ const paginatedEntities = SearchFilterChain.paginate(filteredEntities, pagination);
60
+ const filteredEntityNames = new Set(paginatedEntities.map(e => e.name));
61
+ const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
62
+ return { entities: paginatedEntities, relations: filteredRelations };
63
+ }
64
+ /**
65
+ * Tokenize a boolean query into tokens.
66
+ *
67
+ * Handles quoted strings, parentheses, and operators.
68
+ */
69
+ tokenizeBooleanQuery(query) {
70
+ const tokens = [];
71
+ let current = '';
72
+ let inQuotes = false;
73
+ for (let i = 0; i < query.length; i++) {
74
+ const char = query[i];
75
+ if (char === '"') {
76
+ if (inQuotes) {
77
+ // End of quoted string
78
+ tokens.push(current);
79
+ current = '';
80
+ inQuotes = false;
81
+ }
82
+ else {
83
+ // Start of quoted string
84
+ if (current.trim()) {
85
+ tokens.push(current.trim());
86
+ current = '';
87
+ }
88
+ inQuotes = true;
89
+ }
90
+ }
91
+ else if (!inQuotes && (char === '(' || char === ')')) {
92
+ // Parentheses are separate tokens
93
+ if (current.trim()) {
94
+ tokens.push(current.trim());
95
+ current = '';
96
+ }
97
+ tokens.push(char);
98
+ }
99
+ else if (!inQuotes && /\s/.test(char)) {
100
+ // Whitespace outside quotes
101
+ if (current.trim()) {
102
+ tokens.push(current.trim());
103
+ current = '';
104
+ }
105
+ }
106
+ else {
107
+ current += char;
108
+ }
109
+ }
110
+ if (current.trim()) {
111
+ tokens.push(current.trim());
112
+ }
113
+ return tokens;
114
+ }
115
+ /**
116
+ * Parse a boolean search query into an AST.
117
+ *
118
+ * Supports: AND, OR, NOT, parentheses, field-specific queries (field:value)
119
+ */
120
+ parseBooleanQuery(query) {
121
+ const tokens = this.tokenizeBooleanQuery(query);
122
+ let position = 0;
123
+ const peek = () => tokens[position];
124
+ const consume = () => tokens[position++];
125
+ // Parse OR expressions (lowest precedence)
126
+ const parseOr = () => {
127
+ let left = parseAnd();
128
+ while (peek()?.toUpperCase() === 'OR') {
129
+ consume(); // consume 'OR'
130
+ const right = parseAnd();
131
+ left = { type: 'OR', children: [left, right] };
132
+ }
133
+ return left;
134
+ };
135
+ // Parse AND expressions
136
+ const parseAnd = () => {
137
+ let left = parseNot();
138
+ while (peek() && peek()?.toUpperCase() !== 'OR' && peek() !== ')') {
139
+ // Implicit AND if next token is not OR or )
140
+ if (peek()?.toUpperCase() === 'AND') {
141
+ consume(); // consume 'AND'
142
+ }
143
+ const right = parseNot();
144
+ left = { type: 'AND', children: [left, right] };
145
+ }
146
+ return left;
147
+ };
148
+ // Parse NOT expressions
149
+ const parseNot = () => {
150
+ if (peek()?.toUpperCase() === 'NOT') {
151
+ consume(); // consume 'NOT'
152
+ const child = parseNot();
153
+ return { type: 'NOT', child };
154
+ }
155
+ return parsePrimary();
156
+ };
157
+ // Parse primary expressions (terms, field queries, parentheses)
158
+ const parsePrimary = () => {
159
+ const token = peek();
160
+ if (!token) {
161
+ throw new Error('Unexpected end of query');
162
+ }
163
+ // Parentheses
164
+ if (token === '(') {
165
+ consume(); // consume '('
166
+ const node = parseOr();
167
+ if (consume() !== ')') {
168
+ throw new Error('Expected closing parenthesis');
169
+ }
170
+ return node;
171
+ }
172
+ // Field-specific query (field:value)
173
+ if (token.includes(':')) {
174
+ consume();
175
+ const [field, ...valueParts] = token.split(':');
176
+ const value = valueParts.join(':'); // Handle colons in value
177
+ return { type: 'TERM', field: field.toLowerCase(), value: value.toLowerCase() };
178
+ }
179
+ // Regular term
180
+ consume();
181
+ return { type: 'TERM', value: token.toLowerCase() };
182
+ };
183
+ const result = parseOr();
184
+ // Check for unconsumed tokens
185
+ if (position < tokens.length) {
186
+ throw new Error(`Unexpected token: ${tokens[position]}`);
187
+ }
188
+ return result;
189
+ }
190
+ /**
191
+ * Evaluate a boolean query AST against an entity.
192
+ */
193
+ evaluateBooleanQuery(node, entity) {
194
+ switch (node.type) {
195
+ case 'AND':
196
+ return node.children.every(child => this.evaluateBooleanQuery(child, entity));
197
+ case 'OR':
198
+ return node.children.some(child => this.evaluateBooleanQuery(child, entity));
199
+ case 'NOT':
200
+ return !this.evaluateBooleanQuery(node.child, entity);
201
+ case 'TERM': {
202
+ const value = node.value;
203
+ // Field-specific search
204
+ if (node.field) {
205
+ switch (node.field) {
206
+ case 'name':
207
+ return entity.name.toLowerCase().includes(value);
208
+ case 'type':
209
+ case 'entitytype':
210
+ return entity.entityType.toLowerCase().includes(value);
211
+ case 'observation':
212
+ case 'observations':
213
+ return entity.observations.some(obs => obs.toLowerCase().includes(value));
214
+ case 'tag':
215
+ case 'tags':
216
+ return entity.tags ? entity.tags.some(tag => tag.toLowerCase().includes(value)) : false;
217
+ default:
218
+ // Unknown field, search all text fields
219
+ return this.entityMatchesTerm(entity, value);
220
+ }
221
+ }
222
+ // General search across all fields
223
+ return this.entityMatchesTerm(entity, value);
224
+ }
225
+ }
226
+ }
227
+ /**
228
+ * Check if entity matches a search term in any text field.
229
+ */
230
+ entityMatchesTerm(entity, term) {
231
+ const termLower = term.toLowerCase();
232
+ return (entity.name.toLowerCase().includes(termLower) ||
233
+ entity.entityType.toLowerCase().includes(termLower) ||
234
+ entity.observations.some(obs => obs.toLowerCase().includes(termLower)) ||
235
+ (entity.tags?.some(tag => tag.toLowerCase().includes(termLower)) || false));
236
+ }
237
+ /**
238
+ * Validate query complexity to prevent resource exhaustion.
239
+ * Checks nesting depth, term count, and operator count against configured limits.
240
+ */
241
+ validateQueryComplexity(node, depth = 0) {
242
+ // Check nesting depth
243
+ if (depth > QUERY_LIMITS.MAX_DEPTH) {
244
+ throw new ValidationError('Query too complex', [`Query nesting depth ${depth} exceeds maximum of ${QUERY_LIMITS.MAX_DEPTH}`]);
245
+ }
246
+ // Count terms and operators recursively
247
+ const complexity = this.calculateQueryComplexity(node);
248
+ if (complexity.terms > QUERY_LIMITS.MAX_TERMS) {
249
+ throw new ValidationError('Query too complex', [`Query has ${complexity.terms} terms, exceeds maximum of ${QUERY_LIMITS.MAX_TERMS}`]);
250
+ }
251
+ if (complexity.operators > QUERY_LIMITS.MAX_OPERATORS) {
252
+ throw new ValidationError('Query too complex', [`Query has ${complexity.operators} operators, exceeds maximum of ${QUERY_LIMITS.MAX_OPERATORS}`]);
253
+ }
254
+ }
255
+ /**
256
+ * Calculate query complexity metrics.
257
+ */
258
+ calculateQueryComplexity(node, depth = 0) {
259
+ switch (node.type) {
260
+ case 'AND':
261
+ case 'OR':
262
+ const childResults = node.children.map(child => this.calculateQueryComplexity(child, depth + 1));
263
+ return {
264
+ terms: childResults.reduce((sum, r) => sum + r.terms, 0),
265
+ operators: childResults.reduce((sum, r) => sum + r.operators, 1), // +1 for current operator
266
+ maxDepth: Math.max(depth, ...childResults.map(r => r.maxDepth)),
267
+ };
268
+ case 'NOT':
269
+ const notResult = this.calculateQueryComplexity(node.child, depth + 1);
270
+ return {
271
+ terms: notResult.terms,
272
+ operators: notResult.operators + 1,
273
+ maxDepth: Math.max(depth, notResult.maxDepth),
274
+ };
275
+ case 'TERM':
276
+ return {
277
+ terms: 1,
278
+ operators: 0,
279
+ maxDepth: depth,
280
+ };
281
+ }
282
+ }
283
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Fuzzy Search
3
+ *
4
+ * Search with typo tolerance using Levenshtein distance similarity.
5
+ *
6
+ * @module search/FuzzySearch
7
+ */
8
+ import { levenshteinDistance } from '../utils/levenshtein.js';
9
+ import { SEARCH_LIMITS } from '../utils/constants.js';
10
+ import { SearchFilterChain } from './SearchFilterChain.js';
11
+ /**
12
+ * Default fuzzy search similarity threshold (70% match required).
13
+ * Lower values are more permissive (more typos tolerated).
14
+ * Higher values are stricter (fewer typos tolerated).
15
+ */
16
+ export const DEFAULT_FUZZY_THRESHOLD = 0.7;
17
+ /**
18
+ * Performs fuzzy search with configurable similarity threshold.
19
+ */
20
+ export class FuzzySearch {
21
+ storage;
22
+ constructor(storage) {
23
+ this.storage = storage;
24
+ }
25
+ /**
26
+ * Fuzzy search for entities with typo tolerance and pagination.
27
+ *
28
+ * Uses Levenshtein distance to calculate similarity between strings.
29
+ * Matches if similarity >= threshold (0.0 to 1.0).
30
+ *
31
+ * @param query - Search query
32
+ * @param threshold - Similarity threshold (0.0 to 1.0), default DEFAULT_FUZZY_THRESHOLD
33
+ * @param tags - Optional tags filter
34
+ * @param minImportance - Optional minimum importance
35
+ * @param maxImportance - Optional maximum importance
36
+ * @param offset - Number of results to skip (default: 0)
37
+ * @param limit - Maximum number of results (default: 50, max: 200)
38
+ * @returns Filtered knowledge graph with fuzzy matches and pagination applied
39
+ */
40
+ async fuzzySearch(query, threshold = DEFAULT_FUZZY_THRESHOLD, tags, minImportance, maxImportance, offset = 0, limit = SEARCH_LIMITS.DEFAULT) {
41
+ const graph = await this.storage.loadGraph();
42
+ // First filter by fuzzy text match (search-specific)
43
+ const fuzzyMatched = graph.entities.filter(e => {
44
+ return (this.isFuzzyMatch(e.name, query, threshold) ||
45
+ this.isFuzzyMatch(e.entityType, query, threshold) ||
46
+ e.observations.some(o =>
47
+ // For observations, split into words and check each word
48
+ o
49
+ .toLowerCase()
50
+ .split(/\s+/)
51
+ .some(word => this.isFuzzyMatch(word, query, threshold)) ||
52
+ // Also check if the observation contains the query
53
+ this.isFuzzyMatch(o, query, threshold)));
54
+ });
55
+ // Apply tag and importance filters using SearchFilterChain
56
+ const filters = { tags, minImportance, maxImportance };
57
+ const filteredEntities = SearchFilterChain.applyFilters(fuzzyMatched, filters);
58
+ // Apply pagination using SearchFilterChain
59
+ const pagination = SearchFilterChain.validatePagination(offset, limit);
60
+ const paginatedEntities = SearchFilterChain.paginate(filteredEntities, pagination);
61
+ const filteredEntityNames = new Set(paginatedEntities.map(e => e.name));
62
+ const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
63
+ return {
64
+ entities: paginatedEntities,
65
+ relations: filteredRelations,
66
+ };
67
+ }
68
+ /**
69
+ * Check if two strings match with fuzzy logic.
70
+ *
71
+ * Returns true if:
72
+ * - Strings are identical
73
+ * - One contains the other
74
+ * - Levenshtein similarity >= threshold
75
+ *
76
+ * @param str1 - First string
77
+ * @param str2 - Second string
78
+ * @param threshold - Similarity threshold (0.0 to 1.0)
79
+ * @returns True if strings match fuzzily
80
+ */
81
+ isFuzzyMatch(str1, str2, threshold = 0.7) {
82
+ const s1 = str1.toLowerCase();
83
+ const s2 = str2.toLowerCase();
84
+ // Exact match
85
+ if (s1 === s2)
86
+ return true;
87
+ // One contains the other
88
+ if (s1.includes(s2) || s2.includes(s1))
89
+ return true;
90
+ // Calculate similarity using Levenshtein distance
91
+ const distance = levenshteinDistance(s1, s2);
92
+ const maxLength = Math.max(s1.length, s2.length);
93
+ const similarity = 1 - distance / maxLength;
94
+ return similarity >= threshold;
95
+ }
96
+ }