Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79bc3c85b3 | |||
| 6581d2ef45 | |||
| 39db5c4882 |
@@ -10,7 +10,7 @@
|
||||
"plugins": [
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "10.5.4",
|
||||
"version": "10.5.5",
|
||||
"source": "./plugin",
|
||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||
}
|
||||
|
||||
+6
-16
@@ -2,6 +2,12 @@
|
||||
|
||||
All notable changes to claude-mem.
|
||||
|
||||
## [v10.5.4] - 2026-03-09
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **fix: restore modes to correct location** — All modes (`code`, code language variants, `email-investigation`) were erroneously moved from `plugin/modes/` to `plugin/hooks/modes/` during the v10.5.3 release, breaking mode loading. This patch restores them to `plugin/modes/` where they belong.
|
||||
|
||||
## [v10.5.3] - 2026-03-09
|
||||
|
||||
## What's New
|
||||
@@ -1181,19 +1187,3 @@ Version 9.0.0 introduces the **Live Context System** - a major new capability th
|
||||
|
||||
See PR #558 for complete details and diagnostic reports.
|
||||
|
||||
## [v8.5.9] - 2026-01-04
|
||||
|
||||
## What's New
|
||||
|
||||
### Context Header Timestamp
|
||||
|
||||
The context injection header now displays the current date and time, making it easier to understand when context was generated.
|
||||
|
||||
**Example:** `[claude-mem] recent context, 2026-01-04 2:46am EST`
|
||||
|
||||
This appears in both terminal (colored) output and markdown format, including empty state messages.
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v8.5.8...v8.5.9
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "10.5.4",
|
||||
"version": "10.5.5",
|
||||
"description": "Memory compression system for Claude Code - persist context across sessions",
|
||||
"keywords": [
|
||||
"claude",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "10.5.4",
|
||||
"version": "10.5.5",
|
||||
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
|
||||
"author": {
|
||||
"name": "Alex Newman"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claude-mem-plugin",
|
||||
"version": "10.5.4",
|
||||
"version": "10.5.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
File diff suppressed because one or more lines are too long
+11
-11
File diff suppressed because one or more lines are too long
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Observation metadata constants
|
||||
* Shared across hooks, worker service, and UI components
|
||||
*
|
||||
* Note: These are fallback defaults for the code mode.
|
||||
* Actual observation types and concepts are defined per-mode in the modes/ directory.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default observation types (comma-separated string for settings)
|
||||
* Uses code mode defaults as fallback
|
||||
*/
|
||||
export const DEFAULT_OBSERVATION_TYPES_STRING = 'bugfix,feature,refactor,discovery,decision,change';
|
||||
|
||||
/**
|
||||
* Default observation concepts (comma-separated string for settings)
|
||||
* Uses code mode defaults as fallback
|
||||
*/
|
||||
export const DEFAULT_OBSERVATION_CONCEPTS_STRING = 'how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off';
|
||||
@@ -18,27 +18,10 @@ export 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));
|
||||
}
|
||||
// Always read types/concepts from the active mode definition
|
||||
const mode = ModeManager.getInstance().getActiveMode();
|
||||
const observationTypes = new Set(mode.observation_types.map(t => t.id));
|
||||
const observationConcepts = new Set(mode.observation_concepts.map(c => c.id));
|
||||
|
||||
return {
|
||||
totalObservationCount: parseInt(settings.CLAUDE_MEM_CONTEXT_OBSERVATIONS, 10),
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { DEFAULT_OBSERVATION_TYPES_STRING, DEFAULT_OBSERVATION_CONCEPTS_STRING } from '../constants/observation-metadata.js';
|
||||
// NOTE: Do NOT import logger here - it creates a circular dependency
|
||||
// logger.ts depends on SettingsDefaultsManager for its initialization
|
||||
|
||||
@@ -41,9 +40,6 @@ export interface SettingsDefaults {
|
||||
CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS: string;
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: string;
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT: string;
|
||||
// Observation Filtering
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES: string;
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS: string;
|
||||
// Display Configuration
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT: string;
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD: string;
|
||||
@@ -103,9 +99,6 @@ export class SettingsDefaultsManager {
|
||||
CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS: 'false',
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: 'false',
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT: 'true',
|
||||
// Observation Filtering
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES: DEFAULT_OBSERVATION_TYPES_STRING,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS: DEFAULT_OBSERVATION_CONCEPTS_STRING,
|
||||
// Display Configuration
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT: '0',
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD: 'narrative',
|
||||
|
||||
@@ -54,62 +54,6 @@ function CollapsibleSection({
|
||||
);
|
||||
}
|
||||
|
||||
// Chip group with select all/none
|
||||
function ChipGroup({
|
||||
label,
|
||||
options,
|
||||
selectedValues,
|
||||
onToggle,
|
||||
onSelectAll,
|
||||
onSelectNone
|
||||
}: {
|
||||
label: string;
|
||||
options: string[];
|
||||
selectedValues: string[];
|
||||
onToggle: (value: string) => void;
|
||||
onSelectAll: () => void;
|
||||
onSelectNone: () => void;
|
||||
}) {
|
||||
const allSelected = options.every(opt => selectedValues.includes(opt));
|
||||
const noneSelected = options.every(opt => !selectedValues.includes(opt));
|
||||
|
||||
return (
|
||||
<div className="chip-group">
|
||||
<div className="chip-group-header">
|
||||
<span className="chip-group-label">{label}</span>
|
||||
<div className="chip-group-actions">
|
||||
<button
|
||||
type="button"
|
||||
className={`chip-action ${allSelected ? 'active' : ''}`}
|
||||
onClick={onSelectAll}
|
||||
>
|
||||
All
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`chip-action ${noneSelected ? 'active' : ''}`}
|
||||
onClick={onSelectNone}
|
||||
>
|
||||
None
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="chips-container">
|
||||
{options.map(option => (
|
||||
<button
|
||||
key={option}
|
||||
type="button"
|
||||
className={`chip ${selectedValues.includes(option) ? 'selected' : ''}`}
|
||||
onClick={() => onToggle(option)}
|
||||
>
|
||||
{option}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Form field with optional tooltip
|
||||
function FormField({
|
||||
label,
|
||||
@@ -209,24 +153,6 @@ export function ContextSettingsModal({
|
||||
updateSetting(key, newValue);
|
||||
}, [formState, updateSetting]);
|
||||
|
||||
const toggleArrayValue = useCallback((key: keyof Settings, value: string) => {
|
||||
const currentValue = formState[key] || '';
|
||||
const currentArray = currentValue ? currentValue.split(',') : [];
|
||||
const newArray = currentArray.includes(value)
|
||||
? currentArray.filter(v => v !== value)
|
||||
: [...currentArray, value];
|
||||
updateSetting(key, newArray.join(','));
|
||||
}, [formState, updateSetting]);
|
||||
|
||||
const getArrayValues = useCallback((key: keyof Settings): string[] => {
|
||||
const currentValue = formState[key] || '';
|
||||
return currentValue ? currentValue.split(',') : [];
|
||||
}, [formState]);
|
||||
|
||||
const setAllArrayValues = useCallback((key: keyof Settings, values: string[]) => {
|
||||
updateSetting(key, values.join(','));
|
||||
}, [updateSetting]);
|
||||
|
||||
// Handle ESC key
|
||||
useEffect(() => {
|
||||
const handleEsc = (e: KeyboardEvent) => {
|
||||
@@ -240,9 +166,6 @@ export function ContextSettingsModal({
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
const observationTypes = ['bugfix', 'feature', 'refactor', 'discovery', 'decision', 'change'];
|
||||
const observationConcepts = ['how-it-works', 'why-it-exists', 'what-changed', 'problem-solution', 'gotcha', 'pattern', 'trade-off'];
|
||||
|
||||
return (
|
||||
<div className="modal-backdrop" onClick={onClose}>
|
||||
<div className="context-settings-modal" onClick={(e) => e.stopPropagation()}>
|
||||
@@ -322,30 +245,7 @@ export function ContextSettingsModal({
|
||||
</FormField>
|
||||
</CollapsibleSection>
|
||||
|
||||
{/* Section 2: Filters */}
|
||||
<CollapsibleSection
|
||||
title="Filters"
|
||||
description="Which observation types to include"
|
||||
>
|
||||
<ChipGroup
|
||||
label="Type"
|
||||
options={observationTypes}
|
||||
selectedValues={getArrayValues('CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES')}
|
||||
onToggle={(value) => toggleArrayValue('CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES', value)}
|
||||
onSelectAll={() => setAllArrayValues('CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES', observationTypes)}
|
||||
onSelectNone={() => setAllArrayValues('CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES', [])}
|
||||
/>
|
||||
<ChipGroup
|
||||
label="Concept"
|
||||
options={observationConcepts}
|
||||
selectedValues={getArrayValues('CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS')}
|
||||
onToggle={(value) => toggleArrayValue('CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS', value)}
|
||||
onSelectAll={() => setAllArrayValues('CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS', observationConcepts)}
|
||||
onSelectNone={() => setAllArrayValues('CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS', [])}
|
||||
/>
|
||||
</CollapsibleSection>
|
||||
|
||||
{/* Section 3: Display */}
|
||||
{/* Section 2: Display */}
|
||||
<CollapsibleSection
|
||||
title="Display"
|
||||
description="What to show in context tables"
|
||||
|
||||
@@ -24,10 +24,6 @@ export const DEFAULT_SETTINGS = {
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: 'true',
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT: 'true',
|
||||
|
||||
// Observation Filtering (all types and concepts)
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES: 'bugfix,feature,refactor,discovery,decision,change',
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS: 'how-it-works,why-it-exists,what-changed,problem-solution,gotcha,pattern,trade-off',
|
||||
|
||||
// Display Configuration
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT: '5',
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD: 'narrative',
|
||||
|
||||
@@ -38,10 +38,6 @@ export function useSettings() {
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: data.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT,
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT: data.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT,
|
||||
|
||||
// Observation Filtering
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES: data.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES,
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS: data.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS,
|
||||
|
||||
// Display Configuration
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT: data.CLAUDE_MEM_CONTEXT_FULL_COUNT || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_FULL_COUNT,
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD: data.CLAUDE_MEM_CONTEXT_FULL_FIELD || DEFAULT_SETTINGS.CLAUDE_MEM_CONTEXT_FULL_FIELD,
|
||||
|
||||
@@ -76,10 +76,6 @@ export interface Settings {
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT?: string;
|
||||
CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT?: string;
|
||||
|
||||
// Observation Filtering
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES?: string;
|
||||
CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS?: string;
|
||||
|
||||
// Display Configuration
|
||||
CLAUDE_MEM_CONTEXT_FULL_COUNT?: string;
|
||||
CLAUDE_MEM_CONTEXT_FULL_FIELD?: string;
|
||||
|
||||
Reference in New Issue
Block a user