Compare commits

..

16 Commits

Author SHA1 Message Date
Alex Newman b7d43e3247 chore: bump version to 8.0.5
Patch release for context loading bugfix

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 20:08:16 -05:00
Alex Newman e32f2d7b6c Refactor context loading logic to differentiate between code and non-code modes; add new ragtime script for processing markdown files with Claude agent 2025-12-23 20:06:29 -05:00
Alex Newman 65e3047df8 feat: add worker control scripts for start, stop, restart, and status 2025-12-23 16:54:19 -05:00
Alex Newman cc5a9ace6f chore: update mem-search plugin zip file 2025-12-23 16:53:04 -05:00
Alex Newman 20801f3a31 chore: bump version to 8.0.4
Changed worker start script

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 16:52:39 -05:00
Alex Newman 6033498adf fix: correct JSON structure in marketplace.json for plugin definition 2025-12-23 16:43:44 -05:00
Alex Newman f9bd5fd032 chore: update version to 8.0.3 in package.json 2025-12-23 16:38:30 -05:00
Alex Newman a60a8974b6 docs: update changelog for v8.0.3 2025-12-23 16:31:42 -05:00
Alex Newman 2137407663 chore: bump version to 8.0.3 2025-12-23 16:30:48 -05:00
Alex Newman cd2ed80d74 Update mem-search plugin with new features and improvements 2025-12-23 16:29:45 -05:00
Alex Newman fdd8411dea fix: resolve critical worker crashes on startup (v8.0.2 regression)
Fixes #417, #418, #421, #422, #425

1. Handle Chroma sync errors gracefully in DatabaseManager to prevent unhandled promise rejections.

