Files
claude-mem/docs/development.md
T
Alex Newman 12149470a2 Add installation, troubleshooting, and usage documentation for Claude-Mem plugin
- Created comprehensive installation guide detailing quick start, system requirements, and advanced installation steps.
- Developed troubleshooting guide addressing common issues with worker service, hooks, database, and search tools.
- Introduced getting started documentation explaining automatic operation, session summaries, and context injection.
- Added detailed usage instructions for MCP search tools, including query examples and advanced filtering techniques.
2025-10-23 23:40:42 -04:00

9.7 KiB

Development Guide

Building from Source

Prerequisites

  • Node.js 18.0.0 or higher
  • npm (comes with Node.js)
  • Git

Clone and Build

# Clone repository
git clone https://github.com/thedotmack/claude-mem.git
cd claude-mem

# Install dependencies
npm install

# Build all components
npm run build

Build Process

The build process uses esbuild to compile TypeScript:

  1. Compiles TypeScript to JavaScript
  2. Creates standalone executables for each hook in plugin/scripts/
  3. Bundles MCP search server to plugin/scripts/search-server.js
  4. Bundles worker service to plugin/scripts/worker-service.cjs

Build Output:

  • Hook executables: *-hook.js (ESM format)
  • Worker service: worker-service.cjs (CJS format)
  • Search server: search-server.js (ESM format)

Build Scripts

# Build everything
npm run build

# Build only hooks
npm run build:hooks

# The build script is defined in scripts/build-hooks.js

Development Workflow

1. Make Changes

Edit TypeScript source files in src/:

src/
├── bin/hooks/       # Hook entry points
├── hooks/           # Hook implementations
├── services/        # Worker service and database
├── servers/         # MCP search server
├── sdk/             # Claude Agent SDK integration
├── shared/          # Shared utilities
└── utils/           # General utilities

2. Build

npm run build

3. Test

# Run all tests
npm test

# Test specific file
node --test tests/session-lifecycle.test.ts

# Test context injection
npm run test:context

# Verbose context test
npm run test:context:verbose

4. Manual Testing

# Start worker manually
npm run worker:start

# Check worker status
npm run worker:status

# View logs
npm run worker:logs

# Test hooks manually
echo '{"session_id":"test-123","cwd":"'$(pwd)'","source":"startup"}' | node plugin/scripts/context-hook.js

5. Iterate

Repeat steps 1-4 until your changes work as expected.

Adding New Features

Adding a New Hook

  1. Create hook implementation in src/hooks/your-hook.ts:
import { HookInput } from './types';

export async function yourHook(input: HookInput) {
  // Hook implementation
  return {
    hookSpecificOutput: 'Optional output'
  };
}
  1. Create entry point in src/bin/hooks/your-hook.ts:
#!/usr/bin/env node
import { readStdin } from '../../shared/stdin';
import { yourHook } from '../../hooks/your-hook';

async function main() {
  const input = await readStdin();
  const result = await yourHook(input);
  console.log(JSON.stringify(result));
}

main().catch(console.error);
  1. Add to plugin/hooks/hooks.json:
{
  "YourHook": [{
    "hooks": [{
      "type": "command",
      "command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/your-hook.js",
      "timeout": 120
    }]
  }]
}
  1. Rebuild:
npm run build

Modifying Database Schema

  1. Add migration to src/services/sqlite/migrations.ts:
export const migration011: Migration = {
  version: 11,
  up: (db: Database) => {
    db.run(`
      ALTER TABLE observations ADD COLUMN new_field TEXT;
    `);
  },
  down: (db: Database) => {
    // Optional: define rollback
  }
};
  1. Update types in src/services/sqlite/types.ts:
export interface Observation {
  // ... existing fields
  new_field?: string;
}
  1. Update database methods in src/services/sqlite/SessionStore.ts:
createObservation(obs: Observation) {
  // Include new_field in INSERT
}
  1. Test migration:
# Backup database first!
cp ~/.claude-mem/claude-mem.db ~/.claude-mem/claude-mem.db.backup

# Run tests
npm test

Extending SDK Prompts

  1. Modify prompts in src/sdk/prompts.ts:
export function buildObservationPrompt(observation: Observation): string {
  return `
    <observation>
      <!-- Add new XML structure -->
    </observation>
  `;
}
  1. Update parser in src/sdk/parser.ts:
export function parseObservation(xml: string): ParsedObservation {
  // Parse new XML fields
}
  1. Test:
npm test

Adding MCP Search Tools

  1. Add tool definition in src/servers/search-server.ts:
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === 'your_new_tool') {
    // Implement tool logic
    const results = await search.yourNewSearch(params);
    return formatResults(results);
  }
});
  1. Add search method in src/services/sqlite/SessionSearch.ts:
