In-Memoria

repository·main·Indexed 41 days ago

https://github.com/pi22by7/in-memoria

Persistent intelligence infrastructure for agentic development (v0.6.0). In-Memoria extracts and manages developer patterns from codebases, providing a Model Context Protocol (MCP) interface for AI agents like Claude Code to interact with these patterns.

Tokens
19.5K
Snippets
58
Records
85
Agent score
51%

What's inside In-Memoria

  1. How unit tests and integration tests differ

    main

    The project uses two distinct testing layers to balance speed and reliability:

    Unit Tests (src/__tests__/)

    • Framework: Vitest
    • Purpose: Testing single functions or classes in isolation with mocked dependencies.
    • Characteristics: Fast (milliseconds), runs automatically in CI/CD, provides coverage reporting.
    • Execution: npm test

    Integration & Manual Tests (tests/)

    • Framework: Custom Node.js scripts
    • Purpose: Testing multiple components together, full workflows, and manual debugging.
    • Characteristics: Slower (seconds), uses real file systems and databases, requires manual verification.
    • Execution: npm run test:integration or node tests/test-*.js
    // Example Unit Test (src/__tests__/sqlite-db.test.ts)
    it('should store semantic concepts', () => {
      const concept = { id: 'test', name: 'TestClass', ... };
      database.insertSemanticConcept(concept);
      expect(database.getSemanticConcepts()).toHaveLength(1);
    });
    
    // Example Integration Test (tests/test-learning.js)
    const analyzer = new SemanticAnalyzer();
    const concepts = await analyzer.learnFromCodebase("./src");
    console.log(`Learned ${concepts.length} concepts`);
  2. How to use In-Memoria tools effectively

    main

    To get the best results from In-Memoria, follow this mental model for tool selection:

    1. Initial Setup: Always call auto_learn_if_needed first. It is a no-op if intelligence data already exists but ensures the codebase is indexed.
    2. Project Overview: Use get_project_blueprint for high-level understanding of tech stacks, entry points, and architecture.
    3. File Routing: When asking "where should I work?" or "what files do I need to modify?", use predict_coding_approach instead of searching. It is designed to route you directly to relevant files.
    4. Deep Dives: Use analyze_codebase for a one-time, detailed analysis of a specific file or directory (AST structure, complexity metrics). Do not use this for project-wide understanding.
    5. Code Search:
      • Use get_semantic_insights to find code-level symbols (variables, functions, classes) and their relationships/dependencies. Note: This searches code identifiers, not business/domain concepts.
      • Use search_codebase for literal text matching or regex/AST patterns.
    6. Implementation Guidance: Use get_pattern_recommendations to follow existing patterns (e.g., Factory, Singleton) learned from your specific codebase. Use get_developer_profile to understand the codebase's specific style and naming conventions.
  3. Perform manual regression testing for In-Memoria

    main

    If you have modified the core logic or are troubleshooting reliability, follow this sequence to ensure a clean state and verify fixes:

    1. Clean the environment: Remove the existing database.
    2. Rebuild and Re-learn: Build the project and force a fresh learning pass on your target directory.
    3. Verify Database Population: Check that entry_points, key_directories, and feature_map contain expected data.
    4. Test MCP Tools: Run the MCP server and use a client (like Claude Code) to invoke the tools.
    # 1. Clean slate
    rm in-memoria.db
    
    # 2. Relearn with fixes
    npm run build
    node dist/index.js learn . --force
    
    # 3. Verify database populated
    sqlite3 in-memoria.db "SELECT COUNT(*) FROM entry_points;"
    sqlite3 in-memoria.db "SELECT feature_name FROM feature_map;"
    
    # 4. Test MCP tools
    npx in-memoria server
  4. Initialize In-Memoria intelligence

    main

    Before using most In-Memoria tools, you must ensure the codebase intelligence is built.

    • Recommended: Call auto_learn_if_needed. This is the safest method for seamless integration as it only runs if data is missing or stale.
    • Manual: Use learn_codebase_intelligence to build the database from scratch (takes ~30-60s). Use the force=true option if the codebase has undergone significant changes.
  5. Verify feature map coverage

    main

    To ensure the project has correctly mapped its features (including language-support, rust-core, mcp-server, and cli), you can inspect the database directly or via the MCP server.

    Manual Verification Steps:

    1. Restart the MCP server.
    2. Re-run the learning process: npm run learn <project_path>.
    3. Check the feature_map table in the SQLite database.

    Example SQL check:

    SELECT feature_name FROM feature_map;
    npm run learn /path/to/your/project
    
    sqlite3 in-memoria.db "SELECT feature_name FROM feature_map;"
  6. Write a Unit Test with Vitest

    main

    Unit tests should be fast (< 1s), isolated, and avoid external dependencies like the file system or network. Use the createTestWorkspace utility from @tests/helpers/test-utils to manage test environments and ensure you call workspace.cleanup() in the afterEach hook to prevent resource leaks.

    Follow the AAA (Arrange, Act, Assert) pattern.

    import { describe, it, expect, beforeEach, afterEach } from "vitest";
    import { createTestWorkspace } from "@tests/helpers/test-utils";
    
    describe("ComponentName", () => {
      let workspace: ReturnType<typeof createTestWorkspace>;
    
      beforeEach(() => {
        // Setup test environment
        workspace = createTestWorkspace({
          "test.ts": 'export const hello = "world";',
        });
      });
    
      afterEach(() => {
        // Cleanup
        workspace.cleanup();
      });
    
      it("should perform expected behavior", () => {
        // Arrange
        const input = "test input";
    
        // Act
        const result = componentFunction(input);
    
        // Assert
        expect(result).toBe("expected output");
      });
    
      it("should handle edge cases", () => {
        // Test edge cases
        expect(() => componentFunction(null)).toThrow();
      });
    });
  7. Fix Interactive Setup Password Masking

    main

    If you are developing or modifying the in-memoria setup --interactive CLI command, ensure that password inputs correctly mask characters.

    To prevent the terminal from echoing the actual character alongside the asterisk (e.g., y*), use the following sequence to clear the echoed character before writing the mask:

    1. Move cursor back (\b)
    2. Overwrite with a space ( )
    3. Move cursor back again (\b)
    4. Write the asterisk (*)

    This ensures a clean * display for sensitive inputs like OpenAI API keys.

    // Correct way to mask characters in a raw terminal
    } else if (char >= ' ') {
      input += char;
      process.stdout.write('\b \b*');
    }
  8. Avoid Token Overflow in MCP Tools

    main

    When using In-Memoria MCP tools like get_pattern_recommendations or get_developer_profile with large codebases, you may encounter token overflow errors if the response exceeds the client's limit (e.g., 25,000 tokens in Claude Code).

    To prevent this, ensure you are using the latest version of In-Memoria which implements internal limits. If you are building custom tools or extensions, follow these best practices:

    1. Apply Database Limits: Always use LIMIT clauses in SQL queries to avoid fetching thousands of records at once.
    2. Truncate Code Examples: Do not return full source code for every example. Truncate long snippets to a reasonable character count (e.g., 150-200 characters).
    3. Limit Examples per Pattern: Instead of returning all examples associated with a pattern, return only a small subset (e.g., 2 examples).
    4. Implement Pagination: Use limit and offset parameters in your tool schemas to allow users to traverse large datasets incrementally.
  9. Write an Integration Test

    main

    Integration tests verify realistic workflows and multi-component interactions (e.g., MCP Client-Server). They are slower (5-30s) and may require real file system operations. Always ensure you handle errors and exit with a non-zero code on failure to support CI/CD pipelines.

    #!/usr/bin/env node
    
    import { CodeCartographerMCP } from "../dist/mcp-server/server.js";
    
    async function testIntegration() {
      console.log("🧪 Testing integration scenario...\n");
    
      try {
        // Setup
        const server = new CodeCartographerMCP();
        await server.initialize();
    
        // Test
        const result = await server.handleRequest({
          method: "test",
          params: {},
        });
    
        // Verify
        if (!result) {
          throw new Error("Expected result to be defined");
        }
    
        console.log("✅ Integration test passed");
      } catch (error) {
        console.error("❌ Integration test failed:", error);
        process.exit(1);
      }
    }
    
    testIntegration();
  10. Quick Start: Running Tests

    main

    Use the following npm commands to execute different test suites in the project:

    • Unit tests: Fast, automated tests for individual components.
    • Coverage: Runs unit tests and generates coverage reports.
    • Integration tests: Slower, end-to-end tests for full workflows.
    # Run unit tests (fast, automated)
    npm test
    
    # Run with coverage
    npm run test:coverage
    
    # Run integration tests (slower, end-to-end)
    npm run test:integration
  11. Run In-Memoria tests

    main

    In-Memoria uses three main testing layers: Unit tests (Vitest), Integration tests (custom harness), and Manual tests (custom scripts). Use the following commands to execute them based on your needs.

    Unit Tests (Vitest)

    Used for isolated testing of functions, classes, and modules in src/__tests__/.

    • npm test: Run all unit tests.
    • npm test -- --watch: Run in watch mode for development.
    • npm test -- <filename>: Run a specific test file.
    • npm test -- --coverage: Run with coverage reports.
    • npm test -- --grep "<pattern>": Run tests matching a specific pattern.
    • npm test -- --ui: Run with the interactive Vitest UI.

    Integration Tests

    Used for testing multi-component interactions and full workflows in tests/integration/.

    • npm run test:manual: Run all integration tests.
    • node tests/integration/<filename>.js: Run a specific integration test.
    • NODE_OPTIONS='--inspect' node tests/integration/<filename>.js: Run with debugging enabled.

    Manual Tests

    Used for developer debugging and exploration in tests/.

    • node tests/run-all.js: Run all manual tests sequentially.
    • node tests/test-<name>.js: Run a specific manual test.
    • DEBUG=* node tests/test-<name>.js: Run with debug output enabled.
    # Quick Start Summary
    # Run all unit tests
    npm test
    
    # Run tests in watch mode
    npm test -- --watch
    
    # Run specific unit test file
    npm test -- sqlite-db.test.ts
    
    # Run manual integration tests
    npm run test:manual
    
    # Run specific manual test
    node tests/test-simple.js
  12. Run the Interactive Setup Wizard

    main

    The InteractiveSetup utility provides a guided CLI wizard to configure In Memoria for a specific project. It automates the creation of configuration files, language detection, and initial codebase learning.

    The wizard performs the following steps:

    1. Project Basics: Sets the project name and path.
    2. Language Detection: Scans the project to detect supported languages (e.g., TypeScript, Python, Rust, Go).
    3. Intelligence Configuration: Enables real-time analysis and pattern learning.
    4. Vector Embeddings: Configures local semantic search (using transformers.js and the all-MiniLM-L6-v2 model) which runs entirely on your machine without API keys.
    5. File Watching: Sets up patterns for monitoring file changes and defines ignored paths (e.g., node_modules, .git).
    6. Initial Learning: Optionally triggers an immediate analysis of the codebase to extract semantic concepts and patterns.
    7. Configuration Persistence: Saves settings to .in-memoria/config.json and updates .gitignore to include In Memoria artifacts.

    Post-Setup Steps: After the wizard completes, you should:

    1. Run in-memoria server to start the MCP server.
    2. Add In Memoria to your Claude Desktop or Code configuration.
    // Note: The setup is typically invoked via the CLI entrypoint.
    // Once configured, follow the wizard's instructions to start the server.
    in-memoria server