2. Safely handle missing 'claude' executable in SDKAgent with try-catch block around auto-detection.
2025-12-23 16:27:58 -05:00
Alex Newman f491b61f4f chore: update CHANGELOG.md for v8.0.2
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 22:07:02 -05:00
Alex Newman bb30b82102 chore: bump version to 8.0.2
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 22:04:38 -05:00
Alex Newman fefd3c2b29 feat: add Code Development (Chill) mode with selective recording prompts 2025-12-22 22:02:46 -05:00
Alex Newman ff0bc407f3 chore: update CHANGELOG.md for v8.0.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 21:44:02 -05:00
Alex Newman 1cd0b5341f refactor: improve header layout and remove Product Hunt badge
- Move documentation and X (Twitter) links from settings modal to header
- Remove Product Hunt badge from header
- Reorder header icons for better UX (docs, X, Discord, GitHub)
- Clean up settings modal header controls

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 21:42:06 -05:00
17 changed files with 270 additions and 142 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
"plugins": [
{
"name": "claude-mem",
"version": "8.0.1",
"version": "8.0.5",
"source": "./plugin",
"description": "Persistent memory system for Claude Code - context compression across sessions"
}
+37
View File
@@ -4,6 +4,43 @@ 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/).
## [8.0.3] - 2025-12-23
Fix critical worker crashes on startup (v8.0.2 regression)
## [8.0.2] - 2025-12-23
New "chill" remix of code mode for users who want fewer, more selective observations.
## Features
- **code--chill mode**: A behavioral variant that produces fewer observations
- Only records things "painful to rediscover" - shipped features, architectural decisions, non-obvious gotchas
- Skips routine work, straightforward implementations, and obvious changes
- Philosophy: "When in doubt, skip it"
## Documentation
- Updated modes.mdx with all 28 language modes (was 10)
- Added Code Mode Variants section documenting chill mode
## Usage
Set in ~/.claude-mem/settings.json:
```json
{
"CLAUDE_MEM_MODE": "code--chill"
}
```
## [8.0.1] - 2025-12-23
## 🎨 UI Improvements
- **Header Redesign**: Moved documentation and X (Twitter) links from settings modal to main header for better accessibility
- **Removed Product Hunt Badge**: Cleaned up header layout by removing the Product Hunt badge
- **Icon Reorganization**: Reordered header icons for improved UX flow (Docs → X → Discord → GitHub)
## [8.0.0] - 2025-12-23
## 🌍 Major Features
+29 -3
View File
@@ -38,20 +38,46 @@ The standard mode for software development. Captures bug fixes, features, refact
**ID:** `code`
### Code Mode Variants
Behavioral variants that change how the code mode operates:
| Variant | Mode ID | Description |
|---------|---------|-------------|
| **Chill** | `code--chill` | Produces fewer observations. Only records things "painful to rediscover" - shipped features, architectural decisions, and non-obvious gotchas. Skips routine work and obvious changes. |
### Multilingual Code Modes
Inherits all behavior from Code Mode but instructs Claude to generate **all** memory artifacts (titles, narratives, facts, summaries) in the target language.
| Language | Mode ID | Description |
| Language | Mode ID | Native Name |
|----------|---------|-------------|
| **Arabic** | `code--ar` | العربية |
| **Bengali** | `code--bn` | বাংলা |
| **Chinese** | `code--zh` | 中文 |
| **Spanish** | `code--es` | Español |
| **Czech** | `code--cs` | Čeština |
| **Danish** | `code--da` | Dansk |
| **Dutch** | `code--nl` | Nederlands |
| **Finnish** | `code--fi` | Suomi |
| **French** | `code--fr` | Français |
| **German** | `code--de` | Deutsch |
| **Greek** | `code--el` | Ελληνικά |
| **Hebrew** | `code--he` | עברית |
| **Hindi** | `code--hi` | हिन्दी |
| **Hungarian** | `code--hu` | Magyar |
| **Indonesian** | `code--id` | Bahasa Indonesia |
| **Italian** | `code--it` | Italiano |
| **Japanese** | `code--ja` | 日本語 |
| **Korean** | `code--ko` | 한국어 |
| **Portuguese** | `code--pt` | Português |
| **Norwegian** | `code--no` | Norsk |
| **Polish** | `code--pl` | Polski |
| **Portuguese (Brazil)** | `code--pt-br` | Português Brasileiro |
| **Romanian** | `code--ro` | Română |
| **Russian** | `code--ru` | Русский |
| **Spanish** | `code--es` | Español |
| **Swedish** | `code--sv` | Svenska |
| **Thai** | `code--th` | ภาษาไทย |
| **Turkish** | `code--tr` | Türkçe |
| **Ukrainian** | `code--uk` | Українська |
| **Vietnamese** | `code--vi` | Tiếng Việt |
### Email Investigation Mode
+6 -5
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "8.0.1",
"version": "8.0.5",
"description": "Memory compression system for Claude Code - persist context across sessions",
"keywords": [
"claude",
@@ -36,13 +36,14 @@
"sync-marketplace": "node scripts/sync-marketplace.cjs",
"sync-marketplace:force": "node scripts/sync-marketplace.cjs --force",
"build:binaries": "node scripts/build-worker-binary.js",
"worker:start": "claude-mem start",
"worker:stop": "claude-mem stop",
"worker:restart": "claude-mem restart",
"worker:status": "claude-mem status",
"worker:logs": "tail -n 50 ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log",
"worker:tail": "tail -f 50 ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log",
"changelog:generate": "node scripts/generate-changelog.js",
"discord:notify": "node scripts/discord-release-notify.js",
"worker:start": "bun plugin/scripts/worker-cli.js start",
"worker:stop": "bun plugin/scripts/worker-cli.js stop",
"worker:restart": "bun plugin/scripts/worker-cli.js restart",
"worker:status": "bun plugin/scripts/worker-cli.js status",
"translate-readme": "bun scripts/translate-readme/cli.ts -v -o docs/i18n README.md",
"translate:tier1": "npm run translate-readme -- zh ja pt-br ko es de fr",
"translate:tier2": "npm run translate-readme -- he ar ru pl cs nl tr uk",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem",
"version": "8.0.1",
"version": "8.0.5",
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
"author": {
"name": "Alex Newman"
+8
View File
@@ -0,0 +1,8 @@
{
"name": "Code Development (Chill)",
"prompts": {
"recording_focus": "WHAT TO RECORD (SELECTIVE MODE)\n--------------------------------\nOnly record work that would be painful to rediscover:\n- Features that shipped or bugs that got fixed\n- Architectural decisions and their rationale\n- Non-obvious gotchas you'd regret forgetting\n- Significant refactors that change how code is organized\n\nSkip the obvious stuff:\n- Incremental steps toward a goal (just record the final result)\n- Straightforward implementations that follow established patterns\n- Changes that are clear from reading the code or git history\n\nUse verbs like: implemented, fixed, deployed, decided, discovered, restructured\n\n✅ GOOD (would be painful to rediscover):\n- \"Auth tokens now expire after 24h - security requirement from compliance\"\n- \"Moved from REST to GraphQL for the dashboard - 3x faster load times\"\n- \"SQLite locks under concurrent writes - switched to WAL mode\"\n\n❌ SKIP (obvious from code/git):\n- \"Added error handling to the API endpoint\"\n- \"Created a new component for the form\"\n- \"Updated dependencies to latest versions\"",
"skip_guidance": "WHEN TO SKIP (BE LIBERAL)\n-------------------------\nSkip routine operations:\n- Empty status checks\n- Package installations\n- Simple file listings\n- Repetitive operations already documented\n- File research that comes back empty\n\nSkip obvious work:\n- Straightforward implementations following existing patterns\n- Minor refactors (rename, extract, inline)\n- Incremental progress toward a larger goal\n- Changes that are self-explanatory from the code\n- Routine config/dependency updates\n- Exploratory code reading without significant findings\n\n**When in doubt, skip it.** Less is more. Only record what you'd be frustrated to figure out again."
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mem-plugin",
"version": "8.0.0",
"version": "8.0.5",
"private": true,
"description": "Runtime dependencies for claude-mem bundled hooks",
"type": "module",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
+39
View File
@@ -0,0 +1,39 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
import * as fs from "fs";
import * as path from "path";
const pathToFolder = "/Users/alexnewman/Scripts/claude-mem/datasets/emails-markdown/";
const pathToPlugin = "/Users/alexnewman/Scripts/claude-mem/plugin/";
// Or read from a directory
const filesToProcess = fs
.readdirSync(pathToFolder)
.filter((f) => f.endsWith(".md"))
.map((f) => path.join(pathToFolder, f));
var i = 0;
for (const file of filesToProcess) {
i++;
// Limit for testing
if (i > 3) break;
console.log(`\n=== Processing ${file} ===\n`);
for await (const message of query({
prompt: `Read ${file} and think about how it relates to the injected context above (if any).`,
options: {
cwd: pathToFolder,
plugins: [{ type: "local", path: pathToPlugin }],
},
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Plugins:", message.plugins);
console.log("Commands:", message.slash_commands);
}
if (message.type === "assistant") {
console.log("Assistant:", message.message.content);
}
}
}
+24 -6
View File
@@ -55,6 +55,28 @@ function loadContextConfig(): ContextConfig {
const settingsPath = path.join(homedir(), '.claude-mem', 'settings.json');
const settings = SettingsDefaultsManager.loadFromFile(settingsPath);
// For non-code modes, use all types/concepts from active mode instead of settings
const modeId = settings.CLAUDE_MEM_MODE;
const isCodeMode = modeId === 'code' || modeId.startsWith('code--');
let observationTypes: Set<string>;
let observationConcepts: Set<string>;
if (isCodeMode) {
// Code mode: use settings-based filtering
observationTypes = new Set(
settings.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES.split(',').map((t: string) => t.trim()).filter(Boolean)
);
observationConcepts = new Set(
settings.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS.split(',').map((c: string) => c.trim()).filter(Boolean)
);
} else {
// Non-code modes: use all types/concepts from active mode
const mode = ModeManager.getInstance().getActiveMode();
observationTypes = new Set(mode.observation_types.map(t => t.id));
observationConcepts = new Set(mode.observation_concepts.map(c => c.id));
}
return {
totalObservationCount: parseInt(settings.CLAUDE_MEM_CONTEXT_OBSERVATIONS, 10),
fullObservationCount: parseInt(settings.CLAUDE_MEM_CONTEXT_FULL_COUNT, 10),
@@ -63,12 +85,8 @@ function loadContextConfig(): ContextConfig {
showWorkTokens: settings.CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS === 'true',
showSavingsAmount: settings.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT === 'true',
showSavingsPercent: settings.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT === 'true',
observationTypes: new Set(
settings.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES.split(',').map((t: string) => t.trim()).filter(Boolean)
),
observationConcepts: new Set(
settings.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS.split(',').map((c: string) => c.trim()).filter(Boolean)
),
observationTypes,
observationConcepts,
fullObservationField: settings.CLAUDE_MEM_CONTEXT_FULL_FIELD as 'narrative' | 'facts',
showLastSummary: settings.CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY === 'true',
showLastMessage: settings.CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE === 'true',
+3 -1
View File
@@ -31,7 +31,9 @@ export class DatabaseManager {
this.chromaSync = new ChromaSync('claude-mem');
// Start background backfill (fire-and-forget)
this.chromaSync.ensureBackfilled();
this.chromaSync.ensureBackfilled().catch(error => {
logger.error('DB', 'Chroma backfill failed (non-fatal)', {}, error);
});
logger.info('DB', 'Database initialized');
}
+22 -7
View File
@@ -435,15 +435,30 @@ export class SDKAgent {
*/
private findClaudeExecutable(): string {
const settings = SettingsDefaultsManager.loadFromFile(USER_SETTINGS_PATH);
const claudePath = settings.CLAUDE_CODE_PATH ||
execSync(process.platform === 'win32' ? 'where claude' : 'which claude', { encoding: 'utf8', windowsHide: true })
.trim().split('\n')[0].trim();
if (!claudePath) {
throw new Error('Claude executable not found in PATH');
// 1. Check configured path
if (settings.CLAUDE_CODE_PATH) {
// Lazy load fs to keep startup fast
const { existsSync } = require('fs');
if (!existsSync(settings.CLAUDE_CODE_PATH)) {
throw new Error(`CLAUDE_CODE_PATH is set to "${settings.CLAUDE_CODE_PATH}" but the file does not exist.`);
}
return settings.CLAUDE_CODE_PATH;
}
return claudePath;
// 2. Try auto-detection
try {
const claudePath = execSync(
process.platform === 'win32' ? 'where claude' : 'which claude',
{ encoding: 'utf8', windowsHide: true, stdio: ['ignore', 'pipe', 'ignore'] }
).trim().split('\n')[0].trim();
if (claudePath) return claudePath;
} catch (error) {
logger.debug('SDK', 'Claude executable auto-detection failed', error);
}
throw new Error('Claude executable not found. Please either:\n1. Add "claude" to your system PATH, or\n2. Set CLAUDE_CODE_PATH in ~/.claude-mem/settings.json');
}
/**
@@ -264,29 +264,6 @@ export function ContextSettingsModal({
<div className="modal-header">
<h2>Settings</h2>
<div className="header-controls">
<a
href="https://docs.claude-mem.ai"
target="_blank"
rel="noopener noreferrer"
title="Documentation"
className="modal-icon-link"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path>
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path>
</svg>
</a>
<a
href="https://x.com/Claude_Memory"
target="_blank"
rel="noopener noreferrer"
title="X (Twitter)"
className="modal-icon-link"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
</a>
<label className="preview-selector">
Preview for:
<select
+19 -16
View File
@@ -26,12 +26,6 @@ export function Header({
onThemeChange,
onContextPreviewToggle
}: HeaderProps) {
// Resolve effective theme for Product Hunt badge
const isDark = themePreference === 'dark' ||
(themePreference === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
const phBadgeTheme = isDark ? 'dark' : 'light';
const phBadgeUrl = `https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1045833&theme=${phBadgeTheme}`;
return (
<div className="header">
<h1>
@@ -47,20 +41,28 @@ export function Header({
</h1>
<div className="status">
<a
href="https://www.producthunt.com/products/claude-mem?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-claude-mem"
href="https://docs.claude-mem.ai"
target="_blank"
rel="noopener noreferrer"
style={{ display: 'flex', alignItems: 'center' }}
className="icon-link"
title="Documentation"
>
<img
src={phBadgeUrl}
alt="Claude-Mem on Product Hunt"
style={{ width: '180px', height: '40px' }}
width="180"
height="40"
/>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path>
<path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path>
</svg>
</a>
<a
href="https://x.com/Claude_Memory"
target="_blank"
rel="noopener noreferrer"
className="icon-link"
title="Follow us on X"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
</a>
<GitHubStarsButton username="thedotmack" repo="claude-mem" />
<a
href="https://discord.gg/J4wttp9vDu"
target="_blank"
@@ -72,6 +74,7 @@ export function Header({
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z"/>
</svg>
</a>
<GitHubStarsButton username="thedotmack" repo="claude-mem" />
<select
value={currentFilter}
onChange={e => onFilterChange(e.target.value)}