yourNewSearch(params: YourParams): SearchResult[] {
  // Implement FTS5 search
}
  1. Rebuild and test:
npm run build
npm test

Testing

Running Tests

# All tests
npm test

# Specific test file
node --test tests/your-test.test.ts

# With coverage (if configured)
npm test -- --coverage

Writing Tests

Create test files in tests/:

import { describe, it } from 'node:test';
import assert from 'node:assert';

describe('YourFeature', () => {
  it('should do something', () => {
    // Test implementation
    assert.strictEqual(result, expected);
  });
});

Test Database

Use a separate test database:

import { SessionStore } from '../src/services/sqlite/SessionStore';

const store = new SessionStore(':memory:'); // In-memory database

Code Style

TypeScript Guidelines

  • Use TypeScript strict mode
  • Define interfaces for all data structures
  • Use async/await for asynchronous code
  • Handle errors explicitly
  • Add JSDoc comments for public APIs

Formatting

  • Follow existing code formatting
  • Use 2-space indentation
  • Use single quotes for strings
  • Add trailing commas in objects/arrays

Example

/**
 * Create a new observation in the database
 */
export async function createObservation(
  obs: Observation
): Promise<number> {
  try {
    const result = await db.insert('observations', {
      session_id: obs.session_id,
      tool_name: obs.tool_name,
      // ...
    });
    return result.id;
  } catch (error) {
    logger.error('Failed to create observation', error);
    throw error;
  }
}

Debugging

Enable Debug Logging

export DEBUG=claude-mem:*
npm run worker:restart
npm run worker:logs

Inspect Database

sqlite3 ~/.claude-mem/claude-mem.db

# View schema
.schema observations

# Query data
SELECT * FROM observations LIMIT 10;

Trace Observations

Use correlation IDs to trace observations through the pipeline:

sqlite3 ~/.claude-mem/claude-mem.db
SELECT correlation_id, tool_name, created_at
FROM observations
WHERE session_id = 'YOUR_SESSION_ID'
ORDER BY created_at;

Debug Hooks

Run hooks manually with test input:

# Test context hook
echo '{"session_id":"test-123","cwd":"'$(pwd)'","source":"startup"}' | node plugin/scripts/context-hook.js

# Test new hook
echo '{"session_id":"test-123","cwd":"'$(pwd)'","prompt":"test"}' | node plugin/scripts/new-hook.js

Publishing

NPM Publishing

# Update version in package.json
npm version patch  # or minor, or major

# Build
npm run build

# Publish to NPM
npm run release

The release script:

  1. Runs tests
  2. Builds all components
  3. Publishes to NPM registry

Creating a Release

  1. Update version in package.json
  2. Update CHANGELOG.md
  3. Commit changes
  4. Create git tag
  5. Push to GitHub
  6. Publish to NPM
# Update version
npm version 4.2.4

# Update changelog
# Edit CHANGELOG.md manually

# Commit
git add .
git commit -m "chore: Release v4.2.4"

# Tag
git tag v4.2.4

# Push
git push origin main --tags

# Publish to NPM
npm run release

Contributing

Contribution Workflow

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Write tests
  5. Update documentation
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Pull Request Guidelines

  • Clear title: Describe what the PR does
  • Description: Explain why the change is needed
  • Tests: Include tests for new features
  • Documentation: Update docs as needed
  • Changelog: Add entry to CHANGELOG.md
  • Commits: Use clear, descriptive commit messages

Code Review Process

  1. Automated tests must pass
  2. Code review by maintainer
  3. Address feedback
  4. Final approval
  5. Merge to main

Development Tools

  • TypeScript
  • ESLint
  • Prettier
  • SQLite Viewer

Useful Commands

# Check TypeScript types
npx tsc --noEmit

# Lint code (if configured)
npm run lint

# Format code (if configured)
npm run format

# Clean build artifacts
rm -rf plugin/scripts/*.js plugin/scripts/*.cjs

Troubleshooting Development

Build Fails

  1. Clean node_modules:

    rm -rf node_modules
    npm install
    
  2. Check Node.js version:

    node --version  # Should be >= 18.0.0
    
  3. Check for syntax errors:

    npx tsc --noEmit
    

Tests Fail

  1. Check database:

    rm ~/.claude-mem/claude-mem.db
    npm test
    
  2. Check worker status:

    npm run worker:status
    
  3. View logs:

    npm run worker:logs
    

Worker Won't Start

  1. Kill existing process:

    pm2 delete claude-mem-worker
    
  2. Check port:

    lsof -i :37777
    
  3. Try custom port:

    export CLAUDE_MEM_WORKER_PORT=38000
    npm run worker:start
    

Next Steps