Skip to main content

Development Guide

Building from Source

Prerequisites

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

Clone and 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/mcp-server.cjs
  4. Bundles worker service to plugin/scripts/worker-service.cjs
  5. Bundles web viewer UI to plugin/ui/viewer.html
Build Output:
  • Hook executables: *-hook.js (ESM format)
  • Setup version-check: version-check.js (ESM format, sub-100ms)
  • Worker service: worker-service.cjs (CJS format)
  • MCP server: mcp-server.cjs (CJS format)
  • Viewer UI: viewer.html (self-contained HTML bundle)

Build Scripts

Development Workflow

1. Make Changes

Edit TypeScript source files in src/:

2. Build

3. Test

4. Manual Testing

5. Iterate

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

Viewer UI Development

Working with the React Viewer

The web viewer UI is a React application built into a self-contained HTML bundle. Location: src/ui/viewer/ Structure:

Building Viewer UI

Testing Viewer Changes

  1. Make changes to React components in src/ui/viewer/
  2. Build: npm run build
  3. Sync to installed plugin: npm run sync-marketplace
  4. Restart worker: npm run worker:restart
  5. Refresh the worker URL printed by npm run worker:status
Hot Reload: Not currently supported. Full rebuild + restart required for changes.

Adding New Viewer Features

Example: Adding a new card type
  1. Create component in src/ui/viewer/components/cards/YourCard.tsx:
  1. Import and use in Feed.tsx:
  1. Update types if needed in src/ui/viewer/types.ts
  2. Rebuild and test

Viewer UI Architecture

Data Flow:
  1. Worker service exposes HTTP + SSE endpoints
  2. React app fetches initial data via HTTP (paginated)
  3. SSE connection provides real-time updates
  4. Custom hooks handle state management and data merging
  5. Components render cards based on item type
Key Patterns:
  • Infinite Scroll: usePagination hook with Intersection Observer
  • Real-Time Updates: useSSE hook with auto-reconnection
  • Deduplication: merge.ts utilities prevent duplicate items
  • Settings Persistence: useSettings hook with localStorage
  • Theme Support: CSS variables with light/dark/system themes

Adding New Features

Adding a New Hook

  1. Create hook implementation in src/hooks/your-hook.ts:
Note: As of v4.3.1, hooks are self-contained files. The shebang will be added automatically by esbuild during the build process.
  1. Add to plugin/hooks/hooks.json:
  1. Rebuild:

Modifying Database Schema

  1. Add migration to src/services/sqlite/migrations.ts:
  1. Update types in src/services/sqlite/types.ts:
  1. Update database methods in src/services/sqlite/SessionStore.ts:
  1. Test migration:

Extending SDK Prompts

  1. Modify prompts in src/sdk/prompts.ts:
  1. Update parser in src/sdk/parser.ts:
  1. Test:

Adding MCP Search Tools

  1. Add tool definition in src/servers/mcp-server.ts:
  1. Add search method in src/services/sqlite/SessionSearch.ts:
  1. Rebuild and test:

Testing

Testing Philosophy

Claude-mem relies on real-world usage and manual testing rather than traditional unit tests. The project philosophy prioritizes:
  1. Manual verification - Testing features in actual Claude Code sessions
  2. Integration testing - Running the full system end-to-end
  3. Database inspection - Verifying data correctness via SQLite queries
  4. CLI tools - Interactive tools for checking system state
  5. Observability - Comprehensive logging and worker health checks
This approach was chosen because:
  • Hook behavior depends heavily on Claude Code’s runtime environment
  • SDK interactions require real API calls and responses
  • SQLite and Bun runtime provide stability guarantees
  • Manual testing catches integration issues that unit tests miss

Manual Testing Workflow

When developing new features:
  1. Build and sync:
  2. Test in real session:
    • Start Claude Code
    • Trigger the feature you’re testing
    • Verify expected behavior
  3. Check database state:
  4. Monitor worker logs:
  5. Verify queue health (for recovery features):

Testing Tools

Health Checks:
Hook Testing:
Data Verification:

Recovery Feature Testing

For manual recovery features specifically:
  1. Simulate stuck messages:
  2. Test recovery:
  3. Verify results:

Regression Testing

Before releasing:
  1. Test all hook triggers:
    • SessionStart: Start new Claude Code session
    • UserPromptSubmit: Submit a prompt
    • PostToolUse: Use a tool like Read
    • Summary: Let session complete
    • SessionEnd: Close Claude Code
  2. Test core features:
    • Context injection (recent sessions appear)
    • Observation processing (summaries generated)
    • MCP search tools (search returns results)
    • Viewer UI (loads at the worker URL)
    • Manual recovery (stuck messages recovered)
  3. Test edge cases:
    • Worker crash recovery
    • Database locks
    • Port conflicts
    • Large databases
  4. Cross-platform (if applicable):
    • macOS
    • Linux
    • Windows

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

Debugging

Enable Debug Logging

Inspect Database

Trace Observations

Use correlation IDs to trace observations through the pipeline:

Debug Hooks

Run hooks manually with test input:

Publishing

Production releases happen from main only. core-dev and community-edge are source-run branches; see Release Branches.

Version Bump

Update every manifest that carries the package version:
  • package.json
  • plugin/package.json
  • .claude-plugin/marketplace.json
  • .claude-plugin/plugin.json
  • plugin/.claude-plugin/plugin.json
  • .codex-plugin/plugin.json
  • plugin/.codex-plugin/plugin.json
  • openclaw/openclaw.plugin.json
Verify the old version is gone and the new version appears everywhere expected:

Build, Tag, and Publish

Publishing to npm requires the maintainer’s npm credentials and 2FA:
Only after npm resolves the version, create the GitHub release and regenerate the changelog:
Do not hand-edit CHANGELOG.md; it is generated from GitHub releases.

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: Do not hand-edit CHANGELOG.md; it is generated during release
  • 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

Troubleshooting Development

Build Fails

  1. Clean node_modules:
  2. Check Node.js version:
  3. Check for syntax errors:

Tests Fail

  1. Check database:
  2. Check worker status:
  3. View logs:

Worker Won’t Start

  1. Kill existing process:
  2. Check port:
  3. Try custom port:

Next Steps