Compare commits

...

6 Commits

Author SHA1 Message Date
Alex Newman c231e8d076 chore: Bump version to 6.1.1 2025-11-20 20:39:40 -05:00
Alex Newman b62e93577c fix: Use dynamic project name detection for ChromaDB collections and observations (#142)
* fix: Use dynamic project name detection instead of hardcoded values

Fixes #140

Previously, the worker process used hardcoded "claude-mem" for:
- ChromaSync instantiation in DatabaseManager
- ChromaDB collection naming in search-server

This caused all observations to be tagged with "claude-mem" regardless
of the actual project being worked on.

Now both services use getCurrentProjectName() to dynamically detect the
project based on the worker's current working directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Simplify viewer UI overflow CSS to enable scrolling

- Remove overcomplicated nested overflow containers
- Use explicit 100vh for layout height
- Add overflow: hidden to main-col to constrain feed
- Keep simple overflow-y: auto on feed element
- Fix issue where feed content wouldn't scroll

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-20 20:37:57 -05:00
Alex Newman 0787e47b1a Add AI Memory Economics analysis to README
Added a new section for AI Memory Economics analysis with key insights and a link.
2025-11-20 00:47:44 -05:00
Alex Newman f9843fe593 docs: Compress CLAUDE.md to bare essentials
Removed verbose explanations and kept only critical reference info:
- What the project is
- Architecture overview (hooks, worker, database, skills, chroma, viewer)
- Build commands for different scenarios
- Environment variables
- File locations
- Quick reference commands

Moved general coding standards to ~/.claude/CLAUDE.md (global config).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 18:12:27 -05:00
Alex Newman 5b772ee768 docs: Fix v6.1.0 release notes accuracy 2025-11-19 17:24:21 -05:00
Alex Newman baabf14bfa docs: Update CHANGELOG.md for v6.1.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 17:14:45 -05:00
11 changed files with 109 additions and 233 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
"plugins": [
{
"name": "claude-mem",
"version": "6.1.0",
"version": "6.1.1",
"source": "./plugin",
"description": "Persistent memory system for Claude Code - context compression across sessions"
}
+12
View File
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [6.1.0] - 2025-11-19
## Viewer UI: Responsive Layout Improvements
The viewer UI now handles narrow screens better with responsive breakpoints:
- Community button relocates to sidebar below 600px width
- Projects dropdown relocates to sidebar below 480px width
- Sidebar constrained to 400px max width
Makes the viewer usable on phones and narrow browser windows.
## [6.0.9] - 2025-11-17
## Queue Depth Indicator Feature
+30 -185
View File
@@ -6,175 +6,33 @@
Claude-mem is a Claude Code plugin providing persistent memory across sessions. It captures tool usage, compresses observations using the Claude Agent SDK, and injects relevant context into future sessions.
**Your Role**: You are working on the plugin itself. When users interact with Claude Code with this plugin installed, your observations get captured and become their persistent memory.
**Current Version**: 6.1.1
**Current Version**: 6.1.0
## Architecture
## IMPORTANT: Skills Are Auto-Invoked
**5 Lifecycle Hooks**: SessionStart → UserPromptSubmit → PostToolUse → Summary → SessionEnd
**There is no `/skill` command.** Skills auto-invoke based on description metadata matching user queries. Don't document manual invocation (e.g., "Run `/skill troubleshoot`"). Instead: "The troubleshoot skill auto-activates when issues are detected."
**Hooks** (`src/hooks/*.ts`) - TypeScript → ESM, built to `plugin/scripts/*-hook.js`
## Critical Architecture Knowledge
**Worker Service** (`src/services/worker-service.ts`) - Express API on port 37777, PM2-managed, handles AI processing asynchronously
### The Lifecycle Flow
**Database** (`src/services/sqlite/`) - SQLite3 at `~/.claude-mem/claude-mem.db` with FTS5 full-text search
1. **SessionStart** → smart-install.js runs first (pre-hook), then `context-hook.ts` runs
- Smart installer checks dependencies (cached, only runs on version changes)
- Starts PM2 worker if not healthy
- Injects context from previous sessions (configurable observation count)
**Search Skill** (`plugin/skills/mem-search/SKILL.md`) - HTTP API for searching past work, auto-invoked when users ask about history
2. **UserPromptSubmit**`new-hook.ts` runs
- Creates session record in SQLite
- Saves raw user prompt for FTS5 search
**Chroma** (`src/services/sync/ChromaSync.ts`) - Vector embeddings for semantic search
3. **PostToolUse** `save-hook.ts` runs
- Captures your tool executions
- Sends to worker service for AI compression
**Viewer UI** (`src/ui/viewer/`) - React interface at http://localhost:37777, built to `plugin/ui/viewer.html`
4. **Summary** → Summary hook generates session summaries
## Build Commands
5. **SessionEnd** `cleanup-hook.ts` runs
- Marks session complete (graceful, not DELETE)
- Skips on `/clear` to preserve ongoing sessions
**Hooks only**: `npm run build && npm run sync-marketplace`
**Note**: smart-install.js is a pre-hook script (not a lifecycle hook). It's called before context-hook via command chaining in hooks.json and only runs when dependencies need updating.
**Worker changes**: `npm run build && npm run sync-marketplace && npm run worker:restart`
### Key Components
**Skills only**: `npm run sync-marketplace`
**Hooks** (`src/hooks/*.ts`)
- Built to `plugin/scripts/*-hook.js` (ESM format)
- Must output valid JSON to `hookSpecificOutput` field
- Called by Claude Code lifecycle events
**Worker Service** (`src/services/worker-service.ts`)
- Express.js API on port 37777 (configurable via `CLAUDE_MEM_WORKER_PORT`)
- Managed by PM2 (auto-started by hooks)
- Built to `plugin/worker-service.cjs` (CJS format)
- Handles AI processing asynchronously to avoid hook timeouts
**Database** (`src/services/sqlite/`)
- SQLite3 with better-sqlite3 (NOT bun:sqlite - that's legacy)
- Location: `~/.claude-mem/claude-mem.db`
- FTS5 virtual tables for full-text search
- `SessionStore` = CRUD, `SessionSearch` = FTS5 queries
**Search Skill** (`plugin/skills/mem-search/SKILL.md`)
- Provides access to all search functionality via HTTP API + skill
- Auto-invoked when users ask about past work, decisions, or history
- Uses HTTP endpoints instead of MCP tools (~2,250 token savings per session)
- 10 search operations: observations, sessions, prompts, by-type, by-file, by-concept, timelines, etc.
**Chroma Vector Database** (`src/services/sync/ChromaSync.ts`)
- Hybrid semantic + keyword search architecture
- Automatic vector embedding synchronization
- 90-day recency filtering for relevant results
- Combined with SQLite FTS5 for optimal search performance
**Viewer UI** (`src/ui/viewer/`)
- React + TypeScript web interface accessible at http://localhost:37777
- Real-time memory stream visualization via Server-Sent Events (SSE)
- Infinite scroll pagination for observations, sessions, and user prompts
- Project filtering and settings persistence
- Built to `plugin/ui/viewer.html` (self-contained bundle via esbuild)
- Auto-reconnection and error recovery
## How to Make Changes
### When You Modify Hooks
```bash
npm run build
npm run sync-marketplace
```
Changes take effect on next Claude Code session. No worker restart needed.
### When You Modify Worker Service
```bash
npm run build
npm run sync-marketplace
npm run worker:restart
```
Must restart PM2 worker for changes to take effect.
### When You Modify Search Skill
```bash
npm run sync-marketplace
```
Skill changes take effect immediately on next Claude Code session. No build or restart needed (skills are markdown).
### When You Modify Viewer UI
```bash
npm run build
npm run sync-marketplace
npm run worker:restart
```
Changes to React components, styles, or viewer logic require rebuilding and restarting the worker. Refresh browser to see changes.
### Build Pipeline
1. `npm run build` → Compiles TypeScript, outputs to `plugin/`
2. `npm run sync-marketplace` → Syncs to `~/.claude/plugins/marketplaces/thedotmack/`
3. Changes are live for next session (hooks/skills) or after restart (worker)
## Coding Standards
**Philosophy**: Write the dumb, obvious thing first. Add complexity only when you hit the problem.
**Key Principles:**
1. **YAGNI**: Don't build it until you need it
2. **DRY**: Extract patterns after second duplication, not before
3. **Fail Fast**: Explicit errors beat silent failures
4. **Simple First**: Write the obvious solution, optimize only if needed
5. **Delete Aggressively**: Less code = fewer bugs
6. **Semantic Naming**: Always name variables, parameters, and API endpoints with verbose, self-documenting names that optimize for comprehension by both humans and LLMs, not brevity (e.g., `wait_until_obs_is_saved=true` vs `wait=true`)
**Common anti-patterns to avoid:**
- Ceremonial wrapper functions for constants (just export the constant)
- Unused default parameters (remove if never used)
- Magic numbers without named constants
- Silent failures instead of explicit errors
- Fragile string parsing (use structured JSON output)
- Copy-pasted promise wrappers (extract helper functions)
- Overengineered "defensive" code for problems you don't have
## Common Tasks
### Adding a New Hook
1. Create `src/hooks/new-hook.ts`
2. Add to `scripts/build-hooks.js` build list
3. Add configuration to `plugin/hooks/hooks.json`
4. Build and sync: `npm run build && npm run sync-marketplace`
**Note**: smart-install.js is not a hook - it's a pre-hook dependency checker that runs before context-hook via command chaining.
### Modifying Database Schema
1. Update schema in `src/services/sqlite/schema.ts`
2. Update SessionStore/SessionSearch classes
3. Migration strategy: The plugin currently recreates on schema changes (alpha phase). Production deployments will require proper migration handling.
### Debugging Worker Issues
```bash
pm2 list # Check worker status
npm run worker:logs # View logs
npm run worker:restart # Restart if needed
pm2 delete claude-mem-worker # Force clean start
```
### Testing Changes Locally
1. Make changes in `src/`
2. `npm run build && npm run sync-marketplace`
3. Start new Claude Code session (hooks) or restart worker (worker changes)
4. Check `~/.claude-mem/claude-mem.db` for database state
5. Use mem-search skill to verify behavior (auto-invoked when asking about past work)
### Version Bumps
Use the `version-bump` skill (auto-invokes when requesting version updates). It handles:
- Semantic version increments (patch/minor/major)
- Updates all version references (package.json, plugin.json, CLAUDE.md, marketplace.json)
- Creates git tags and GitHub releases
- Auto-generates CHANGELOG.md from releases
## Investigation Best Practices
When investigations fail persistently, use Task agents for comprehensive file analysis instead of repeated grep/search. Deploy agents to read full files and answer specific questions - more efficient than multiple rounds of searching.
**Viewer UI**: `npm run build && npm run sync-marketplace && npm run worker:restart`
## Environment Variables
@@ -182,37 +40,24 @@ When investigations fail persistently, use Task agents for comprehensive file an
- `CLAUDE_MEM_CONTEXT_OBSERVATIONS` - Observations injected at SessionStart (default: 50)
- `CLAUDE_MEM_WORKER_PORT` - Worker service port (default: 37777)
## Key Design Decisions
### Why PM2 Instead of Direct Process
Hooks have strict timeout limits. PM2 manages a persistent background worker, allowing AI processing to continue after hooks complete.
### Why SQLite FTS5
Enables instant full-text search across thousands of observations without external dependencies. Automatic sync triggers keep FTS5 tables synchronized.
### Why Graceful Cleanup
Changed from aggressive DELETE requests to marking sessions complete. Prevents interrupting summary generation and other async operations.
### Why Smart Install Caching
npm install is expensive (2-5s). Caching version state and only installing on changes makes SessionStart nearly instant (10ms).
### Why Web-Based Viewer UI
Real-time visibility into memory stream helps users understand what's being captured and how context is being built. SSE provides instant updates without polling. Self-contained HTML bundle (esbuild) eliminates deployment complexity - everything served from a single file.
## File Locations
**Source**: `<project-root>/src/` - TypeScript source files
**Built Plugin**: `<project-root>/plugin/` - Compiled JavaScript outputs
**Installed Plugin**: `~/.claude/plugins/marketplaces/thedotmack/` - User's installed plugin location
**Database**: `~/.claude-mem/claude-mem.db` - SQLite database with observations, sessions, summaries
**Chroma Database**: `~/.claude-mem/chroma/` - Vector embeddings for semantic search
**Usage Logs**: `~/.claude-mem/usage-logs/usage-YYYY-MM-DD.jsonl` - Daily API usage tracking
- **Source**: `<project-root>/src/`
- **Built Plugin**: `<project-root>/plugin/`
- **Installed Plugin**: `~/.claude/plugins/marketplaces/thedotmack/`
- **Database**: `~/.claude-mem/claude-mem.db`
- **Chroma**: `~/.claude-mem/chroma/`
- **Usage Logs**: `~/.claude-mem/usage-logs/usage-YYYY-MM-DD.jsonl`
## Quick Reference
**Build**: `npm run build`
**Sync**: `npm run sync-marketplace`
**Worker Restart**: `npm run worker:restart`
**Worker Logs**: `npm run worker:logs`
**Usage Analysis**: `npm run usage:today`
**Viewer UI**: http://localhost:37777 (auto-starts with worker)
```bash
npm run build # Compile TypeScript
npm run sync-marketplace # Copy to ~/.claude/plugins
npm run worker:restart # Restart PM2 worker
npm run worker:logs # View worker logs
pm2 list # Check worker status
pm2 delete claude-mem-worker # Force clean start
```
**Viewer UI**: http://localhost:37777
+7
View File
@@ -53,6 +53,13 @@
---
> **🚀 NEW: [AI Memory Economics - Full Analysis](https://thedotmack.craft.me/Zv7zBKybchfYre)**
> Solving AI's compute crisis: $73.5M annual savings for 300K users
> 83% token reduction | 4-day ROI | 9,092% first-year return
> *Published: November 20, 2025*
---
## Quick Start
Start a new Claude Code session in the terminal and enter the following commands:
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "6.1.0",
"version": "6.1.1",
"description": "Memory compression system for Claude Code - persist context across sessions",
"keywords": [
"claude",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "6.1.0",
"version": "6.1.1",
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
"author": {
"name": "Alex Newman"
File diff suppressed because one or more lines are too long
+7 -2
View File
@@ -289,17 +289,21 @@
box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica', 'Arial', sans-serif;
background: var(--color-bg-primary);
color: var(--color-text-primary);
font-size: 14px;
overflow: hidden;
}
.full-height-flex-layout {
display: flex;
height: 100%;
height: 100vh;
position: relative;
}
@@ -307,6 +311,7 @@
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.sidebar {
+2 -2
View File
@@ -17,13 +17,13 @@ import { basename } from 'path';
import { SessionSearch } from '../services/sqlite/SessionSearch.js';
import { SessionStore } from '../services/sqlite/SessionStore.js';
import { ObservationSearchResult, SessionSummarySearchResult, UserPromptSearchResult } from '../services/sqlite/types.js';
import { VECTOR_DB_DIR } from '../shared/paths.js';
import { VECTOR_DB_DIR, getCurrentProjectName } from '../shared/paths.js';
// Initialize search instances
let search: SessionSearch;
let store: SessionStore;
let chromaClient: Client | null = null;
const COLLECTION_NAME = 'cm__claude-mem';
const COLLECTION_NAME = `cm__${getCurrentProjectName()}`;
try {
search = new SessionSearch();
+4 -2
View File
@@ -12,6 +12,7 @@ import { SessionStore } from '../sqlite/SessionStore.js';
import { SessionSearch } from '../sqlite/SessionSearch.js';
import { ChromaSync } from '../sync/ChromaSync.js';
import { logger } from '../../utils/logger.js';
import { getCurrentProjectName } from '../../shared/paths.js';
import type { DBSession } from '../worker-types.js';
export class DatabaseManager {
@@ -27,8 +28,9 @@ export class DatabaseManager {
this.sessionStore = new SessionStore();
this.sessionSearch = new SessionSearch();
// Initialize ChromaSync
this.chromaSync = new ChromaSync('claude-mem');
// Initialize ChromaSync with actual project name
const projectName = getCurrentProjectName();
this.chromaSync = new ChromaSync(projectName);
// Start background backfill (fire-and-forget, with error logging)
this.chromaSync.ensureBackfilled().catch((error) => {
+7 -2
View File
@@ -289,17 +289,21 @@
box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica', 'Arial', sans-serif;
background: var(--color-bg-primary);
color: var(--color-text-primary);
font-size: 14px;
overflow: hidden;
}
.full-height-flex-layout {
display: flex;
height: 100%;
height: 100vh;
position: relative;
}
@@ -307,6 +311,7 @@
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.sidebar {