Skip to main content

Development Guide

Building from Source

Prerequisites

  • Node.js satisfying ^20.19.0 || >=22.12.0 (see package.json)
  • npm (comes with Node.js)
  • Bun 1.1.31 or higher (required to run tests)
  • 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, hand-written; installs missing plugin dependencies and records the install marker)
  • Worker service: worker-service.cjs (CJS format)
  • MCP server: mcp-server.cjs (CJS format)
  • Viewer UI: viewer.html (self-contained HTML bundle)

Committed release bundles

Marketplace installs run the committed files in plugin/scripts/. When changing release versions or worker lifecycle code, regenerate and commit the affected runtime bundles with npm run build. A newer manifest paired with an older worker bundle can trigger repeated version-mismatch restarts. CI checks committed bundle versions before rebuilding:
If a replacement worker still reports a stale version, hooks remember the failed recycle in the data directory and skip further recycles of that unchanged bundle. Rebuild or reinstall the bundle to correct the version; a changed bundle allows another recycle attempt.

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 uses automated tests alongside manual verification in real host sessions. The automated suite runs with Bun. scripts/test-lanes.ts divides discovered tests into two lanes: the fast lane is the default for npm test; the integration lane includes browser tests, tests under tests/integration/, and smart-file-read service tests. Use npm run test:all to run both lanes, and npm run test:lanes:check to check that the lanes are disjoint and cover every discovered test file. Run tests relevant to your change during development. Manual verification can then check host integration, database state, logs, and worker health in a real session. It complements automated regression coverage; a manual check does not establish that the automated suite passes.

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

Releases ship from main only, and pull requests target main.

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 docs/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 docs/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