@chude/memory
v4.0.0
Published
Cross-project context persistence for Claude Code sessions
Downloads
113
Maintainers
Readme
@chude/memory
Cross-project context persistence for Claude Code sessions.
Problem
Claude Code sessions are per-directory and deleted after 30 days. Context does not transfer between projects. Knowledge gained in one project is invisible to work in another.
Solution
Extract session JSONL files into a searchable SQLite database accessible from any project via the memory CLI.
Installation
bun add -g @chude/memorySetup
Install Claude Code hooks for automatic session sync:
memory installVerify installation:
memory doctorUsage
# Sync sessions to database
memory sync
# Search across all sessions
memory search "authentication patterns"
# Get context for a specific project
memory context wow-system
# List recent sessions
memory list
# Show session details
memory show <session-id>
# Find related sessions
memory related <session-id>
# Browse sessions interactively
memory browseHow It Works
- Claude Code stores sessions as JSONL files in
~/.claude/projects/ memory syncextracts messages, topics, and entities into a SQLite database with FTS5- Claude Code hooks trigger background sync automatically on session end
memory searchandmemory contextquery the database from any project directory
Data Paths
| Purpose | Path | Override |
|---------|------|----------|
| Config | ~/.config/memory/config.json | XDG_CONFIG_HOME |
| Database | ~/.local/share/memory/memory.db | XDG_DATA_HOME |
| Logs | ~/.local/share/memory/logs/ | XDG_DATA_HOME |
| Legacy memory files | ~/.memory/ | MEMORY_HOME |
Tool-managed paths follow the XDG Base Directory Specification. Override with XDG_CONFIG_HOME and XDG_DATA_HOME.
Legacy memory files are retained for compatibility with pre-v4 markdown sidecars. They are not read or written by default. To index them during sync, use memory sync --include-memory-files, set MEMORY_LEGACY_MEMORY_FILES=1, or set legacyMemoryFiles.enabled=true in config. To generate legacy daily logs with memory backfill, pass --write-memory-files or use the same env/config opt-in. MEMORY_HOME follows the GNUPGHOME / JAVA_HOME tradition: the value is the exact directory path, not a base directory under which a subdirectory is appended. Empty string is ignored; no ~ expansion.
Secret Handling
Remote provider credentials should come from environment injection, not plaintext config files. embedding.apiKey is retained only as deprecated compatibility input.
Use apiKeyEnv when a provider needs a runtime key:
{
"embedding": {
"provider": "openai",
"apiKeyEnv": "OPENAI_API_KEY"
}
}Use apiKeyRef only as opaque metadata for an external secret manager:
{
"embedding": {
"provider": "openai",
"apiKeyRef": "authkey://memory/openai-api-key"
}
}memory never resolves apiKeyRef to a raw secret and never calls authkey get. If you use authkey, inject secrets into the child process:
authkey run --env memory -- memory sync --embed
authkey run --env memory -- memory extract memory-nexusKnown secret patterns in newly synced transcript content, tool inputs/results, extraction payloads, embeddings, and CLI JSON exports are redacted before storage or provider egress. Raw JSON backups require explicit opt-in:
memory export backup.json --include-sensitiveProvider Support
Provider support is explicit and registry-backed. Built-in embedding providers are local, openai, ollama, and openai-compatible. Built-in extraction providers are claude-cli, anthropic, openai, ollama, and openai-compatible.
Use openai-compatible for gateways or providers that expose OpenAI-compatible APIs:
{
"embedding": {
"provider": "openai-compatible",
"baseUrl": "https://gateway.example.com/v1",
"apiKeyEnv": "MEMORY_GATEWAY_API_KEY"
}
}LLM_PROVIDER selects the extraction provider. LLM_MODEL overrides the extraction model without changing embedding configuration.
AI-First Design
This tool is designed for Claude to use via the Bash tool:
# Claude runs these commands to access cross-project knowledge
memory context <project-name>
memory search "query" --limit 5Standard CLI output works for both humans and AI agents.
Programmatic API
Install as a dependency:
bun add @chude/memoryImport and call execute functions:
import {
executeSyncCommand,
executeSearchCommand,
executeContextCommand,
type CommandResult,
type SyncCommandOptions,
type SearchCommandOptions,
type SearchMode,
} from "@chude/memory";
// Sync sessions to database
const syncResult = await executeSyncCommand({ quiet: true });
// syncResult: { exitCode: 0 }
// Search sessions
const searchResult = await executeSearchCommand("authentication patterns", {
limit: "5",
json: true,
});
// Get project context
const contextResult = await executeContextCommand("my-project", {
json: true,
days: 7,
});Exported Functions
| Function | Parameters | Returns |
|----------|------------|---------|
| executeSyncCommand | options: SyncCommandOptions | Promise<CommandResult> |
| executeSearchCommand | query: string, options: SearchCommandOptions | Promise<CommandResult> |
| executeListCommand | options: ListCommandOptions | Promise<CommandResult> |
| executeStatsCommand | options: StatsCommandOptions | Promise<CommandResult> |
| executeContextCommand | project: string, options: ContextCommandOptions | Promise<CommandResult> |
| executeRelatedCommand | sessionId: string, options: RelatedCommandOptions | Promise<CommandResult> |
| executeShowCommand | sessionId: string, options: ShowCommandOptions | Promise<CommandResult> |
| executeBrowseCommand | options: BrowseCommandOptions | Promise<CommandResult> |
| executeInstallCommand | options: InstallOptions | Promise<CommandResult> |
| executeUninstallCommand | options: UninstallOptions | Promise<CommandResult> |
| executeStatusCommand | options: StatusOptions | Promise<CommandResult> |
| executeDoctorCommand | options: DoctorOptions | Promise<CommandResult> |
| executePurgeCommand | options: PurgeCommandOptions | Promise<CommandResult> |
| executeExportCommand | outputPath: string, options: ExportOptions | Promise<CommandResult> |
| executeImportCommand | inputPath: string, options: ImportOptions | Promise<CommandResult> |
| executeCompletionCommand | shell: string | CommandResult |
CommandResult
interface CommandResult {
exitCode: number; // 0 = success, 1 = error/not found
}All functions handle their own database initialization and teardown. They never call process.exit().
Domain Types
The following domain types are exported for TypeScript consumers who need typed search and stats operations:
| Type | Description |
|------|-------------|
| SearchMode | Union type: "auto" \| "fts" \| "vector" \| "hybrid". Controls search strategy. |
| HybridSearchOptions | Extends SearchOptions with mode and noDecay fields for hybrid search. |
| IStatsService | Port interface for database statistics queries. |
| StatsResult | Return type from IStatsService.getStats(): session/message/tool-use totals, database size, and per-project breakdown. |
| ProjectStats | Per-project statistics: projectName, sessionCount, messageCount. |
import type {
SearchMode,
HybridSearchOptions,
IStatsService,
StatsResult,
ProjectStats,
} from "@chude/memory";
// Typed search options
const opts: HybridSearchOptions = {
mode: "hybrid" satisfies SearchMode,
limit: 10,
};
// Typed stats result
function processStats(stats: StatsResult): void {
console.log(`${stats.totalSessions} sessions, ${stats.totalMessages} messages`);
stats.projectBreakdown.forEach((p: ProjectStats) => {
console.log(` ${p.projectName}: ${p.messageCount} messages`);
});
}Previously Published As
This package was previously published as memory-nexus. The old package name now installs a deprecation stub. See MIGRATION.md for upgrade instructions.
Development
Quality gates
bun run typecheck
bun run build
bun test --timeout 15000
bun run test:isolation
bun run test:coverage
bun auditbun run quality runs the release gate sequence. bun run test:coverage uses an Istanbul-backed Bun harness and is intentionally strict: statements, branches, functions, and lines must each be available and at least 95%. Missing metrics fail the gate.
Running tests on Windows
Current 2026-05-28 verification has bun test --timeout 15000 passing on Windows 11 with Bun 1.3.5. A previous full-suite run crashed with Bun's panic(main thread): integer overflow signature at ~6.8GB peak memory pressure; keep the subdirectory workaround available if that upstream runtime crash returns.
Fallback workaround: run the suite by subdirectory.
bun test src/infrastructure/
bun test src/presentation/
bun test src/application src/domain
bun test tests/helpers tests/generators tests/infrastructure tests/integration tests/smokeOr run a single file directly:
bun test src/path/to/file.test.tsLinux and macOS contributors should run the full suite normally.
License
MIT
